• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

suculent / thinx-device-api / #252646960

14 Mar 2026 04:35PM UTC coverage: 52.052% (-10.0%) from 62.077%
#252646960

push

suculent
Revert test bootstrap experiments to baseline

1399 of 3653 branches covered (38.3%)

Branch coverage included in aggregate %.

27 of 40 new or added lines in 3 files covered. (67.5%)

1153 existing lines in 32 files now uncovered.

5996 of 10554 relevant lines covered (56.81%)

10.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

29.03
/spec/jasmine/ZZ-RouterTransferSpec.js
1
/* Router integration test only; does not have to cover full unit functionality. */
2

3
const THiNX = require("../../thinx-core.js");
1✔
4

5
let chai = require('chai');
1✔
6
var expect = require('chai').expect;
1✔
7
let chaiHttp = require('chai-http');
1✔
8
chai.use(chaiHttp);
1✔
9

10
let thx;
11

12
var envi = require("../_envi.json");
1✔
13

14
describe("Device Ownership Transfer (noauth)", function () {
1✔
15

16
    beforeAll((done) => {
1✔
17
        console.log(`🚸 [chai] >>> running Transfer (noauth) spec`);
1✔
18
        thx = new THiNX();
1✔
19
        thx.init(() => {
1✔
20
            done();
×
21
        });
22
    });
23

24
    afterAll(() => {
1✔
25
        console.log(`🚸 [chai] <<< completed Transfer (noauth) spec`);
1✔
26
    });
27

28
    it("POST /api/transfer/request (noauth, invalid)", function (done) {
1✔
29
        chai.request(thx.app)
×
30
            .post('/api/transfer/request')
31
            .send({})
32
            .end((_err, res) => {
33
                expect(res.status).to.equal(401);
×
34
                done();
×
35
            });
36
    }, 30000);
37

38
    it("GET /api/transfer/decline (noauth, invalid)", function (done) {
1✔
39
        chai.request(thx.app)
×
40
            .get('/api/transfer/decline')
41
            .end((_err, res) => {
42
                expect(res.status).to.equal(400);
×
43
                expect(res.text).to.be.a('string'); // <html>
×
44
                done();
×
45
            });
46
    }, 30000);
47

48
    it("POST /api/transfer/decline (noauth, invalid)", function (done) {
1✔
49
        chai.request(thx.app)
×
50
            .post('/api/transfer/decline')
51
            .send({})
52
            .end((_err, res) => {
53
                expect(res.status).to.equal(401);
×
54
                done();
×
55
            });
56
    }, 30000);
57

58
    it("GET /api/transfer/accept (noauth, invalid)", function (done) {
1✔
59
        chai.request(thx.app)
×
60
            .get('/api/transfer/accept')
61
            .end((_err, res) => {
62
                expect(res.status).to.equal(400);
×
63
                expect(res.text).to.be.a('string');
×
64
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
65
                done();
×
66
            });
67
    }, 30000);
68

69
    it("POST /api/transfer/accept (noauth, invalid)", function (done) {
1✔
70
        chai.request(thx.app)
×
71
            .get('/api/transfer/accept')
72
            .send({})
73
            .end((_err, res) => {
74
                expect(res.status).to.equal(400);
×
75
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
76
                done();
×
77
            });
78
    }, 30000);
79
});
80

81
describe("Transfer (JWT)", function () {
1✔
82

83
    let agent;
84
    let jwt;
85
    let transfer_id;
86
  
87
    beforeAll((done) => {
1✔
88
        console.log(`🚸 [chai] >>> running Transfer (JWT) spec`);
1✔
89
        agent = chai.request.agent(thx.app);
1✔
90
        agent
1✔
91
            .post('/api/login')
92
            .send({ username: 'dynamic', password: 'dynamic', remember: false })
93
            .catch((e) => { console.log(e); })
×
94
            .then(function (res) {
95
                expect(res).to.have.cookie('x-thx-core');
1✔
UNCOV
96
                let body = JSON.parse(res.text);
×
UNCOV
97
                jwt = 'Bearer ' + body.access_token;
×
UNCOV
98
                done();
×
99
            });
100
    });
101

102
    afterAll((done) => {
1✔
103
        agent.close();
1✔
104
        if (thx && thx.server) thx.server.close();
1!
105
        console.log(`🚸 [chai] <<< completed Transfer (JWT) spec`);
1✔
106
        done();
1✔
107
    });
108

109
    // save trid for accept and decline, create valid version of this; needs at least two owners and one device
110
    it("POST /api/transfer/request (jwt, invalid)", function (done) {
1✔
UNCOV
111
        chai.request(thx.app)
×
112
            .post('/api/transfer/request')
113
            .set('Authorization', jwt)
114
            .send({})
115
            .end((_err, res) => {
UNCOV
116
                expect(res.status).to.equal(200);
×
UNCOV
117
                expect(res.text).to.be.a('string'); 
×
UNCOV
118
                expect(res.text).to.equal('{"success":false,"response":"missing_recipient"}');
×
UNCOV
119
                done();
×
120
            });
121
    }, 30000);
122

123
    // migrate using invalid data (owner_id instead of e-mail)
124
    it("POST /api/transfer/request (jwt, semi-valid)", function (done) {
1✔
UNCOV
125
        chai.request(thx.app)
×
126
            .post('/api/transfer/request')
127
            .set('Authorization', jwt)
128
            .send({ to: envi.dynamic.owner, udids: [envi.udid], mig_sources: true, mig_apikeys: true })
129
            .end((_err, res) => {
UNCOV
130
                expect(res.status).to.equal(200);
×
UNCOV
131
                expect(res.text).to.be.a('string'); 
×
UNCOV
132
                expect(res.text).to.equal('{"success":false,"response":"recipient_unknown"}');
×
UNCOV
133
                done();
×
134
            });
135
    }, 30000);
136

137
    // migrate from dynamic owner to cimrman
138
    it("POST /api/transfer/request (jwt, valid)", function (done) {
1✔
UNCOV
139
        chai.request(thx.app)
×
140
            .post('/api/transfer/request')
141
            .set('Authorization', jwt)
142
            .send({ to: "cimrman@thinx.cloud", udids: [envi.udid], mig_sources: false, mig_apikeys: false })
143
            .end((_err, res) => {
UNCOV
144
                console.log("🚸 [chai] POST /api/transfer/request (jwt, valid) response: ", res.text);
×
UNCOV
145
                expect(res.status).to.equal(200);
×
UNCOV
146
                expect(res.text).to.be.a('string'); 
×
UNCOV
147
                let j = JSON.parse(res.text);
×
UNCOV
148
                transfer_id = j.response;
×
UNCOV
149
                expect(j.success).to.equal(true);
×
UNCOV
150
                done();
×
151
            });
152
    }, 30000);
153

154
    it("GET /api/transfer/decline (jwt, invalid)", function (done) {
1✔
UNCOV
155
        chai.request(thx.app)
×
156
            .get('/api/transfer/decline')
157
            .set('Authorization', jwt)
158
            .end((_err, res) => {
UNCOV
159
                expect(res.status).to.equal(400);
×
UNCOV
160
                expect(res.text).to.be.a('string'); // <html>
×
UNCOV
161
                done();
×
162
            });
163
    }, 30000);
164

165
    it("POST /api/transfer/decline (jwt, invalid)", function (done) {
1✔
UNCOV
166
        chai.request(thx.app)
×
167
            .post('/api/transfer/decline')
168
            .set('Authorization', jwt)
169
            .send({})
170
            .end((_err, res) => {
UNCOV
171
                expect(res.status).to.equal(400);
×
UNCOV
172
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
UNCOV
173
                done();
×
174
            });
175
    }, 30000);
176

177
    it("GET /api/transfer/accept (jwt, invalid)", function (done) {
1✔
UNCOV
178
        chai.request(thx.app)
×
179
            .get('/api/transfer/accept')
180
            .set('Authorization', jwt)
181
            .end((_err, res) => {
UNCOV
182
                expect(res.status).to.equal(400);
×
UNCOV
183
                expect(res.text).to.be.a('string');
×
UNCOV
184
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
UNCOV
185
                done();
×
186
            });
187
    }, 30000);
188

189
    it("POST /api/transfer/accept (jwt, invalid)", function (done) {
1✔
UNCOV
190
        chai.request(thx.app)
×
191
            .post('/api/transfer/accept')
192
            .set('Authorization', jwt)
193
            .send({})
194
            .end((_err, res) => {
UNCOV
195
                expect(res.status).to.equal(400);
×
UNCOV
196
                expect(res.text).to.be.a('string');
×
UNCOV
197
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
UNCOV
198
                done();
×
199
            });
200
    }, 30000);
201

202
    it("POST /api/transfer/accept (noauth, null)", function (done) {
1✔
UNCOV
203
        chai.request(thx.app)
×
204
            .get('/api/transfer/accept')
205
            .set('Authorization', jwt)
206
            .send({ owner: null, transfer_id: null, udid: null})
207
            .end((_err, res) => {
UNCOV
208
                expect(res.status).to.equal(400);
×
UNCOV
209
                expect(res.text).to.be.a('string');
×
UNCOV
210
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
UNCOV
211
                done();
×
212
            });
213
    }, 30000);
214

215
    // v2
216

217
    it("POST /api/v2/transfer/request (jwt, invalid)", function (done) {
1✔
UNCOV
218
        chai.request(thx.app)
×
219
            .post('/api/v2/transfer/request')
220
            .set('Authorization', jwt)
221
            .send({})
222
            .end((_err, res) => {
UNCOV
223
                expect(res.status).to.equal(200);
×
UNCOV
224
                expect(res.text).to.be.a('string');
×
UNCOV
225
                expect(res.text).to.equal('{"success":false,"response":"missing_recipient"}');
×
UNCOV
226
                done();
×
227
            });
228
    }, 30000);
229

230
    it("GET /api/v2/transfer/decline (jwt, invalid)", function (done) {
1✔
UNCOV
231
        chai.request(thx.app)
×
232
            .get('/api/v2/transfer/decline')
233
            .set('Authorization', jwt)
234
            .end((_err, res) => {
UNCOV
235
                expect(res.status).to.equal(400);
×
UNCOV
236
                expect(res.text).to.be.a('string'); // <html>
×
UNCOV
237
                done();
×
238
            });
239
    }, 30000);
240

241
    it("POST /api/v2/transfer/decline (jwt, missing transfer_id)", function (done) {
1✔
UNCOV
242
        chai.request(thx.app)
×
243
            .post('/api/v2/transfer/decline')
244
            .set('Authorization', jwt)
245
            .send({ udid: null})
246
            .end((_err, res) => {
UNCOV
247
                expect(res.status).to.equal(400);
×
UNCOV
248
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
UNCOV
249
                done();
×
250
            });
251
    }, 30000);
252

253
    it("POST /api/v2/transfer/decline (jwt, missing owner)", function (done) {
1✔
UNCOV
254
        chai.request(thx.app)
×
255
            .post('/api/v2/transfer/decline')
256
            .set('Authorization', jwt)
257
            .send({ udid: null, transfer_id: transfer_id })
258
            .end((_err, res) => {
UNCOV
259
                expect(res.status).to.equal(400);
×
UNCOV
260
                expect(res.text).to.be.a('string');
×
UNCOV
261
                expect(res.text).to.equal('{"success":false,"response":"owner_missing"}');
×
UNCOV
262
                done();
×
263
            });
264
    }, 30000);
265

266
    it("POST /api/v2/transfer/decline (jwt, invalid) 2", function (done) {
1✔
UNCOV
267
        chai.request(thx.app)
×
268
            .post('/api/v2/transfer/decline')
269
            .set('Authorization', jwt)
270
            .send({ udid: null, transfer_id: transfer_id, owner: envi.dynamic.owner })
271
            .end((_err, res) => {
UNCOV
272
                expect(res.status).to.equal(400);
×
UNCOV
273
                expect(res.text).to.be.a('string');
×
UNCOV
274
                expect(res.text).to.equal('{"success":false,"response":"udids_missing"}');
×
UNCOV
275
                done();
×
276
            });
277
    }, 30000);
278

279
    it("GET /api/v2/transfer/decline (jwt, invalid) 2", function (done) {
1✔
UNCOV
280
        chai.request(thx.app)
×
281
            .post('/api/v2/transfer/decline')
282
            .set('Authorization', jwt)
283
            .send({ transfer_id: "transfer_id", owner: envi.dynamic.owner })
284
            .end((_err, res) => {
UNCOV
285
                expect(res.status).to.equal(400);
×
UNCOV
286
                expect(res.text).to.be.a('string');
×
UNCOV
287
                expect(res.text).to.equal('{"success":false,"response":"udids_missing"}');
×
UNCOV
288
                done();
×
289
            });
290
    }, 30000);
291

292
    it("GET /api/v2/transfer/accept (jwt, invalid)", function (done) {
1✔
UNCOV
293
        chai.request(thx.app)
×
294
            .get('/api/v2/transfer/accept')
295
            .set('Authorization', jwt)
296
            .end((_err, res) => {
UNCOV
297
                expect(res.status).to.equal(400);
×
UNCOV
298
                expect(res.text).to.be.a('string');
×
UNCOV
299
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
UNCOV
300
                done();
×
301
            });
302
    }, 30000);
303

304
    it("POST /api/v2/transfer/accept (jwt, invalid)", function (done) {
1✔
UNCOV
305
        chai.request(thx.app)
×
306
            .post('/api/v2/transfer/accept')
307
            .set('Authorization', jwt)
308
            .send({ udid: null, transfer_id: transfer_id })
309
            .end((_err, res) => {
UNCOV
310
                expect(res.status).to.equal(400);
×
UNCOV
311
                expect(res.text).to.be.a('string');
×
UNCOV
312
                expect(res.text).to.equal('{"success":false,"response":"owner_missing"}');
×
UNCOV
313
                done();
×
314
            });
315
    }, 30000);
316

317
    it("POST /api/v2/transfer/accept (jwt, invalid) 2", function (done) {
1✔
UNCOV
318
        chai.request(thx.app)
×
319
            .post('/api/v2/transfer/accept')
320
            .set('Authorization', jwt)
321
            .send({ udids: null, transfer_id: transfer_id, owner: envi.dynamic.owner })
322
            .end((_err, res) => {
UNCOV
323
                expect(res.status).to.equal(400);
×
UNCOV
324
                expect(res.text).to.be.a('string');
×
UNCOV
325
                expect(res.text).to.equal('{"success":false,"response":"udids_missing"}');
×
UNCOV
326
                done();
×
327
            });
328
    }, 30000);
329

330
    it("POST /api/v2/transfer/accept III", function (done) {
1✔
UNCOV
331
        chai.request(thx.app)
×
332
            .post('/api/v2/transfer/accept')
333
            .set('Authorization', jwt)
334
            .send({ udids: [envi.dynamic.udid], transfer_id: transfer_id, owner: envi.dynamic.owner }) // will probably need real device using GET /api/device
335
            .end((_err, res) => {
UNCOV
336
                expect(res.status).to.equal(200);
×
UNCOV
337
                expect(res.text).to.be.a('string');
×
UNCOV
338
                done();
×
339
            });
340
    }, 30000);
341

342
    it("POST /api/v2/transfer/decline IV", function (done) {
1✔
UNCOV
343
        chai.request(thx.app)
×
344
            .post('/api/v2/transfer/decline')
345
            .set('Authorization', jwt)
346
            .send({ udids: [envi.dynamic.udid], transfer_id: transfer_id, owner: envi.dynamic.owner }) // will probably need real device using GET /api/device
347
            .end((_err, res) => {
UNCOV
348
                expect(res.status).to.equal(200);
×
UNCOV
349
                expect(res.text).to.be.a('string');
×
UNCOV
350
                expect(res.text).to.equal('{"success":true,"response":"decline_complete_no_such_dtid"}');
×
351
                // returns HTML
UNCOV
352
                done();
×
353
            });
354
    }, 30000);
355

356
    it("GET /api/v2/transfer/decline V", function (done) {
1✔
UNCOV
357
        chai.request(thx.app)
×
358
            .get('/api/v2/transfer/decline')
359
            .set('Authorization', jwt)
360
            .send({ udids: [envi.dynamic.udid], transfer_id: transfer_id, owner: envi.dynamic.owner }) // will probably need real device using GET /api/device
361
            .end((_err, res) => {
UNCOV
362
                expect(res.status).to.equal(400);
×
UNCOV
363
                expect(res.text).to.be.a('string');
×
UNCOV
364
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
365
                // returns HTML
UNCOV
366
                done();
×
367
            });
368
    }, 30000);
369

370
    it("POST /api/v2/transfer/accept (jwt, null)", function (done) {
1✔
UNCOV
371
        chai.request(thx.app)
×
372
            .get('/api/v2/transfer/accept')
373
            .set('Authorization', jwt)
374
            .send({ owner: null, transfer_id: null, udids: null})
375
            .end((_err, res) => {
UNCOV
376
                expect(res.status).to.equal(400);
×
UNCOV
377
                expect(res.text).to.be.a('string');
×
UNCOV
378
                expect(res.text).to.equal('{"success":false,"response":"transfer_id_missing"}');
×
UNCOV
379
                done();
×
380
            });
381
    }, 30000);
382

383
    it("GET /api/v2/transfer/accept (jwt, null)", function (done) {
1✔
UNCOV
384
        chai.request(thx.app)
×
385
            .get('/api/v2/transfer/accept?transfer_id='+transfer_id)
386
            .set('Authorization', jwt)
387
            .end((_err, res) => {
UNCOV
388
                expect(res.status).to.equal(200);
×
UNCOV
389
                expect(res.text).to.be.a('string');
×
UNCOV
390
                done();
×
391
            });
392
    }, 30000);
393
                
394
});
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc