Skip to content

Commit 82fe425

Browse files
authored
Merge pull request #38 from AlCalzone/test-tradfri-client
Add and improve tests for `TradfriClient`
2 parents 5f58181 + 48e5ba9 commit 82fe425

5 files changed

Lines changed: 450 additions & 112 deletions

File tree

build/tradfri-client.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export declare class TradfriClient extends EventEmitter implements OperationProv
8484
* @returns true if the observer was set up, false otherwise (e.g. if it already exists)
8585
*/
8686
observeResource(path: string, callback: (resp: CoapResponse) => void): Promise<boolean>;
87+
private getObserverUrl(path);
8788
/**
8889
* Checks if a resource is currently being observed
8990
* @param path The path of the resource
@@ -130,6 +131,13 @@ export declare class TradfriClient extends EventEmitter implements OperationProv
130131
private observeGroup_callback(instanceId, response);
131132
private observeScenes_callback(groupId, response);
132133
private observeScene_callback(groupId, instanceId, response);
134+
/**
135+
* Handles a non-successful response, e.g. by error logging
136+
* @param resp The response with a code that indicates an unsuccessful request
137+
* @param context Some logging context to identify where the error comes from
138+
* @returns true if the calling method may proceed, false if it should break
139+
*/
140+
private handleNonSuccessfulResponse(resp, context, ignore404?);
133141
/**
134142
* Pings the gateway to check if it is alive
135143
* @param timeout - (optional) Timeout in ms, after which the ping is deemed unanswered. Default: 5000ms

build/tradfri-client.js

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,8 @@ class TradfriClient extends events_1.EventEmitter {
115115
*/
116116
observeResource(path, callback) {
117117
return __awaiter(this, void 0, void 0, function* () {
118-
path = normalizeResourcePath(path);
119118
// check if we are already observing this resource
120-
const observerUrl = `${this.requestBase}${path}`;
119+
const observerUrl = this.getObserverUrl(path);
121120
if (this.observedPaths.indexOf(observerUrl) > -1)
122121
return false;
123122
// start observing
@@ -126,12 +125,16 @@ class TradfriClient extends events_1.EventEmitter {
126125
return true;
127126
});
128127
}
128+
getObserverUrl(path) {
129+
path = normalizeResourcePath(path);
130+
return path.startsWith(this.requestBase) ? path : `${this.requestBase}${path}`;
131+
}
129132
/**
130133
* Checks if a resource is currently being observed
131134
* @param path The path of the resource
132135
*/
133136
isObserving(path) {
134-
const observerUrl = path.startsWith(this.requestBase) ? path : `${this.requestBase}${path}`;
137+
const observerUrl = this.getObserverUrl(path);
135138
return this.observedPaths.indexOf(observerUrl) > -1;
136139
}
137140
/**
@@ -140,9 +143,8 @@ class TradfriClient extends events_1.EventEmitter {
140143
* @param path The path of the resource
141144
*/
142145
stopObservingResource(path) {
143-
path = normalizeResourcePath(path);
144146
// remove observer
145-
const observerUrl = path.startsWith(this.requestBase) ? path : `${this.requestBase}${path}`;
147+
const observerUrl = this.getObserverUrl(path);
146148
const index = this.observedPaths.indexOf(observerUrl);
147149
if (index === -1)
148150
return;
@@ -187,9 +189,10 @@ class TradfriClient extends events_1.EventEmitter {
187189
}
188190
observeDevices_callback(response) {
189191
return __awaiter(this, void 0, void 0, function* () {
192+
// check response code
190193
if (response.code.toString() !== "2.05") {
191-
this.emit("error", new Error(`unexpected response (${response.code.toString()}) to observeDevices.`));
192-
return;
194+
if (!this.handleNonSuccessfulResponse(response, `observeDevices()`, false))
195+
return;
193196
}
194197
const newDevices = parsePayload(response);
195198
logger_1.log(`got all devices: ${JSON.stringify(newDevices)}`);
@@ -244,9 +247,10 @@ class TradfriClient extends events_1.EventEmitter {
244247
// gets called whenever "get /15001/<instanceId>" updates
245248
// returns true when the device was received successfully
246249
observeDevice_callback(instanceId, response) {
250+
// check response code
247251
if (response.code.toString() !== "2.05") {
248-
this.emit("error", new Error(`unexpected response (${response.code.toString()}) to observeDevice(${instanceId}).`));
249-
return false;
252+
if (!this.handleNonSuccessfulResponse(response, `observeDevice(${instanceId})`))
253+
return false;
250254
}
251255
const result = parsePayload(response);
252256
logger_1.log(`observeDevice > ` + JSON.stringify(result), "debug");
@@ -277,9 +281,10 @@ class TradfriClient extends events_1.EventEmitter {
277281
// gets called whenever "get /15004" updates
278282
observeGroups_callback(response) {
279283
return __awaiter(this, void 0, void 0, function* () {
284+
// check response code
280285
if (response.code.toString() !== "2.05") {
281-
this.emit("error", new Error(`unexpected response (${response.code.toString()}) to getAllGroups.`));
282-
return;
286+
if (!this.handleNonSuccessfulResponse(response, `observeGroups()`, false))
287+
return;
283288
}
284289
const newGroups = parsePayload(response);
285290
logger_1.log(`got all groups: ${JSON.stringify(newGroups)}`);
@@ -359,15 +364,8 @@ class TradfriClient extends events_1.EventEmitter {
359364
// gets called whenever "get /15004/<instanceId>" updates
360365
observeGroup_callback(instanceId, response) {
361366
// check response code
362-
switch (response.code.toString()) {
363-
case "2.05": break; // all good
364-
case "4.04":// not found
365-
// We know this group existed or we wouldn't have requested it
366-
// This means it has been deleted
367-
// TODO: Should we delete it here or where its being handled right now?
368-
return false;
369-
default:
370-
this.emit("error", new Error(`unexpected response (${response.code.toString()}) to getGroup(${instanceId}).`));
367+
if (response.code.toString() !== "2.05") {
368+
if (!this.handleNonSuccessfulResponse(response, `observeGroup(${instanceId})`))
371369
return false;
372370
}
373371
const result = parsePayload(response);
@@ -395,9 +393,10 @@ class TradfriClient extends events_1.EventEmitter {
395393
// gets called whenever "get /15005/<groupId>" updates
396394
observeScenes_callback(groupId, response) {
397395
return __awaiter(this, void 0, void 0, function* () {
396+
// check response code
398397
if (response.code.toString() !== "2.05") {
399-
this.emit("error", new Error(`unexpected response (${response.code.toString()}) to observeScenes(${groupId}).`));
400-
return;
398+
if (!this.handleNonSuccessfulResponse(response, `observeScenes(${groupId})`, false))
399+
return;
401400
}
402401
const groupInfo = this.groups[groupId];
403402
const newScenes = parsePayload(response);
@@ -445,15 +444,8 @@ class TradfriClient extends events_1.EventEmitter {
445444
// gets called whenever "get /15005/<groupId>/<instanceId>" updates
446445
observeScene_callback(groupId, instanceId, response) {
447446
// check response code
448-
switch (response.code.toString()) {
449-
case "2.05": break; // all good
450-
case "4.04":// not found
451-
// We know this scene existed or we wouldn't have requested it
452-
// This means it has been deleted
453-
// TODO: Should we delete it here or where its being handled right now?
454-
return false;
455-
default:
456-
this.emit("error", new Error(`unexpected response (${response.code.toString()}) to observeScene(${groupId}, ${instanceId}).`));
447+
if (response.code.toString() !== "2.05") {
448+
if (!this.handleNonSuccessfulResponse(response, `observeScene(${groupId}, ${instanceId})`))
457449
return false;
458450
}
459451
const result = parsePayload(response);
@@ -466,6 +458,27 @@ class TradfriClient extends events_1.EventEmitter {
466458
this.emit("scene updated", groupId, scene.link(this));
467459
return true;
468460
}
461+
/**
462+
* Handles a non-successful response, e.g. by error logging
463+
* @param resp The response with a code that indicates an unsuccessful request
464+
* @param context Some logging context to identify where the error comes from
465+
* @returns true if the calling method may proceed, false if it should break
466+
*/
467+
handleNonSuccessfulResponse(resp, context, ignore404 = true) {
468+
// check response code
469+
const code = resp.code.toString();
470+
const payload = parsePayload(resp) || "";
471+
if (code === "4.04" && ignore404) {
472+
// not found
473+
// An observed resource has been deleted - all good
474+
// The observer will be removed soon
475+
return false;
476+
}
477+
else {
478+
this.emit("error", new Error(`unexpected response (${code}) to ${context}: ${payload}`));
479+
return false;
480+
}
481+
}
469482
/**
470483
* Pings the gateway to check if it is alive
471484
* @param timeout - (optional) Timeout in ms, after which the ping is deemed unanswered. Default: 5000ms
@@ -580,12 +593,14 @@ exports.TradfriClient = TradfriClient;
580593
function normalizeResourcePath(path) {
581594
path = path || "";
582595
while (path.startsWith("/"))
583-
path = path.substring(1);
596+
path = path.slice(1);
584597
while (path.endsWith("/"))
585-
path = path.substring(0, -1);
598+
path = path.slice(0, -1);
586599
return path;
587600
}
588601
function parsePayload(response) {
602+
if (response.payload == null)
603+
return null;
589604
switch (response.format) {
590605
case 0: // text/plain
591606
case null:// assume text/plain

0 commit comments

Comments
 (0)