update dependencies and devDependencies, fix lint issues
[squeep-indie-auther] / test / src / service.js
1 'use strict';
2
3 const assert = require('assert');
4 const sinon = require('sinon');
5 const { AsyncLocalStorage } = require('node:async_hooks');
6
7 const StubDb = require('../stub-db');
8 const StubLogger = require('../stub-logger');
9 const Service = require('../../src/service');
10 const Config = require('../../config');
11
12
13 describe('Service', function () {
14 let service, stubLogger, stubDb, options, asyncLocalStorage;
15 let req, res, ctx;
16
17 beforeEach(function () {
18 asyncLocalStorage = new AsyncLocalStorage();
19 options = new Config('test');
20 stubDb = new StubDb();
21 stubDb._reset();
22 stubLogger = new StubLogger();
23 stubLogger._reset();
24 service = new Service(stubLogger, stubDb, options, asyncLocalStorage);
25 sinon.stub(service.manager);
26 sinon.stub(service.sessionManager);
27 sinon.stub(service.authenticator);
28 sinon.stub(service.resourceAuthenticator);
29 sinon.stub(service, 'setResponseType');
30 sinon.stub(service, 'serveFile');
31 sinon.stub(service, 'ingestBody').resolves();
32 req = {
33 getHeader: sinon.stub(),
34 };
35 res = {
36 setHeader: sinon.stub(),
37 write: sinon.stub(),
38 end: sinon.stub(),
39 };
40 ctx = {
41 params: {},
42 };
43 });
44
45 afterEach(function () {
46 sinon.restore();
47 });
48
49 it('instantiates', function () {
50 assert(service);
51 });
52
53 it('instantiates with config coverage', async function () {
54 options.dingus.selfBaseUrl = 'https://example.com/';
55 service = new Service(stubLogger, stubDb, options);
56 assert(service);
57 });
58
59 it('instantiates with config coverage', async function () {
60 delete options.dingus.selfBaseUrl;
61 service = new Service(stubLogger, stubDb, options);
62 assert(service);
63 });
64
65 describe('initialize', function () {
66 it('covers', async function () {
67 await service.initialize();
68 assert(service.manager.initialize.called);
69 });
70 }); // initialize
71
72 describe('preHandler', async function () {
73 it('persists url into context', async function () {
74 req.url = 'https://example.com/foo';
75 sinon.stub(service.__proto__.__proto__, 'preHandler').resolves();
76 await service.asyncLocalStorage.run({}, async () => {
77 await service.preHandler(req, res, ctx);
78 const logObject = service.asyncLocalStorage.getStore();
79 assert('requestId' in logObject);
80 });
81 assert.strictEqual(ctx.url, req.url);
82 });
83 }); // preHandler
84
85 describe('handlerGetAdminLogin', function () {
86 it('covers', async function () {
87 await service.handlerGetAdminLogin(req, res, ctx);
88 assert(service.sessionManager.getAdminLogin.called);
89 });
90 }); // handlerGetAdminLogin
91
92 describe('handlerPostAdminLogin', function () {
93 it('covers', async function () {
94 await service.handlerPostAdminLogin(req, res, ctx);
95 assert(service.sessionManager.postAdminLogin.called);
96 });
97 }); // handlerPostAdminLogin
98
99 describe('handlerGetAdminLogout', function () {
100 it('covers', async function () {
101 await service.handlerGetAdminLogout(req, res, ctx);
102 assert(service.sessionManager.getAdminLogout.called);
103 });
104 }); // handlerGetAdminLogout
105
106 describe('handlerGetAdminSettings', function () {
107 it('covers authenticated', async function () {
108 service.authenticator.sessionRequiredLocal.resolves(true);
109 await service.handlerGetAdminSettings(req, res, ctx);
110 assert(service.sessionManager.getAdminSettings.called);
111 });
112 it('covers unauthenticated', async function () {
113 service.authenticator.sessionRequiredLocal.resolves(false);
114 await service.handlerGetAdminSettings(req, res, ctx);
115 assert(service.sessionManager.getAdminSettings.notCalled);
116 });
117 }); // handlerGetAdminSettings
118
119 describe('handlerPostAdminSettings', function () {
120 it('covers authenticated', async function () {
121 service.authenticator.sessionRequiredLocal.resolves(true);
122 await service.handlerPostAdminSettings(req, res, ctx);
123 assert(service.sessionManager.postAdminSettings.called);
124 });
125 it('covers unauthenticated', async function () {
126 service.authenticator.sessionRequiredLocal.resolves(false);
127 await service.handlerPostAdminSettings(req, res, ctx);
128 assert(service.sessionManager.postAdminSettings.notCalled);
129 });
130 }); // handlerPostAdminSettings
131
132 describe('handlerGetAdmin', function () {
133 it('covers authenticated', async function () {
134 service.authenticator.sessionRequiredLocal.resolves(true);
135 await service.handlerGetAdmin(req, res, ctx);
136 assert(service.manager.getAdmin.called);
137 });
138 it('covers unauthenticated', async function () {
139 service.authenticator.sessionRequiredLocal.resolves(false);
140 await service.handlerGetAdmin(req, res, ctx);
141 assert(service.manager.getAdmin.notCalled);
142 });
143 }); // handlerGetAdmin
144
145 describe('handlerPostAdmin', function () {
146 it('covers authenticated', async function () {
147 service.authenticator.sessionRequiredLocal.resolves(true);
148 await service.handlerPostAdmin(req, res, ctx);
149 assert(service.manager.postAdmin.called);
150 });
151 it('covers unauthenticated', async function () {
152 service.authenticator.sessionRequiredLocal.resolves(false);
153 await service.handlerPostAdmin(req, res, ctx);
154 assert(service.manager.getAdmin.notCalled);
155 });
156 }); // handlerPostAdmin
157
158 describe('handlerGetRoot', function () {
159 it('covers', async function () {
160 await service.handlerGetRoot(req, res, ctx);
161 assert(service.manager.getRoot.called);
162 });
163 }); // handlerGetRoot
164
165 describe('handlerGetAdminTicket', function () {
166 it('covers authenticated', async function () {
167 service.authenticator.sessionRequiredLocal.resolves(true);
168 await service.handlerGetAdminTicket(req, res, ctx);
169 assert(service.manager.getAdminTicket.called);
170 });
171 it('covers unauthenticated', async function () {
172 service.authenticator.sessionRequiredLocal.resolves(false);
173 await service.handlerGetAdminTicket(req, res, ctx);
174 assert(service.manager.getAdminTicket.notCalled);
175 });
176 }); // handlerGetAdminTicket
177
178 describe('handlerPostAdminTicket', function () {
179 it('covers authenticated', async function () {
180 service.authenticator.sessionRequiredLocal.resolves(true);
181 await service.handlerPostAdminTicket(req, res, ctx);
182 assert(service.manager.postAdminTicket.called);
183 });
184 it('covers unauthenticated', async function () {
185 service.authenticator.sessionRequiredLocal.resolves(false);
186 await service.handlerPostAdminTicket(req, res, ctx);
187 assert(service.manager.postAdminTicket.notCalled);
188 });
189 }); // handlerPostAdminTicket
190
191 describe('handlerGetMeta', function () {
192 it('covers', async function () {
193 await service.handlerGetMeta(req, res, ctx);
194 assert(service.manager.getMeta.called);
195 });
196 }); // handlerGetMeta
197
198 describe('handlerGetHealthcheck', function () {
199 it('covers', async function () {
200 await service.handlerGetHealthcheck(req, res, ctx);
201 assert(service.manager.getHealthcheck.called);
202 });
203 it('cover errors', async function () {
204 const expectedException = 'blah';
205 service.manager.getHealthcheck.rejects(expectedException);
206 try {
207 await service.handlerGetHealthcheck(req, res, ctx);
208 assert.fail('did not get expected exception');
209 } catch (e) {
210 assert.strictEqual(e.name, expectedException, 'did not get expected exception');
211 }
212 assert(service.manager.getHealthcheck.called);
213 });
214 }); // handlerGetHealthcheck
215
216 describe('handlerInternalServerError', function () {
217 let ServiceClass, DingusClass;
218 before(function () {
219 ServiceClass = Object.getPrototypeOf(service);
220 DingusClass = Object.getPrototypeOf(ServiceClass);
221 });
222 it('covers no redirect', async function () {
223 sinon.stub(DingusClass, 'handlerInternalServerError');
224 await service.handlerInternalServerError(req, res, ctx);
225 assert(DingusClass.handlerInternalServerError.called);
226 });
227 it('covers redirect', async function () {
228 sinon.stub(DingusClass, 'handlerInternalServerError');
229 ctx.session = {
230 redirectUri: new URL('https://client.example.com/app'),
231 clientIdentifier: new URL('https://client.exmaple.com/'),
232 state: '123456',
233 };
234 await service.handlerInternalServerError(req, res, ctx);
235 assert(!DingusClass.handlerInternalServerError.called);
236 assert(res.setHeader.called);
237 assert.strictEqual(res.statusCode, 302);
238 });
239 }); // handlerInternalServerError
240
241 describe('handlerGetAuthorization', function () {
242 it('covers authenticated', async function() {
243 service.authenticator.sessionRequiredLocal.resolves(true);
244 await service.handlerGetAuthorization(req, res, ctx);
245 assert(service.manager.getAuthorization.called);
246 });
247 it('covers unauthenticated', async function() {
248 service.authenticator.sessionRequiredLocal.resolves(false);
249 await service.handlerGetAuthorization(req, res, ctx);
250 assert(service.manager.getAuthorization.notCalled);
251 });
252 }); // handlerGetAuthorization
253
254 describe('handlerPostAuthorization', function () {
255 it('covers', async function () {
256 await service.handlerPostAuthorization(req, res, ctx);
257 assert(service.manager.postAuthorization.called);
258 });
259 }); // handlerPostAuthorization
260
261 describe('handlerPostConsent', function () {
262 it('covers', async function () {
263 service.serveFile.resolves();
264 await service.handlerPostConsent(req, res, ctx);
265 assert(service.manager.postConsent.called);
266 });
267 }); // handlerPostConsent
268
269 describe('handlerPostToken', function () {
270 it('covers', async function () {
271 await service.handlerPostToken(req, res, ctx);
272 assert(service.manager.postToken.called);
273 });
274 }); // handlerPostToken
275
276 describe('handlerPostTicket', function () {
277 it('covers', async function () {
278 await service.handlerPostTicket(req, res, ctx);
279 assert(service.manager.postTicket.called);
280 });
281 }); // handlerPostTicket
282
283 describe('handlerPostIntrospection', function () {
284 it('covers', async function () {
285 await service.handlerPostIntrospection(req, res, ctx);
286 assert(service.manager.postIntrospection.called);
287 });
288 }); // handlerPostIntrospection
289
290 describe('handlerPostRevocation', function () {
291 it('covers', async function () {
292 await service.handlerPostRevocation(req, res, ctx);
293 assert(service.manager.postRevocation.called);
294 });
295 }); // handlerPostRevocation
296
297 describe('handlerPostUserInfo', function () {
298 it('covers', async function () {
299 await service.handlerPostUserInfo(req, res, ctx);
300 assert(service.manager.postUserInfo.called);
301 });
302 }); // handlerPostUserInfo
303
304 describe('handlerGetAdminMaintenance', function () {
305 it('covers authenticated', async function () {
306 service.authenticator.sessionRequiredLocal.resolves(true);
307 await service.handlerGetAdminMaintenance(req, res, ctx);
308 assert(service.manager.getAdminMaintenance.called);
309 });
310 it('covers unauthenticated', async function () {
311 service.authenticator.sessionRequiredLocal.resolves(false);
312 await service.handlerGetAdminMaintenance(req, res, ctx);
313 assert(service.manager.getAdminMaintenance.notCalled);
314 });
315 }); // handlerGetAdminMaintenance
316
317 describe('handlerWhaGwan', function () {
318 it('covers', async function () {
319 await assert.rejects(() => service.handlerWhaGwan(req. res, ctx));
320 });
321 }); // handlerWhaGwan
322
323 });