node-hue-api
Version:
Philips Hue API Library for Node.js
666 lines (492 loc) • 20.6 kB
JavaScript
'use strict';
const expect = require('chai').expect
, v3Api = require('../v3').v3.api
, discovery = require('../index').discovery
, testValues = require('../../test/support/testValues.js')
, model = require('@peter-murray/hue-bridge-model').model
, instanceChecks = model.instanceChecks
, LightGroup = model.LightGroup
, Zone = model.Zone
, Room = model.Room
, Entertainment = model.Entertainment
;
const NEW_GROUP_NAME = 'd4b3af3ab4df72d10666726d';
describe('Hue API #groups', function () {
this.timeout(5000);
const GROUP_LIGHTS = [2, 3]
, ZONE_LIGHTS = [2, 3, 4]
;
let hue;
before(async () => {
const searchResults = await discovery.nupnpSearch();
expect(searchResults).to.have.length.at.least(1);
const localApi = v3Api.createLocal(searchResults[0].ipaddress);
hue = await localApi.connect(testValues.username);
});
describe('#getAll()', () => {
it('should return all groups', async () => {
const result = await hue.groups.getAll();
expect(result).to.be.instanceof(Array);
// The injected all lights special group
expect(result[0]).to.have.property('name', 'Group 0');
expect(result[0]).to.have.property('id', 0);
// TODO this is now a Group object test the values
expect(result[1]).to.have.property('name');
expect(result[1]).to.have.property('lights');
expect(result[1]).to.have.property('type');
expect(result[1]).to.have.property('state');
expect(result[1]).to.have.property('recycle');
expect(result[1]).to.have.property('action');
});
});
describe('#getGroup()', () => {
let existingGroup;
before(async () => {
const allGroups = await hue.groups.getAll();
// Use the last group as the group to test on
existingGroup = allGroups[allGroups.length - 1];
});
it('should get the All Lights Group', async () => {
const result = await hue.groups.getGroup(0);
expect(result.name).to.equal('Group 0');
expect(result.id).to.equal(0);
});
it('should get a room group', async () => {
const result = await hue.groups.getGroup(existingGroup.id);
expect(result).to.have.property('id').to.equal(existingGroup.id);
expect(result).to.have.property('name').to.equal(existingGroup.name);
//TODO could do more checks here
});
it('should fail to resolve a group for an invalid id number', async () => {
try {
await hue.groups.getGroup(65534);
expect.fail('should not get here');
} catch (err) {
expect(err.message).to.contain('not available');
}
});
it('should fail to resolve a group for an invalid id as a string', async () => {
try {
await hue.groups.getGroup('ab62c6');
expect.fail('should not get here');
} catch (err) {
expect(err.message).to.contain('not a parsable number');
}
});
});
describe('#getGroupByName()', () => {
it('should get an existing group', async () => {
const allGroups = await hue.groups.getAll()
, targetGroupName = allGroups[1].name
, groups = await hue.groups.getGroupByName(targetGroupName)
;
expect(groups).to.be.instanceof(Array);
expect(groups).to.have.length.greaterThan(0);
expect(groups[0]).to.have.property('name').to.equal(targetGroupName);
});
});
describe('creating groups', () => {
function deleteExistingGroups(name) {
return hue.groups.getGroupByName(name)
.then(matchedGroups => {
if (matchedGroups && matchedGroups.length > 0) {
const promises = [];
matchedGroups.forEach(group => {
promises.push(hue.groups.deleteGroup(group.id));
});
return Promise.all(promises);
} else {
return true;
}
});
}
beforeEach('remove group before creation', async () => {
await deleteExistingGroups(NEW_GROUP_NAME);
});
afterEach('cleanup created group', async () => {
await deleteExistingGroups(NEW_GROUP_NAME);
});
// describe('#createRoom()', () => {
//
// it('should work on deprecated function', async () => {
// const name = NEW_GROUP_NAME
// , lights = []
// ;
//
// const result = await hue.groups.createRoom(name, lights);
// expect(result).to.have.property('name').to.equal(name);
// expect(result).to.have.property('lights').to.have.members(toStringArray(lights));
// });
// });
// describe('#createZone()', () => {
//
// it('should work on deprecated function', async () => {
// const name = NEW_GROUP_NAME
// , lights = GROUP_LIGHTS
// ;
//
// const result = await hue.groups.createZone(name, lights);
// expect(result).to.have.property('name').to.equal(name);
// expect(result).to.have.property('lights').to.have.members(toStringArray(lights));
// });
// });
describe('#createGroup()', () => {
// describe('old deprecated parameters', () => {
//
// it('should create a new group', async () => {
// const name = NEW_GROUP_NAME
// , lights = GROUP_LIGHTS
// ;
//
// const result = await hue.groups.createGroup(name, lights);
// expect(result).to.have.property('name').to.equal(name);
// expect(result).to.have.property('lights').to.have.members(toStringArray(lights));
// });
// });
describe('LightGroup', () => {
it('should create a new group', async () => {
const group = new LightGroup();
group.name = NEW_GROUP_NAME;
group.lights = GROUP_LIGHTS;
const result = await hue.groups.createGroup(group);
expect(result instanceof model.Group).to.be.true;
expect(result).to.have.property('id').to.be.greaterThan(0);
expect(result).to.have.property('name').to.equal(NEW_GROUP_NAME);
expect(result).to.have.property('lights').to.have.members(toStringArray(GROUP_LIGHTS));
expect(result).to.have.property('recycle').to.be.false;
});
});
});
describe('Room', () => {
it('should create a new room', async () => {
const name = NEW_GROUP_NAME
, roomClass = 'Gym'
;
const room = new Room();
room.name = NEW_GROUP_NAME;
room.class = roomClass;
const result = await hue.groups.createGroup(room);
expect(instanceChecks.isGroupInstance(result)).to.be.true;
expect(result).to.have.property('id').to.be.greaterThan(0);
expect(result).to.have.property('name').to.equal(name);
expect(result).to.have.property('type').to.equal('Room');
expect(result).to.have.property('class').to.equal(roomClass);
expect(result).to.have.property('lights').to.be.empty;
});
it('should create a room when only providing a name', async () => {
const room = new Room();
room.name = NEW_GROUP_NAME;
const result = await hue.groups.createGroup(room);
expect(instanceChecks.isGroupInstance(result)).to.be.true;
expect(result).to.have.property('id').to.be.greaterThan(0);
expect(result).to.have.property('name').to.equal(NEW_GROUP_NAME);
expect(result).to.have.property('type').to.equal('Room');
expect(result).to.have.property('class').to.equal('Other');
});
});
describe('Zone', () => {
it('should create a new zone', async () => {
const zone = new Zone();
zone.name = NEW_GROUP_NAME;
zone.lights = ZONE_LIGHTS;
const result = await hue.groups.createGroup(zone);
expect(instanceChecks.isGroupInstance(result)).to.be.true;
expect(result).to.have.property('id').to.be.greaterThan(0);
expect(result).to.have.property('name').to.equal(NEW_GROUP_NAME);
expect(result).to.have.property('lights').to.have.members(toStringArray(ZONE_LIGHTS));
expect(result).to.have.property('type').to.equal('Zone');
});
});
describe('Entertainment', () => {
it('should create a new entertainment group', async () => {
const entertainment = new Entertainment();
entertainment.name = NEW_GROUP_NAME;
// entertainment.lights = [];
const result = await hue.groups.createGroup(entertainment);
expect(instanceChecks.isGroupInstance(result)).to.be.true;
expect(result).to.have.property('id').to.be.greaterThan(0);
expect(result).to.have.property('name').to.equal(NEW_GROUP_NAME);
expect(result).to.have.property('lights').to.be.empty;
expect(result).to.have.property('type').to.equal('Entertainment');
});
});
});
describe('#deleteGroup()', () => {
const DELETE_GROUP_NAME = 'TestGroupToBeDeleted';
let groupToBeDeleted;
afterEach(async() => {
if (groupToBeDeleted) {
const groups = await hue.groups.getGroupByName(DELETE_GROUP_NAME);
let promises;
if (groups && groups.length > 0) {
promises = groups.map(group => hue.groups.deleteGroup(group));
}
if (promises) {
await Promise.all(promises);
}
}
});
describe('LightGroup', () => {
beforeEach('create LightGroup', async () => {
const group = new LightGroup();
group.name = DELETE_GROUP_NAME;
group.lights = GROUP_LIGHTS;
groupToBeDeleted = await hue.groups.createGroup(group);
});
it('should delete using a group object', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted);
expect(result).to.be.true;
});
it('should delete using a group id', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted.id);
expect(result).to.be.true;
});
});
describe('Zone', () => {
beforeEach('create Zone', async () => {
const group = new Zone();
group.name = DELETE_GROUP_NAME;
group.lights = ZONE_LIGHTS;
groupToBeDeleted = await hue.groups.createGroup(group);
});
it('should delete using a group object', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted);
expect(result).to.be.true;
});
it('should delete using a group id', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted.id);
expect(result).to.be.true;
});
});
describe('Room', () => {
beforeEach('create Room', async () => {
const group = new Room();
group.name = DELETE_GROUP_NAME;
groupToBeDeleted = await hue.groups.createGroup(group);
});
it('should delete using a group object', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted);
expect(result).to.be.true;
});
it('should delete using a group id', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted.id);
expect(result).to.be.true;
});
});
describe('Entertainment', () => {
beforeEach('create Entertainment Group', async () => {
const group = new Entertainment();
group.name = DELETE_GROUP_NAME;
groupToBeDeleted = await hue.groups.createGroup(group);
});
it('should delete using a group object', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted);
expect(result).to.be.true;
});
it('should delete using a group id', async () => {
const result = await hue.groups.deleteGroup(groupToBeDeleted.id);
expect(result).to.be.true;
});
});
});
describe('#updateAttributes()', () => {
let group = null;
afterEach('delete updated group', async () => {
if (group) {
await hue.groups.deleteGroup(group);
}
});
describe('LightGroup', () => {
beforeEach('createGroup group for update', async () => {
const newGroup = new LightGroup();
newGroup.name = 'LightGroup Updates';
newGroup.lights = [2];
group = await hue.groups.createGroup(newGroup);
});
it('should update the name', async () => {
const newName = `renamed-new ${Date.now()}`;
group.name = newName;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('name').to.equal(newName);
expect(updatedGroup).to.have.property('lights').to.have.members(group.lights);
});
it('should update the lights', async () => {
const newLights = [2, 3, 4];
group.lights = newLights;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('name').to.equal(group.name);
expect(updatedGroup).to.have.property('lights').to.have.members(toStringArray(newLights));
});
it('should update the name and lights', async () => {
// TODO hardcoded flaky test when hue config changes
const newLights = [4, 6]
, newName = `renamed-${Date.now()}`
;
group.name = newName;
group.lights = newLights;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('name').to.equal(newName);
expect(updatedGroup).to.have.property('lights').to.have.members(toStringArray(newLights));
});
});
describe('Room', () => {
beforeEach('create room for update', async () => {
const newGroup = new Room();
newGroup.name = 'Custom Room';
newGroup.class = 'Gym';
group = await hue.groups.createGroup(newGroup);
});
it('should update the name', async () => {
const name = 'Custom Room Updated';
group.name = name;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('name').to.equal(name);
});
// lights can only be assigned to a single room and all mine are assigned
it.skip('should update the lights', async () => {
const lights = [4];
group.lights = lights;
const result = await hue.groups.updateAttributes(group)
, updatedGroup = await hue.groups.get(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('lights').to.equal(toStringArray(lights));
});
it('should change the class', async () => {
group.class = 'Other';
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('class').to.equal('Other');
});
});
describe('Zone', () => {
beforeEach('create zone for update', async () => {
const newGroup = new Zone();
newGroup.name = 'Custom Zone';
newGroup.class = 'Lounge';
group = await hue.groups.createGroup(newGroup);
});
it('should update the name', async () => {
const name = 'Custom Zone Updated';
group.name = name;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('name').to.equal(name);
});
it('should update the lights', async () => {
const lights = [4];
group.lights = lights;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('lights').to.have.members(toStringArray(lights));
});
it('should change the class', async () => {
group.class = 'Nursery';
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('class').to.equal('Nursery');
});
});
describe('Entertainment', () => {
beforeEach('create entertainment for update', async () => {
const newGroup = new Entertainment();
newGroup.name = 'Custom Entertainment';
group = await hue.groups.createGroup(newGroup);
});
it('should update the name', async () => {
const name = 'Custom Name';
group.name = name;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('name').to.equal(name);
});
it('should update the lights', async () => {
const lights = [testValues.streamingLightId];
group.lights = lights;
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('lights').to.have.members(toStringArray(lights));
});
it('should change the class', async () => {
group.class = 'Other';
const result = await hue.groups.updateGroupAttributes(group)
, updatedGroup = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(updatedGroup).to.have.property('id').to.equal(group.id);
expect(updatedGroup).to.have.property('class').to.equal('Other');
});
});
});
describe('#setGroupState()', () => {
let group;
beforeEach('create LightGroup for setState', async () => {
const groupToCreate = new LightGroup();
groupToCreate.name = 'setGroupState Tests';
groupToCreate.lights = testValues.streamingLightId;
group = await hue.groups.createGroup(groupToCreate);
});
afterEach('delete test group for setState', async () => {
if (group) {
await hue.groups.deleteGroup(group);
}
});
it('should set on state to true', async () => {
const lightState = {on: true}
, result = await hue.groups.setGroupState(group, lightState)
, groupStatus = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(groupStatus).to.have.property('action');
expect(groupStatus.action).to.have.property('on').to.be.true;
});
it('should set on state to false using GroupState', async () => {
const lightState = new model.lightStates.GroupLightState().off()
, result = await hue.groups.setGroupState(group, lightState)
, groupStatus = await hue.groups.getGroup(group)
;
expect(result).to.be.true;
expect(groupStatus).to.have.property('action');
expect(groupStatus.action).to.have.property('on').to.be.false;
});
//TODO could expand tests to rooms, zone and entertainment, but if it works for one should work for all
});
});
function toStringArray(values) {
return values.map(v => `${v}`);
}