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

suculent / thinx-device-api / #252646768

01 Nov 2025 03:31PM UTC coverage: 46.298% (-25.7%) from 71.971%
#252646768

push

suculent
testing upgraded mqtt package

1123 of 3470 branches covered (32.36%)

Branch coverage included in aggregate %.

5324 of 10455 relevant lines covered (50.92%)

4.07 hits per line

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

37.89
/spec/jasmine/ZZ-RouterSourcesSpec.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
var envi = require("../_envi.json");
1✔
11

12
let thx;
13

14
describe("Sources (noauth)", function () {
1✔
15

16
    beforeAll((done) => {
1✔
17
        console.log(`🚸 [chai] >>> running Sources (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 Sources (noauth) spec`);
1✔
26
    });
27

28
    it("GET /api/user/sources/list", function (done) {
1✔
29
        chai.request(thx.app)
×
30
            .get('/api/user/sources/list')
31
            .end((err, res) => {
32
                expect(res.status).to.equal(401);
×
33
                done();
×
34
            });
35
    }, 30000);
36

37
    it("POST /api/user/source", function (done) {
1✔
38
        chai.request(thx.app)
×
39
            .post('/api/user/source')
40
            .send({})
41
            .end((err, res) => {
42
                expect(res.status).to.equal(401);
×
43
                done();
×
44
            });
45
    }, 30000);
46

47
    it("POST /api/user/source/revoke (invalid)", function (done) {
1✔
48
        chai.request(thx.app)
×
49
            .post('/api/user/source/revoke')
50
            .send({ key_id: null })
51
            .end((err, res) => {
52
                expect(res.status).to.equal(401);
×
53
                done();
×
54
            });
55
    }, 30000);
56
});
57

58
describe("Sources (JWT)", function () {
1✔
59

60
    let agent;
61
    let jwt;
62
  
63
    beforeAll((done) => {
1✔
64
        console.log(`🚸 [chai] >>> running Sources (JWT) spec`);
1✔
65
        agent = chai.request.agent(thx.app);
1✔
66
        agent
1✔
67
            .post('/api/login')
68
            .send({ username: 'dynamic', password: 'dynamic', remember: false })
69
            .catch((e) => { console.log(e); })
×
70
            .then(function (res) {
71
                expect(res).to.have.cookie('x-thx-core');
1✔
72
                let body = JSON.parse(res.text);
×
73
                jwt = 'Bearer ' + body.access_token;
×
74
                done();
×
75
            });
76
    });
77
  
78
    afterAll((done) => {
1✔
79
        agent.close();
1✔
80
        console.log(`🚸 [chai] <<< completed Sources (JWT) spec`);
1✔
81
        done();
1✔
82
    });
83

84
    let source_for_revocation = null;
1✔
85

86
    let mock_source = {
1✔
87
        owner: envi.dynamic.oid,
88
        alias: "mock-source",
89
        url: "https://github.com/suculent/thinx-firmware-esp8266-pio.git",
90
        branch: "master",
91
        secret: process.env.GITHUB_SECRET
92
      };
93

94
    it("GET /api/user/sources/list (valid)", function (done) {
1✔
95
        chai.request(thx.app)
×
96
            .get('/api/user/sources/list')
97
            .set('Authorization', jwt)
98
            .end((err, res) => {
99
                console.log("[chai] GET /api/user/sources/list (valid)", res.text);
×
100
                expect(res.status).to.equal(200);
×
101
                let j = JSON.parse(res.text);
×
102
                expect(j.success).to.equal(true);
×
103
                expect(j.response).to.be.an('object');
×
104
                done();
×
105
            });
106
    }, 30000);
107

108

109
    it("GET /api/v2/source", function (done) {
1✔
110
        chai.request(thx.app)
×
111
            .get('/api/v2/source')
112
            .set('Authorization', jwt)
113
            .end((err, res) => {
114
                console.log("[chai] GET /api/v2/source", res.text);
×
115
                expect(res.status).to.equal(200);
×
116
                let j = JSON.parse(res.text);
×
117
                expect(j.success).to.equal(true);
×
118
                expect(j.response).to.be.an('object');
×
119
                done();
×
120
            });
121
    }, 30000);
122

123
    it("POST /api/user/source (invalid)", function (done) {
1✔
124
        chai.request(thx.app)
×
125
            .post('/api/user/source')
126
            .set('Authorization', jwt)
127
            .send({})
128
            .end((err, res) => {
129
                expect(res.status).to.equal(200);
×
130
                expect(res.text).to.equal('{"success":false,"response":"missing_source_alias"}');
×
131
                done();
×
132
            });
133
    }, 30000);
134

135
    it("POST /api/user/source (semi-valid, does not fetch)", function (done) {
1✔
136
        chai.request(thx.app)
×
137
            .post('/api/user/source')
138
            .set('Authorization', jwt)
139
            .send(mock_source)
140
            .end((err, res) => {
141
                console.log("[chai] POST /api/user/source (semi-valid, does not fetch) response:", res.text);
×
142
                expect(res.text).to.be.a('string');
×
143
                let r = JSON.parse(res.text);
×
144
                expect(res.status).to.equal(200);
×
145
                expect(r.success).to.equal(true);
×
146
                done();
×
147
            });
148
    }, 30000);
149

150
    it("PUT /api/v2/source (semi-valid, does not fetch)", function (done) {
1✔
151
        chai.request(thx.app)
×
152
            .put('/api/v2/source')
153
            .set('Authorization', jwt)
154
            .send(mock_source)
155
            .end((err, res) => {
156
                console.log("[chai] PUT /api/v2/source (semi-valid, does not fetch) response:", res.text);
×
157
                expect(res.text).to.be.a('string');
×
158
                let r = JSON.parse(res.text);
×
159
                expect(res.status).to.equal(200);
×
160
                expect(r.success).to.equal(true);
×
161
                done();
×
162
            });
163
    }, 30000);
164

165
    it("POST /api/user/source/revoke", function (done) {
1✔
166
        expect(source_for_revocation !== 0);
×
167
        chai.request(thx.app)
×
168
            .post('/api/user/source/revoke')
169
            .set('Authorization', jwt)
170
            .send({ source_id: null })
171
            .end((err, res) => {
172
                expect(res.status).to.equal(200);
×
173
                expect(res.text).to.equal('{"success":false,"response":"missing_source_ids"}');
×
174
                done();
×
175
            });
176
    }, 30000);
177

178
    it("POST /api/user/source/revoke (valid)", function (done) {
1✔
179
        chai.request(thx.app)
×
180
            .post('/api/user/source/revoke')
181
            .set('Authorization', jwt)
182
            .send({ source_ids: source_for_revocation })
183
            .end((err, res) => {
184
                expect(res.status).to.equal(200);
×
185
                expect(res.text).to.equal('{"success":true,"source_ids":[]}');
×
186
                done();
×
187
            });
188
    }, 30000);
189

190
    it("DELETE /api/user/source/revoke (valid)", function (done) {
1✔
191
        chai.request(thx.app)
×
192
            .delete('/api/v2/source')
193
            .set('Authorization', jwt)
194
            .send({ source_ids: source_for_revocation })
195
            .end((err, res) => {
196
                console.log("🚸 [chai] DELETE /api/v2/source response:", res.text, res.status);
×
197
                expect(res.status).to.equal(200);
×
198
                // expect(res.text).to.equal('{"success":true,"source_ids":[]}'); already deleted
199
                done();
×
200
            });
201
    }, 30000);
202
});
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