edilkamin 1.6.2 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/cli-tests.yml +1 -1
- package/.github/workflows/documentation.yml +1 -1
- package/.github/workflows/publish.yml +6 -4
- package/.github/workflows/tests.yml +1 -1
- package/README.md +31 -7
- package/dist/esm/browser-bundle.test.d.ts +1 -0
- package/dist/esm/browser-bundle.test.js +29 -0
- package/dist/esm/cli.js +69 -10
- package/dist/esm/configureAmplify.test.d.ts +1 -0
- package/dist/esm/configureAmplify.test.js +37 -0
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/library.d.ts +18 -6
- package/dist/esm/library.js +87 -55
- package/dist/esm/library.test.js +230 -192
- package/dist/esm/token-storage.d.ts +14 -0
- package/dist/esm/token-storage.js +81 -0
- package/eslint.config.mjs +12 -1
- package/package.json +15 -3
- package/src/browser-bundle.test.ts +21 -0
- package/src/buffer-utils.test.ts +1 -1
- package/src/cli.ts +113 -40
- package/src/configureAmplify.test.ts +47 -0
- package/src/index.ts +1 -1
- package/src/library.test.ts +279 -206
- package/src/library.ts +125 -70
- package/src/token-storage.ts +78 -0
package/dist/esm/library.test.js
CHANGED
|
@@ -8,7 +8,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { strict as assert } from "assert";
|
|
11
|
-
import axios from "axios";
|
|
12
11
|
import pako from "pako";
|
|
13
12
|
import sinon from "sinon";
|
|
14
13
|
import { configure, createAuthService } from "../src/library";
|
|
@@ -24,15 +23,20 @@ const createGzippedBuffer = (data) => {
|
|
|
24
23
|
data: Array.from(compressed),
|
|
25
24
|
};
|
|
26
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Helper to create a mock Response object for fetch.
|
|
28
|
+
*/
|
|
29
|
+
const mockResponse = (data, status = 200) => ({
|
|
30
|
+
ok: status >= 200 && status < 300,
|
|
31
|
+
status,
|
|
32
|
+
statusText: status >= 200 && status < 300 ? "OK" : "Error",
|
|
33
|
+
json: () => Promise.resolve(data),
|
|
34
|
+
});
|
|
27
35
|
describe("library", () => {
|
|
28
|
-
let
|
|
36
|
+
let fetchStub;
|
|
29
37
|
const expectedToken = "mockJwtToken";
|
|
30
38
|
beforeEach(() => {
|
|
31
|
-
|
|
32
|
-
get: sinon.stub(),
|
|
33
|
-
put: sinon.stub(),
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
35
|
-
});
|
|
39
|
+
fetchStub = sinon.stub(globalThis, "fetch");
|
|
36
40
|
});
|
|
37
41
|
afterEach(() => {
|
|
38
42
|
sinon.restore();
|
|
@@ -81,8 +85,7 @@ describe("library", () => {
|
|
|
81
85
|
};
|
|
82
86
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
87
|
const authService = createAuthService(authStub);
|
|
84
|
-
const token = yield authService.signIn(expectedUsername, expectedPassword, true
|
|
85
|
-
);
|
|
88
|
+
const token = yield authService.signIn(expectedUsername, expectedPassword, true);
|
|
86
89
|
assert.equal(token, expectedToken);
|
|
87
90
|
}));
|
|
88
91
|
it("should throw an error if sign-in fails", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -108,6 +111,68 @@ describe("library", () => {
|
|
|
108
111
|
});
|
|
109
112
|
}));
|
|
110
113
|
});
|
|
114
|
+
describe("getSession", () => {
|
|
115
|
+
it("should return idToken by default", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
|
+
const mockAuth = {
|
|
117
|
+
signIn: sinon.stub().resolves({ isSignedIn: true }),
|
|
118
|
+
signOut: sinon.stub().resolves(),
|
|
119
|
+
fetchAuthSession: sinon.stub().resolves({
|
|
120
|
+
tokens: {
|
|
121
|
+
idToken: { toString: () => "mock-id-token" },
|
|
122
|
+
accessToken: { toString: () => "mock-access-token" },
|
|
123
|
+
},
|
|
124
|
+
}),
|
|
125
|
+
};
|
|
126
|
+
const { getSession, signIn } = createAuthService(mockAuth);
|
|
127
|
+
yield signIn("user", "pass");
|
|
128
|
+
const token = yield getSession();
|
|
129
|
+
assert.equal(token, "mock-id-token");
|
|
130
|
+
}));
|
|
131
|
+
it("should return accessToken when legacy=true", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
132
|
+
const mockAuth = {
|
|
133
|
+
signIn: sinon.stub().resolves({ isSignedIn: true }),
|
|
134
|
+
signOut: sinon.stub().resolves(),
|
|
135
|
+
fetchAuthSession: sinon.stub().resolves({
|
|
136
|
+
tokens: {
|
|
137
|
+
idToken: { toString: () => "mock-id-token" },
|
|
138
|
+
accessToken: { toString: () => "mock-access-token" },
|
|
139
|
+
},
|
|
140
|
+
}),
|
|
141
|
+
};
|
|
142
|
+
const { getSession, signIn } = createAuthService(mockAuth);
|
|
143
|
+
yield signIn("user", "pass");
|
|
144
|
+
const token = yield getSession(false, true);
|
|
145
|
+
assert.equal(token, "mock-access-token");
|
|
146
|
+
}));
|
|
147
|
+
it("should throw error when no session exists", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
+
const mockAuth = {
|
|
149
|
+
signIn: sinon.stub().resolves({ isSignedIn: true }),
|
|
150
|
+
signOut: sinon.stub().resolves(),
|
|
151
|
+
fetchAuthSession: sinon.stub().resolves({ tokens: null }),
|
|
152
|
+
};
|
|
153
|
+
const { getSession } = createAuthService(mockAuth);
|
|
154
|
+
yield assert.rejects(() => __awaiter(void 0, void 0, void 0, function* () { return getSession(); }), {
|
|
155
|
+
name: "AssertionError",
|
|
156
|
+
message: "No session found - please sign in first",
|
|
157
|
+
});
|
|
158
|
+
}));
|
|
159
|
+
it("should pass forceRefresh to fetchAuthSession", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
const mockAuth = {
|
|
161
|
+
signIn: sinon.stub().resolves({ isSignedIn: true }),
|
|
162
|
+
signOut: sinon.stub().resolves(),
|
|
163
|
+
fetchAuthSession: sinon.stub().resolves({
|
|
164
|
+
tokens: {
|
|
165
|
+
idToken: { toString: () => "mock-id-token" },
|
|
166
|
+
accessToken: { toString: () => "mock-access-token" },
|
|
167
|
+
},
|
|
168
|
+
}),
|
|
169
|
+
};
|
|
170
|
+
const { getSession, signIn } = createAuthService(mockAuth);
|
|
171
|
+
yield signIn("user", "pass");
|
|
172
|
+
yield getSession(true);
|
|
173
|
+
assert.ok(mockAuth.fetchAuthSession.calledWith({ forceRefresh: true }));
|
|
174
|
+
}));
|
|
175
|
+
});
|
|
111
176
|
describe("configure", () => {
|
|
112
177
|
const expectedApi = [
|
|
113
178
|
"deviceInfo",
|
|
@@ -121,29 +186,25 @@ describe("library", () => {
|
|
|
121
186
|
"getTargetTemperature",
|
|
122
187
|
"setTargetTemperature",
|
|
123
188
|
];
|
|
124
|
-
it("should create API methods with the correct baseURL", () => {
|
|
125
|
-
const baseURL = "https://example.com/api";
|
|
189
|
+
it("should create API methods with the correct baseURL", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
190
|
+
const baseURL = "https://example.com/api/";
|
|
191
|
+
fetchStub.resolves(mockResponse({ test: "data" }));
|
|
126
192
|
const api = configure(baseURL);
|
|
127
|
-
assert.deepEqual(axiosStub.args, [
|
|
128
|
-
[
|
|
129
|
-
{
|
|
130
|
-
baseURL,
|
|
131
|
-
},
|
|
132
|
-
],
|
|
133
|
-
]);
|
|
134
193
|
assert.deepEqual(Object.keys(api), expectedApi);
|
|
135
|
-
|
|
136
|
-
|
|
194
|
+
// Verify baseURL is used when making a request
|
|
195
|
+
yield api.deviceInfo(expectedToken, "mockMac");
|
|
196
|
+
assert.ok(fetchStub.calledOnce);
|
|
197
|
+
assert.ok(fetchStub.firstCall.args[0].startsWith(baseURL));
|
|
198
|
+
}));
|
|
199
|
+
it("should create API methods with the default baseURL", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
200
|
+
fetchStub.resolves(mockResponse({ test: "data" }));
|
|
137
201
|
const api = configure();
|
|
138
|
-
assert.deepEqual(axiosStub.args, [
|
|
139
|
-
[
|
|
140
|
-
{
|
|
141
|
-
baseURL: API_URL,
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
]);
|
|
145
202
|
assert.deepEqual(Object.keys(api), expectedApi);
|
|
146
|
-
|
|
203
|
+
// Verify default baseURL is used when making a request
|
|
204
|
+
yield api.deviceInfo(expectedToken, "mockMac");
|
|
205
|
+
assert.ok(fetchStub.calledOnce);
|
|
206
|
+
assert.ok(fetchStub.firstCall.args[0].startsWith(API_URL));
|
|
207
|
+
}));
|
|
147
208
|
});
|
|
148
209
|
describe("API Methods", () => {
|
|
149
210
|
const mockDeviceInfo = {
|
|
@@ -161,19 +222,16 @@ describe("library", () => {
|
|
|
161
222
|
},
|
|
162
223
|
},
|
|
163
224
|
};
|
|
164
|
-
it("should call
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
};
|
|
168
|
-
axiosStub.returns(mockAxios);
|
|
169
|
-
const api = configure("https://example.com/api");
|
|
225
|
+
it("should call fetch for deviceInfo", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
226
|
+
fetchStub.resolves(mockResponse(mockDeviceInfo));
|
|
227
|
+
const api = configure("https://example.com/api/");
|
|
170
228
|
const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
|
|
171
|
-
assert.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
229
|
+
assert.ok(fetchStub.calledOnce);
|
|
230
|
+
assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device/mockMacAddress/info");
|
|
231
|
+
assert.deepEqual(fetchStub.firstCall.args[1], {
|
|
232
|
+
method: "GET",
|
|
233
|
+
headers: { Authorization: `Bearer ${expectedToken}` },
|
|
234
|
+
});
|
|
177
235
|
assert.deepEqual(result, mockDeviceInfo);
|
|
178
236
|
}));
|
|
179
237
|
// Tests for setPowerOn and setPowerOff
|
|
@@ -189,28 +247,25 @@ describe("library", () => {
|
|
|
189
247
|
expectedValue: 0,
|
|
190
248
|
},
|
|
191
249
|
].forEach(({ method, call, expectedValue }) => {
|
|
192
|
-
it(`should call
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
};
|
|
196
|
-
axiosStub.returns(mockAxios);
|
|
197
|
-
const api = configure("https://example.com/api");
|
|
250
|
+
it(`should call fetch for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
251
|
+
fetchStub.resolves(mockResponse({ success: true }));
|
|
252
|
+
const api = configure("https://example.com/api/");
|
|
198
253
|
// Invoke the method using the mapped call function
|
|
199
|
-
|
|
200
|
-
assert.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
254
|
+
yield call(api);
|
|
255
|
+
assert.ok(fetchStub.calledOnce);
|
|
256
|
+
assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/mqtt/command");
|
|
257
|
+
assert.deepEqual(fetchStub.firstCall.args[1], {
|
|
258
|
+
method: "PUT",
|
|
259
|
+
headers: {
|
|
260
|
+
"Content-Type": "application/json",
|
|
261
|
+
Authorization: "Bearer mockToken",
|
|
262
|
+
},
|
|
263
|
+
body: JSON.stringify({
|
|
264
|
+
mac_address: "mockMacAddress",
|
|
265
|
+
name: "power",
|
|
266
|
+
value: expectedValue,
|
|
267
|
+
}),
|
|
268
|
+
});
|
|
214
269
|
}));
|
|
215
270
|
});
|
|
216
271
|
const getterTests = [
|
|
@@ -231,19 +286,16 @@ describe("library", () => {
|
|
|
231
286
|
},
|
|
232
287
|
];
|
|
233
288
|
getterTests.forEach(({ method, call, expectedResult }) => {
|
|
234
|
-
it(`should call
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
};
|
|
238
|
-
axiosStub.returns(mockAxios);
|
|
239
|
-
const api = configure("https://example.com/api");
|
|
289
|
+
it(`should call fetch and return the correct value for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
290
|
+
fetchStub.resolves(mockResponse(mockDeviceInfo));
|
|
291
|
+
const api = configure("https://example.com/api/");
|
|
240
292
|
const result = yield call(api, expectedToken, "mockMacAddress");
|
|
241
|
-
assert.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
293
|
+
assert.ok(fetchStub.calledOnce);
|
|
294
|
+
assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device/mockMacAddress/info");
|
|
295
|
+
assert.deepEqual(fetchStub.firstCall.args[1], {
|
|
296
|
+
method: "GET",
|
|
297
|
+
headers: { Authorization: `Bearer ${expectedToken}` },
|
|
298
|
+
});
|
|
247
299
|
assert.equal(result, expectedResult);
|
|
248
300
|
}));
|
|
249
301
|
});
|
|
@@ -259,119 +311,100 @@ describe("library", () => {
|
|
|
259
311
|
},
|
|
260
312
|
];
|
|
261
313
|
setterTests.forEach(({ method, call, payload }) => {
|
|
262
|
-
it(`should call
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
"
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
],
|
|
277
|
-
]);
|
|
278
|
-
assert.equal(result.status, 200);
|
|
314
|
+
it(`should call fetch and send the correct payload for ${method}`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
315
|
+
fetchStub.resolves(mockResponse({ success: true }));
|
|
316
|
+
const api = configure("https://example.com/api/");
|
|
317
|
+
yield call(api, expectedToken, "mockMacAddress", payload.value);
|
|
318
|
+
assert.ok(fetchStub.calledOnce);
|
|
319
|
+
assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/mqtt/command");
|
|
320
|
+
assert.deepEqual(fetchStub.firstCall.args[1], {
|
|
321
|
+
method: "PUT",
|
|
322
|
+
headers: {
|
|
323
|
+
"Content-Type": "application/json",
|
|
324
|
+
Authorization: `Bearer ${expectedToken}`,
|
|
325
|
+
},
|
|
326
|
+
body: JSON.stringify(Object.assign({ mac_address: "mockMacAddress" }, payload)),
|
|
327
|
+
});
|
|
279
328
|
}));
|
|
280
329
|
});
|
|
281
330
|
});
|
|
282
331
|
describe("registerDevice", () => {
|
|
283
332
|
it("should call POST /device with correct payload", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
284
|
-
const
|
|
333
|
+
const mockResponseData = {
|
|
285
334
|
macAddress: "AABBCCDDEEFF",
|
|
286
335
|
deviceName: "Test Stove",
|
|
287
336
|
deviceRoom: "Living Room",
|
|
288
337
|
serialNumber: "EDK123",
|
|
289
338
|
};
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
get: sinon.stub(),
|
|
293
|
-
put: sinon.stub(),
|
|
294
|
-
};
|
|
295
|
-
axiosStub.returns(mockAxios);
|
|
296
|
-
const api = configure("https://example.com/api");
|
|
339
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
340
|
+
const api = configure("https://example.com/api/");
|
|
297
341
|
const result = yield api.registerDevice(expectedToken, "AA:BB:CC:DD:EE:FF", "EDK123", "Test Stove", "Living Room");
|
|
298
|
-
assert.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
342
|
+
assert.ok(fetchStub.calledOnce);
|
|
343
|
+
assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device");
|
|
344
|
+
assert.deepEqual(fetchStub.firstCall.args[1], {
|
|
345
|
+
method: "POST",
|
|
346
|
+
headers: {
|
|
347
|
+
"Content-Type": "application/json",
|
|
348
|
+
Authorization: `Bearer ${expectedToken}`,
|
|
349
|
+
},
|
|
350
|
+
body: JSON.stringify({
|
|
351
|
+
macAddress: "AABBCCDDEEFF",
|
|
352
|
+
deviceName: "Test Stove",
|
|
353
|
+
deviceRoom: "Living Room",
|
|
354
|
+
serialNumber: "EDK123",
|
|
355
|
+
}),
|
|
356
|
+
});
|
|
357
|
+
assert.deepEqual(result, mockResponseData);
|
|
311
358
|
}));
|
|
312
359
|
it("should normalize MAC address by removing colons", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
get: sinon.stub(),
|
|
316
|
-
put: sinon.stub(),
|
|
317
|
-
};
|
|
318
|
-
axiosStub.returns(mockAxios);
|
|
319
|
-
const api = configure("https://example.com/api");
|
|
360
|
+
fetchStub.resolves(mockResponse({}));
|
|
361
|
+
const api = configure("https://example.com/api/");
|
|
320
362
|
yield api.registerDevice(expectedToken, "AA:BB:CC:DD:EE:FF", "EDK123");
|
|
321
|
-
|
|
363
|
+
const body = JSON.parse(fetchStub.firstCall.args[1].body);
|
|
364
|
+
assert.equal(body.macAddress, "AABBCCDDEEFF");
|
|
322
365
|
}));
|
|
323
366
|
it("should use empty strings as defaults for name and room", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
get: sinon.stub(),
|
|
327
|
-
put: sinon.stub(),
|
|
328
|
-
};
|
|
329
|
-
axiosStub.returns(mockAxios);
|
|
330
|
-
const api = configure("https://example.com/api");
|
|
367
|
+
fetchStub.resolves(mockResponse({}));
|
|
368
|
+
const api = configure("https://example.com/api/");
|
|
331
369
|
yield api.registerDevice(expectedToken, "AABBCCDDEEFF", "EDK123");
|
|
332
|
-
|
|
333
|
-
assert.equal(
|
|
370
|
+
const body = JSON.parse(fetchStub.firstCall.args[1].body);
|
|
371
|
+
assert.equal(body.deviceName, "");
|
|
372
|
+
assert.equal(body.deviceRoom, "");
|
|
334
373
|
}));
|
|
335
374
|
});
|
|
336
375
|
describe("editDevice", () => {
|
|
337
376
|
it("should call PUT /device/{mac} with correct payload", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
338
|
-
const
|
|
377
|
+
const mockResponseData = {
|
|
339
378
|
macAddress: "AABBCCDDEEFF",
|
|
340
379
|
deviceName: "Updated Name",
|
|
341
380
|
deviceRoom: "Basement",
|
|
342
381
|
serialNumber: "EDK123",
|
|
343
382
|
};
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
get: sinon.stub(),
|
|
347
|
-
post: sinon.stub(),
|
|
348
|
-
};
|
|
349
|
-
axiosStub.returns(mockAxios);
|
|
350
|
-
const api = configure("https://example.com/api");
|
|
383
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
384
|
+
const api = configure("https://example.com/api/");
|
|
351
385
|
const result = yield api.editDevice(expectedToken, "AA:BB:CC:DD:EE:FF", "Updated Name", "Basement");
|
|
352
|
-
assert.
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
386
|
+
assert.ok(fetchStub.calledOnce);
|
|
387
|
+
assert.equal(fetchStub.firstCall.args[0], "https://example.com/api/device/AABBCCDDEEFF");
|
|
388
|
+
assert.deepEqual(fetchStub.firstCall.args[1], {
|
|
389
|
+
method: "PUT",
|
|
390
|
+
headers: {
|
|
391
|
+
"Content-Type": "application/json",
|
|
392
|
+
Authorization: `Bearer ${expectedToken}`,
|
|
393
|
+
},
|
|
394
|
+
body: JSON.stringify({
|
|
395
|
+
deviceName: "Updated Name",
|
|
396
|
+
deviceRoom: "Basement",
|
|
397
|
+
}),
|
|
398
|
+
});
|
|
399
|
+
assert.deepEqual(result, mockResponseData);
|
|
363
400
|
}));
|
|
364
401
|
it("should use empty strings as defaults for name and room", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
get: sinon.stub(),
|
|
368
|
-
post: sinon.stub(),
|
|
369
|
-
};
|
|
370
|
-
axiosStub.returns(mockAxios);
|
|
371
|
-
const api = configure("https://example.com/api");
|
|
402
|
+
fetchStub.resolves(mockResponse({}));
|
|
403
|
+
const api = configure("https://example.com/api/");
|
|
372
404
|
yield api.editDevice(expectedToken, "AABBCCDDEEFF");
|
|
373
|
-
|
|
374
|
-
assert.equal(
|
|
405
|
+
const body = JSON.parse(fetchStub.firstCall.args[1].body);
|
|
406
|
+
assert.equal(body.deviceName, "");
|
|
407
|
+
assert.equal(body.deviceRoom, "");
|
|
375
408
|
}));
|
|
376
409
|
});
|
|
377
410
|
describe("deviceInfo with compressed responses", () => {
|
|
@@ -380,7 +413,7 @@ describe("library", () => {
|
|
|
380
413
|
commands: { power: true },
|
|
381
414
|
temperatures: { enviroment: 19, board: 25 },
|
|
382
415
|
};
|
|
383
|
-
const
|
|
416
|
+
const mockResponseData = {
|
|
384
417
|
status: createGzippedBuffer(statusData),
|
|
385
418
|
nvm: {
|
|
386
419
|
user_parameters: {
|
|
@@ -388,11 +421,8 @@ describe("library", () => {
|
|
|
388
421
|
},
|
|
389
422
|
},
|
|
390
423
|
};
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
};
|
|
394
|
-
axiosStub.returns(mockAxios);
|
|
395
|
-
const api = configure("https://example.com/api");
|
|
424
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
425
|
+
const api = configure("https://example.com/api/");
|
|
396
426
|
const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
|
|
397
427
|
assert.deepEqual(result.status, statusData);
|
|
398
428
|
}));
|
|
@@ -406,18 +436,15 @@ describe("library", () => {
|
|
|
406
436
|
is_sound_active: true,
|
|
407
437
|
},
|
|
408
438
|
};
|
|
409
|
-
const
|
|
439
|
+
const mockResponseData = {
|
|
410
440
|
status: {
|
|
411
441
|
commands: { power: true },
|
|
412
442
|
temperatures: { enviroment: 19 },
|
|
413
443
|
},
|
|
414
444
|
nvm: createGzippedBuffer(nvmData),
|
|
415
445
|
};
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
};
|
|
419
|
-
axiosStub.returns(mockAxios);
|
|
420
|
-
const api = configure("https://example.com/api");
|
|
446
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
447
|
+
const api = configure("https://example.com/api/");
|
|
421
448
|
const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
|
|
422
449
|
assert.deepEqual(result.nvm, nvmData);
|
|
423
450
|
}));
|
|
@@ -435,15 +462,12 @@ describe("library", () => {
|
|
|
435
462
|
is_sound_active: false,
|
|
436
463
|
},
|
|
437
464
|
};
|
|
438
|
-
const
|
|
465
|
+
const mockResponseData = {
|
|
439
466
|
status: createGzippedBuffer(statusData),
|
|
440
467
|
nvm: createGzippedBuffer(nvmData),
|
|
441
468
|
};
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
};
|
|
445
|
-
axiosStub.returns(mockAxios);
|
|
446
|
-
const api = configure("https://example.com/api");
|
|
469
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
470
|
+
const api = configure("https://example.com/api/");
|
|
447
471
|
const result = yield api.deviceInfo(expectedToken, "mockMacAddress");
|
|
448
472
|
assert.deepEqual(result.status, statusData);
|
|
449
473
|
assert.deepEqual(result.nvm, nvmData);
|
|
@@ -453,15 +477,12 @@ describe("library", () => {
|
|
|
453
477
|
commands: { power: true },
|
|
454
478
|
temperatures: { enviroment: 19 },
|
|
455
479
|
};
|
|
456
|
-
const
|
|
480
|
+
const mockResponseData = {
|
|
457
481
|
status: createGzippedBuffer(statusData),
|
|
458
482
|
nvm: { user_parameters: { enviroment_1_temperature: 22 } },
|
|
459
483
|
};
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
};
|
|
463
|
-
axiosStub.returns(mockAxios);
|
|
464
|
-
const api = configure("https://example.com/api");
|
|
484
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
485
|
+
const api = configure("https://example.com/api/");
|
|
465
486
|
const result = yield api.getPower(expectedToken, "mockMacAddress");
|
|
466
487
|
assert.equal(result, true);
|
|
467
488
|
}));
|
|
@@ -470,15 +491,12 @@ describe("library", () => {
|
|
|
470
491
|
commands: { power: true },
|
|
471
492
|
temperatures: { enviroment: 19, board: 25 },
|
|
472
493
|
};
|
|
473
|
-
const
|
|
494
|
+
const mockResponseData = {
|
|
474
495
|
status: createGzippedBuffer(statusData),
|
|
475
496
|
nvm: { user_parameters: { enviroment_1_temperature: 22 } },
|
|
476
497
|
};
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
};
|
|
480
|
-
axiosStub.returns(mockAxios);
|
|
481
|
-
const api = configure("https://example.com/api");
|
|
498
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
499
|
+
const api = configure("https://example.com/api/");
|
|
482
500
|
const result = yield api.getEnvironmentTemperature(expectedToken, "mockMacAddress");
|
|
483
501
|
assert.equal(result, 19);
|
|
484
502
|
}));
|
|
@@ -488,17 +506,37 @@ describe("library", () => {
|
|
|
488
506
|
enviroment_1_temperature: 22,
|
|
489
507
|
},
|
|
490
508
|
};
|
|
491
|
-
const
|
|
509
|
+
const mockResponseData = {
|
|
492
510
|
status: { commands: { power: true }, temperatures: { enviroment: 19 } },
|
|
493
511
|
nvm: createGzippedBuffer(nvmData),
|
|
494
512
|
};
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
};
|
|
498
|
-
axiosStub.returns(mockAxios);
|
|
499
|
-
const api = configure("https://example.com/api");
|
|
513
|
+
fetchStub.resolves(mockResponse(mockResponseData));
|
|
514
|
+
const api = configure("https://example.com/api/");
|
|
500
515
|
const result = yield api.getTargetTemperature(expectedToken, "mockMacAddress");
|
|
501
516
|
assert.equal(result, 22);
|
|
502
517
|
}));
|
|
503
518
|
});
|
|
519
|
+
describe("Error Handling", () => {
|
|
520
|
+
const errorTests = [
|
|
521
|
+
{ status: 400, statusText: "Bad Request" },
|
|
522
|
+
{ status: 401, statusText: "Unauthorized" },
|
|
523
|
+
{ status: 404, statusText: "Not Found" },
|
|
524
|
+
{ status: 500, statusText: "Internal Server Error" },
|
|
525
|
+
];
|
|
526
|
+
errorTests.forEach(({ status, statusText }) => {
|
|
527
|
+
it(`should throw error when fetch returns ${status}`, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
528
|
+
const errorResponse = {
|
|
529
|
+
ok: false,
|
|
530
|
+
status,
|
|
531
|
+
statusText,
|
|
532
|
+
json: () => Promise.resolve({ error: statusText }),
|
|
533
|
+
};
|
|
534
|
+
fetchStub.resolves(errorResponse);
|
|
535
|
+
const api = configure("https://example.com/api/");
|
|
536
|
+
yield assert.rejects(() => __awaiter(void 0, void 0, void 0, function* () { return api.deviceInfo(expectedToken, "mockMac"); }), {
|
|
537
|
+
message: `HTTP ${status}: ${statusText}`,
|
|
538
|
+
});
|
|
539
|
+
}));
|
|
540
|
+
});
|
|
541
|
+
});
|
|
504
542
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom storage adapter for AWS Amplify that persists to file system.
|
|
3
|
+
* Used for CLI to maintain sessions between invocations.
|
|
4
|
+
*/
|
|
5
|
+
export declare const createFileStorage: () => {
|
|
6
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
7
|
+
getItem: (key: string) => Promise<string | null>;
|
|
8
|
+
removeItem: (key: string) => Promise<void>;
|
|
9
|
+
clear: () => Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Clears all stored session data.
|
|
13
|
+
*/
|
|
14
|
+
export declare const clearSession: () => Promise<void>;
|