<commit_before>import * as sinon from 'sinon';
import { assert } from 'chai';
import os from 'os';
import fs from 'fs';
import stream from 'stream';
import RED from 'node-red';
import Promise from 'es6-promises';
import { DeviceIdResolver, DeviceState, DeviceManager, DeviceManagerStore } from '../../dist/device-manager';

const PROC_CPUINFO = [
	'processor	: 0\n',
	'model name	: ARMv6-compatible processor rev 7 (v6l)\n',
	'BogoMIPS	: 2.00\n',
	'Features	: half thumb fastmult vfp edsp java tls \n',
	'CPU implementer	: 0x41\n',
	'CPU architecture: 7\n',
	'CPU variant	: 0x0\n',
	'CPU part	: 0xb76\n',
	'CPU revision	: 7\n',
	'Hardware	: BCM2708\n',
	'Revision	: 0010\n',
	'Serial		: 00000000ffff9999\n',
	null
];

let server = sinon.spy();
let settings = sinon.spy();
RED.init(server, settings);

describe('DeviceIdResolver', () => {
	let sandbox;
	beforeEach(() => {
		sandbox = sinon.sandbox.create();
	});
	afterEach(() => {
		sandbox = sandbox.restore();
	});

  it('should resolve the unique device identifier', done => {
    let resolver = new DeviceIdResolver();
    resolver.resolve().then(id => {
      console.log(`id = [${id}]`);
      assert.isDefined(id);
      assert.isNotNull(id);
      done();
    }).catch(err => {
      done(err);
    });
  });

  it('should return the serial number', done => {
    let resolver = new DeviceIdResolver();
		sandbox.stub(fs, 'stat').yields();
		sandbox.stub(fs, 'read').yields(null, 'my-serial-number');
    resolver.resolve().then(id => {
			assert.equal('EDN:my-serial-number', id);
      done();
    }).catch(err => {
      done(err);
    });
  });

  it('should return the cpuinfo serial', done => {
    let resolver = new DeviceIdResolver();
		sandbox.stub(fs, 'stat').onFirstCall().yields(new Error()).onSecondCall().yields();
		let i = 0;
		let readStream = new stream.Readable();
		readStream._read = () => {
			readStream.push(PROC_CPUINFO[i++]);
		};
		sandbox.stub(fs, 'createReadStream').onFirstCall().returns(readStream);
    resolver.resolve().then(id => {
			assert.equal('RPi:00000000ffff9999', id);
      done();
    }).catch(err => {
      done(err);
    });
  });

  it('should return the MAC address', done => {
    let resolver = new DeviceIdResolver();
		sandbox.stub(fs, 'stat').onFirstCall().yields(new Error())
			.onSecondCall().yields(new Error())
			.onThirdCall().yields();
		sandbox.stub(os, 'networkInterfaces').returns({
			'en0' : [
				{ mac: '00:00:00:00:00:00' },
				{ mac: 'AA:bb:cc:dd:ee:FF' },
			]
		});
    resolver.resolve().then(id => {
			assert.equal('MAC:en0:aa-bb-cc-dd-ee-ff', id);
      done();
    }).catch(err => {
      done(err);
    });
  });
});

describe('DeviceState', () => {
	let sandbox;
	beforeEach(() => {
		sandbox = sinon.sandbox.create();
	});
	afterEach(() => {
		sandbox = sandbox.restore();
	});

  it('should return whether or not CANDY IoT board is installed', done => {
    let state = new DeviceState(() => {}, () => {});
    state.testIfCANDYIoTInstalled().then(version => {
      console.log(`installed version? => ${version}`);
      done();
    }).catch(err => {
      done(err);
    });
  });
  describe('#testIfUIisEnabled()', () => {
    it('should tell the UI is enabled', done => {
      let state = new DeviceState(() => {}, () => {});
      state.testIfUIisEnabled(__dirname + '/test-flow-enabled.json').then(enabled => {
        assert.isTrue(enabled);
        done();
      }).catch(err => {
        done(err);
      });
    });
    it('should tell the UI is DISABLED', done => {
      let state = new DeviceState(() => {}, () => {});
      state.testIfUIisEnabled(__dirname + '/test-flow-disabled.json').then(enabled => {
        assert.isFalse(enabled);
        done();
      }).catch(err => {
        done(err);
      });
    });
  });
});

describe('DeviceManagerStore', () => {
	let sandbox, store;
	beforeEach(() => {
		sandbox = sinon.sandbox.create();
		store = new DeviceManagerStore();
	});
	afterEach(() => {
		sandbox = sandbox.restore();
	});

	describe('#_onFlowFileChangedFunc()', () => {
	  it('should do nothing unless the flow file is modified', done => {
			let promise = sandbox.stub(new Promise());
			promise.then.yields(false); // modified = false
			sandbox.stub(store.deviceState, 'loadAndSetFlowSignature').returns(promise);
			store.deviceState.onFlowFileChanged().then(() => {
				done();<commit_msg>Add a new test case for DeviceState class<commit_after>import * as sinon from 'sinon';
import { assert } from 'chai';
import os from 'os';
import fs from 'fs';
import stream from 'stream';
import cproc from 'child_process';
import RED from 'node-red';
import Promise from 'es6-promises';
import { DeviceIdResolver, DeviceState, DeviceManager, DeviceManagerStore } from '../../dist/device-manager';

const PROC_CPUINFO = [
	'processor	: 0\n',
	'model name	: ARMv6-compatible processor rev 7 (v6l)\n',
	'BogoMIPS	: 2.00\n',
	'Features	: half thumb fastmult vfp edsp java tls \n',
	'CPU implementer	: 0x41\n',
	'CPU architecture: 7\n',
	'CPU variant	: 0x0\n',
	'CPU part	: 0xb76\n',
	'CPU revision	: 7\n',
	'Hardware	: BCM2708\n',
	'Revision	: 0010\n',
	'Serial		: 00000000ffff9999\n',
	null
];

let server = sinon.spy();
let settings = sinon.spy();
RED.init(server, settings);

describe('DeviceIdResolver', () => {
	let sandbox;
	beforeEach(() => {
		sandbox = sinon.sandbox.create();
	});
	afterEach(() => {
		sandbox = sandbox.restore();
	});

  it('should resolve the unique device identifier', done => {
    let resolver = new DeviceIdResolver();
    resolver.resolve().then(id => {
      console.log(`id = [${id}]`);
      assert.isDefined(id);
      assert.isNotNull(id);
      done();
    }).catch(err => {
      done(err);
    });
  });

  it('should return the serial number', done => {
    let resolver = new DeviceIdResolver();
		sandbox.stub(fs, 'stat').yields();
		sandbox.stub(fs, 'read').yields(null, 'my-serial-number');
    resolver.resolve().then(id => {
			assert.equal('EDN:my-serial-number', id);
      done();
    }).catch(err => {
      done(err);
    });
  });

  it('should return the cpuinfo serial', done => {
    let resolver = new DeviceIdResolver();
		sandbox.stub(fs, 'stat').onFirstCall().yields(new Error()).onSecondCall().yields();
		let i = 0;
		let readStream = new stream.Readable();
		readStream._read = () => {
			readStream.push(PROC_CPUINFO[i++]);
		};
		sandbox.stub(fs, 'createReadStream').onFirstCall().returns(readStream);
    resolver.resolve().then(id => {
			assert.equal('RPi:00000000ffff9999', id);
      done();
    }).catch(err => {
      done(err);
    });
  });

  it('should return the MAC address', done => {
    let resolver = new DeviceIdResolver();
		sandbox.stub(fs, 'stat').onFirstCall().yields(new Error())
			.onSecondCall().yields(new Error())
			.onThirdCall().yields();
		sandbox.stub(os, 'networkInterfaces').returns({
			'en0' : [
				{ mac: '00:00:00:00:00:00' },
				{ mac: 'AA:bb:cc:dd:ee:FF' },
			]
		});
    resolver.resolve().then(id => {
			assert.equal('MAC:en0:aa-bb-cc-dd-ee-ff', id);
      done();
    }).catch(err => {
      done(err);
    });
  });
});

describe('DeviceState', () => {
	let sandbox;
	let state;
	beforeEach(() => {
    state = new DeviceState(() => {}, () => {});
		sandbox = sinon.sandbox.create();
	});
	afterEach(() => {
		sandbox = sandbox.restore();
	});

  describe('#testIfUIisEnabled()', () => {
	  it('should return whether or not CANDY IoT board is installed', done => {
	    state.testIfCANDYIoTInstalled().then(version => {
	      console.log(`installed version? => [${version}]`);
	      done();
	    }).catch(err => {
	      done(err);
	    });
	  });

	  it('should return the installed CANDY IoT Board version', done => {
			let stubCproc = sandbox.stub(cproc);
			let which = sandbox.stub({
				on: () => {}
			});
			which.on.onFirstCall().yields(0);
			stubCproc.spawn.onFirstCall().returns(which);

			let stdout = sandbox.stub({
				on: () => {}
			});
			stdout.on.onFirstCall().yields(JSON.stringify({
				version: '1234'
			}));
			let ciot = sandbox.stub({
				stdout: stdout,
				on: () => {}
			});
			stubCproc.spawn.onSecondCall().returns(ciot);

	    state.testIfCANDYIoTInstalled().then(version => {
	      assert.equal('1234', version);
	      done();
	    }).catch(err => {
	      done(err);
	    });
	  });
	});

  describe('#testIfUIisEnabled()', () => {
    it('should tell the UI is enabled', done => {
      state.testIfUIisEnabled(__dirname + '/test-flow-enabled.json').then(enabled => {
        assert.isTrue(enabled);
        done();
      }).catch(err => {
        done(err);
      });
    });
    it('should tell the UI is DISABLED', done => {
      state.testIfUIisEnabled(__dirname + '/test-flow-disabled.json').then(enabled => {
        assert.isFalse(enabled);
        done();
      }).catch(err => {
        done(err);
      });
    });
  });
});

describe('DeviceManagerStore', () => {
	let sandbox, store;
	beforeEach(() => {
		sandbox = sinon.sandbox.create();
		store = new DeviceManagerStore();
	});
	afterEach(() => {
		sandbox = sandbox.restore();
	});

	describe('#_onFlowFileChangedFunc()', () => {
	  it('should do nothing unless the flow file is modified', done => {
			let promise = sandbox.stub(new Promise());
			promise.then.yields(false); // modified = false
			sandbox.stub(store.deviceState, 'loadAndSetFlowSignature').returns(promise);
			store.deviceState.onFlowFileChanged().then(() => {
				done();
{'fraction_non_alphanumeric': 0.19724430312665606, 'fraction_numerical': 0.014732379438261792, 'mean_word_length': 3.2813067150635207, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 90, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3205874', 'n_tokens_mistral': 3528, 'n_tokens_neox': 3215, 'n_words': 636}