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 : }
|