nodejs-structure-cli 1.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.
- package/README.md +32 -0
- package/bin/index.js +143 -0
- package/lib/generator.js +145 -0
- package/lib/modules/app-setup.js +479 -0
- package/lib/modules/caching-setup.js +76 -0
- package/lib/modules/config-files.js +151 -0
- package/lib/modules/database-setup.js +116 -0
- package/lib/modules/kafka-setup.js +249 -0
- package/lib/modules/project-setup.js +32 -0
- package/lib/prompts.js +128 -0
- package/package.json +66 -0
- package/templates/clean-architecture/js/src/domain/models/User.js.ejs +11 -0
- package/templates/clean-architecture/js/src/errors/ApiError.js +14 -0
- package/templates/clean-architecture/js/src/errors/BadRequestError.js +11 -0
- package/templates/clean-architecture/js/src/errors/BadRequestError.spec.js.ejs +22 -0
- package/templates/clean-architecture/js/src/errors/NotFoundError.js +11 -0
- package/templates/clean-architecture/js/src/errors/NotFoundError.spec.js.ejs +22 -0
- package/templates/clean-architecture/js/src/index.js.ejs +56 -0
- package/templates/clean-architecture/js/src/infrastructure/config/env.js.ejs +47 -0
- package/templates/clean-architecture/js/src/infrastructure/log/logger.js +36 -0
- package/templates/clean-architecture/js/src/infrastructure/log/logger.spec.js.ejs +63 -0
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +88 -0
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +142 -0
- package/templates/clean-architecture/js/src/infrastructure/webserver/middleware/errorMiddleware.js +30 -0
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +93 -0
- package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js.ejs +6 -0
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +190 -0
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +234 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/context.spec.js.ejs +31 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +66 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -0
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +19 -0
- package/templates/clean-architecture/js/src/interfaces/routes/api.js.ejs +17 -0
- package/templates/clean-architecture/js/src/interfaces/routes/api.spec.js.ejs +38 -0
- package/templates/clean-architecture/js/src/usecases/CreateUser.js.ejs +14 -0
- package/templates/clean-architecture/js/src/usecases/CreateUser.spec.js.ejs +51 -0
- package/templates/clean-architecture/js/src/usecases/DeleteUser.js +11 -0
- package/templates/clean-architecture/js/src/usecases/DeleteUser.spec.js.ejs +47 -0
- package/templates/clean-architecture/js/src/usecases/GetAllUsers.js +12 -0
- package/templates/clean-architecture/js/src/usecases/GetAllUsers.spec.js.ejs +61 -0
- package/templates/clean-architecture/js/src/usecases/UpdateUser.js.ejs +11 -0
- package/templates/clean-architecture/js/src/usecases/UpdateUser.spec.js.ejs +48 -0
- package/templates/clean-architecture/js/src/utils/errorMessages.js +14 -0
- package/templates/clean-architecture/js/src/utils/httpCodes.js +9 -0
- package/templates/clean-architecture/ts/src/config/env.ts.ejs +46 -0
- package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +6 -0
- package/templates/clean-architecture/ts/src/domain/user.ts.ejs +9 -0
- package/templates/clean-architecture/ts/src/errors/ApiError.ts +15 -0
- package/templates/clean-architecture/ts/src/errors/BadRequestError.spec.ts.ejs +22 -0
- package/templates/clean-architecture/ts/src/errors/BadRequestError.ts +9 -0
- package/templates/clean-architecture/ts/src/errors/NotFoundError.spec.ts.ejs +22 -0
- package/templates/clean-architecture/ts/src/errors/NotFoundError.ts +9 -0
- package/templates/clean-architecture/ts/src/index.ts.ejs +144 -0
- package/templates/clean-architecture/ts/src/infrastructure/log/logger.spec.ts.ejs +63 -0
- package/templates/clean-architecture/ts/src/infrastructure/log/logger.ts +36 -0
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +175 -0
- package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +125 -0
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +331 -0
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +208 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.spec.ts.ejs +32 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +29 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -0
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +17 -0
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.spec.ts.ejs +40 -0
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts.ejs +18 -0
- package/templates/clean-architecture/ts/src/usecases/createUser.spec.ts.ejs +51 -0
- package/templates/clean-architecture/ts/src/usecases/createUser.ts.ejs +11 -0
- package/templates/clean-architecture/ts/src/usecases/deleteUser.spec.ts.ejs +47 -0
- package/templates/clean-architecture/ts/src/usecases/deleteUser.ts +9 -0
- package/templates/clean-architecture/ts/src/usecases/getAllUsers.spec.ts.ejs +63 -0
- package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +10 -0
- package/templates/clean-architecture/ts/src/usecases/updateUser.spec.ts.ejs +48 -0
- package/templates/clean-architecture/ts/src/usecases/updateUser.ts.ejs +10 -0
- package/templates/clean-architecture/ts/src/utils/errorMessages.ts +12 -0
- package/templates/clean-architecture/ts/src/utils/errorMiddleware.ts.ejs +27 -0
- package/templates/clean-architecture/ts/src/utils/httpCodes.ts +7 -0
- package/templates/common/.cursorrules.ejs +60 -0
- package/templates/common/.dockerignore +12 -0
- package/templates/common/.env.example.ejs +60 -0
- package/templates/common/.gitattributes +46 -0
- package/templates/common/.gitlab-ci.yml.ejs +86 -0
- package/templates/common/.lintstagedrc +6 -0
- package/templates/common/.prettierrc +7 -0
- package/templates/common/.snyk.ejs +45 -0
- package/templates/common/Dockerfile +73 -0
- package/templates/common/Jenkinsfile.ejs +87 -0
- package/templates/common/README.md.ejs +148 -0
- package/templates/common/_github/workflows/ci.yml.ejs +46 -0
- package/templates/common/_github/workflows/security.yml.ejs +36 -0
- package/templates/common/_gitignore +5 -0
- package/templates/common/_husky/pre-commit +4 -0
- package/templates/common/caching/clean/js/CreateUser.js.ejs +29 -0
- package/templates/common/caching/clean/js/DeleteUser.js.ejs +27 -0
- package/templates/common/caching/clean/js/GetAllUsers.js.ejs +37 -0
- package/templates/common/caching/clean/js/UpdateUser.js.ejs +27 -0
- package/templates/common/caching/clean/ts/createUser.ts.ejs +27 -0
- package/templates/common/caching/clean/ts/deleteUser.ts.ejs +24 -0
- package/templates/common/caching/clean/ts/getAllUsers.ts.ejs +34 -0
- package/templates/common/caching/clean/ts/updateUser.ts.ejs +25 -0
- package/templates/common/caching/js/memoryCache.js.ejs +60 -0
- package/templates/common/caching/js/memoryCache.spec.js.ejs +101 -0
- package/templates/common/caching/js/redisClient.js.ejs +75 -0
- package/templates/common/caching/js/redisClient.spec.js.ejs +147 -0
- package/templates/common/caching/ts/memoryCache.spec.ts.ejs +102 -0
- package/templates/common/caching/ts/memoryCache.ts.ejs +73 -0
- package/templates/common/caching/ts/redisClient.spec.ts.ejs +157 -0
- package/templates/common/caching/ts/redisClient.ts.ejs +89 -0
- package/templates/common/database/js/database.js.ejs +19 -0
- package/templates/common/database/js/database.spec.js.ejs +56 -0
- package/templates/common/database/js/models/User.js.ejs +91 -0
- package/templates/common/database/js/models/User.js.mongoose.ejs +35 -0
- package/templates/common/database/js/models/User.spec.js.ejs +94 -0
- package/templates/common/database/js/mongoose.js.ejs +33 -0
- package/templates/common/database/js/mongoose.spec.js.ejs +43 -0
- package/templates/common/database/ts/database.spec.ts.ejs +56 -0
- package/templates/common/database/ts/database.ts.ejs +21 -0
- package/templates/common/database/ts/models/User.spec.ts.ejs +100 -0
- package/templates/common/database/ts/models/User.ts.ejs +102 -0
- package/templates/common/database/ts/models/User.ts.mongoose.ejs +34 -0
- package/templates/common/database/ts/mongoose.spec.ts.ejs +42 -0
- package/templates/common/database/ts/mongoose.ts.ejs +28 -0
- package/templates/common/docker-compose.yml.ejs +159 -0
- package/templates/common/ecosystem.config.js.ejs +40 -0
- package/templates/common/eslint.config.mjs.ejs +77 -0
- package/templates/common/health/js/healthRoute.js.ejs +50 -0
- package/templates/common/health/js/healthRoute.spec.js.ejs +70 -0
- package/templates/common/health/ts/healthRoute.spec.ts.ejs +76 -0
- package/templates/common/health/ts/healthRoute.ts.ejs +49 -0
- package/templates/common/jest.config.js.ejs +32 -0
- package/templates/common/jest.e2e.config.js.ejs +8 -0
- package/templates/common/kafka/js/config/kafka.js +9 -0
- package/templates/common/kafka/js/config/kafka.spec.js.ejs +27 -0
- package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +30 -0
- package/templates/common/kafka/js/messaging/baseConsumer.spec.js.ejs +58 -0
- package/templates/common/kafka/js/messaging/userEventSchema.js.ejs +12 -0
- package/templates/common/kafka/js/messaging/userEventSchema.spec.js.ejs +27 -0
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.js.ejs +44 -0
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.spec.js.ejs +86 -0
- package/templates/common/kafka/js/services/kafkaService.js.ejs +93 -0
- package/templates/common/kafka/js/services/kafkaService.spec.js.ejs +106 -0
- package/templates/common/kafka/js/utils/kafkaEvents.js.ejs +7 -0
- package/templates/common/kafka/ts/config/kafka.spec.ts.ejs +27 -0
- package/templates/common/kafka/ts/config/kafka.ts +7 -0
- package/templates/common/kafka/ts/messaging/baseConsumer.spec.ts.ejs +50 -0
- package/templates/common/kafka/ts/messaging/baseConsumer.ts.ejs +27 -0
- package/templates/common/kafka/ts/messaging/userEventSchema.spec.ts.ejs +51 -0
- package/templates/common/kafka/ts/messaging/userEventSchema.ts.ejs +12 -0
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.spec.ts.ejs +86 -0
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.ts.ejs +38 -0
- package/templates/common/kafka/ts/services/kafkaService.spec.ts.ejs +81 -0
- package/templates/common/kafka/ts/services/kafkaService.ts.ejs +95 -0
- package/templates/common/kafka/ts/utils/kafkaEvents.ts.ejs +5 -0
- package/templates/common/migrate-mongo-config.js.ejs +31 -0
- package/templates/common/migrations/init.js.ejs +23 -0
- package/templates/common/package.json.ejs +137 -0
- package/templates/common/prompts/add-feature.md.ejs +26 -0
- package/templates/common/prompts/project-context.md.ejs +43 -0
- package/templates/common/prompts/troubleshoot.md.ejs +28 -0
- package/templates/common/public/css/style.css +147 -0
- package/templates/common/scripts/run-e2e.js.ejs +63 -0
- package/templates/common/shutdown/js/gracefulShutdown.js.ejs +65 -0
- package/templates/common/shutdown/js/gracefulShutdown.spec.js.ejs +149 -0
- package/templates/common/shutdown/ts/gracefulShutdown.spec.ts.ejs +179 -0
- package/templates/common/shutdown/ts/gracefulShutdown.ts.ejs +59 -0
- package/templates/common/sonar-project.properties.ejs +27 -0
- package/templates/common/src/config/auth.js.ejs +19 -0
- package/templates/common/src/config/auth.ts.ejs +19 -0
- package/templates/common/src/controllers/authController.js.ejs +101 -0
- package/templates/common/src/controllers/authController.ts.ejs +101 -0
- package/templates/common/src/middleware/auth.js.ejs +20 -0
- package/templates/common/src/middleware/auth.ts.ejs +25 -0
- package/templates/common/src/middleware/upload.js.ejs +31 -0
- package/templates/common/src/middleware/upload.ts.ejs +32 -0
- package/templates/common/src/routes/authRoutes.js.ejs +20 -0
- package/templates/common/src/routes/authRoutes.ts.ejs +20 -0
- package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +120 -0
- package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +120 -0
- package/templates/common/src/utils/errorMiddleware.spec.js.ejs +79 -0
- package/templates/common/src/utils/errorMiddleware.spec.ts.ejs +94 -0
- package/templates/common/swagger.yml.ejs +118 -0
- package/templates/common/tsconfig.json +23 -0
- package/templates/common/views/ejs/index.ejs +55 -0
- package/templates/common/views/pug/index.pug +40 -0
- package/templates/db/mysql/V1__Initial_Setup.sql.ejs +10 -0
- package/templates/db/postgres/V1__Initial_Setup.sql.ejs +10 -0
- package/templates/mvc/js/src/config/env.js.ejs +46 -0
- package/templates/mvc/js/src/config/swagger.js.ejs +6 -0
- package/templates/mvc/js/src/controllers/userController.js.ejs +288 -0
- package/templates/mvc/js/src/controllers/userController.spec.js.ejs +481 -0
- package/templates/mvc/js/src/errors/ApiError.js +14 -0
- package/templates/mvc/js/src/errors/BadRequestError.js +11 -0
- package/templates/mvc/js/src/errors/BadRequestError.spec.js.ejs +22 -0
- package/templates/mvc/js/src/errors/NotFoundError.js +11 -0
- package/templates/mvc/js/src/errors/NotFoundError.spec.js.ejs +22 -0
- package/templates/mvc/js/src/graphql/context.js.ejs +7 -0
- package/templates/mvc/js/src/graphql/context.spec.js.ejs +29 -0
- package/templates/mvc/js/src/graphql/index.js.ejs +5 -0
- package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -0
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -0
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +64 -0
- package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -0
- package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +19 -0
- package/templates/mvc/js/src/index.js.ejs +141 -0
- package/templates/mvc/js/src/routes/api.js.ejs +15 -0
- package/templates/mvc/js/src/routes/api.spec.js.ejs +41 -0
- package/templates/mvc/js/src/utils/errorMessages.js +14 -0
- package/templates/mvc/js/src/utils/errorMiddleware.js +29 -0
- package/templates/mvc/js/src/utils/httpCodes.js +9 -0
- package/templates/mvc/js/src/utils/logger.js +40 -0
- package/templates/mvc/js/src/utils/logger.spec.js.ejs +63 -0
- package/templates/mvc/ts/src/config/env.ts.ejs +45 -0
- package/templates/mvc/ts/src/config/swagger.ts.ejs +6 -0
- package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +481 -0
- package/templates/mvc/ts/src/controllers/userController.ts.ejs +292 -0
- package/templates/mvc/ts/src/errors/ApiError.ts +15 -0
- package/templates/mvc/ts/src/errors/BadRequestError.spec.ts.ejs +22 -0
- package/templates/mvc/ts/src/errors/BadRequestError.ts +9 -0
- package/templates/mvc/ts/src/errors/NotFoundError.spec.ts.ejs +27 -0
- package/templates/mvc/ts/src/errors/NotFoundError.ts +9 -0
- package/templates/mvc/ts/src/graphql/context.spec.ts.ejs +30 -0
- package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -0
- package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -0
- package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -0
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -0
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +29 -0
- package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -0
- package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +17 -0
- package/templates/mvc/ts/src/index.ts.ejs +157 -0
- package/templates/mvc/ts/src/routes/api.spec.ts.ejs +59 -0
- package/templates/mvc/ts/src/routes/api.ts.ejs +17 -0
- package/templates/mvc/ts/src/utils/errorMessages.ts +12 -0
- package/templates/mvc/ts/src/utils/errorMiddleware.ts.ejs +27 -0
- package/templates/mvc/ts/src/utils/httpCodes.ts +7 -0
- package/templates/mvc/ts/src/utils/logger.spec.ts.ejs +63 -0
- package/templates/mvc/ts/src/utils/logger.ts +36 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
const UserController = require('@/interfaces/controllers/userController');
|
|
2
|
+
const ERROR_MESSAGES = require('@/utils/errorMessages');
|
|
3
|
+
const CreateUser = require('@/usecases/CreateUser');
|
|
4
|
+
const GetAllUsers = require('@/usecases/GetAllUsers');
|
|
5
|
+
const UpdateUser = require('@/usecases/UpdateUser');
|
|
6
|
+
const DeleteUser = require('@/usecases/DeleteUser');
|
|
7
|
+
|
|
8
|
+
jest.mock('@/usecases/CreateUser');
|
|
9
|
+
jest.mock('@/usecases/GetAllUsers');
|
|
10
|
+
jest.mock('@/usecases/UpdateUser');
|
|
11
|
+
jest.mock('@/usecases/DeleteUser');
|
|
12
|
+
<%_ if (communication === 'Kafka') { -%>
|
|
13
|
+
jest.mock('@/infrastructure/messaging/kafkaClient', () => ({
|
|
14
|
+
sendMessage: jest.fn().mockResolvedValue(undefined)
|
|
15
|
+
}));
|
|
16
|
+
<%_ } -%>
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
describe('UserController (Clean Architecture)', () => {
|
|
20
|
+
let userController;
|
|
21
|
+
let mockCreateUserUseCase;
|
|
22
|
+
let mockGetAllUsersUseCase;
|
|
23
|
+
let mockUpdateUserUseCase;
|
|
24
|
+
let mockDeleteUserUseCase;
|
|
25
|
+
<%_ if (communication !== 'GraphQL') { -%>
|
|
26
|
+
let mockRequest;
|
|
27
|
+
let mockResponse;
|
|
28
|
+
let mockNext;
|
|
29
|
+
<%_ } -%>
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
jest.resetAllMocks();
|
|
33
|
+
|
|
34
|
+
userController = new UserController();
|
|
35
|
+
|
|
36
|
+
// Retrieve the mocked instances created inside UserController constructor
|
|
37
|
+
mockCreateUserUseCase = CreateUser.mock.instances[0];
|
|
38
|
+
mockGetAllUsersUseCase = GetAllUsers.mock.instances[0];
|
|
39
|
+
mockUpdateUserUseCase = UpdateUser.mock.instances[0];
|
|
40
|
+
mockDeleteUserUseCase = DeleteUser.mock.instances[0];
|
|
41
|
+
|
|
42
|
+
<%_ if (communication !== 'GraphQL') { -%>
|
|
43
|
+
mockRequest = {
|
|
44
|
+
body: {},
|
|
45
|
+
params: {}
|
|
46
|
+
};
|
|
47
|
+
mockResponse = {
|
|
48
|
+
status: jest.fn().mockReturnThis(),
|
|
49
|
+
json: jest.fn()
|
|
50
|
+
};
|
|
51
|
+
mockNext = jest.fn();
|
|
52
|
+
<%_ } -%>
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('getUsers', () => {
|
|
56
|
+
it('should return successfully (Happy Path)', async () => {
|
|
57
|
+
const usersMock = [{ id: '1', name: 'Test', email: 'test@example.com' }];
|
|
58
|
+
mockGetAllUsersUseCase.execute.mockResolvedValue(usersMock);
|
|
59
|
+
|
|
60
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
61
|
+
const result = await userController.getUsers();
|
|
62
|
+
expect(result).toEqual(usersMock);
|
|
63
|
+
<%_ } else { -%>
|
|
64
|
+
await userController.getUsers(mockRequest, mockResponse, mockNext);
|
|
65
|
+
expect(mockResponse.json).toHaveBeenCalledWith(usersMock);
|
|
66
|
+
<%_ } -%>
|
|
67
|
+
expect(mockGetAllUsersUseCase.execute).toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should handle errors correctly (Error Handling)', async () => {
|
|
71
|
+
const error = new Error('UseCase Error');
|
|
72
|
+
mockGetAllUsersUseCase.execute.mockRejectedValue(error);
|
|
73
|
+
|
|
74
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
75
|
+
await expect(userController.getUsers()).rejects.toThrow(error);
|
|
76
|
+
<%_ } else { -%>
|
|
77
|
+
await userController.getUsers(mockRequest, mockResponse, mockNext);
|
|
78
|
+
expect(mockNext).toHaveBeenCalledWith(error);
|
|
79
|
+
<%_ } -%>
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('createUser', () => {
|
|
84
|
+
it('should successfully create a new user (Happy Path)', async () => {
|
|
85
|
+
const payload = { name: 'Alice', email: 'alice@example.com' };
|
|
86
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
87
|
+
const dataArg = payload;
|
|
88
|
+
<%_ } else { -%>
|
|
89
|
+
mockRequest.body = payload;
|
|
90
|
+
<%_ } -%>
|
|
91
|
+
const expectedUser = { id: '1', ...payload };
|
|
92
|
+
|
|
93
|
+
mockCreateUserUseCase.execute.mockResolvedValue(expectedUser);
|
|
94
|
+
|
|
95
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
96
|
+
const result = await userController.createUser(dataArg);
|
|
97
|
+
expect(result).toEqual(expectedUser);
|
|
98
|
+
<%_ } else { -%>
|
|
99
|
+
await userController.createUser(mockRequest, mockResponse, mockNext);
|
|
100
|
+
<%_ if (communication === 'Kafka') { -%>
|
|
101
|
+
const { sendMessage } = require('@/infrastructure/messaging/kafkaClient');
|
|
102
|
+
expect(sendMessage).toHaveBeenCalled();
|
|
103
|
+
<%_ } -%>
|
|
104
|
+
expect(mockResponse.status).toHaveBeenCalledWith(201);
|
|
105
|
+
|
|
106
|
+
expect(mockResponse.json).toHaveBeenCalledWith(expectedUser);
|
|
107
|
+
<%_ } -%>
|
|
108
|
+
expect(mockCreateUserUseCase.execute).toHaveBeenCalledWith(payload.name, payload.email);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('updateUser', () => {
|
|
113
|
+
it('should successfully update a user (Happy Path)', async () => {
|
|
114
|
+
const id = '1';
|
|
115
|
+
const payload = { name: 'Alice Updated' };
|
|
116
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
117
|
+
const idArg = id;
|
|
118
|
+
const dataArg = payload;
|
|
119
|
+
<%_ } else { -%>
|
|
120
|
+
mockRequest.params = { id };
|
|
121
|
+
mockRequest.body = payload;
|
|
122
|
+
<%_ } -%>
|
|
123
|
+
const expectedUser = { id, ...payload };
|
|
124
|
+
|
|
125
|
+
mockUpdateUserUseCase.execute.mockResolvedValue(expectedUser);
|
|
126
|
+
|
|
127
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
128
|
+
const result = await userController.updateUser(idArg, dataArg);
|
|
129
|
+
expect(result.name).toBe(payload.name);
|
|
130
|
+
<%_ } else { -%>
|
|
131
|
+
await userController.updateUser(mockRequest, mockResponse, mockNext);
|
|
132
|
+
expect(mockResponse.json).toHaveBeenCalled();
|
|
133
|
+
<%_ } -%>
|
|
134
|
+
<%_ if (communication === 'Kafka') { -%>
|
|
135
|
+
const { sendMessage } = require('@/infrastructure/messaging/kafkaClient');
|
|
136
|
+
expect(sendMessage).toHaveBeenCalled();
|
|
137
|
+
<%_ } -%>
|
|
138
|
+
expect(mockUpdateUserUseCase.execute).toHaveBeenCalledWith(id, payload);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should handle database errors during update (Error Handling)', async () => {
|
|
142
|
+
const id = '1';
|
|
143
|
+
const error = new Error('Database Error');
|
|
144
|
+
mockUpdateUserUseCase.execute.mockRejectedValue(error);
|
|
145
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
146
|
+
await expect(userController.updateUser(id, { name: 'Fail' })).rejects.toThrow(error);
|
|
147
|
+
<%_ } else { -%>
|
|
148
|
+
await userController.updateUser(mockRequest, mockResponse, mockNext);
|
|
149
|
+
expect(mockNext).toHaveBeenCalledWith(error);
|
|
150
|
+
<%_ } -%>
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('deleteUser', () => {
|
|
155
|
+
it('should successfully delete a user (Happy Path)', async () => {
|
|
156
|
+
const id = '1';
|
|
157
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
158
|
+
const idArg = id;
|
|
159
|
+
<%_ } else { -%>
|
|
160
|
+
mockRequest.params = { id };
|
|
161
|
+
<%_ } -%>
|
|
162
|
+
mockDeleteUserUseCase.execute.mockResolvedValue(true);
|
|
163
|
+
|
|
164
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
165
|
+
const result = await userController.deleteUser(idArg);
|
|
166
|
+
expect(result).toBe(true);
|
|
167
|
+
<%_ } else { -%>
|
|
168
|
+
await userController.deleteUser(mockRequest, mockResponse, mockNext);
|
|
169
|
+
expect(mockResponse.status).toHaveBeenCalledWith(200);
|
|
170
|
+
<%_ } -%>
|
|
171
|
+
<%_ if (communication === 'Kafka') { -%>
|
|
172
|
+
const { sendMessage } = require('@/infrastructure/messaging/kafkaClient');
|
|
173
|
+
expect(sendMessage).toHaveBeenCalled();
|
|
174
|
+
<%_ } -%>
|
|
175
|
+
expect(mockDeleteUserUseCase.execute).toHaveBeenCalledWith(id);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('should throw error if user not found during deletion (Error Handling)', async () => {
|
|
179
|
+
const id = '999';
|
|
180
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
181
|
+
mockDeleteUserUseCase.execute.mockResolvedValue(false);
|
|
182
|
+
await expect(userController.deleteUser(id)).rejects.toThrow(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
183
|
+
<%_ } else { -%>
|
|
184
|
+
mockRequest.params = { id };
|
|
185
|
+
mockDeleteUserUseCase.execute.mockResolvedValue(false);
|
|
186
|
+
await userController.deleteUser(mockRequest, mockResponse, mockNext);
|
|
187
|
+
expect(mockResponse.status).toHaveBeenCalledWith(404);
|
|
188
|
+
<%_ } -%>
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('should handle database errors during deletion (Error Handling)', async () => {
|
|
192
|
+
const id = '1';
|
|
193
|
+
const error = new Error('Database Error');
|
|
194
|
+
mockDeleteUserUseCase.execute.mockRejectedValue(error);
|
|
195
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
196
|
+
await expect(userController.deleteUser(id)).rejects.toThrow(error);
|
|
197
|
+
<%_ } else { -%>
|
|
198
|
+
mockRequest.params = { id };
|
|
199
|
+
await userController.deleteUser(mockRequest, mockResponse, mockNext);
|
|
200
|
+
expect(mockNext).toHaveBeenCalledWith(error);
|
|
201
|
+
<%_ } -%>
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe('createUser Error Paths', () => {
|
|
206
|
+
it('should handle database errors during creation (Error Handling)', async () => {
|
|
207
|
+
const error = new Error('Database Error');
|
|
208
|
+
mockCreateUserUseCase.execute.mockRejectedValue(error);
|
|
209
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
210
|
+
await expect(userController.createUser({ name: 'Alice', email: 'alice@example.com' })).rejects.toThrow(error);
|
|
211
|
+
<%_ } else { -%>
|
|
212
|
+
mockRequest.body = { name: 'Alice', email: 'alice@example.com' };
|
|
213
|
+
await userController.createUser(mockRequest, mockResponse, mockNext);
|
|
214
|
+
expect(mockNext).toHaveBeenCalledWith(error);
|
|
215
|
+
<%_ } -%>
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
describe('updateUser Error Paths', () => {
|
|
220
|
+
it('should handle database errors during update (Error Handling)', async () => {
|
|
221
|
+
const id = '1';
|
|
222
|
+
const error = new Error('Database Error');
|
|
223
|
+
mockUpdateUserUseCase.execute.mockRejectedValue(error);
|
|
224
|
+
<%_ if (communication === 'GraphQL') { -%>
|
|
225
|
+
await expect(userController.updateUser(id, { name: 'Bob' })).rejects.toThrow(error);
|
|
226
|
+
<%_ } else { -%>
|
|
227
|
+
mockRequest.params = { id };
|
|
228
|
+
mockRequest.body = { name: 'Bob' };
|
|
229
|
+
await userController.updateUser(mockRequest, mockResponse, mockNext);
|
|
230
|
+
expect(mockNext).toHaveBeenCalledWith(error);
|
|
231
|
+
<%_ } -%>
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const UserRepository = require('../../infrastructure/repositories/UserRepository');
|
|
2
|
+
|
|
3
|
+
const gqlContext = async ({ req }) => {
|
|
4
|
+
const token = req.headers.authorization || '';
|
|
5
|
+
const userRepository = new UserRepository();
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
token,
|
|
9
|
+
userRepository
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = { gqlContext };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const { gqlContext } = require('@/interfaces/graphql/context');
|
|
2
|
+
const { resolvers } = require('@/interfaces/graphql/resolvers');
|
|
3
|
+
const { typeDefs } = require('@/interfaces/graphql/typeDefs');
|
|
4
|
+
|
|
5
|
+
jest.mock('@/infrastructure/repositories/UserRepository');
|
|
6
|
+
|
|
7
|
+
describe('GraphQL Context', () => {
|
|
8
|
+
it('should exercise GraphQL index entry points', () => {
|
|
9
|
+
expect(resolvers).toBeDefined();
|
|
10
|
+
expect(typeDefs).toBeDefined();
|
|
11
|
+
});
|
|
12
|
+
it('should return context with token when authorization header is present', async () => {
|
|
13
|
+
const mockRequest = {
|
|
14
|
+
headers: {
|
|
15
|
+
authorization: 'Bearer token123',
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const context = await gqlContext({ req: mockRequest });
|
|
20
|
+
expect(context.token).toBe('Bearer token123');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should return context with empty token when authorization header is missing', async () => {
|
|
24
|
+
const mockRequest = {
|
|
25
|
+
headers: {},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const context = await gqlContext({ req: mockRequest });
|
|
29
|
+
expect(context.token).toBe('');
|
|
30
|
+
});
|
|
31
|
+
});
|
package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const UserController = require('../../controllers/userController');
|
|
2
|
+
|
|
3
|
+
const userController = new UserController();
|
|
4
|
+
|
|
5
|
+
const userResolvers = {
|
|
6
|
+
Query: {
|
|
7
|
+
getAllUsers: async () => {
|
|
8
|
+
return await userController.getUsers();
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
Mutation: {
|
|
12
|
+
createUser: async (_, { name, email }) => {
|
|
13
|
+
return await userController.createUser({ name, email });
|
|
14
|
+
},
|
|
15
|
+
updateUser: async (_, { id, name, email }) => {
|
|
16
|
+
return await userController.updateUser(id, { name, email });
|
|
17
|
+
},
|
|
18
|
+
deleteUser: async (_, { id }) => {
|
|
19
|
+
return await userController.deleteUser(id);
|
|
20
|
+
}
|
|
21
|
+
}<%_ if (database === 'MongoDB') { -%>,
|
|
22
|
+
User: {
|
|
23
|
+
id: (parent) => parent.id || parent._id
|
|
24
|
+
}<%_ } %>
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
module.exports = { userResolvers };
|
package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs
ADDED
|
@@ -0,0 +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
|
+
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
|
+
});
|
|
@@ -0,0 +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
|
+
updateUser(id: ID!, name: String, email: String): User
|
|
15
|
+
deleteUser(id: ID!): Boolean
|
|
16
|
+
}
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
module.exports = { userTypes };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const UserController = require('../controllers/userController');
|
|
4
|
+
<% if (auth && auth !== 'None') { %>const { authMiddleware } = require('../middleware/auth');<% } %>
|
|
5
|
+
<% if (includeMulter) { %>const { upload } = require('../middleware/upload');<% } %>
|
|
6
|
+
<% if (auth && auth !== 'None') { %>const authRoutes = require('./authRoutes');<% } %>
|
|
7
|
+
|
|
8
|
+
const userController = new UserController();
|
|
9
|
+
|
|
10
|
+
<% if (auth && auth !== 'None') { %>router.use('/auth', authRoutes);<% } %>
|
|
11
|
+
|
|
12
|
+
router.get('/users', (req, res, next) => userController.getUsers(req, res, next));
|
|
13
|
+
router.post('/users', <% if (includeMulter) { %>upload.single('image'), <% } %>(req, res, next) => userController.createUser(req, res, next));
|
|
14
|
+
router.patch('/users/:id', <% if (includeMulter) { %>upload.single('image'), <% } %>(req, res, next) => userController.updateUser(req, res, next));
|
|
15
|
+
router.delete('/users/:id', (req, res, next) => userController.deleteUser(req, res, next));
|
|
16
|
+
|
|
17
|
+
module.exports = router;
|
|
@@ -0,0 +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
|
+
});
|
|
@@ -0,0 +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<% if (auth && auth !== 'None') { %>, password<% } %><% if (includeMulter) { %>, imageUrl<% } %>) {
|
|
9
|
+
const user = new User(null, name, email<% if (auth && auth !== 'None') { %>, password<% } %><% if (includeMulter) { %>, imageUrl<% } %>);
|
|
10
|
+
return await this.userRepository.save(user);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = CreateUser;
|
|
@@ -0,0 +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
|
+
});
|
|
@@ -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
|
+
});
|