UNPKG

zigbee-bridge

Version:

An open source ZigBee gateway solution with node.js.

459 lines (427 loc) 17.9 kB
const expect = require('chai').expect; const zcl = require('../lib/components/zcl'); describe('APIs Arguments Check for Throwing Error', function() { describe('#.frame', function() { let frameCntl = {frameType: 1, manufSpec: 0, direction: 0, disDefaultRsp: 1}; it('should be a function', function() { expect(zcl.frame).to.be.a('function'); }); it('should throw TypeError if input frameCntl is not an object', function() { expect(function() { return zcl.frame(undefined, 0, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(null, 0, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(NaN, 0, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame([], 0, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(true, 0, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(new Date(), 0, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(function() {}, 0, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, 'genOnOff'); }).not.to.throw(TypeError); }); it('should throw TypeError if input manufCode is not a number', function() { expect(function() { return zcl.frame(frameCntl, undefined, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, null, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, NaN, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, [], 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, true, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, new Date(), 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, function() {}, 0, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); }); it('should throw TypeError if input seqNum is not a number', function() { expect(function() { return zcl.frame(frameCntl, 0, undefined, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, null, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, NaN, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, [], 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, true, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, new Date(), 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, function() {}, 'toggle', {}, 'genOnOff'); }).to.throw(TypeError); }); it('should throw TypeError if input cmd is not a number and not a string', function() { expect(function() { return zcl.frame(frameCntl, 0, 0, undefined, {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, null, {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, NaN, {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, [], {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, true, {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, new Date(), {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, function() {}, {}, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, 'genOnOff'); }).not.to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 2, {}, 'genOnOff'); }).not.to.throw(TypeError); }); it('should throw TypeError if input zclPayload is not an object and not an array', function() { expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', undefined, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', null, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', NaN, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', true, 'genOnOff'); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, 'genOnOff'); }).not.to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', [], 'genOnOff'); }).not.to.throw(TypeError); }); it('should throw TypeError if input clusterId is not a number and not a string', function() { expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, undefined); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, null); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, NaN); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, []); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, true); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, new Date()); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, function() {}); }).to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, 'genOnOff'); }).not.to.throw(TypeError); expect(function() { return zcl.frame(frameCntl, 0, 0, 'toggle', {}, 6); }).not.to.throw(TypeError); }); }); describe('#.parse', function() { let zclBuf = new Buffer([0x11, 0x00, 0x02]); const rethrow = (err) => { if (err) throw err; }; it('should be a function', function() { expect(zcl.parse).to.be.a('function'); }); it('should throw TypeError if input zclBuf is not a buffer', function() { expect(function() { return zcl.parse(undefined, 0, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(null, 0, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(NaN, 0, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse([], 0, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(true, 0, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(new Date(), 0, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(function() {}, 0, rethrow); }).to.throw(TypeError); }); it('should throw TypeError if input clusterId is not a number and not a string', function() { expect(function() { return zcl.parse(zclBuf, undefined, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, null, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, NaN, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, [], rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, true, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, new Date(), rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, function() {}, rethrow); }).to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, 'genOnOff', function() {}); }).not.to.throw(TypeError); expect(function() { return zcl.parse(zclBuf, 6, function() {}); }).not.to.throw(TypeError); }); }); describe('#.header', function() { it('should be a function', function() { expect(zcl.header).to.be.a('function'); }); it('should throw TypeError if input buf is not a buffer', function() { expect(function() { return zcl.header(undefined); }).to.throw(TypeError); expect(function() { return zcl.header(null); }).to.throw(TypeError); expect(function() { return zcl.header(NaN); }).to.throw(TypeError); expect(function() { return zcl.header([]); }).to.throw(TypeError); expect(function() { return zcl.header(true); }).to.throw(TypeError); expect(function() { return zcl.header(new Date()); }).to.throw(TypeError); expect(function() { return zcl.header(function() {}); }).to.throw(TypeError); }); }); }); describe('Module Methods Check', function() { describe('zcl foundation #.frame and #.parse Check', function() { let zclFrames = [ { frameCntl: { frameType: 0, manufSpec: 0, direction: 0, disDefaultRsp: 1, }, manufCode: 0, seqNum: 0, cmdId: 'writeUndiv', payload: [ {attrId: 0x1234, dataType: 0x41, attrData: 'hello'}, {attrId: 0xabcd, dataType: 0x24, attrData: [100, 2406]}, {attrId: 0x1234, dataType: 0x08, attrData: 60}, ], }, { frameCntl: { frameType: 0, manufSpec: 1, direction: 0, disDefaultRsp: 1, }, manufCode: 0xaaaa, seqNum: 1, cmdId: 'configReport', payload: [ {direction: 0, attrId: 0x0001, dataType: 0x20, minRepIntval: 500, maxRepIntval: 1000, repChange: 10}, {direction: 1, attrId: 0x0001, timeout: 999}, {direction: 0, attrId: 0x0001, dataType: 0x43, minRepIntval: 100, maxRepIntval: 200}, ], }, { frameCntl: { frameType: 0, manufSpec: 0, direction: 1, disDefaultRsp: 1, }, manufCode: 0, seqNum: 2, cmdId: 'writeStrcut', payload: [ {attrId: 0x0011, selector: {indicator: 3, indexes: [0x0101, 0x0202, 0x0303]}, dataType: 0x21, attrData: 60000}, {attrId: 0x0022, selector: {indicator: 0}, dataType: 0x50, attrData: {elmType: 0x20, numElms: 3, elmVals: [1, 2, 3]}}, {attrId: 0x0033, selector: {indicator: 1, indexes: [0x0101]}, dataType: 0x4c, attrData: {numElms: 0x01, structElms: [{elmType: 0x20, elmVal: 1}]}}, ], }, ]; zclFrames.forEach(function(zclFrame) { let zBuf; it('zcl foundation framer and parser Check', function() { zBuf = zcl.frame(zclFrame.frameCntl, zclFrame.manufCode, zclFrame.seqNum, zclFrame.cmdId, zclFrame.payload); zcl.parse(zBuf, function(err, result) { expect(result).to.eql(zclFrame); }); }); }); }); describe('zcl functional #.frame and #.parse Check', function() { let zclFrames = [ { frameCntl: { frameType: 1, manufSpec: 0, direction: 0, disDefaultRsp: 1, }, manufCode: 0, seqNum: 0, cmdId: 'add', payload: { groupid: 0x1234, sceneid: 0x08, transtime: 0x2468, scenename: 'genscenes', extensionfieldsets: [{clstId: 0x0006, len: 0x3, extField: [0x01, 0x02, 0x03]}, {clstId: 0x0009, len: 0x5, extField: [0x05, 0x04, 0x03, 0x02, 0x01]}], }, }, { frameCntl: { frameType: 1, manufSpec: 1, direction: 1, disDefaultRsp: 0, }, manufCode: 0xaaaa, seqNum: 1, cmdId: 'addRsp', payload: { status: 0x26, groupId: 0xffff, sceneId: 0x06, }, }, { frameCntl: { frameType: 1, manufSpec: 0, direction: 1, disDefaultRsp: 1, }, manufCode: 0, seqNum: 2, cmdId: 'getSceneMembershipRsp', payload: { status: 0x01, capacity: 0x02, groupid: 0x2468, scenecount: 3, scenelist: [0x22, 0x33, 0x56], }, }, ]; zclFrames.forEach(function(zclFrame) { let zBuf; it('zcl functional framer and parser Check', function() { zBuf = zcl.frame(zclFrame.frameCntl, zclFrame.manufCode, zclFrame.seqNum, zclFrame.cmdId, zclFrame.payload, 0x0005); zcl.parse(zBuf, 0x0005, function(err, result) { if (result.cmdId === 'add') { result.frameCntl.direction = 0; } else { result.frameCntl.direction = 1; } expect(result).to.eql(zclFrame); }); }); }); }); describe('zcl #.header Check', function() { let headers = [ { buf: new Buffer([0x00, 0x00, 0x00]), obj: { frameCntl: {frameType: 0, manufSpec: 0, direction: 0, disDefaultRsp: 0}, manufCode: null, seqNum: 0, cmdId: 0, }, }, { buf: new Buffer([0x1d, 0x34, 0x12, 0xff, 0x01]), obj: { frameCntl: {frameType: 1, manufSpec: 1, direction: 1, disDefaultRsp: 1}, manufCode: 0x1234, seqNum: 0xff, cmdId: 0x01, }, }, ]; headers.forEach(function(header) { let result = zcl.header(header.buf); it('zcl header Check', function() { expect(result).to.eql(header.obj); }); }); }); describe('zcl #.header Check - Bad command', function() { let headers = [ { buf: new Buffer([0x1e, 0x34, 0x12, 0xff, 0x01]), }, { buf: new Buffer([0x1f, 0x34, 0x12, 0xff, 0x01]), }, ]; headers.forEach(function(header) { let result = zcl.header(header.buf); it('zcl header Check', function() { expect(result).to.be.undefined; }); }); }); });