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