@anthonylzq/simba.js 7.2.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,6 @@ const { platform } = require('os')
2
2
  const { promisify } = require('util')
3
3
  const exec = promisify(require('child_process').exec)
4
4
  const writeFile = require('../utils/writeFile')
5
- const { ENVIRONMENTS_WITH_DB_URI } = require('../utils/constants')
6
5
 
7
6
  /**
8
7
  * @param {Object} args
@@ -13,7 +12,6 @@ const { ENVIRONMENTS_WITH_DB_URI } = require('../utils/constants')
13
12
  */
14
13
  module.exports = async ({ projectName, graphql, dbIsSQL }) => {
15
14
  const createFoldersCommand = `mkdir ${projectName}/test`
16
- const dbURI = dbIsSQL ? process.env.DB_URI : process.env.MONGO_URI
17
15
 
18
16
  if (platform() === 'win32')
19
17
  await exec(createFoldersCommand.replaceAll('/', '\\'))
@@ -28,7 +26,6 @@ const config: Config.InitialOptions = {
28
26
  preset: 'ts-jest',
29
27
  testEnvironment: 'node',
30
28
  testTimeout: 1 * 60 * 1000,
31
- globalSetup: './test/jestGlobalSetup.ts',
32
29
  modulePaths: ['<rootDir>/src', '<rootDir>/node_modules'],
33
30
  roots: ['.'],
34
31
  moduleFileExtensions: ['js', 'json', 'ts'],
@@ -46,32 +43,18 @@ export default config
46
43
  index: {
47
44
  content: graphql
48
45
  ? `import axios from 'axios'
49
- import { Static, TObject, TProperties, Type } from '@sinclair/typebox'
50
- import Ajv from 'ajv'
51
- import addFormats from 'ajv-formats'
46
+ import z from 'zod'
52
47
 
53
48
  import { Server } from '../src/network'
54
49
  import { userDto } from '../src/schemas'
55
50
 
56
- const ajv = addFormats(new Ajv(), ['email'])
57
- .addKeyword('kind')
58
- .addKeyword('modifier')
59
-
60
- const BASE_URL = 'http://localhost:${process.env.PORT || 1996}'
61
- const validator = <T extends TProperties>(
62
- schema: TObject<T>,
63
- object: unknown
64
- ) => {
65
- const validate = ajv.compile(schema)
66
-
67
- return validate(object)
68
- }
69
- const baseResponseDto = Type.Object({
70
- error: Type.Boolean(),
71
- message: Type.String()
51
+ const BASE_URL = \`http://localhost:\${process.env.PORT || 1996}\`
52
+ const baseResponseDto = z.object({
53
+ error: z.boolean(),
54
+ message: z.string()
72
55
  })
73
56
 
74
- type BaseResponseDTO = Static<typeof baseResponseDto>
57
+ type BaseResponseDTO = z.infer<typeof baseResponseDto>
75
58
 
76
59
  describe('Simba.js tests', () => {
77
60
  beforeAll(async () => {
@@ -82,40 +65,28 @@ describe('Simba.js tests', () => {
82
65
  let userID = ${dbIsSQL ? 0 : "''"}
83
66
 
84
67
  describe('API: GET /', () => {
85
- let data: BaseResponseDTO
86
-
87
- test('Should return 200 as status code', async () => {
68
+ it('Should return 200 with a successful operation', async () => {
88
69
  const result = await axios.get<BaseResponseDTO>(BASE_URL)
89
70
 
90
- data = result.data
91
71
  expect(result.status).toBe(200)
92
- })
93
-
94
- test('Should be a successfully operation', () => {
95
- expect(data.error).toBe(false)
96
- })
97
-
98
- test('Should be return baseResponseDto', () => {
99
- expect(validator(baseResponseDto, data)).toBe(true)
72
+ expect(result.data.error).toBe(false)
73
+ expect(baseResponseDto.parse(result.data).error).toBe(false)
100
74
  })
101
75
  })
102
76
 
103
77
  describe('API: storeUser mutation', () => {
104
- const storeUserResponse = Type.Object({
105
- data: Type.Object({
78
+ const storeUserResponse = z.object({
79
+ data: z.object({
106
80
  user: userDto
107
81
  })
108
82
  })
109
83
 
110
- type StoreUserDTO = Static<typeof storeUserResponse>
111
-
112
- let data: StoreUserDTO
113
- let status: number
84
+ type StoreUserDTO = z.infer<typeof storeUserResponse>
114
85
 
115
- test('Should return 200 as status code', async () => {
116
- const result = await axios.post<StoreUserDTO>(\`\${BASE_URL}/api\`, {
117
- query: \`mutation storeUser($user: StoreUserInput!) {
118
- user: storeUser(user: $user) {
86
+ it('Should create a user successfully', async () => {
87
+ const result = await axios.post<StoreUserDTO>(\`\${BASE_URL}/graphql\`, {
88
+ query: \`mutation store($user: UserInput!) {
89
+ user: store(user: $user) {
119
90
  id
120
91
  name
121
92
  lastName
@@ -131,68 +102,26 @@ describe('Simba.js tests', () => {
131
102
  }
132
103
  })
133
104
 
134
- data = result.data
135
- status = result.status
136
105
  userID = result.data.data.user.id ?? userID
137
- expect(status).toBe(200)
138
- })
139
-
140
- test('Should return storeUserResponse', () => {
141
- expect(validator(storeUserResponse, data)).toBe(true)
142
- })
143
- })
144
-
145
- describe('API: getUsers query', () => {
146
- const getUsersResponse = Type.Object({
147
- data: Type.Object({
148
- users: Type.Array(userDto)
149
- })
150
- })
151
-
152
- type GetAllUsersDTO = Static<typeof getUsersResponse>
153
-
154
- let data: GetAllUsersDTO
155
- let status: number
156
-
157
- test('Should return 200 as status code', async () => {
158
- const result = await axios.post<GetAllUsersDTO>(\`\${BASE_URL}/api\`, {
159
- query: \`query getUsers {
160
- users: getUsers {
161
- id
162
- name
163
- lastName
164
- createdAt
165
- updatedAt
166
- }
167
- }\`
168
- })
169
-
170
- data = result.data
171
- status = result.status
172
- expect(status).toBe(200)
173
- })
174
-
175
- test('Should return getUsersResponse', () => {
176
- expect(validator(getUsersResponse, data)).toBe(true)
106
+ expect(userID).toBeTruthy()
107
+ expect(result.status).toBe(200)
108
+ expect(storeUserResponse.safeParse(result.data).success).toBe(true)
177
109
  })
178
110
  })
179
111
 
180
112
  describe('API: getUser query', () => {
181
- const getUserResponse = Type.Object({
182
- data: Type.Object({
113
+ const getUserResponse = z.object({
114
+ data: z.object({
183
115
  user: userDto
184
116
  })
185
117
  })
186
118
 
187
- type GetOneUserDTO = Static<typeof getUserResponse>
119
+ type GetOneUserDTO = z.infer<typeof getUserResponse>
188
120
 
189
- let data: GetOneUserDTO
190
- let status: number
191
-
192
- test('Should return 200 as status code', async () => {
193
- const result = await axios.post<GetOneUserDTO>(\`\${BASE_URL}/api\`, {
194
- query: \`query getUser($id: ${dbIsSQL ? 'Int' : 'ID'}!) {
195
- user: getUser(id: $id) {
121
+ it('Should return a user', async () => {
122
+ const result = await axios.post<GetOneUserDTO>(\`\${BASE_URL}/graphql\`, {
123
+ query: \`query getById($id: ${dbIsSQL ? 'Float' : 'String'}!) {
124
+ user: getById(id: $id) {
196
125
  id
197
126
  name
198
127
  lastName
@@ -205,32 +134,26 @@ describe('Simba.js tests', () => {
205
134
  }
206
135
  })
207
136
 
208
- data = result.data
209
- status = result.status
210
- expect(status).toBe(200)
211
- })
212
-
213
- test('Should return getOneUserResponse', () => {
214
- expect(validator(getUserResponse, data)).toBe(true)
137
+ expect(result.status).toBe(200)
138
+ expect(getUserResponse.safeParse(result.data).success).toBe(true)
215
139
  })
216
140
  })
217
141
 
218
142
  describe('API: updateUser mutation', () => {
219
- const updateUserResponse = Type.Object({
220
- data: Type.Object({
143
+ const updateUserResponse = z.object({
144
+ data: z.object({
221
145
  user: userDto
222
146
  })
223
147
  })
224
148
 
225
- type UpdateUserDTO = Static<typeof updateUserResponse>
149
+ type UpdateUserDTO = z.infer<typeof updateUserResponse>
226
150
 
227
- let data: UpdateUserDTO
228
- let status: number
229
-
230
- test('Should return 200 as status code', async () => {
231
- const result = await axios.post<UpdateUserDTO>(\`\${BASE_URL}/api\`, {
232
- query: \`mutation updateUser($user: UpdateUserInput!) {
233
- user: updateUser(user: $user) {
151
+ it('Should update a user successfully', async () => {
152
+ const result = await axios.post<UpdateUserDTO>(\`\${BASE_URL}/graphql\`, {
153
+ query: \`mutation update($id: ${
154
+ dbIsSQL ? 'Float' : 'String'
155
+ }!, $user: UserInput!) {
156
+ user: update(id: $id, user: $user) {
234
157
  id
235
158
  name
236
159
  lastName
@@ -239,100 +162,40 @@ describe('Simba.js tests', () => {
239
162
  }
240
163
  }\`,
241
164
  variables: {
165
+ id: userID,
242
166
  user: {
243
- id: userID,
244
167
  lastName: 'Luzquiños',
245
168
  name: 'Anthony'
246
169
  }
247
170
  }
248
171
  })
249
172
 
250
- data = result.data
251
- status = result.status
252
- expect(status).toBe(200)
253
- })
254
-
255
- test('Should return updateUserResponse', () => {
256
- expect(validator(updateUserResponse, data)).toBe(true)
173
+ expect(result.status).toBe(200)
174
+ expect(updateUserResponse.safeParse(result.data).success).toBe(true)
257
175
  })
258
176
  })
259
177
 
260
178
  describe('API: deleteUser mutation', () => {
261
- const deleteUserResponse = Type.Object({
262
- data: Type.Object({
263
- result: Type.String()
179
+ const deleteUserResponse = z.object({
180
+ data: z.object({
181
+ result: z.string()
264
182
  })
265
183
  })
266
184
 
267
- type DeleteUserDTO = Static<typeof deleteUserResponse>
268
-
269
- let data: DeleteUserDTO
270
- let status: number
185
+ type DeleteUserDTO = z.infer<typeof deleteUserResponse>
271
186
 
272
- test('Should return 200 as status code', async () => {
273
- const result = await axios.post<DeleteUserDTO>(\`\${BASE_URL}/api\`, {
274
- query: \`mutation deleteUser($id: ${dbIsSQL ? 'Int' : 'ID'}!) {
275
- result: deleteUser(id: $id)
187
+ it('Should delete the created user', async () => {
188
+ const result = await axios.post<DeleteUserDTO>(\`\${BASE_URL}/graphql\`, {
189
+ query: \`mutation deleteById($id: ${dbIsSQL ? 'Float' : 'String'}!) {
190
+ result: deleteById(id: $id)
276
191
  }\`,
277
192
  variables: {
278
193
  id: userID
279
194
  }
280
195
  })
281
196
 
282
- data = result.data
283
- status = result.status
284
- expect(status).toBe(200)
285
- })
286
-
287
- test('Should return deleteUserResponse', () => {
288
- expect(validator(deleteUserResponse, data)).toBe(true)
289
- })
290
- })
291
-
292
- describe('API: deleteAllUsers mutation', () => {
293
- const deleteAllUserResponse = Type.Object({
294
- data: Type.Object({
295
- result: Type.String()
296
- })
297
- })
298
-
299
- type DeleteAllUsersDTO = Static<typeof deleteAllUserResponse>
300
-
301
- let data: DeleteAllUsersDTO
302
- let status: number
303
-
304
- test('Should return 200 as status code', async () => {
305
- await axios.post(\`\${BASE_URL}/api\`, {
306
- query: \`mutation storeUser($user: StoreUserInput!) {
307
- user: storeUser(user: $user) {
308
- id
309
- name
310
- lastName
311
- createdAt
312
- updatedAt
313
- }
314
- }\`,
315
- variables: {
316
- user: {
317
- lastName: 'Lzq',
318
- name: 'Anthony'
319
- }
320
- }
321
- })
322
-
323
- const result = await axios.post<DeleteAllUsersDTO>(\`\${BASE_URL}/api\`, {
324
- query: \`mutation deleteAllUsers {
325
- result: deleteAllUsers
326
- }\`
327
- })
328
-
329
- data = result.data
330
- status = result.status
331
- expect(status).toBe(200)
332
- })
333
-
334
- test('Should return deleteAllUsersResponse', () => {
335
- expect(validator(deleteAllUserResponse, data)).toBe(true)
197
+ expect(result.status).toBe(200)
198
+ expect(deleteUserResponse.safeParse(result.data).success).toBe(true)
336
199
  })
337
200
  })
338
201
  })
@@ -340,37 +203,20 @@ describe('Simba.js tests', () => {
340
203
  afterAll(async () => {
341
204
  await Server.stop()
342
205
  })
343
- })
344
- `
206
+ })\n`
345
207
  : `import axios from 'axios'
346
- import { Static, TObject, TProperties, Type } from '@sinclair/typebox'
347
- import Ajv from 'ajv'
208
+ import z from 'zod'
348
209
 
349
210
  import { Server } from '../src/network'
350
211
  import { userDto } from '../src/schemas'
351
212
 
352
- const ajv = new Ajv({
353
- removeAdditional: true,
354
- useDefaults: true,
355
- coerceTypes: true,
356
- nullable: true
213
+ const BASE_URL = \`http://localhost:\${process.env.PORT || 1996}\`
214
+ const baseResponseDto = z.object({
215
+ error: z.boolean(),
216
+ message: z.string()
357
217
  })
358
218
 
359
- const BASE_URL = 'http://localhost:${process.env.PORT || 1996}'
360
- const validator = <T extends TProperties>(
361
- schema: TObject<T>,
362
- object: unknown
363
- ) => {
364
- const validate = ajv.compile(schema)
365
-
366
- return validate(object)
367
- }
368
- const baseResponseDto = Type.Object({
369
- error: Type.Boolean(),
370
- message: Type.String()
371
- })
372
-
373
- type BaseResponseDTO = Static<typeof baseResponseDto>
219
+ type BaseResponseDTO = z.infer<typeof baseResponseDto>
374
220
 
375
221
  describe('Simba.js tests', () => {
376
222
  beforeAll(async () => {
@@ -381,36 +227,24 @@ describe('Simba.js tests', () => {
381
227
  let userID = ${dbIsSQL ? 0 : "''"}
382
228
 
383
229
  describe('API: GET /', () => {
384
- let data: BaseResponseDTO
385
-
386
- test('Should return 200 as status code', async () => {
230
+ it('Should return 200 with a successful operation', async () => {
387
231
  const result = await axios.get<BaseResponseDTO>(BASE_URL)
388
232
 
389
- data = result.data
390
233
  expect(result.status).toBe(200)
391
- })
392
-
393
- test('Should be a successfully operation', () => {
394
- expect(data.error).toBe(false)
395
- })
396
-
397
- test('Should be return baseResponseDto', () => {
398
- expect(validator(baseResponseDto, data)).toBe(true)
234
+ expect(result.data.error).toBe(false)
235
+ expect(baseResponseDto.parse(result.data).error).toBe(false)
399
236
  })
400
237
  })
401
238
 
402
239
  describe('API: POST /api/users', () => {
403
- const storeUserResponse = Type.Object({
404
- error: Type.Boolean(),
240
+ const storeUserResponse = z.object({
241
+ error: z.boolean(),
405
242
  message: userDto
406
243
  })
407
244
 
408
- type StoreUserDTO = Static<typeof storeUserResponse>
245
+ type StoreUserDTO = z.infer<typeof storeUserResponse>
409
246
 
410
- let data: StoreUserDTO
411
- let status: number
412
-
413
- test('Should return 201 as status code', async () => {
247
+ it('Should create a user successfully', async () => {
414
248
  const result = await axios.post<StoreUserDTO>(\`\${BASE_URL}/api/users\`, {
415
249
  args: {
416
250
  lastName: 'Lzq',
@@ -418,91 +252,42 @@ describe('Simba.js tests', () => {
418
252
  }
419
253
  })
420
254
 
421
- data = result.data
422
- status = result.status
423
255
  userID = result.data.message.id ?? userID
424
- expect(status).toBe(201)
425
- })
426
-
427
- test('Should be a successfully operation', () => {
428
- expect(data.error).toBe(false)
429
- })
430
-
431
- test('Should return storeUserResponse', () => {
432
- expect(validator(storeUserResponse, data)).toBe(true)
433
- })
434
- })
435
-
436
- describe('API: GET /api/users', () => {
437
- const getAllUsersResponse = Type.Object({
438
- error: Type.Boolean(),
439
- message: Type.Array(userDto)
440
- })
441
-
442
- type GetAllUsersDTO = Static<typeof getAllUsersResponse>
443
-
444
- let data: GetAllUsersDTO
445
- let status: number
446
-
447
- test('Should return 200 as status code', async () => {
448
- const result = await axios.get<GetAllUsersDTO>(\`\${BASE_URL}/api/users\`)
449
-
450
- data = result.data
451
- status = result.status
452
- expect(status).toBe(200)
453
- })
454
-
455
- test('Should be a successfully operation', () => {
456
- expect(data.error).toBe(false)
457
- })
458
-
459
- test('Should return getAllUsersResponse', () => {
460
- expect(validator(getAllUsersResponse, data)).toBe(true)
256
+ expect(userID).toBeTruthy()
257
+ expect(result.status).toBe(201)
258
+ expect(result.data.error).toBe(false)
259
+ expect(storeUserResponse.parse(result.data).error).toBe(false)
461
260
  })
462
261
  })
463
262
 
464
263
  describe('API: GET /api/user/:id', () => {
465
- const getOneUserResponse = Type.Object({
466
- error: Type.Boolean(),
264
+ const getOneUserResponse = z.object({
265
+ error: z.boolean(),
467
266
  message: userDto
468
267
  })
469
268
 
470
- type GetOneUserDTO = Static<typeof getOneUserResponse>
269
+ type GetOneUserDTO = z.infer<typeof getOneUserResponse>
471
270
 
472
- let data: GetOneUserDTO
473
- let status: number
474
-
475
- test('Should return 200 as status code', async () => {
271
+ it('Should return a user', async () => {
476
272
  const result = await axios.get<GetOneUserDTO>(
477
273
  \`\${BASE_URL}/api/user/\${userID}\`
478
274
  )
479
275
 
480
- data = result.data
481
- status = result.status
482
- expect(status).toBe(200)
483
- })
484
-
485
- test('Should be a successfully operation', () => {
486
- expect(data.error).toBe(false)
487
- })
488
-
489
- test('Should return getOneUserResponse', () => {
490
- expect(validator(getOneUserResponse, data)).toBe(true)
276
+ expect(result.status).toBe(200)
277
+ expect(result.data.error).toBe(false)
278
+ expect(getOneUserResponse.parse(result.data).error).toBe(false)
491
279
  })
492
280
  })
493
281
 
494
282
  describe('API: PATCH /api/user/:id', () => {
495
- const updateUserResponse = Type.Object({
496
- error: Type.Boolean(),
283
+ const updateUserResponse = z.object({
284
+ error: z.boolean(),
497
285
  message: userDto
498
286
  })
499
287
 
500
- type UpdateUserDTO = Static<typeof updateUserResponse>
288
+ type UpdateUserDTO = z.infer<typeof updateUserResponse>
501
289
 
502
- let data: UpdateUserDTO
503
- let status: number
504
-
505
- test('Should return 200 as status code', async () => {
290
+ it('Should update a user successfully', async () => {
506
291
  const result = await axios.patch<UpdateUserDTO>(
507
292
  \`\${BASE_URL}/api/user/\${userID}\`,
508
293
  {
@@ -513,70 +298,21 @@ describe('Simba.js tests', () => {
513
298
  }
514
299
  )
515
300
 
516
- data = result.data
517
- status = result.status
518
- expect(status).toBe(200)
519
- })
520
-
521
- test('Should be a successfully operation', () => {
522
- expect(data.error).toBe(false)
523
- })
524
-
525
- test('Should return updateUserResponse', () => {
526
- expect(validator(updateUserResponse, data)).toBe(true)
301
+ expect(result.status).toBe(200)
302
+ expect(result.data.error).toBe(false)
303
+ expect(updateUserResponse.parse(result.data).error).toBe(false)
527
304
  })
528
305
  })
529
306
 
530
307
  describe('API: DELETE /api/user/:id', () => {
531
- let data: BaseResponseDTO
532
- let status: number
533
-
534
- test('Should return 200 as status code', async () => {
308
+ it('Should delete the created user', async () => {
535
309
  const result = await axios.delete<BaseResponseDTO>(
536
310
  \`\${BASE_URL}/api/user/\${userID}\`
537
311
  )
538
312
 
539
- data = result.data
540
- status = result.status
541
- expect(status).toBe(200)
542
- })
543
-
544
- test('Should be a successfully operation', () => {
545
- expect(data.error).toBe(false)
546
- })
547
-
548
- test('Should return deleteUserResponse', () => {
549
- expect(validator(baseResponseDto, data)).toBe(true)
550
- })
551
- })
552
-
553
- describe('API: DELETE /api/users', () => {
554
- let data: BaseResponseDTO
555
- let status: number
556
-
557
- test('Should return 200 as status code', async () => {
558
- await axios.post(\`\${BASE_URL}/api/users\`, {
559
- args: {
560
- lastName: 'Lzq',
561
- name: 'Anthony'
562
- }
563
- })
564
-
565
- const result = await axios.delete<BaseResponseDTO>(
566
- \`\${BASE_URL}/api/users\`
567
- )
568
-
569
- data = result.data
570
- status = result.status
571
- expect(status).toBe(200)
572
- })
573
-
574
- test('Should be a successfully operation', () => {
575
- expect(data.error).toBe(false)
576
- })
577
-
578
- test('Should return deleteAllUsersResponse', () => {
579
- expect(validator(baseResponseDto, data)).toBe(true)
313
+ expect(result.status).toBe(200)
314
+ expect(result.data.error).toBe(false)
315
+ expect(baseResponseDto.parse(result.data).error).toBe(false)
580
316
  })
581
317
  })
582
318
  })
@@ -584,37 +320,14 @@ describe('Simba.js tests', () => {
584
320
  afterAll(async () => {
585
321
  await Server.stop()
586
322
  })
587
- })
588
- `,
323
+ })\n`,
589
324
  file: `${projectName}/test/index.test.ts`
590
- },
591
- jestGlobalSetup: {
592
- content: `module.exports = () => {
593
- if (process.env.NODE_ENV === 'local') require('./setEnvVars')
594
- }
595
- `,
596
- file: `${projectName}/test/jestGlobalSetup.ts`
597
- },
598
- setEnvVars: {
599
- content: `process.env.DB_URI =\n${
600
- ENVIRONMENTS_WITH_DB_URI.includes(process.env.NODE_ENV)
601
- ? ` '${dbURI}'\n`
602
- : dbIsSQL
603
- ? ` 'postgres://postgres:postgres@postgres:5432/${projectName}'\n`
604
- : ` 'mongodb://mongo:mongo@mongo:27017/${projectName}'\n`
605
- }`,
606
- file: `${projectName}/test/setEnvVars.ts`
607
325
  }
608
326
  }
609
327
  }
610
328
 
611
329
  await Promise.all([
612
330
  writeFile(data.jestConfig.file, data.jestConfig.content),
613
- writeFile(data.test.index.file, data.test.index.content),
614
- writeFile(
615
- data.test.jestGlobalSetup.file,
616
- data.test.jestGlobalSetup.content
617
- ),
618
- writeFile(data.test.setEnvVars.file, data.test.setEnvVars.content)
331
+ writeFile(data.test.index.file, data.test.index.content)
619
332
  ])
620
333
  }