Branch data Line data Source code
1 [ + ]: 1 : /**
2 : 1 : * @module auth-route-test
3 : 1 : * @desc The leaderboard-api authentication route testing module.
4 : 1 : * @version 1.0.0
5 : 1 : * @author Essam A. El-Sherif
6 : 1 : */
7 : 1 :
8 : 1 : /* Import node.js core modules */
9 : 1 : import assert from 'node:assert/strict';
10 : 1 : import fs from 'node:fs';
11 : 1 : import http from 'node:http';
12 : 1 : import https from 'node:https';
13 : 1 : import runner from 'node:test';
14 : 1 : import { fileURLToPath } from 'node:url';
15 : 1 : import { dirname, join } from 'node:path';
16 : 1 :
17 : 1 : /* Import package dependencies */
18 : 1 : import dotenv from 'dotenv';
19 : 1 :
20 : 1 : /* Import local dependencies */
21 : 1 : import { TestData } from './test-data.js'
22 : 1 :
23 : 1 : /* Emulate commonJS __filename and __dirname constants */
24 : 1 : const __filename = fileURLToPath(import.meta.url);
25 : 1 : const __dirname = dirname(__filename);
26 : 1 :
27 : 1 : /* Configure dotenv path to read the package .env file */
28 : 1 : dotenv.config({path: join(__dirname, '../.env')});
29 : 1 :
30 : 1 : /* Prepare test environment */
31 : 1 : const suites = new Map();
32 : 1 :
33 : 1 : const url = new URL('http://server');
34 : 1 :
35 : 1 : url.host = process.env.lb_serverHost;
36 : 1 : url.port = process.env.lb_serverPort;
37 : 1 : url.pathname = process.env.lb_serverPath;
38 : 1 :
39 : 1 : if(process.env.lb_serverProtocol === 'https'){
40 : 1 : url.protocol = 'https';
41 : 1 : }
42 : 1 : const baseUrl = `${url.href}/auth`;
43 : 1 :
44 : 1 : let testUsers = null;
45 : 1 :
46 : 1 : /**
47 : 1 : * @func Main
48 : 1 : * @async
49 : 1 : * @desc The module entry point function.
50 : 1 : */
51 [ + ]: 1 : (async () => {
52 : 1 : const testData = new TestData();
53 : 1 : testUsers = testData.testUsers;
54 : 1 :
55 : 1 : await testData.unregisterTestUsers();
56 : 1 : await testData.registerTestUsers();
57 : 1 :
58 : 1 : loadTestData();
59 : 1 :
60 [ + ]: 1 : runner.after(async() => {
61 : 1 : await testData.unregisterTestUsers();
62 : 1 : });
63 : 1 : nodeRunner(runner);
64 : 1 :
65 : 1 : })('Main Function');
66 : 1 :
67 : 1 : /**
68 : 1 : * @func loadTestData
69 : 1 : * @desc Load test data.
70 : 1 : */
71 [ + ]: 1 : function loadTestData(){
72 : 1 :
73 : 1 : let testData = null;
74 : 1 : let suiteDesc = '';
75 : 1 : let testObj = null;
76 : 1 :
77 : 1 : // TEST SUITE ### - Test Authentication Route - createUser
78 : 1 : suiteDesc = 'Test Authentication Route - createUser';
79 : 1 : suites.set(suiteDesc, []);
80 : 1 :
81 : 1 : // TEST ### - Test createUser invalid ... test#1
82 : 1 : testData = {};
83 : 1 :
84 : 1 : testObj = {
85 : 1 : reqMethod: 'POST',
86 : 1 : reqBody: undefined,
87 : 1 : resCode: 400,
88 : 1 : resBody: 'Authentication Error: none or invalid request payload',
89 : 1 : };
90 : 1 :
91 : 1 : testData.method = testMethod.bind(testObj);
92 : 1 : testData.desc = 'Test createUser invalid ... test#1';
93 : 1 :
94 : 1 : testData.skip = false;
95 : 1 : suites.get(suiteDesc).push(testData);
96 : 1 :
97 : 1 : // TEST ### - Test createUser invalid ... test#2
98 : 1 : testData = {};
99 : 1 :
100 : 1 : testObj = {
101 : 1 : reqMethod: 'POST',
102 : 1 : reqBody: {},
103 : 1 : resCode: 400,
104 : 1 : resBody: 'Authentication Error: none or invalid request payload',
105 : 1 : };
106 : 1 :
107 : 1 : testData.method = testMethod.bind(testObj);
108 : 1 : testData.desc = 'Test createUser invalid ... test#2';
109 : 1 :
110 : 1 : testData.skip = false;
111 : 1 : suites.get(suiteDesc).push(testData);
112 : 1 :
113 : 1 : // TEST ### - Test createUser invalid ... test#3
114 : 1 : testData = {};
115 : 1 :
116 : 1 : testObj = {
117 : 1 : reqMethod: 'POST',
118 : 1 : reqBody: {username: 'admin'},
119 : 1 : resCode: 400,
120 : 1 : resBody: 'Authentication Error: no password given',
121 : 1 : };
122 : 1 :
123 : 1 : testData.method = testMethod.bind(testObj);
124 : 1 : testData.desc = 'Test createUser invalid ... test#3';
125 : 1 :
126 : 1 : testData.skip = false;
127 : 1 : suites.get(suiteDesc).push(testData);
128 : 1 :
129 : 1 : // TEST ### - Test createUser invalid ... test#4
130 : 1 : testData = {};
131 : 1 :
132 : 1 : testObj = {
133 : 1 : reqMethod: 'POST',
134 : 1 : reqBody: {password: 'admin'},
135 : 1 : resCode: 400,
136 : 1 : resBody: 'Authentication Error: no username given',
137 : 1 : };
138 : 1 :
139 : 1 : testData.method = testMethod.bind(testObj);
140 : 1 : testData.desc = 'Test createUser invalid ... test#4';
141 : 1 :
142 : 1 : testData.skip = false;
143 : 1 : suites.get(suiteDesc).push(testData);
144 : 1 :
145 : 1 : // TEST ### - Test createUser invalid ... test#5
146 : 1 : testData = {};
147 : 1 :
148 : 1 : testObj = {
149 : 1 : reqMethod: 'POST',
150 : 1 : reqBody: {username: 'admin', password: 'admin'},
151 : 1 : resCode: 401,
152 : 1 : resBody: 'Authentication Error: username already exists',
153 : 1 : };
154 : 1 :
155 : 1 : testData.method = testMethod.bind(testObj);
156 : 1 : testData.desc = 'Test createUser invalid ... test#5';
157 : 1 :
158 : 1 : testData.skip = false;
159 : 1 : suites.get(suiteDesc).push(testData);
160 : 1 :
161 : 1 : // TEST ### - Test createUser valid ... test#1
162 : 1 : testData = {};
163 : 1 :
164 : 1 : testObj = {
165 : 1 : reqMethod: 'POST',
166 : 1 : reqBody: {username: 'test', password: 'test'},
167 : 1 : resCode: 201,
168 : 1 : resBody: {token: 'JWT'},
169 : 1 : };
170 : 1 :
171 : 1 : testData.method = testMethod.bind(testObj);
172 : 1 : testData.desc = 'Test createUser valid ... test#1';
173 : 1 :
174 : 1 : testData.skip = false;
175 : 1 : suites.get(suiteDesc).push(testData);
176 : 1 :
177 : 1 : // TEST SUITE ### - Test Authentication Route - updateUser
178 : 1 : suiteDesc = 'Test Authentication Route - updateUser';
179 : 1 : suites.set(suiteDesc, []);
180 : 1 :
181 : 1 : // TEST ### - Test updateUser invalid ... test#1
182 : 1 : testData = {};
183 : 1 :
184 : 1 : testObj = {
185 : 1 : reqMethod: 'PUT',
186 : 1 : reqBody: undefined,
187 : 1 : resCode: 400,
188 : 1 : resBody: 'Authentication Error: none or invalid request payload',
189 : 1 : };
190 : 1 :
191 : 1 : testData.method = testMethod.bind(testObj);
192 : 1 : testData.desc = 'Test updateUser invalid ... test#1';
193 : 1 :
194 : 1 : testData.skip = false;
195 : 1 : suites.get(suiteDesc).push(testData);
196 : 1 :
197 : 1 : // TEST ### - Test updateUser invalid ... test#2
198 : 1 : testData = {};
199 : 1 :
200 : 1 : testObj = {
201 : 1 : reqMethod: 'PUT',
202 : 1 : reqBody: {},
203 : 1 : resCode: 400,
204 : 1 : resBody: 'Authentication Error: none or invalid request payload',
205 : 1 : };
206 : 1 :
207 : 1 : testData.method = testMethod.bind(testObj);
208 : 1 : testData.desc = 'Test updateUser invalid ... test#2';
209 : 1 :
210 : 1 : testData.skip = false;
211 : 1 : suites.get(suiteDesc).push(testData);
212 : 1 :
213 : 1 : // TEST ### - Test updateUser invalid ... test#3
214 : 1 : testData = {};
215 : 1 :
216 : 1 : testObj = {
217 : 1 : reqMethod: 'PUT',
218 : 1 : reqBody: {username: 'admin'},
219 : 1 : resCode: 400,
220 : 1 : resBody: 'Authentication Error: no password given',
221 : 1 : };
222 : 1 :
223 : 1 : testData.method = testMethod.bind(testObj);
224 : 1 : testData.desc = 'Test updateUser invalid ... test#3';
225 : 1 :
226 : 1 : testData.skip = false;
227 : 1 : suites.get(suiteDesc).push(testData);
228 : 1 :
229 : 1 : // TEST ### - Test updateUser invalid ... test#4
230 : 1 : testData = {};
231 : 1 :
232 : 1 : testObj = {
233 : 1 : reqMethod: 'PUT',
234 : 1 : reqBody: {password: 'admin'},
235 : 1 : resCode: 400,
236 : 1 : resBody: 'Authentication Error: no username given',
237 : 1 : };
238 : 1 :
239 : 1 : testData.method = testMethod.bind(testObj);
240 : 1 : testData.desc = 'Test updateUser invalid ... test#4';
241 : 1 :
242 : 1 : testData.skip = false;
243 : 1 : suites.get(suiteDesc).push(testData);
244 : 1 :
245 : 1 : // TEST ### - Test updateUser invalid ... test#5
246 : 1 : testData = {};
247 : 1 :
248 : 1 : testObj = {
249 : 1 : reqMethod: 'PUT',
250 : 1 : reqBody: {username: 'xxx', password: 'xxx'},
251 : 1 : resCode: 401,
252 : 1 : resBody: 'Authentication Error: username does not exist',
253 : 1 : };
254 : 1 :
255 : 1 : testData.method = testMethod.bind(testObj);
256 : 1 : testData.desc = 'Test updateUser invalid ... test#5';
257 : 1 :
258 : 1 : testData.skip = false;
259 : 1 : suites.get(suiteDesc).push(testData);
260 : 1 :
261 : 1 : // TEST ### - Test updateUser invalid ... test#6
262 : 1 : testData = {};
263 : 1 :
264 : 1 : testObj = {
265 : 1 : reqMethod: 'PUT',
266 : 1 : reqBody: {username: 'admin', password: 'xxx'},
267 : 1 : resCode: 401,
268 : 1 : resBody: 'Authentication Error: invalid password',
269 : 1 : };
270 : 1 :
271 : 1 : testData.method = testMethod.bind(testObj);
272 : 1 : testData.desc = 'Test updateUser invalid ... test#6';
273 : 1 :
274 : 1 : testData.skip = false;
275 : 1 : suites.get(suiteDesc).push(testData);
276 : 1 :
277 : 1 : // TEST ### - Test updateUser valid ... test#1
278 : 1 : testData = {};
279 : 1 :
280 : 1 : testObj = {
281 : 1 : reqMethod: 'PUT',
282 : 1 : reqBody: {username: 'admin', password: 'admin'},
283 : 1 : resCode: 201,
284 : 1 : resBody: {token: 'JWT'},
285 : 1 : };
286 : 1 :
287 : 1 : testData.method = testMethod.bind(testObj);
288 : 1 : testData.desc = 'Test updateUser valid ... test#1';
289 : 1 :
290 : 1 : testData.skip = false;
291 : 1 : suites.get(suiteDesc).push(testData);
292 : 1 :
293 : 1 : // TEST ### - Test updateUser valid ... test#2
294 : 1 : testData = {};
295 : 1 :
296 : 1 : testData = {};
297 : 1 :
298 : 1 : testObj = {
299 : 1 : reqMethod: 'PUT',
300 : 1 : reqBody: {username: 'admin', password: 'admin', newpassword: 'admin'},
301 : 1 : resCode: 201,
302 : 1 : resBody: {token: 'JWT'},
303 : 1 : };
304 : 1 :
305 : 1 : testData.method = testMethod.bind(testObj);
306 : 1 : testData.desc = 'Test updateUser valid ... test#2';
307 : 1 :
308 : 1 : testData.skip = false;
309 : 1 : suites.get(suiteDesc).push(testData);
310 : 1 :
311 : 1 : // TEST SUITE ### - Test Authentication Route - deleteUser
312 : 1 : suiteDesc = 'Test Authentication Route - deleteUser';
313 : 1 : suites.set(suiteDesc, []);
314 : 1 :
315 : 1 : // TEST ### - Test deleteUser invalid ... test#1
316 : 1 : testData = {};
317 : 1 :
318 : 1 : testObj = {
319 : 1 : reqMethod: 'PATCH',
320 : 1 : reqBody: undefined,
321 : 1 : resCode: 400,
322 : 1 : resBody: 'Authentication Error: none or invalid request payload',
323 : 1 : };
324 : 1 :
325 : 1 : testData.method = testMethod.bind(testObj);
326 : 1 : testData.desc = 'Test deleteUser invalid ... test#1';
327 : 1 :
328 : 1 : testData.skip = false;
329 : 1 : suites.get(suiteDesc).push(testData);
330 : 1 :
331 : 1 : // TEST ### - Test deleteUser invalid ... test#2
332 : 1 : testData = {};
333 : 1 :
334 : 1 : testObj = {
335 : 1 : reqMethod: 'PATCH',
336 : 1 : reqBody: {},
337 : 1 : resCode: 400,
338 : 1 : resBody: 'Authentication Error: none or invalid request payload',
339 : 1 : };
340 : 1 :
341 : 1 : testData.method = testMethod.bind(testObj);
342 : 1 : testData.desc = 'Test deleteUser invalid ... test#2';
343 : 1 :
344 : 1 : testData.skip = false;
345 : 1 : suites.get(suiteDesc).push(testData);
346 : 1 :
347 : 1 : // TEST ### - Test deleteUser invalid ... test#3
348 : 1 : testData = {};
349 : 1 :
350 : 1 : testObj = {
351 : 1 : reqMethod: 'PATCH',
352 : 1 : reqBody: {username: 'admin'},
353 : 1 : resCode: 400,
354 : 1 : resBody: 'Authentication Error: no password given',
355 : 1 : };
356 : 1 :
357 : 1 : testData.method = testMethod.bind(testObj);
358 : 1 : testData.desc = 'Test deleteUser invalid ... test#3';
359 : 1 :
360 : 1 : testData.skip = false;
361 : 1 : suites.get(suiteDesc).push(testData);
362 : 1 :
363 : 1 : // TEST ### - Test deleteUser invalid ... test#4
364 : 1 : testData = {};
365 : 1 :
366 : 1 : testObj = {
367 : 1 : reqMethod: 'PATCH',
368 : 1 : reqBody: {password: 'admin'},
369 : 1 : resCode: 400,
370 : 1 : resBody: 'Authentication Error: no username given',
371 : 1 : };
372 : 1 :
373 : 1 : testData.method = testMethod.bind(testObj);
374 : 1 : testData.desc = 'Test deleteUser invalid ... test#4';
375 : 1 :
376 : 1 : testData.skip = false;
377 : 1 : suites.get(suiteDesc).push(testData);
378 : 1 :
379 : 1 : // TEST ### - Test deleteUser invalid ... test#5
380 : 1 : testData = {};
381 : 1 :
382 : 1 : testObj = {
383 : 1 : reqMethod: 'PATCH',
384 : 1 : reqBody: {username: 'xxx', password: 'xxx'},
385 : 1 : resCode: 401,
386 : 1 : resBody: 'Authentication Error: username does not exist',
387 : 1 : };
388 : 1 :
389 : 1 : testData.method = testMethod.bind(testObj);
390 : 1 : testData.desc = 'Test deleteUser invalid ... test#5';
391 : 1 :
392 : 1 : testData.skip = false;
393 : 1 : suites.get(suiteDesc).push(testData);
394 : 1 :
395 : 1 : // TEST ### - Test deleteUser invalid ... test#6
396 : 1 : testData = {};
397 : 1 :
398 : 1 : testObj = {
399 : 1 : reqMethod: 'PATCH',
400 : 1 : reqBody: {username: 'admin', password: 'xxx'},
401 : 1 : resCode: 401,
402 : 1 : resBody: 'Authentication Error: invalid password',
403 : 1 : };
404 : 1 :
405 : 1 : testData.method = testMethod.bind(testObj);
406 : 1 : testData.desc = 'Test deleteUser invalid ... test#6';
407 : 1 :
408 : 1 : testData.skip = false;
409 : 1 : suites.get(suiteDesc).push(testData);
410 : 1 :
411 : 1 : // TEST ### - Test deleteUser valid ... test#1
412 : 1 : testData = {};
413 : 1 :
414 : 1 : testObj = {
415 : 1 : reqMethod: 'PATCH',
416 : 1 : reqBody: {username: 'test', password: 'test'},
417 : 1 : resCode: 204,
418 : 1 : resBody: '',
419 : 1 : };
420 : 1 :
421 : 1 : testData.method = testMethod.bind(testObj);
422 : 1 : testData.desc = 'Test deleteUser valid ... test#1';
423 : 1 :
424 : 1 : testData.skip = false;
425 : 1 : suites.get(suiteDesc).push(testData);
426 : 1 :
427 : 1 : // TEST SUITE ### - Test Authentication Route - getUsers
428 : 1 : suiteDesc = 'Test Authentication Route - getUsers';
429 : 1 : suites.set(suiteDesc, []);
430 : 1 :
431 : 1 : // TEST ### - Test getUsers valid ... test#1
432 : 1 : testData = {};
433 : 1 :
434 : 1 : testObj = {
435 : 1 : reqMethod: 'GET',
436 : 1 : reqBody: '',
437 : 1 : resCode: 200,
438 : 1 : resBody: '',
439 : 1 : };
440 : 1 :
441 : 1 : testData.method = testMethod.bind(testObj);
442 : 1 : testData.desc = 'Test getUsers valid ... test#1';
443 : 1 :
444 : 1 : testData.skip = false;
445 : 1 : suites.get(suiteDesc).push(testData);
446 : 1 : }
447 : 1 :
448 : 1 : /**
449 : 1 : * @func nodeRunner
450 : 1 : * @param {object} runner - The node core module 'node:test' object.
451 : 1 : * @desc Carry out the loaded tests using node test runner.
452 : 1 : */
453 [ + ]: 1 : function nodeRunner(runner){
454 : 1 :
455 [ + ]: 1 : for(let [suiteDesc, suiteTests] of suites){
456 [ + ]: 4 : runner.suite(suiteDesc, () => {
457 [ + ]: 4 : for(let cmdObj of suiteTests){
458 [ + ]: 22 : runner.test(cmdObj.desc, {skip: cmdObj.skip}, async () => {
459 : 22 : await cmdObj.method();
460 : 22 : });
461 : 22 : }
462 : 4 : });
463 : 4 : }
464 : 1 : }
465 : 1 :
466 : 1 : /**
467 : 1 : * @func
468 : 1 : * @async
469 : 1 : * @desc Carries out the assertions tests.
470 : 1 : */
471 [ + ]: 22 : async function testMethod(){
472 [ + ]: 22 : await new Promise((resolve, reject) => {
473 : 22 :
474 : 22 : let module = http;
475 : 22 : let reqOptions = { method: this.reqMethod };
476 : 22 :
477 : 22 : if(new URL(baseUrl).protocol === 'https:'){
478 : 22 : module = https;
479 : 22 : reqOptions.rejectUnauthorized = false;
480 : 22 : }
481 : 22 :
482 [ + ]: 22 : const cr = module.request(baseUrl, reqOptions, (res) => {
483 : 22 : let body = '';
484 [ + ]: 22 : res.on('data', (chunk) => {
485 : 21 : body += chunk;
486 : 22 : });
487 : 22 :
488 [ + ]: 22 : res.on('end', () => {
489 : 22 : try{
490 : 22 : assert.strictEqual(res.statusCode, this.resCode);
491 : 22 :
492 [ + ]: 22 : if(this.reqMethod.toUpperCase() !== 'GET'){
493 [ + ]: 21 : if(typeof this.resBody === 'string'){
494 : 18 : assert.strictEqual(body, this.resBody);
495 [ + ]: 18 : }
496 : 3 : else
497 : 3 : if(typeof this.resBody === 'object'){
498 : 3 : assert('token' in JSON.parse(body));
499 : 3 : }
500 : 21 : }
501 : 22 : resolve();
502 : 22 : }
503 [ - ]: 22 : catch(err){ /* node:coverage disable */
504 : : reject(err);
505 : : } /* node:coverage enable */
506 : 22 : });
507 : 22 : });
508 : 22 :
509 [ + ]: 22 : if(typeof this.reqBody === 'object'){
510 : 18 : this.reqBody = JSON.stringify(this.reqBody);
511 : 18 : cr.setHeader('Content-Type', 'application/json; charset=UTF-8');
512 : 18 : cr.write(this.reqBody);
513 [ + ]: 18 : }
514 : 4 : else
515 [ + ]: 4 : if(typeof this.reqBody === 'string'){
516 : 1 : cr.setHeader('Content-Type', 'text/plain; charset=UTF-8');
517 : 1 : cr.write(this.reqBody);
518 : 1 : }
519 : 22 :
520 : 22 : cr.end();
521 : 22 : });
522 : 22 : }
|