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