nodejs-quickstart-structure 1.18.1 → 1.19.1

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.
Files changed (235) hide show
  1. package/CHANGELOG.md +309 -294
  2. package/LICENSE +15 -15
  3. package/README.md +2 -1
  4. package/lib/generator.js +139 -139
  5. package/lib/modules/app-setup.js +401 -401
  6. package/lib/modules/caching-setup.js +76 -73
  7. package/lib/modules/config-files.js +151 -151
  8. package/lib/modules/database-setup.js +116 -116
  9. package/lib/modules/kafka-setup.js +249 -191
  10. package/lib/modules/project-setup.js +32 -31
  11. package/lib/prompts.js +100 -100
  12. package/package.json +78 -67
  13. package/templates/clean-architecture/js/src/domain/models/User.js +9 -9
  14. package/templates/clean-architecture/js/src/errors/ApiError.js +14 -14
  15. package/templates/clean-architecture/js/src/errors/BadRequestError.js +11 -10
  16. package/templates/clean-architecture/js/src/errors/BadRequestError.spec.js.ejs +22 -21
  17. package/templates/clean-architecture/js/src/errors/NotFoundError.js +11 -10
  18. package/templates/clean-architecture/js/src/errors/NotFoundError.spec.js.ejs +22 -21
  19. package/templates/clean-architecture/js/src/index.js.ejs +55 -55
  20. package/templates/clean-architecture/js/src/infrastructure/config/env.js.ejs +47 -47
  21. package/templates/clean-architecture/js/src/infrastructure/log/logger.js +36 -36
  22. package/templates/clean-architecture/js/src/infrastructure/log/logger.spec.js.ejs +63 -63
  23. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +69 -39
  24. package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +142 -81
  25. package/templates/clean-architecture/js/src/infrastructure/webserver/middleware/errorMiddleware.js +30 -30
  26. package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +89 -89
  27. package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js.ejs +6 -6
  28. package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +156 -75
  29. package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +234 -138
  30. package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -13
  31. package/templates/clean-architecture/js/src/interfaces/graphql/context.spec.js.ejs +31 -31
  32. package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -5
  33. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -6
  34. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -21
  35. package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +66 -49
  36. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -6
  37. package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +19 -17
  38. package/templates/clean-architecture/js/src/interfaces/routes/api.js +12 -10
  39. package/templates/clean-architecture/js/src/interfaces/routes/api.spec.js.ejs +38 -38
  40. package/templates/clean-architecture/js/src/usecases/CreateUser.js +14 -14
  41. package/templates/clean-architecture/js/src/usecases/CreateUser.spec.js.ejs +51 -51
  42. package/templates/clean-architecture/js/src/usecases/DeleteUser.js +11 -0
  43. package/templates/clean-architecture/js/src/usecases/DeleteUser.spec.js.ejs +47 -0
  44. package/templates/clean-architecture/js/src/usecases/GetAllUsers.js +12 -12
  45. package/templates/clean-architecture/js/src/usecases/GetAllUsers.spec.js.ejs +61 -61
  46. package/templates/clean-architecture/js/src/usecases/UpdateUser.js +11 -0
  47. package/templates/clean-architecture/js/src/usecases/UpdateUser.spec.js.ejs +48 -0
  48. package/templates/clean-architecture/js/src/utils/errorMessages.js +14 -0
  49. package/templates/clean-architecture/js/src/utils/httpCodes.js +9 -9
  50. package/templates/clean-architecture/ts/src/config/env.ts.ejs +46 -46
  51. package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +6 -6
  52. package/templates/clean-architecture/ts/src/domain/user.ts +7 -7
  53. package/templates/clean-architecture/ts/src/errors/ApiError.ts +15 -15
  54. package/templates/clean-architecture/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
  55. package/templates/clean-architecture/ts/src/errors/BadRequestError.ts +9 -8
  56. package/templates/clean-architecture/ts/src/errors/NotFoundError.spec.ts.ejs +22 -21
  57. package/templates/clean-architecture/ts/src/errors/NotFoundError.ts +9 -8
  58. package/templates/clean-architecture/ts/src/index.ts.ejs +139 -139
  59. package/templates/clean-architecture/ts/src/infrastructure/log/logger.spec.ts.ejs +63 -63
  60. package/templates/clean-architecture/ts/src/infrastructure/log/logger.ts +36 -36
  61. package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +175 -85
  62. package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +74 -0
  63. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +331 -185
  64. package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +173 -84
  65. package/templates/clean-architecture/ts/src/interfaces/graphql/context.spec.ts.ejs +32 -32
  66. package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -17
  67. package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -3
  68. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -4
  69. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
  70. package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +29 -21
  71. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -4
  72. package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +17 -15
  73. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.spec.ts.ejs +40 -40
  74. package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +13 -11
  75. package/templates/clean-architecture/ts/src/usecases/createUser.spec.ts.ejs +51 -51
  76. package/templates/clean-architecture/ts/src/usecases/createUser.ts +13 -13
  77. package/templates/clean-architecture/ts/src/usecases/deleteUser.spec.ts.ejs +47 -0
  78. package/templates/clean-architecture/ts/src/usecases/deleteUser.ts +9 -0
  79. package/templates/clean-architecture/ts/src/usecases/getAllUsers.spec.ts.ejs +63 -63
  80. package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +10 -10
  81. package/templates/clean-architecture/ts/src/usecases/updateUser.spec.ts.ejs +48 -0
  82. package/templates/clean-architecture/ts/src/usecases/updateUser.ts +9 -0
  83. package/templates/clean-architecture/ts/src/utils/errorMessages.ts +12 -0
  84. package/templates/clean-architecture/ts/src/utils/errorMiddleware.ts.ejs +27 -27
  85. package/templates/clean-architecture/ts/src/utils/httpCodes.ts +7 -7
  86. package/templates/common/.cursorrules.ejs +60 -60
  87. package/templates/common/.dockerignore +12 -12
  88. package/templates/common/.env.example.ejs +41 -41
  89. package/templates/common/.gitattributes +46 -0
  90. package/templates/common/.gitlab-ci.yml.ejs +86 -86
  91. package/templates/common/.lintstagedrc +6 -6
  92. package/templates/common/.prettierrc +7 -7
  93. package/templates/common/Dockerfile +73 -73
  94. package/templates/common/Jenkinsfile.ejs +87 -87
  95. package/templates/common/README.md.ejs +294 -270
  96. package/templates/common/SECURITY.md +20 -20
  97. package/templates/common/_github/workflows/ci.yml.ejs +46 -46
  98. package/templates/common/_github/workflows/security.yml.ejs +36 -36
  99. package/templates/common/_gitignore +5 -5
  100. package/templates/common/_husky/pre-commit +4 -4
  101. package/templates/common/caching/clean/js/CreateUser.js.ejs +29 -29
  102. package/templates/common/caching/clean/js/DeleteUser.js.ejs +27 -0
  103. package/templates/common/caching/clean/js/GetAllUsers.js.ejs +37 -37
  104. package/templates/common/caching/clean/js/UpdateUser.js.ejs +27 -0
  105. package/templates/common/caching/clean/ts/createUser.ts.ejs +27 -27
  106. package/templates/common/caching/clean/ts/deleteUser.ts.ejs +24 -0
  107. package/templates/common/caching/clean/ts/getAllUsers.ts.ejs +34 -34
  108. package/templates/common/caching/clean/ts/updateUser.ts.ejs +25 -0
  109. package/templates/common/caching/js/memoryCache.js.ejs +60 -60
  110. package/templates/common/caching/js/memoryCache.spec.js.ejs +101 -101
  111. package/templates/common/caching/js/redisClient.js.ejs +75 -75
  112. package/templates/common/caching/js/redisClient.spec.js.ejs +147 -147
  113. package/templates/common/caching/ts/memoryCache.spec.ts.ejs +102 -102
  114. package/templates/common/caching/ts/memoryCache.ts.ejs +73 -64
  115. package/templates/common/caching/ts/redisClient.spec.ts.ejs +157 -157
  116. package/templates/common/caching/ts/redisClient.ts.ejs +89 -80
  117. package/templates/common/database/js/database.js.ejs +19 -19
  118. package/templates/common/database/js/database.spec.js.ejs +56 -56
  119. package/templates/common/database/js/models/User.js.ejs +79 -53
  120. package/templates/common/database/js/models/User.js.mongoose.ejs +23 -19
  121. package/templates/common/database/js/models/User.spec.js.ejs +94 -84
  122. package/templates/common/database/js/mongoose.js.ejs +33 -33
  123. package/templates/common/database/js/mongoose.spec.js.ejs +43 -43
  124. package/templates/common/database/ts/database.spec.ts.ejs +56 -56
  125. package/templates/common/database/ts/database.ts.ejs +21 -21
  126. package/templates/common/database/ts/models/User.spec.ts.ejs +100 -84
  127. package/templates/common/database/ts/models/User.ts.ejs +87 -61
  128. package/templates/common/database/ts/models/User.ts.mongoose.ejs +30 -25
  129. package/templates/common/database/ts/mongoose.spec.ts.ejs +42 -42
  130. package/templates/common/database/ts/mongoose.ts.ejs +28 -28
  131. package/templates/common/docker-compose.yml.ejs +159 -159
  132. package/templates/common/ecosystem.config.js.ejs +40 -40
  133. package/templates/common/eslint.config.mjs.ejs +77 -77
  134. package/templates/common/health/js/healthRoute.js.ejs +50 -47
  135. package/templates/common/health/js/healthRoute.spec.js.ejs +70 -70
  136. package/templates/common/health/ts/healthRoute.spec.ts.ejs +76 -76
  137. package/templates/common/health/ts/healthRoute.ts.ejs +49 -46
  138. package/templates/common/jest.config.js.ejs +32 -32
  139. package/templates/common/jest.e2e.config.js.ejs +8 -8
  140. package/templates/common/kafka/js/config/kafka.js +9 -9
  141. package/templates/common/kafka/js/config/kafka.spec.js.ejs +27 -27
  142. package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +30 -30
  143. package/templates/common/kafka/js/messaging/baseConsumer.spec.js.ejs +58 -58
  144. package/templates/common/kafka/js/messaging/userEventSchema.js.ejs +12 -11
  145. package/templates/common/kafka/js/messaging/userEventSchema.spec.js.ejs +27 -27
  146. package/templates/common/kafka/js/messaging/welcomeEmailConsumer.js.ejs +44 -31
  147. package/templates/common/kafka/js/messaging/welcomeEmailConsumer.spec.js.ejs +86 -49
  148. package/templates/common/kafka/js/services/kafkaService.js.ejs +93 -93
  149. package/templates/common/kafka/js/services/kafkaService.spec.js.ejs +106 -106
  150. package/templates/common/kafka/js/utils/kafkaEvents.js.ejs +7 -0
  151. package/templates/common/kafka/ts/config/kafka.spec.ts.ejs +27 -27
  152. package/templates/common/kafka/ts/config/kafka.ts +7 -7
  153. package/templates/common/kafka/ts/messaging/baseConsumer.spec.ts.ejs +50 -50
  154. package/templates/common/kafka/ts/messaging/baseConsumer.ts.ejs +27 -27
  155. package/templates/common/kafka/ts/messaging/userEventSchema.spec.ts.ejs +51 -51
  156. package/templates/common/kafka/ts/messaging/userEventSchema.ts.ejs +12 -11
  157. package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.spec.ts.ejs +86 -49
  158. package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.ts.ejs +38 -25
  159. package/templates/common/kafka/ts/services/kafkaService.spec.ts.ejs +81 -81
  160. package/templates/common/kafka/ts/services/kafkaService.ts.ejs +95 -95
  161. package/templates/common/kafka/ts/utils/kafkaEvents.ts.ejs +5 -0
  162. package/templates/common/migrate-mongo-config.js.ejs +31 -31
  163. package/templates/common/migrations/init.js.ejs +23 -23
  164. package/templates/common/package.json.ejs +119 -118
  165. package/templates/common/prompts/add-feature.md.ejs +26 -26
  166. package/templates/common/prompts/project-context.md.ejs +43 -43
  167. package/templates/common/prompts/troubleshoot.md.ejs +28 -28
  168. package/templates/common/public/css/style.css +147 -147
  169. package/templates/common/scripts/run-e2e.js.ejs +63 -63
  170. package/templates/common/shutdown/js/gracefulShutdown.js.ejs +65 -61
  171. package/templates/common/shutdown/js/gracefulShutdown.spec.js.ejs +149 -160
  172. package/templates/common/shutdown/ts/gracefulShutdown.spec.ts.ejs +179 -158
  173. package/templates/common/shutdown/ts/gracefulShutdown.ts.ejs +59 -55
  174. package/templates/common/sonar-project.properties.ejs +27 -27
  175. package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +120 -49
  176. package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +120 -49
  177. package/templates/common/src/utils/errorMiddleware.spec.js.ejs +79 -79
  178. package/templates/common/src/utils/errorMiddleware.spec.ts.ejs +94 -94
  179. package/templates/common/swagger.yml.ejs +118 -66
  180. package/templates/common/tsconfig.json +22 -22
  181. package/templates/common/views/ejs/index.ejs +55 -55
  182. package/templates/common/views/pug/index.pug +40 -40
  183. package/templates/db/mysql/V1__Initial_Setup.sql.ejs +10 -9
  184. package/templates/db/postgres/V1__Initial_Setup.sql.ejs +10 -9
  185. package/templates/mvc/js/src/config/env.js.ejs +46 -46
  186. package/templates/mvc/js/src/config/swagger.js.ejs +6 -6
  187. package/templates/mvc/js/src/controllers/userController.js.ejs +246 -105
  188. package/templates/mvc/js/src/controllers/userController.spec.js.ejs +481 -209
  189. package/templates/mvc/js/src/errors/ApiError.js +14 -14
  190. package/templates/mvc/js/src/errors/BadRequestError.js +11 -10
  191. package/templates/mvc/js/src/errors/BadRequestError.spec.js.ejs +22 -21
  192. package/templates/mvc/js/src/errors/NotFoundError.js +11 -10
  193. package/templates/mvc/js/src/errors/NotFoundError.spec.js.ejs +22 -21
  194. package/templates/mvc/js/src/graphql/context.js.ejs +7 -7
  195. package/templates/mvc/js/src/graphql/context.spec.js.ejs +29 -29
  196. package/templates/mvc/js/src/graphql/index.js.ejs +5 -5
  197. package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -6
  198. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -19
  199. package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +64 -47
  200. package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -6
  201. package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +19 -17
  202. package/templates/mvc/js/src/index.js.ejs +136 -136
  203. package/templates/mvc/js/src/routes/api.js +10 -8
  204. package/templates/mvc/js/src/routes/api.spec.js.ejs +41 -36
  205. package/templates/mvc/js/src/utils/errorMessages.js +14 -0
  206. package/templates/mvc/js/src/utils/errorMiddleware.js +29 -29
  207. package/templates/mvc/js/src/utils/httpCodes.js +9 -9
  208. package/templates/mvc/js/src/utils/logger.js +40 -40
  209. package/templates/mvc/js/src/utils/logger.spec.js.ejs +63 -63
  210. package/templates/mvc/ts/src/config/env.ts.ejs +45 -45
  211. package/templates/mvc/ts/src/config/swagger.ts.ejs +6 -6
  212. package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +481 -203
  213. package/templates/mvc/ts/src/controllers/userController.ts.ejs +248 -107
  214. package/templates/mvc/ts/src/errors/ApiError.ts +15 -15
  215. package/templates/mvc/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
  216. package/templates/mvc/ts/src/errors/BadRequestError.ts +9 -8
  217. package/templates/mvc/ts/src/errors/NotFoundError.spec.ts.ejs +27 -21
  218. package/templates/mvc/ts/src/errors/NotFoundError.ts +9 -8
  219. package/templates/mvc/ts/src/graphql/context.spec.ts.ejs +30 -30
  220. package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -12
  221. package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -3
  222. package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -4
  223. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
  224. package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +29 -21
  225. package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -4
  226. package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +17 -15
  227. package/templates/mvc/ts/src/index.ts.ejs +156 -153
  228. package/templates/mvc/ts/src/routes/api.spec.ts.ejs +59 -40
  229. package/templates/mvc/ts/src/routes/api.ts +12 -10
  230. package/templates/mvc/ts/src/utils/errorMessages.ts +12 -0
  231. package/templates/mvc/ts/src/utils/errorMiddleware.ts.ejs +27 -27
  232. package/templates/mvc/ts/src/utils/httpCodes.ts +7 -7
  233. package/templates/mvc/ts/src/utils/logger.spec.ts.ejs +63 -63
  234. package/templates/mvc/ts/src/utils/logger.ts +36 -36
  235. package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.ts.ejs +0 -37
@@ -1,49 +1,66 @@
1
- const { userResolvers } = require('@/interfaces/graphql/resolvers/user.resolvers');
2
-
3
- const mockGetUsers = jest.fn().mockResolvedValue([{ id: '1', name: 'John Doe', email: 'john@example.com' }]);
4
- const mockCreateUser = jest.fn().mockResolvedValue({ id: '1', name: 'Jane', email: 'jane@example.com' });
5
-
6
- jest.mock('@/interfaces/controllers/userController', () => {
7
- return jest.fn().mockImplementation(() => ({
8
- getUsers: (...args) => mockGetUsers(...args),
9
- createUser: (...args) => mockCreateUser(...args)
10
- }));
11
- });
12
-
13
- describe('User Resolvers', () => {
14
- afterEach(() => {
15
- jest.clearAllMocks();
16
- });
17
-
18
- describe('Query.getAllUsers', () => {
19
- it('should return all users', async () => {
20
- const result = await userResolvers.Query.getAllUsers();
21
- expect(result).toEqual([{ id: '1', name: 'John Doe', email: 'john@example.com' }]);
22
- expect(mockGetUsers).toHaveBeenCalledTimes(1);
23
- });
24
- });
25
-
26
- describe('Mutation.createUser', () => {
27
- it('should create and return a new user', async () => {
28
- const result = await userResolvers.Mutation.createUser(null, { name: 'Jane', email: 'jane@example.com' });
29
- expect(result).toEqual({ id: '1', name: 'Jane', email: 'jane@example.com' });
30
- expect(mockCreateUser).toHaveBeenCalledWith({ name: 'Jane', email: 'jane@example.com' });
31
- expect(mockCreateUser).toHaveBeenCalledTimes(1);
32
- });
33
- });
34
- <%_ if (database === 'MongoDB') { -%>
35
- describe('User.id', () => {
36
- it('should return parent.id if available', () => {
37
- const parent = { id: '123' };
38
- const result = userResolvers.User.id(parent);
39
- expect(result).toBe('123');
40
- });
41
-
42
- it('should fallback to parent._id if id is not available', () => {
43
- const parent = { _id: '456' };
44
- const result = userResolvers.User.id(parent);
45
- expect(result).toBe('456');
46
- });
47
- });
48
- <%_ } -%>
49
- });
1
+ const { userResolvers } = require('@/interfaces/graphql/resolvers/user.resolvers');
2
+
3
+ const mockGetUsers = jest.fn().mockResolvedValue([{ id: '1', name: 'John Doe', email: 'john@example.com' }]);
4
+ const mockCreateUser = jest.fn().mockResolvedValue({ id: '1', name: 'Jane', email: 'jane@example.com' });
5
+
6
+ jest.mock('@/interfaces/controllers/userController', () => {
7
+ return jest.fn().mockImplementation(() => ({
8
+ getUsers: (...args) => mockGetUsers(...args),
9
+ createUser: (...args) => mockCreateUser(...args),
10
+ updateUser: jest.fn().mockImplementation((id, data) => Promise.resolve({ id, ...data })),
11
+ deleteUser: jest.fn().mockImplementation(() => Promise.resolve(true))
12
+ }));
13
+ });
14
+
15
+ describe('User Resolvers', () => {
16
+ afterEach(() => {
17
+ jest.clearAllMocks();
18
+ });
19
+
20
+ describe('Query.getAllUsers', () => {
21
+ it('should return all users', async () => {
22
+ const result = await userResolvers.Query.getAllUsers();
23
+ expect(result).toEqual([{ id: '1', name: 'John Doe', email: 'john@example.com' }]);
24
+ expect(mockGetUsers).toHaveBeenCalledTimes(1);
25
+ });
26
+ });
27
+
28
+ describe('Mutation.createUser', () => {
29
+ it('should create and return a new user', async () => {
30
+ const result = await userResolvers.Mutation.createUser(null, { name: 'Jane', email: 'jane@example.com' });
31
+ expect(result).toEqual({ id: '1', name: 'Jane', email: 'jane@example.com' });
32
+ expect(mockCreateUser).toHaveBeenCalledWith({ name: 'Jane', email: 'jane@example.com' });
33
+ expect(mockCreateUser).toHaveBeenCalledTimes(1);
34
+ });
35
+ });
36
+
37
+ describe('Mutation.updateUser', () => {
38
+ it('should update and return the user', async () => {
39
+ const payload = { name: 'Updated' };
40
+ const result = await userResolvers.Mutation.updateUser(null, { id: '1', ...payload });
41
+ expect(result).toMatchObject(payload);
42
+ });
43
+ });
44
+
45
+ describe('Mutation.deleteUser', () => {
46
+ it('should delete and return true', async () => {
47
+ const result = await userResolvers.Mutation.deleteUser(null, { id: '1' });
48
+ expect(result).toBe(true);
49
+ });
50
+ });
51
+ <%_ if (database === 'MongoDB') { -%>
52
+ describe('User.id', () => {
53
+ it('should return parent.id if available', () => {
54
+ const parent = { id: '123' };
55
+ const result = userResolvers.User.id(parent);
56
+ expect(result).toBe('123');
57
+ });
58
+
59
+ it('should fallback to parent._id if id is not available', () => {
60
+ const parent = { _id: '456' };
61
+ const result = userResolvers.User.id(parent);
62
+ expect(result).toBe('456');
63
+ });
64
+ });
65
+ <%_ } -%>
66
+ });
@@ -1,6 +1,6 @@
1
- const { mergeTypeDefs } = require('@graphql-tools/merge');
2
- const { userTypes } = require('./user.types');
3
-
4
- const typeDefs = mergeTypeDefs([userTypes]);
5
-
6
- module.exports = { typeDefs };
1
+ const { mergeTypeDefs } = require('@graphql-tools/merge');
2
+ const { userTypes } = require('./user.types');
3
+
4
+ const typeDefs = mergeTypeDefs([userTypes]);
5
+
6
+ module.exports = { typeDefs };
@@ -1,17 +1,19 @@
1
- const userTypes = `#graphql
2
- type User {
3
- id: ID!
4
- name: String!
5
- email: String!
6
- }
7
-
8
- type Query {
9
- getAllUsers: [User]
10
- }
11
-
12
- type Mutation {
13
- createUser(name: String!, email: String!): User
14
- }
15
- `;
16
-
17
- module.exports = { userTypes };
1
+ const userTypes = `#graphql
2
+ type User {
3
+ id: ID!
4
+ name: String!
5
+ email: String!
6
+ }
7
+
8
+ type Query {
9
+ getAllUsers: [User]
10
+ }
11
+
12
+ type Mutation {
13
+ createUser(name: String!, email: String!): User
14
+ updateUser(id: ID!, name: String, email: String): User
15
+ deleteUser(id: ID!): Boolean
16
+ }
17
+ `;
18
+
19
+ module.exports = { userTypes };
@@ -1,10 +1,12 @@
1
- const express = require('express');
2
- const router = express.Router();
3
- const UserController = require('../controllers/userController');
4
-
5
- const userController = new UserController();
6
-
7
- router.post('/users', (req, res, next) => userController.createUser(req, res, next));
8
- router.get('/users', (req, res, next) => userController.getUsers(req, res, next));
9
-
10
- module.exports = router;
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const UserController = require('../controllers/userController');
4
+
5
+ const userController = new UserController();
6
+
7
+ router.post('/users', (req, res, next) => userController.createUser(req, res, next));
8
+ router.get('/users', (req, res, next) => userController.getUsers(req, res, next));
9
+ router.patch('/users/:id', (req, res, next) => userController.updateUser(req, res, next));
10
+ router.delete('/users/:id', (req, res, next) => userController.deleteUser(req, res, next));
11
+
12
+ module.exports = router;
@@ -1,38 +1,38 @@
1
- const request = require('supertest');
2
- const express = require('express');
3
- const router = require('@/interfaces/routes/api');
4
-
5
- const mockGetUsers = jest.fn().mockImplementation((req, res) => res.status(200).json([{ id: '1', name: 'John Doe' }]));
6
- const mockCreateUser = jest.fn().mockImplementation((req, res) => res.status(201).json({ id: '1', name: 'Test' }));
7
-
8
- jest.mock('@/interfaces/controllers/userController', () => {
9
- return jest.fn().mockImplementation(() => ({
10
- getUsers: (...args) => mockGetUsers(...args),
11
- createUser: (...args) => mockCreateUser(...args)
12
- }));
13
- });
14
-
15
- describe('ApiRoutes', () => {
16
- let app;
17
-
18
- beforeEach(() => {
19
- app = express();
20
- app.use(express.json());
21
- app.use('/api', router);
22
- });
23
-
24
- it('POST /api/users should call controller.createUser', async () => {
25
- await request(app)
26
- .post('/api/users')
27
- .send({ name: 'Test', email: 'test@example.com' });
28
-
29
- expect(mockCreateUser).toHaveBeenCalledTimes(1);
30
- });
31
-
32
- it('GET /api/users should call controller.getUsers', async () => {
33
- await request(app)
34
- .get('/api/users');
35
-
36
- expect(mockGetUsers).toHaveBeenCalledTimes(1);
37
- });
38
- });
1
+ const request = require('supertest');
2
+ const express = require('express');
3
+ const router = require('@/interfaces/routes/api');
4
+
5
+ const mockGetUsers = jest.fn().mockImplementation((req, res) => res.status(200).json([{ id: '1', name: 'John Doe' }]));
6
+ const mockCreateUser = jest.fn().mockImplementation((req, res) => res.status(201).json({ id: '1', name: 'Test' }));
7
+
8
+ jest.mock('@/interfaces/controllers/userController', () => {
9
+ return jest.fn().mockImplementation(() => ({
10
+ getUsers: (...args) => mockGetUsers(...args),
11
+ createUser: (...args) => mockCreateUser(...args)
12
+ }));
13
+ });
14
+
15
+ describe('ApiRoutes', () => {
16
+ let app;
17
+
18
+ beforeEach(() => {
19
+ app = express();
20
+ app.use(express.json());
21
+ app.use('/api', router);
22
+ });
23
+
24
+ it('POST /api/users should call controller.createUser', async () => {
25
+ await request(app)
26
+ .post('/api/users')
27
+ .send({ name: 'Test', email: 'test@example.com' });
28
+
29
+ expect(mockCreateUser).toHaveBeenCalledTimes(1);
30
+ });
31
+
32
+ it('GET /api/users should call controller.getUsers', async () => {
33
+ await request(app)
34
+ .get('/api/users');
35
+
36
+ expect(mockGetUsers).toHaveBeenCalledTimes(1);
37
+ });
38
+ });
@@ -1,14 +1,14 @@
1
- const User = require('../domain/models/User');
2
-
3
- class CreateUser {
4
- constructor(userRepository) {
5
- this.userRepository = userRepository;
6
- }
7
-
8
- async execute(name, email) {
9
- const user = new User(null, name, email);
10
- return await this.userRepository.save(user);
11
- }
12
- }
13
-
14
- module.exports = CreateUser;
1
+ const User = require('../domain/models/User');
2
+
3
+ class CreateUser {
4
+ constructor(userRepository) {
5
+ this.userRepository = userRepository;
6
+ }
7
+
8
+ async execute(name, email) {
9
+ const user = new User(null, name, email);
10
+ return await this.userRepository.save(user);
11
+ }
12
+ }
13
+
14
+ module.exports = CreateUser;
@@ -1,51 +1,51 @@
1
- const CreateUser = require('@/usecases/CreateUser');
2
- const UserRepository = require('@/infrastructure/repositories/UserRepository');
3
- <%_ if (caching !== 'None') { -%>
4
- const cacheService = require('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>');
5
- <%_ } -%>
6
-
7
- jest.mock('@/infrastructure/repositories/UserRepository');
8
- <%_ if (caching !== 'None') { -%>
9
- jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
- get: jest.fn(),
11
- set: jest.fn(),
12
- del: jest.fn()
13
- }));
14
- <%_ } -%>
15
-
16
- describe('CreateUser UseCase', () => {
17
- let createUser;
18
- let mockUserRepository;
19
-
20
- beforeEach(() => {
21
- mockUserRepository = new UserRepository();
22
- createUser = new CreateUser(mockUserRepository);
23
- jest.clearAllMocks();
24
- });
25
-
26
- it('should create and save a new user', async () => {
27
- const name = 'Test User';
28
- const email = 'test@example.com';
29
- const expectedResult = { id: 1, name, email };
30
-
31
- mockUserRepository.save.mockResolvedValue(expectedResult);
32
-
33
- const result = await createUser.execute(name, email);
34
-
35
- expect(mockUserRepository.save).toHaveBeenCalledTimes(1);
36
- const savedUser = mockUserRepository.save.mock.calls[0][0];
37
- expect(savedUser.name).toBe(name);
38
- expect(savedUser.email).toBe(email);
39
- expect(result).toEqual(expectedResult);
40
- <%_ if (caching !== 'None') { -%>
41
- expect(cacheService.del).toHaveBeenCalledWith('users:all');
42
- <%_ } -%>
43
- });
44
-
45
- it('should throw an error if repository fails', async () => {
46
- const error = new Error('Database error');
47
- mockUserRepository.save.mockRejectedValue(error);
48
-
49
- await expect(createUser.execute('Test', 'test@test.com')).rejects.toThrow(error);
50
- });
51
- });
1
+ const CreateUser = require('@/usecases/CreateUser');
2
+ const UserRepository = require('@/infrastructure/repositories/UserRepository');
3
+ <%_ if (caching !== 'None') { -%>
4
+ const cacheService = require('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>');
5
+ <%_ } -%>
6
+
7
+ jest.mock('@/infrastructure/repositories/UserRepository');
8
+ <%_ if (caching !== 'None') { -%>
9
+ jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
+ get: jest.fn(),
11
+ set: jest.fn(),
12
+ del: jest.fn()
13
+ }));
14
+ <%_ } -%>
15
+
16
+ describe('CreateUser UseCase', () => {
17
+ let createUser;
18
+ let mockUserRepository;
19
+
20
+ beforeEach(() => {
21
+ mockUserRepository = new UserRepository();
22
+ createUser = new CreateUser(mockUserRepository);
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('should create and save a new user', async () => {
27
+ const name = 'Test User';
28
+ const email = 'test@example.com';
29
+ const expectedResult = { id: 1, name, email };
30
+
31
+ mockUserRepository.save.mockResolvedValue(expectedResult);
32
+
33
+ const result = await createUser.execute(name, email);
34
+
35
+ expect(mockUserRepository.save).toHaveBeenCalledTimes(1);
36
+ const savedUser = mockUserRepository.save.mock.calls[0][0];
37
+ expect(savedUser.name).toBe(name);
38
+ expect(savedUser.email).toBe(email);
39
+ expect(result).toEqual(expectedResult);
40
+ <%_ if (caching !== 'None') { -%>
41
+ expect(cacheService.del).toHaveBeenCalledWith('users:all');
42
+ <%_ } -%>
43
+ });
44
+
45
+ it('should throw an error if repository fails', async () => {
46
+ const error = new Error('Database error');
47
+ mockUserRepository.save.mockRejectedValue(error);
48
+
49
+ await expect(createUser.execute('Test', 'test@test.com')).rejects.toThrow(error);
50
+ });
51
+ });
@@ -0,0 +1,11 @@
1
+ class DeleteUser {
2
+ constructor(userRepository) {
3
+ this.userRepository = userRepository;
4
+ }
5
+
6
+ async execute(id) {
7
+ return this.userRepository.delete(id);
8
+ }
9
+ }
10
+
11
+ module.exports = DeleteUser;
@@ -0,0 +1,47 @@
1
+ const DeleteUser = require('@/usecases/DeleteUser');
2
+ const UserRepository = require('@/infrastructure/repositories/UserRepository');
3
+ <%_ if (caching !== 'None') { -%>
4
+ const cacheService = require('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>');
5
+ <%_ } -%>
6
+
7
+ jest.mock('@/infrastructure/repositories/UserRepository');
8
+ <%_ if (caching !== 'None') { -%>
9
+ jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
+ get: jest.fn(),
11
+ set: jest.fn(),
12
+ del: jest.fn()
13
+ }));
14
+ <%_ } -%>
15
+
16
+ describe('DeleteUser UseCase', () => {
17
+ let deleteUser;
18
+ let mockUserRepository;
19
+
20
+ beforeEach(() => {
21
+ mockUserRepository = new UserRepository();
22
+ deleteUser = new DeleteUser(mockUserRepository);
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('should delete and return the user', async () => {
27
+ const id = 1;
28
+ const expectedResult = { id, name: 'Deleted User', email: 'test@test.com' };
29
+
30
+ mockUserRepository.delete.mockResolvedValue(expectedResult);
31
+
32
+ const result = await deleteUser.execute(id);
33
+
34
+ expect(mockUserRepository.delete).toHaveBeenCalledWith(id);
35
+ expect(result).toEqual(expectedResult);
36
+ <%_ if (caching !== 'None') { -%>
37
+ expect(cacheService.del).toHaveBeenCalledWith('users:all');
38
+ <%_ } %>
39
+ });
40
+
41
+ it('should throw an error if repository fails', async () => {
42
+ const error = new Error('Database error');
43
+ mockUserRepository.delete.mockRejectedValue(error);
44
+
45
+ await expect(deleteUser.execute(1)).rejects.toThrow(error);
46
+ });
47
+ });
@@ -1,12 +1,12 @@
1
-
2
- class GetAllUsers {
3
- constructor(userRepository) {
4
- this.userRepository = userRepository;
5
- }
6
-
7
- async execute() {
8
- return await this.userRepository.getUsers();
9
- }
10
- }
11
-
12
- module.exports = GetAllUsers;
1
+
2
+ class GetAllUsers {
3
+ constructor(userRepository) {
4
+ this.userRepository = userRepository;
5
+ }
6
+
7
+ async execute() {
8
+ return await this.userRepository.getUsers();
9
+ }
10
+ }
11
+
12
+ module.exports = GetAllUsers;
@@ -1,61 +1,61 @@
1
- const GetAllUsers = require('@/usecases/GetAllUsers');
2
- const UserRepository = require('@/infrastructure/repositories/UserRepository');
3
- <%_ if (caching !== 'None') { -%>
4
- const cacheService = require('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>');
5
- <%_ } -%>
6
-
7
- jest.mock('@/infrastructure/repositories/UserRepository');
8
- <%_ if (caching !== 'None') { -%>
9
- jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
- get: jest.fn(),
11
- set: jest.fn(),
12
- del: jest.fn()
13
- }));
14
- <%_ } -%>
15
-
16
- describe('GetAllUsers UseCase', () => {
17
- let getAllUsers;
18
- let mockUserRepository;
19
-
20
- beforeEach(() => {
21
- mockUserRepository = new UserRepository();
22
- getAllUsers = new GetAllUsers(mockUserRepository);
23
- jest.clearAllMocks();
24
- });
25
-
26
- it('should retrieve all users', async () => {
27
- const expectedUsers = [{ id: 1, name: 'Alice', email: 'alice@example.com' }];
28
- mockUserRepository.getUsers.mockResolvedValue(expectedUsers);
29
- <%_ if (caching !== 'None') { -%>
30
- cacheService.get.mockResolvedValue(null); // Cache miss
31
- <%_ } -%>
32
- const result = await getAllUsers.execute();
33
-
34
- expect(mockUserRepository.getUsers).toHaveBeenCalledTimes(1);
35
- expect(result).toEqual(expectedUsers);
36
- <%_ if (caching !== 'None') { -%>
37
- expect(cacheService.set).toHaveBeenCalled();
38
- <%_ } -%>
39
- });
40
-
41
- <%_ if (caching !== 'None') { -%>
42
- it('should return from cache if available', async () => {
43
- const cachedUsers = [{ id: 1, name: 'Cached', email: 'cached@example.com' }];
44
- cacheService.get.mockResolvedValue(cachedUsers);
45
-
46
- const result = await getAllUsers.execute();
47
-
48
- expect(mockUserRepository.getUsers).not.toHaveBeenCalled();
49
- expect(result).toEqual(cachedUsers);
50
- });
51
- <%_ } -%>
52
-
53
- it('should throw an error if repository fails', async () => {
54
- const error = new Error('Database error');
55
- mockUserRepository.getUsers.mockRejectedValue(error);
56
- <%_ if (caching !== 'None') { -%>
57
- cacheService.get.mockResolvedValue(null); // Cache miss
58
- <%_ } -%>
59
- await expect(getAllUsers.execute()).rejects.toThrow(error);
60
- });
61
- });
1
+ const GetAllUsers = require('@/usecases/GetAllUsers');
2
+ const UserRepository = require('@/infrastructure/repositories/UserRepository');
3
+ <%_ if (caching !== 'None') { -%>
4
+ const cacheService = require('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>');
5
+ <%_ } -%>
6
+
7
+ jest.mock('@/infrastructure/repositories/UserRepository');
8
+ <%_ if (caching !== 'None') { -%>
9
+ jest.mock('<% if (caching === "Redis") { %>@/infrastructure/caching/redisClient<% } else { %>@/infrastructure/caching/memoryCache<% } %>', () => ({
10
+ get: jest.fn(),
11
+ set: jest.fn(),
12
+ del: jest.fn()
13
+ }));
14
+ <%_ } -%>
15
+
16
+ describe('GetAllUsers UseCase', () => {
17
+ let getAllUsers;
18
+ let mockUserRepository;
19
+
20
+ beforeEach(() => {
21
+ mockUserRepository = new UserRepository();
22
+ getAllUsers = new GetAllUsers(mockUserRepository);
23
+ jest.clearAllMocks();
24
+ });
25
+
26
+ it('should retrieve all users', async () => {
27
+ const expectedUsers = [{ id: 1, name: 'Alice', email: 'alice@example.com' }];
28
+ mockUserRepository.getUsers.mockResolvedValue(expectedUsers);
29
+ <%_ if (caching !== 'None') { -%>
30
+ cacheService.get.mockResolvedValue(null); // Cache miss
31
+ <%_ } -%>
32
+ const result = await getAllUsers.execute();
33
+
34
+ expect(mockUserRepository.getUsers).toHaveBeenCalledTimes(1);
35
+ expect(result).toEqual(expectedUsers);
36
+ <%_ if (caching !== 'None') { -%>
37
+ expect(cacheService.set).toHaveBeenCalled();
38
+ <%_ } -%>
39
+ });
40
+
41
+ <%_ if (caching !== 'None') { -%>
42
+ it('should return from cache if available', async () => {
43
+ const cachedUsers = [{ id: 1, name: 'Cached', email: 'cached@example.com' }];
44
+ cacheService.get.mockResolvedValue(cachedUsers);
45
+
46
+ const result = await getAllUsers.execute();
47
+
48
+ expect(mockUserRepository.getUsers).not.toHaveBeenCalled();
49
+ expect(result).toEqual(cachedUsers);
50
+ });
51
+ <%_ } -%>
52
+
53
+ it('should throw an error if repository fails', async () => {
54
+ const error = new Error('Database error');
55
+ mockUserRepository.getUsers.mockRejectedValue(error);
56
+ <%_ if (caching !== 'None') { -%>
57
+ cacheService.get.mockResolvedValue(null); // Cache miss
58
+ <%_ } -%>
59
+ await expect(getAllUsers.execute()).rejects.toThrow(error);
60
+ });
61
+ });
@@ -0,0 +1,11 @@
1
+ class UpdateUser {
2
+ constructor(userRepository) {
3
+ this.userRepository = userRepository;
4
+ }
5
+
6
+ async execute(id, data) {
7
+ return this.userRepository.update(id, data);
8
+ }
9
+ }
10
+
11
+ module.exports = UpdateUser;