particle-api-js 11.1.7 → 12.0.1

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.
Files changed (85) hide show
  1. package/README.md +90 -10
  2. package/dist/particle.min.js +1 -1
  3. package/dist/particle.min.js.map +1 -1
  4. package/fs.d.ts +2 -0
  5. package/lib/fs.d.ts +2 -0
  6. package/lib/fs.js +3 -0
  7. package/lib/package.json +110 -0
  8. package/lib/src/Agent.d.ts +40 -0
  9. package/lib/src/Agent.d.ts.map +1 -0
  10. package/lib/src/Agent.js +233 -0
  11. package/lib/src/Agent.js.map +1 -0
  12. package/lib/src/Client.d.ts +80 -0
  13. package/lib/src/Client.d.ts.map +1 -0
  14. package/lib/src/Client.js +104 -0
  15. package/lib/src/Client.js.map +1 -0
  16. package/lib/src/Defaults.d.ts +6 -0
  17. package/lib/src/Defaults.d.ts.map +1 -0
  18. package/lib/src/Defaults.js +12 -0
  19. package/lib/src/Defaults.js.map +1 -0
  20. package/lib/src/EventStream.d.ts +31 -0
  21. package/lib/src/EventStream.d.ts.map +1 -0
  22. package/lib/src/EventStream.js +275 -0
  23. package/lib/src/EventStream.js.map +1 -0
  24. package/lib/src/Library.d.ts +33 -0
  25. package/lib/src/Library.d.ts.map +1 -0
  26. package/lib/src/Library.js +19 -0
  27. package/lib/src/Library.js.map +1 -0
  28. package/{src/Particle.js → lib/src/Particle.d.ts} +623 -1779
  29. package/lib/src/Particle.d.ts.map +1 -0
  30. package/lib/src/Particle.js +2578 -0
  31. package/lib/src/Particle.js.map +1 -0
  32. package/lib/src/types/common.d.ts +73 -0
  33. package/lib/src/types/common.d.ts.map +1 -0
  34. package/lib/src/types/common.js +3 -0
  35. package/lib/src/types/common.js.map +1 -0
  36. package/lib/src/types/index.d.ts +4 -0
  37. package/lib/src/types/index.d.ts.map +1 -0
  38. package/lib/src/types/index.js +20 -0
  39. package/lib/src/types/index.js.map +1 -0
  40. package/lib/src/types/requests.d.ts +568 -0
  41. package/lib/src/types/requests.d.ts.map +1 -0
  42. package/lib/src/types/requests.js +3 -0
  43. package/lib/src/types/requests.js.map +1 -0
  44. package/lib/src/types/responses.d.ts +449 -0
  45. package/lib/src/types/responses.d.ts.map +1 -0
  46. package/lib/src/types/responses.js +3 -0
  47. package/lib/src/types/responses.js.map +1 -0
  48. package/package.json +35 -14
  49. package/scripts/postprocess-docs.js +306 -0
  50. package/typedoc.json +20 -0
  51. package/.circleci/config.yml +0 -104
  52. package/.nvmrc +0 -1
  53. package/CHANGELOG.md +0 -404
  54. package/EventStream-e2e-browser.html +0 -39
  55. package/EventStream-e2e-node.js +0 -34
  56. package/RELEASE.md +0 -12
  57. package/bower.json +0 -30
  58. package/docs/api.md +0 -2594
  59. package/eslint.config.mjs +0 -7
  60. package/examples/login/login.html +0 -17
  61. package/karma.conf.js +0 -80
  62. package/src/Agent.js +0 -397
  63. package/src/Client.js +0 -171
  64. package/src/Defaults.js +0 -8
  65. package/src/EventStream.js +0 -269
  66. package/src/Library.js +0 -33
  67. package/test/Agent.integration.js +0 -23
  68. package/test/Agent.spec.js +0 -488
  69. package/test/Client.spec.js +0 -216
  70. package/test/Defaults.spec.js +0 -30
  71. package/test/EventStream.feature +0 -65
  72. package/test/EventStream.spec.js +0 -263
  73. package/test/FakeAgent.js +0 -27
  74. package/test/Library.spec.js +0 -40
  75. package/test/Particle.integration.js +0 -38
  76. package/test/Particle.spec.js +0 -3198
  77. package/test/fixtures/index.js +0 -15
  78. package/test/fixtures/libraries.json +0 -33
  79. package/test/fixtures/library.json +0 -31
  80. package/test/fixtures/libraryVersions.json +0 -211
  81. package/test/out.tmp +0 -0
  82. package/test/support/FixtureHttpServer.js +0 -28
  83. package/test/test-setup.js +0 -17
  84. package/tsconfig.json +0 -17
  85. package/webpack.config.js +0 -46
@@ -1,488 +0,0 @@
1
- 'use strict';
2
- const FormData = require('form-data');
3
- const { sinon, expect } = require('./test-setup');
4
- const Agent = require('../src/Agent.js');
5
-
6
- describe('Agent', () => {
7
- beforeEach(() => {
8
- sinon.restore();
9
- });
10
-
11
- describe('constructor', () => {
12
- it('calls setBaseUrl', () => {
13
- const baseUrl = 'https://foo.com';
14
- sinon.stub(Agent.prototype, 'setBaseUrl');
15
- const agent = new Agent(baseUrl);
16
- expect(agent.setBaseUrl).to.have.property('callCount', 1);
17
- expect(agent.setBaseUrl.firstCall.args).to.have.lengthOf(1);
18
- expect(agent.setBaseUrl.firstCall.args[0]).to.eql(baseUrl);
19
- });
20
- });
21
-
22
- describe('sanitize files', () => {
23
- it('can call sanitize will falsy value', () => {
24
- const agent = new Agent();
25
- expect(agent._sanitizeFiles(undefined)).to.be.undefined;
26
- });
27
-
28
- it('sanitizes file names', () => {
29
- const agent = new Agent();
30
- const original = { one: 'content1', two: 'content2' };
31
- const actual = agent._sanitizeFiles(original);
32
- expect(actual).to.eql({
33
- 'file': {
34
- 'data': 'content1',
35
- 'path': 'one'
36
- },
37
- 'file2': {
38
- 'data': 'content2',
39
- 'path': 'two'
40
- }
41
- });
42
- });
43
- });
44
-
45
- describe('resource operations', () => {
46
- let uri, method, auth, headers, query, data, context, agent;
47
-
48
- beforeEach(() => {
49
- uri = 'http://example.com/v1';
50
- method = 'get';
51
- auth = 'fake-token';
52
- headers = { 'X-FOO': 'foo', 'X-BAR': 'bar' };
53
- query = 'foo=1&bar=2';
54
- data = { foo: true, bar: false };
55
- context = { blah: {} };
56
- agent = new Agent();
57
- agent.request = sinon.stub();
58
- agent.request.resolves('fake-response');
59
- });
60
-
61
- it('can GET a resource', () => {
62
- return agent.get({ uri, auth, headers, query, context }).then(() => {
63
- expect(agent.request).to.be.calledWith({ uri, method, auth, headers, query, context });
64
- });
65
- });
66
-
67
- it('can HEAD a resource', () => {
68
- method = 'head';
69
- return agent.head({ uri, auth, headers, query, context }).then(() => {
70
- expect(agent.request).to.be.calledWith({ uri, method, auth, headers, query, context });
71
- });
72
- });
73
-
74
- it('can POST a resource', () => {
75
- method = 'post';
76
- return agent.post({ uri, auth, headers, data, context }).then(() => {
77
- expect(agent.request).to.be.calledWith({ uri, method, auth, headers, data, context });
78
- });
79
- });
80
-
81
- it('can PUT a resource', () => {
82
- method = 'put';
83
- return agent.put({ uri, auth, headers, data, context, query }).then(() => {
84
- expect(agent.request).to.be.calledWith({ uri, method, auth, headers, data, context, query });
85
- });
86
- });
87
-
88
- it('can DELETE a resource', () => {
89
- method = 'delete';
90
- return agent.delete({ uri, auth, headers, data, context }).then(() => {
91
- expect(agent.request).to.be.calledWith({ uri, method, auth, headers, data, context });
92
- });
93
- });
94
- });
95
-
96
- describe('authorize', () => {
97
- let agent;
98
-
99
- beforeEach(() => {
100
- agent = new Agent();
101
- });
102
-
103
- it('authorize no auth is unchanged', () => {
104
- expect(agent._getAuthorizationHeader(undefined)).to.eql({});
105
- });
106
-
107
- it('authorize with bearer', () => {
108
- const auth = '123';
109
- const bearer = 'Bearer 123';
110
- const headers = agent._getAuthorizationHeader(auth);
111
- expect(headers).to.eql({ Authorization: bearer });
112
- });
113
- });
114
-
115
- describe('request', () => {
116
- let agent;
117
-
118
- beforeEach(() => {
119
- agent = new Agent();
120
- agent._promiseResponse = sinon.stub();
121
- agent._promiseResponse.resolves('fake-response');
122
- agent._buildRequest = sinon.stub();
123
- agent._sanitizeFiles = sinon.stub();
124
- });
125
-
126
- it('sanitizes files from a request', () => {
127
- const sanitizedFiles = { a:'a' };
128
- const files = {};
129
- const form = {};
130
- agent._sanitizeFiles.returns(sanitizedFiles);
131
-
132
- return agent.request({ uri: 'abc', method: 'post', data: '123', query: 'all', form, files })
133
- .then((res) => {
134
- expect(res).to.be.equal('fake-response');
135
- expect(agent._sanitizeFiles).calledOnce.calledWith(sinon.match.same(files));
136
- });
137
- });
138
-
139
- it('uses default arguments for request', () => {
140
- const args = ['abc', { args: '123' }];
141
- agent._buildRequest.returns(args);
142
- return agent.request({ uri: 'abc', method:'post' })
143
- .then((res) => {
144
- expect(res).to.be.equal('fake-response');
145
- expect(agent._promiseResponse).calledOnce.calledWith(args);
146
- });
147
- });
148
-
149
- it('builds and sends the request', () => {
150
- const agent = new Agent();
151
- const options = {
152
- uri: 'http://example.com/v1',
153
- method: 'get',
154
- auth: 'fake-token',
155
- headers: { 'X-FOO': 'foo', 'X-BAR': 'bar' },
156
- query: 'foo=1&bar=2',
157
- data: { foo: true, bar: false },
158
- files: undefined,
159
- form: undefined,
160
- context
161
- };
162
- agent._buildRequest = sinon.stub();
163
- agent._buildRequest.returns('fake-request');
164
- agent._promiseResponse = sinon.stub();
165
- agent._promiseResponse.resolves('fake-response');
166
-
167
- return agent.request(options).then((res) => {
168
- expect(res).to.be.equal('fake-response');
169
- expect(agent._buildRequest).calledOnce;
170
- expect(agent._buildRequest).calledWith(options);
171
- expect(agent._promiseResponse).calledOnce;
172
- expect(agent._promiseResponse).calledWith('fake-request');
173
- });
174
- });
175
-
176
- it('builds a promise to call _promiseResponse', () => {
177
- const agent = new Agent();
178
- const req = sinon.stub();
179
- const response = {
180
- ok: true,
181
- status: 200,
182
- json: () => Promise.resolve('response')
183
- };
184
- req.resolves(response);
185
- const promise = agent._promiseResponse([], false, req);
186
- expect(promise).has.property('then');
187
- return promise.then((resp) => {
188
- expect(resp).to.be.eql({
189
- body: 'response',
190
- statusCode: 200
191
- });
192
- });
193
- });
194
-
195
- it('can handle error responses', () => {
196
- const failResponseData = [
197
- {
198
- name: 'error text includes body error description',
199
- response: {
200
- status: 404,
201
- statusText: 'file not found',
202
- text: () => Promise.resolve('{"error_description": "file not found"}')
203
- },
204
- errorDescription: 'HTTP error 404 from 123.url - file not found'
205
- },
206
- {
207
- name: 'error text with no body description',
208
- response: {
209
- status: 404,
210
- text: () => Promise.resolve(''),
211
- },
212
- errorDescription: 'HTTP error 404 from 123.url'
213
- },
214
- {
215
- name: 'error text with no status',
216
- response: {},
217
- errorDescription: 'Network error from 123.url'
218
- }
219
- ];
220
- const agent = new Agent();
221
- const req = sinon.stub();
222
- const requests = failResponseData.map((failData) => {
223
- const response = Object.assign({
224
- ok: false
225
- }, failData.response);
226
- req.resolves(response);
227
- const promise = agent._promiseResponse(['123.url'] , false, req);
228
- return promise.catch((resp) => {
229
- expect(resp.statusCode).to.eql(failData.response.status);
230
- expect(resp.errorDescription).to.eql(failData.errorDescription);
231
- expect(resp.shortErrorDescription).to.eql(failData.response.statusText);
232
- });
233
- });
234
- return Promise.all(requests);
235
- });
236
- });
237
-
238
- describe('build request', () => {
239
- let agent;
240
-
241
- beforeEach(() => {
242
- agent = new Agent('abc');
243
- });
244
-
245
- it('uses a baseURL if provided', () => {
246
- const [uri] = agent._buildRequest({ uri: '/uri', method: 'get' });
247
- expect(uri).to.equal('abc/uri');
248
- });
249
-
250
- it('uses the provided uri if no baseURL is provided', () => {
251
- agent.setBaseUrl(undefined);
252
- const [uri] = agent._buildRequest({ uri: 'uri', method: 'get' });
253
- expect(uri).to.equal('uri');
254
- });
255
-
256
- it('generates context headers when one is provided', () => {
257
- const context = { tool: { name: 'spanner' } };
258
- const [, opts] = agent._buildRequest({ uri: '/uri', method: 'get', context });
259
- expect(opts.headers).to.have.property('X-Particle-Tool', 'spanner');
260
- });
261
-
262
- it('generates auth headers when an auth token is provided', () => {
263
- const auth = 'abcd-1235';
264
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get', auth });
265
- expect(opts.headers).to.have.property('Authorization', `Bearer ${auth}`);
266
- });
267
-
268
- it('adds new query params with the given query object', () => {
269
- const query = { foo: 1, bar: 2 };
270
- const [uri] = agent._buildRequest({ uri: '/uri', method: 'get', query });
271
- expect(uri).to.equal('abc/uri?foo=1&bar=2');
272
- });
273
-
274
- it('adds query params without colliding with existing ones', () => {
275
- const query = { foo: 1, bar: 2 };
276
- const [uri] = agent._buildRequest({ uri: '/uri?test=true', method: 'get', query });
277
- expect(uri).to.equal('abc/uri?test=true&foo=1&bar=2');
278
- });
279
-
280
- it('adds the provided data as a JSON request body', () => {
281
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get', data: { a: 'abcd' } });
282
- expect(opts.body).to.eql('{"a":"abcd"}');
283
- expect(opts.headers).to.have.property('Content-Type', 'application/json');
284
- });
285
-
286
- it('keeps the body as provided if it is a FormData instance', () => {
287
- const data = new FormData();
288
- data.append('file', 'data or blob');
289
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'put', data });
290
- expect(opts.body).to.eql(data);
291
- expect(opts.headers).to.not.have.property('Content-Type');
292
- });
293
-
294
- it('should setup form send when form data is given', () => {
295
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get', form: { a: 'abcd' } });
296
- expect(opts.body).to.eql('a=abcd');
297
- });
298
-
299
- it('should attach files', () => {
300
- const files = {
301
- file: { data: makeFile('filedata'), path: 'filepath' },
302
- file2: { data: makeFile('file2data'), path: 'file2path' }
303
- };
304
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get', files });
305
- expect(opts.body.toString()).to.equal('[object FormData]');
306
- expect(extractFilename(opts.body, 'file', 0)).to.eql('filepath');
307
- expect(extractFilename(opts.body, 'file2', 3)).to.eql('file2path');
308
- expect(opts.headers).to.not.have.property('Content-Type');
309
- });
310
-
311
- it('should attach files and form data', () => {
312
- const files = {
313
- file: { data: makeFile('filedata'), path: 'filepath' },
314
- file2: { data: makeFile('file2data'), path: 'file2path' }
315
- };
316
- const form = { form1: 'value1', form2: 'value2' };
317
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get', files, form });
318
- expect(opts.body.toString()).to.equal('[object FormData]');
319
- expect(extractFilename(opts.body, 'file', 0)).to.eql('filepath');
320
- expect(extractFilename(opts.body, 'file2', 3)).to.eql('file2path');
321
- expect(extractFormName(opts.body, 'form1', 6, true)).to.eql('value1');
322
- expect(extractFormName(opts.body, 'form2', 9, true)).to.eql('value2');
323
- expect(opts.headers).to.not.have.property('Content-Type');
324
- });
325
-
326
- it('should handle nested dirs', () => {
327
- const files = {
328
- file: { data: makeFile('filedata'), path: 'filepath.ino' },
329
- file2: { data: makeFile('file2data'), path: 'dir/file2path.cpp' }
330
- };
331
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get', files });
332
- expect(extractFilename(opts.body, 'file', 0)).to.eql('filepath.ino');
333
- expect(extractFilename(opts.body, 'file2', 3)).to.eql('dir/file2path.cpp');
334
- });
335
-
336
- it('sets the user agent to particle-api-js', () => {
337
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get' });
338
- expect(opts.headers).to.have.property('User-Agent').that.match(/^particle-api-js/);
339
- });
340
-
341
- if (!inBrowser()){
342
- it('should handle Windows nested dirs', () => {
343
- const files = {
344
- file: { data: makeFile('filedata'), path: 'dir\\windowsfilepath.cpp' }
345
- };
346
- const [, opts] = agent._buildRequest({ uri: 'uri', method: 'get', files });
347
- expect(extractFilename(opts.body, 'file', 0)).to.eql('dir/windowsfilepath.cpp');
348
- });
349
- }
350
-
351
- function inBrowser(){
352
- return typeof window !== 'undefined';
353
- }
354
-
355
- function makeFile(data){
356
- if (inBrowser()){
357
- return new Blob([data]);
358
- } else {
359
- return data;
360
- }
361
- }
362
-
363
- function extractFilename(formData, fieldName, fieldIndex){
364
- if (inBrowser()){
365
- return formData.get(fieldName).name;
366
- } else {
367
- return /filename="([^"]*)"/.exec(formData._streams[fieldIndex])[1];
368
- }
369
- }
370
-
371
- function extractFormName(formData, fieldName, fieldIndex){
372
- if (inBrowser()){
373
- return formData.get(fieldName);
374
- } else {
375
- return formData._streams[fieldIndex + 1];
376
- }
377
- }
378
- });
379
-
380
- describe('context', () => {
381
- let agent;
382
-
383
- beforeEach(() => {
384
- agent = new Agent();
385
- });
386
-
387
- describe('_nameAtVersion', () => {
388
- it('returns empty string when no name given', () => {
389
- expect(agent._nameAtVersion('', '1.2.3')).to.eql('');
390
- });
391
-
392
- it('returns just the name when no version given', () => {
393
- expect(agent._nameAtVersion('fred')).to.eql('fred');
394
- });
395
-
396
- it('returns name@version when both are given', () => {
397
- expect(agent._nameAtVersion('fred', '1.2.3')).to.eql('fred@1.2.3');
398
- });
399
- });
400
-
401
- describe('_getContextHeaders', () => {
402
- it('generates the tool context when defined', () => {
403
- const context = { tool: { name: 'spanner' } };
404
- const subject = agent._getContextHeaders(context);
405
- expect(subject).to.have.property('X-Particle-Tool', 'spanner');
406
- });
407
-
408
- it('does not add the tool context header when not defined',() => {
409
- const context = { tool: { name2: 'spanner' } };
410
- const subject = agent._getContextHeaders(context);
411
- expect(subject).to.not.have.property('X-Particle-Tool');
412
- });
413
-
414
- it('generates the project context header when defined',() => {
415
- const context = { project: { name: 'blinky' } };
416
- const subject = agent._getContextHeaders(context);
417
- expect(subject).to.have.property('X-Particle-Project', 'blinky');
418
- });
419
-
420
- it('does not generate the project context header when not defined',() => {
421
- const context = { project: { name2: 'blinky' } };
422
- const subject = agent._getContextHeaders(context);
423
- expect(subject).to.not.have.property('X-Particle-Project');
424
- });
425
- });
426
-
427
- describe('_getToolContext', () => {
428
- it('does not add a header when the tool name is not defined', () => {
429
- const tool = { noname: 'cli' };
430
- const subject = agent._getToolContext(tool);
431
- expect(subject).to.eql({});
432
- });
433
-
434
- it('adds a header when the tool is defined', () => {
435
- const tool = { name: 'cli' };
436
- const subject = agent._getToolContext(tool);
437
- expect(subject).to.eql({ 'X-Particle-Tool': 'cli' });
438
- });
439
-
440
- it('adds a header when the tool and components is defined', () => {
441
- const tool = {
442
- name: 'cli',
443
- version: '1.2.3',
444
- components: [
445
- { name: 'bar', version: 'a.b.c' },
446
- { name: 'foo', version: '0.0.1' }
447
- ]
448
- };
449
- const subject = agent._getToolContext(tool);
450
- expect(subject).to.eql({ 'X-Particle-Tool': 'cli@1.2.3, bar@a.b.c, foo@0.0.1' });
451
- });
452
- });
453
-
454
- describe('_addProjectContext', () => {
455
- it('adds a header when the project is defined', () => {
456
- const project = { name: 'blinky' };
457
- const subject = agent._getProjectContext(project);
458
- expect(subject).to.have.property('X-Particle-Project', 'blinky');
459
- });
460
-
461
- it('does not set the header when the project has no name', () => {
462
- const project = { noname: 'blinky' };
463
- const subject = agent._getProjectContext(project);
464
- expect(subject).to.not.have.property('X-Particle-Project');
465
- });
466
- });
467
-
468
- describe('_buildSemicolonSeparatedProperties', () => {
469
- const obj = { name: 'fred', color: 'pink' };
470
-
471
- it('returns empty string when no default property', () => {
472
- expect(agent._buildSemicolonSeparatedProperties(obj)).to.be.eql('');
473
- });
474
-
475
- it('returns empty string when default property does not exist', () => {
476
- expect(agent._buildSemicolonSeparatedProperties(obj, 'job')).to.be.eql('');
477
- });
478
-
479
- it('returns the default property only', () => {
480
- expect(agent._buildSemicolonSeparatedProperties({ name:'fred' }, 'name')).eql('fred');
481
- });
482
-
483
- it('returns the default property plus additional properties', () => {
484
- expect(agent._buildSemicolonSeparatedProperties(obj, 'name')).eql('fred; color=pink');
485
- });
486
- });
487
- });
488
- });
@@ -1,216 +0,0 @@
1
- 'use strict';
2
- const { expect, sinon } = require('./test-setup');
3
- const Client = require('../src/Client');
4
- const fixtures = require('./fixtures');
5
- const Library = require('../src/Library');
6
-
7
- let api;
8
- const token = 'tok';
9
- let client;
10
-
11
-
12
- describe('Client', () => {
13
- beforeEach(() => {
14
- api = {};
15
- client = new Client({ api: api, auth: token });
16
- });
17
-
18
- describe('constructor', () => {
19
- it('sets the auth token', () => {
20
- expect(client.auth).to.equal(token);
21
- });
22
- it('sets the api', () => {
23
- expect(client.api).to.equal(api);
24
- });
25
- });
26
-
27
- describe('libraries', () => {
28
- it('resolves to a list of Library objects', () => {
29
- api.listLibraries = () => Promise.resolve({ body: fixtures.read('libraries.json') });
30
- return client.libraries().then(libraries => {
31
- expect(libraries.length).to.equal(1);
32
- expect(libraries[0].name).to.equal('neopixel');
33
- });
34
- });
35
- });
36
-
37
- describe('library', () => {
38
- it('resolves to a Library objects', () => {
39
- api.getLibrary = () => Promise.resolve({ body: fixtures.read('library.json') });
40
- return client.library('neopixel').then(library => {
41
- expect(library.name).to.equal('neopixel');
42
- });
43
- });
44
- });
45
-
46
- describe('libraryVersions', () => {
47
- it('resolves to a Library objects', () => {
48
- api.getLibraryVersions = () => Promise.resolve({ body: fixtures.read('libraryVersions.json') });
49
- return client.libraryVersions().then(libraries => {
50
- expect(libraries.length).to.equal(9);
51
- expect(libraries[0].name).to.equal('neopixel');
52
- expect(libraries[0].version).to.equal('0.0.10');
53
- expect(libraries[1].version).to.equal('0.0.9');
54
- });
55
- });
56
- });
57
-
58
- describe('downloadFile', () => {
59
- it('delegates to api', () => {
60
- api.downloadFile = ({ uri }) => Promise.resolve(`${uri} delegated`);
61
- return expect(client.downloadFile('uri')).to.eventually.equal('uri delegated');
62
- });
63
- });
64
-
65
- describe('compileCode', () => {
66
- it('delegates to api', () => {
67
- api.compileCode = ({ files, platformId, targetVersion, auth }) => {
68
- return Promise.resolve([files, platformId, targetVersion, auth]);
69
- };
70
- return expect(client.compileCode('a', 'b', 'c')).to.eventually.eql(['a', 'b', 'c', client.auth]);
71
- });
72
- });
73
-
74
- describe('signalDevice', () => {
75
- it('delegates to api', () => {
76
- api.signalDevice = () => {
77
- return Promise.resolve([true, client.auth]);
78
- };
79
- return expect(client.signalDevice({ deviceId: 'testid', signal: true }))
80
- .to.eventually.eql([true, client.auth]);
81
- });
82
- });
83
-
84
- describe('publishLibrary', () => {
85
- it('delegates to api and returns the library metadata on success', () => {
86
- const name = 'fred';
87
- const metadata = { name };
88
- const library = new Library(client, metadata);
89
- api.publishLibrary = sinon.stub().resolves({ body: { data: metadata } });
90
- return client.publishLibrary(name)
91
- .then(actual => {
92
- expect(actual).to.eql(library);
93
- expect(api.publishLibrary).to.have.been.calledWith({ name, auth:token });
94
- });
95
- });
96
-
97
- it('delegates to api and calls _throwError to handle the error', () => {
98
- const error = { message:'I don\'t like vegetables' };
99
- api.publishLibrary = sinon.stub().rejects(error);
100
- const name = 'notused';
101
- return client.publishLibrary(name)
102
- .then(() => {
103
- throw new Error('expected an exception');
104
- })
105
- .catch(actual => {
106
- expect(actual).to.eql(error);
107
- expect(api.publishLibrary).to.have.been.calledWith({ name, auth:token });
108
- });
109
- });
110
- });
111
-
112
- describe('contributeLibrary', () => {
113
- it('delegates to api and returns the library metadata on success', () => {
114
- const archive = {};
115
- const metadata = { name:'' };
116
- const library = new Library(client, metadata);
117
- api.contributeLibrary = sinon.stub().resolves({ body: { data: metadata } });
118
- return client.contributeLibrary(archive)
119
- .then(actual => {
120
- expect(actual).to.eql(library);
121
- expect(api.contributeLibrary).to.have.been.calledWith({ archive, auth:token });
122
- });
123
- });
124
-
125
- it('delegates to api and calls _throwError to handle the error', () => {
126
- const archive = {};
127
- const error = { message:'I don\'t like vegetables' };
128
- api.contributeLibrary = sinon.stub().rejects(error);
129
- return client.contributeLibrary(archive)
130
- .then(() => {
131
- throw new Error('expected an exception');
132
- })
133
- .catch(actual => {
134
- expect(actual).to.eql(error);
135
- expect(api.contributeLibrary).to.have.been.calledWith({ archive, auth:token });
136
- });
137
- });
138
- });
139
-
140
- describe('listDevices', () => {
141
- it('delegates to api', () => {
142
- api.listDevices = ({ auth }) => {
143
- return Promise.resolve([auth]);
144
- };
145
- return expect(client.listDevices()).to.eventually.eql([client.auth]);
146
- });
147
- });
148
-
149
- describe('listBuildTargets', () => {
150
- it('delegates to api', () => {
151
- const response = {
152
- targets: [
153
- {
154
- platforms: [0, 6],
155
- prereleases: [],
156
- version: '1.2.3',
157
- firmware_vendor: 'Foo'
158
- }, {
159
- platforms: [6, 8],
160
- prereleases: [6],
161
- version: '4.5.6',
162
- firmware_vendor: 'Bar'
163
- }
164
- ]
165
- };
166
- const expected = [
167
- {
168
- version: '1.2.3',
169
- platform: 0,
170
- prerelease: false,
171
- firmware_vendor: 'Foo'
172
- }, {
173
- version: '1.2.3',
174
- platform: 6,
175
- prerelease: false,
176
-
177
- firmware_vendor: 'Foo'
178
- }, {
179
- version: '4.5.6',
180
- platform: 6,
181
- prerelease: true,
182
- firmware_vendor: 'Bar'
183
- }, {
184
- version: '4.5.6',
185
- platform: 8,
186
- prerelease: false,
187
- firmware_vendor: 'Bar'
188
- },
189
- ];
190
- api.listBuildTargets = () => {
191
- return Promise.resolve({ body: response });
192
- };
193
- return expect(client.listBuildTargets()).to.eventually.eql(expected);
194
- });
195
- });
196
-
197
- describe('trackingIdentity', () => {
198
- it('delegates to api and unpacks the body', () => {
199
- api.trackingIdentity = ({ auth, full, context }) => {
200
- return Promise.resolve({ body: { auth, full, context } });
201
- };
202
- const context = { abd:123 };
203
- const full = 456;
204
- return expect(client.trackingIdentity({ full, context })).to.eventually.eql({ auth: client.auth, full, context });
205
- });
206
-
207
- it('delegates to api with default parameters and unpacks the body', () => {
208
- api.trackingIdentity = ({ auth, full, context }) => {
209
- return Promise.resolve({ body: { auth, full, context } });
210
- };
211
- const context = undefined;
212
- const full = false;
213
- return expect(client.trackingIdentity()).to.eventually.eql({ auth:client.auth, full, context });
214
- });
215
- });
216
- });