LCOV - code coverage report
Current view: top level - test - test-data.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 246 254 96.9 %
Date: 2025-04-23 17:26:57 Functions: 23 24 95.8 %
Branches: 28 34 82.4 %

           Branch data     Line data    Source code
       1            [ + ]:          3 : /**
       2                 :          3 :  * @module  test-data
       3                 :          3 :  * @desc    Module for creating, registering/unregistering test users/activities into the leaderboard-api server.
       4                 :          3 :  * @version 1.0.0
       5                 :          3 :  * @author  Essam A. El-Sherif
       6                 :          3 :  */
       7                 :          3 : 
       8                 :          3 : /* Import node.js core modules */
       9                 :          3 : import http               from 'node:http';
      10                 :          3 : import https              from 'node:https';
      11                 :          3 : import { fileURLToPath }  from 'node:url';
      12                 :          3 : import { dirname, join }  from 'node:path';
      13                 :          3 : 
      14                 :          3 : /* Import package dependencies */
      15                 :          3 : import dotenv from 'dotenv';
      16                 :          3 : 
      17                 :          3 : /* Emulate commonJS __filename and __dirname constants */
      18                 :          3 : const __filename = fileURLToPath(import.meta.url);
      19                 :          3 : const __dirname  = dirname(__filename);
      20                 :          3 : 
      21                 :          3 : /* Configure dotenv path to read the package .env file */
      22                 :          3 : dotenv.config({path: join(__dirname, '../.env')});
      23                 :          3 : 
      24                 :          3 : /**
      25                 :          3 :  * @class
      26                 :          3 :  * @static
      27                 :          3 :  * @desc Class for creating, registering/unregistering test users/activities into the leaderboard-api server.
      28                 :          3 :  */
      29            [ + ]:          3 : export class TestData{
      30                 :          3 : 
      31            [ - ]:          3 :         #prot = process.env.lb_serverProtocol || 'http';
      32                 :          3 :         #host = process.env.lb_serverHost;
      33                 :          3 :         #port = process.env.lb_serverPort;
      34                 :          3 :         #path = process.env.lb_serverPath;
      35                 :          3 : 
      36                 :          3 :         #userPrefix = 'user@';
      37                 :          3 :         #passwordPrefix = 'password-';
      38                 :          3 :         #activityPrefix = 'activity-';
      39                 :          3 : 
      40                 :          3 :         #initUser = 'admin';
      41                 :          3 :         #initPassword = 'admin';
      42                 :          3 :         #initActivity = 'activity-a';
      43                 :          3 : 
      44                 :          3 :         #usersMap = new Map();
      45                 :          3 :         #actsMap = new Map();
      46                 :          3 : 
      47                 :          3 :         /**
      48                 :          3 :      * @method
      49                 :          3 :          * @instance
      50                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
      51                 :          3 :          * @param    {number} numUsers - Number of users to create.
      52                 :          3 :          * @param    {number} numActivities - Number of activities to create.
      53                 :          3 :          * @param    {boolean} init - To create special user/activity.
      54                 :          3 :          * @desc     Constructs and returns a TestData object.
      55                 :          3 :          */
      56            [ + ]:          3 :         constructor(numUsers = 2, numActivities = 2, init = true){
      57                 :          3 :                 this.numUsers = numUsers;
      58                 :          3 :                 this.numActivities = numActivities;
      59                 :          3 :                 this.init = init;
      60                 :          3 : 
      61                 :          3 :                 this.createTestUsers();
      62                 :          3 :                 this.createTestActivities();
      63                 :          3 :         }
      64                 :          3 : 
      65                 :          3 :         /**
      66                 :          3 :      * @method
      67                 :          3 :          * @instance
      68                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
      69                 :          3 :          * @desc     Create and keep a set of numUsers users.
      70                 :          3 :          */
      71            [ + ]:          3 :         createTestUsers(){
      72                 :          3 : 
      73                 :          3 :                 if(this.init){
      74                 :          3 :                         this.#usersMap.set(this.#initUser, {
      75                 :          3 :                                 username: this.#initUser,
      76                 :          3 :                                 password: this.#initPassword,
      77                 :          3 :                         });
      78                 :          3 :                 }
      79                 :          3 : 
      80            [ + ]:          3 :                 for(let i = 1; i <= this.numUsers; i++){
      81                 :          7 :                         this.#usersMap.set(`${this.#userPrefix}${i}`, {
      82                 :          7 :                                 username: `${this.#userPrefix}${i}`,
      83                 :          7 :                                 password: `${this.#passwordPrefix}${i}`,
      84                 :          7 :                         });
      85                 :          7 :                 }
      86                 :          3 :         }
      87                 :          3 : 
      88                 :          3 :         /**
      89                 :          3 :      * @method
      90                 :          3 :          * @instance
      91                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
      92                 :          3 :          * @desc     Create and keep a set of numActivities activities.
      93                 :          3 :          */
      94            [ + ]:          3 :         createTestActivities(){
      95                 :          3 : 
      96                 :          3 :                 if(this.init){
      97                 :          3 :                         this.#actsMap.set(this.#initActivity, [{
      98                 :          3 :                                 activity: this.#initActivity,
      99                 :          3 :                                 username: this.#initUser,
     100                 :          3 :                                 score: 100,
     101                 :          3 :                         }]);
     102                 :          3 :                 }
     103                 :          3 : 
     104            [ + ]:          3 :                 for(let i = 1; i <= this.numActivities; i++){
     105                 :          7 :                         let acts = [];
     106            [ + ]:          7 :                         for(let j = 1; j <= this.numUsers; j++){
     107                 :         17 :                                 acts.push({
     108                 :         17 :                                         activity: `${this.#activityPrefix}${i}`,
     109                 :         17 :                                         username: `${this.#userPrefix}${j}`,
     110                 :         17 :                                         score: i * 100 + j * 10,
     111                 :         17 :                                 });
     112                 :         17 :                         }
     113                 :          7 :                         this.#actsMap.set(`${this.#activityPrefix}${i}`, acts);
     114                 :          7 :                 }
     115                 :          3 : 
     116                 :          3 :         }
     117                 :          3 : 
     118                 :          3 :         /**
     119                 :          3 :      * @member   testUsers
     120                 :          3 :          * @instance
     121                 :          3 :          * @readonly
     122                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
     123                 :          3 :          * @desc     Get an array of testUsers objects.
     124                 :          3 :          */
     125            [ + ]:          3 :         get testUsers(){
     126                 :          3 :                 return [...this.#usersMap.values()];
     127                 :          3 :         }
     128                 :          3 : 
     129                 :          3 :         /**
     130                 :          3 :      * @member   testActivities
     131                 :          3 :          * @instance
     132                 :          3 :          * @readonly
     133                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
     134                 :          3 :          * @desc     Get an array of testActivities objects.
     135                 :          3 :          */
     136                 :          3 :         get testActivities(){
     137                 :          0 :                 return [...this.#actsMap.values()].flat();
     138                 :          0 :         }
     139                 :          3 : 
     140                 :          3 :         /**
     141                 :          3 :      * @method
     142                 :          3 :          * @instance
     143                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
     144                 :          3 :          * @returns  {Promise} Promise object that will fulfill with an array of test users registered.
     145                 :          3 :          * @desc     Register the test users into the leaderboard-api server.
     146                 :          3 :          */
     147            [ + ]:          3 :         registerTestUsers(){
     148                 :          3 : 
     149       [ + ][ + ]:          3 :                 return Promise.all([...this.#usersMap.values()].map(user => new Promise((resolve) => {
     150                 :          9 : 
     151                 :          9 :                         const url = `${this.#prot}://${this.#host}:${this.#port}${this.#path}/auth`;
     152            [ - ]:          9 :                         const module = this.#prot === 'https' ? https : http;
     153            [ + ]:          9 :                         const cr = module.request(url, {method: 'POST', rejectUnauthorized: false}, (res) => {
     154                 :          9 : 
     155                 :          9 :                                 let body = '';
     156            [ + ]:          9 :                                 res.on('data', (chunk) => {
     157                 :          9 :                                         body += chunk;
     158                 :          9 :                                 });
     159                 :          9 : 
     160            [ + ]:          9 :                                 res.on('end', () => {
     161                 :          9 :                                         if(res.statusCode === 201){
     162                 :          9 :                                                 user.token = JSON.parse(body).token;
     163                 :          9 :                                                 resolve(user);
     164            [ - ]:          9 :                                         }
     165                 :          0 :                                         else{
     166                 :          0 :                                                 resolve(null);
     167                 :          0 :                                         }
     168                 :          9 :                                 });
     169                 :          9 :                         });
     170                 :          9 : 
     171                 :          9 :                         cr.setHeader('Content-Type', 'application/json');
     172                 :          9 :                         cr.write(JSON.stringify(user));
     173                 :          9 :                         cr.end();
     174                 :          3 :                 })));
     175                 :          3 :         }
     176                 :          3 : 
     177                 :          3 :         /**
     178                 :          3 :      * @method
     179                 :          3 :          * @instance
     180                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
     181                 :          3 :          * @returns  {Promise} Promise object that will fulfill with an array of test users unregistered.
     182                 :          3 :          * @desc     Unregister the test users into the leaderboard-api server.
     183                 :          3 :          */
     184            [ + ]:          3 :         unregisterTestUsers(){
     185                 :          6 : 
     186       [ + ][ + ]:          6 :                 return Promise.all([...this.#usersMap.values()].map(user => new Promise((resolve) => {
     187                 :         18 : 
     188                 :         18 :                         const url = `${this.#prot}://${this.#host}:${this.#port}${this.#path}/auth`;
     189            [ - ]:         18 :                         const module = this.#prot === 'https' ? https : http;
     190            [ + ]:         18 :                         const cr = module.request(url, {method: 'PATCH', rejectUnauthorized: false}, (res) => {
     191                 :         18 : 
     192            [ + ]:         18 :                                 res.on('data', () => {
     193                 :         18 :                                 });
     194                 :         18 : 
     195            [ + ]:         18 :                                 res.on('end', () => {
     196            [ + ]:         18 :                                         if(res.statusCode === 204){
     197                 :          9 :                                                 resolve(user);
     198                 :          9 :                                         }
     199                 :          9 :                                         else{
     200                 :          9 :                                                 resolve(null);
     201                 :          9 :                                         }
     202                 :         18 :                                 });
     203                 :         18 :                         });
     204                 :         18 : 
     205                 :         18 :                         delete user.token;
     206                 :         18 : 
     207                 :         18 :                         cr.setHeader('Content-Type', 'application/json');
     208                 :         18 :                         cr.write(JSON.stringify(user));
     209                 :         18 :                         cr.end();
     210                 :          6 :                 })));
     211                 :          6 :         }
     212                 :          3 : 
     213                 :          3 :         /**
     214                 :          3 :      * @method
     215                 :          3 :          * @instance
     216                 :          3 :          * @memberof module:leaderboard-api-test-data.TestData
     217                 :          3 :          * @returns  {Promise} Promise object that will fulfill with an array of test activities registered.
     218                 :          3 :          * @desc     Register the test activities into the leaderboard-api server.
     219                 :          3 :          */
     220            [ + ]:          3 :         registerTestActivities(){
     221                 :          1 : 
     222       [ + ][ + ]:          1 :                 return Promise.all([...this.#actsMap.values()].flat().map(act => new Promise((resolve) => {
     223                 :          9 : 
     224                 :          9 :                         const url = `${this.#prot}://${this.#host}:${this.#port}${this.#path}/score`;
     225            [ - ]:          9 :                         const module = this.#prot === 'https' ? https : http;
     226            [ + ]:          9 :                         const cr = module.request(url, {method: 'POST', rejectUnauthorized: false}, (res) => {
     227                 :          9 : 
     228                 :          9 :                                 let body = '';
     229            [ + ]:          9 :                                 res.on('data', (chunk) => {
     230                 :          9 :                                         body += chunk;
     231                 :          9 :                                 });
     232                 :          9 : 
     233            [ + ]:          9 :                                 res.on('end', () => {
     234                 :          9 :                                         if(res.statusCode === 201){
     235                 :          9 :                                                 resolve(JSON.parse(body));
     236            [ - ]:          9 :                                         }
     237                 :          0 :                                         else{
     238                 :          0 :                                                 resolve(null);
     239                 :          0 :                                         }
     240                 :          9 :                                 });
     241                 :          9 :                         });
     242                 :          9 : 
     243                 :          9 :                         cr.setHeader('Authorization', `Bearer ${this.#usersMap.get(act.username).token}`);
     244                 :          9 :                         cr.setHeader('Content-Type', 'application/json');
     245                 :          9 : 
     246                 :          9 :                         cr.write(JSON.stringify({
     247                 :          9 :                                 username: act.username,
     248                 :          9 :                                 activity: act.activity,
     249                 :          9 :                                 score: act.score,
     250                 :          9 :                         }));
     251                 :          9 :                         cr.end();
     252                 :          1 :                 })));
     253                 :          1 :         }
     254                 :          3 : }

Generated by: LCOV version 1.14