nodejs-quickstart-structure 1.18.0 → 1.19.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/CHANGELOG.md +17 -4
- package/README.md +2 -1
- package/bin/index.js +93 -92
- package/lib/generator.js +1 -1
- package/lib/modules/caching-setup.js +76 -73
- package/lib/modules/config-files.js +4 -0
- package/lib/modules/kafka-setup.js +249 -191
- package/lib/modules/project-setup.js +1 -0
- package/package.json +13 -2
- package/templates/clean-architecture/js/src/errors/BadRequestError.js +11 -10
- package/templates/clean-architecture/js/src/errors/BadRequestError.spec.js.ejs +22 -21
- package/templates/clean-architecture/js/src/errors/NotFoundError.js +11 -10
- package/templates/clean-architecture/js/src/errors/NotFoundError.spec.js.ejs +22 -21
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.js.ejs +69 -39
- package/templates/clean-architecture/js/src/infrastructure/repositories/UserRepository.spec.js.ejs +142 -81
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +1 -1
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.js.ejs +156 -75
- package/templates/clean-architecture/js/src/interfaces/controllers/userController.spec.js.ejs +234 -138
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.js.ejs +27 -21
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/user.resolvers.spec.js.ejs +66 -49
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/user.types.js.ejs +19 -17
- package/templates/clean-architecture/js/src/interfaces/routes/api.js +12 -10
- 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/UpdateUser.js +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/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
- package/templates/clean-architecture/ts/src/errors/BadRequestError.ts +9 -8
- package/templates/clean-architecture/ts/src/errors/NotFoundError.spec.ts.ejs +22 -21
- package/templates/clean-architecture/ts/src/errors/NotFoundError.ts +9 -8
- package/templates/clean-architecture/ts/src/index.ts.ejs +1 -1
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.spec.ts.ejs +175 -85
- package/templates/clean-architecture/ts/src/infrastructure/repositories/userRepository.ts.ejs +74 -0
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.spec.ts.ejs +331 -185
- package/templates/clean-architecture/ts/src/interfaces/controllers/userController.ts.ejs +173 -84
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/user.resolvers.ts.ejs +29 -21
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/user.types.ts.ejs +17 -15
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.ts +13 -11
- 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/updateUser.spec.ts.ejs +48 -0
- package/templates/clean-architecture/ts/src/usecases/updateUser.ts +9 -0
- package/templates/clean-architecture/ts/src/utils/errorMessages.ts +12 -0
- package/templates/common/.gitattributes +46 -0
- package/templates/common/.snyk.ejs +45 -0
- package/templates/common/Dockerfile +17 -9
- package/templates/common/README.md.ejs +295 -263
- package/templates/common/caching/clean/js/DeleteUser.js.ejs +27 -0
- package/templates/common/caching/clean/js/UpdateUser.js.ejs +27 -0
- package/templates/common/caching/clean/ts/deleteUser.ts.ejs +24 -0
- package/templates/common/caching/clean/ts/updateUser.ts.ejs +25 -0
- package/templates/common/caching/ts/memoryCache.ts.ejs +73 -64
- package/templates/common/caching/ts/redisClient.ts.ejs +89 -80
- package/templates/common/database/js/models/User.js.ejs +79 -53
- package/templates/common/database/js/models/User.js.mongoose.ejs +23 -19
- package/templates/common/database/js/models/User.spec.js.ejs +94 -84
- package/templates/common/database/ts/models/User.spec.ts.ejs +100 -84
- package/templates/common/database/ts/models/User.ts.ejs +87 -61
- package/templates/common/database/ts/models/User.ts.mongoose.ejs +30 -25
- package/templates/common/health/js/healthRoute.js.ejs +50 -47
- package/templates/common/health/ts/healthRoute.ts.ejs +49 -46
- package/templates/common/jest.e2e.config.js.ejs +8 -8
- package/templates/common/kafka/js/messaging/baseConsumer.js.ejs +30 -30
- package/templates/common/kafka/js/messaging/userEventSchema.js.ejs +12 -11
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.js.ejs +44 -31
- package/templates/common/kafka/js/messaging/welcomeEmailConsumer.spec.js.ejs +86 -49
- package/templates/common/kafka/js/services/kafkaService.js.ejs +93 -93
- package/templates/common/kafka/js/utils/kafkaEvents.js.ejs +7 -0
- package/templates/common/kafka/ts/messaging/userEventSchema.spec.ts.ejs +51 -51
- package/templates/common/kafka/ts/messaging/userEventSchema.ts.ejs +12 -11
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.spec.ts.ejs +86 -49
- package/templates/common/kafka/ts/messaging/welcomeEmailConsumer.ts.ejs +38 -25
- package/templates/common/kafka/ts/services/kafkaService.ts.ejs +95 -95
- package/templates/common/kafka/ts/utils/kafkaEvents.ts.ejs +5 -0
- package/templates/common/package.json.ejs +10 -2
- package/templates/common/shutdown/js/gracefulShutdown.js.ejs +65 -61
- package/templates/common/shutdown/js/gracefulShutdown.spec.js.ejs +149 -160
- package/templates/common/shutdown/ts/gracefulShutdown.spec.ts.ejs +179 -158
- package/templates/common/shutdown/ts/gracefulShutdown.ts.ejs +59 -55
- package/templates/common/src/tests/e2e/e2e.users.test.js.ejs +120 -49
- package/templates/common/src/tests/e2e/e2e.users.test.ts.ejs +120 -49
- package/templates/common/swagger.yml.ejs +118 -66
- package/templates/db/mysql/V1__Initial_Setup.sql.ejs +10 -9
- package/templates/db/postgres/V1__Initial_Setup.sql.ejs +10 -9
- package/templates/mvc/js/src/controllers/userController.js.ejs +246 -105
- package/templates/mvc/js/src/controllers/userController.spec.js.ejs +481 -209
- package/templates/mvc/js/src/errors/BadRequestError.js +11 -10
- package/templates/mvc/js/src/errors/BadRequestError.spec.js.ejs +22 -21
- package/templates/mvc/js/src/errors/NotFoundError.js +11 -10
- package/templates/mvc/js/src/errors/NotFoundError.spec.js.ejs +22 -21
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.js.ejs +25 -19
- package/templates/mvc/js/src/graphql/resolvers/user.resolvers.spec.js.ejs +64 -47
- package/templates/mvc/js/src/graphql/typeDefs/user.types.js.ejs +19 -17
- package/templates/mvc/js/src/index.js.ejs +1 -1
- package/templates/mvc/js/src/routes/api.js +10 -8
- package/templates/mvc/js/src/routes/api.spec.js.ejs +41 -36
- package/templates/mvc/js/src/utils/errorMessages.js +14 -0
- package/templates/mvc/ts/src/controllers/userController.spec.ts.ejs +481 -203
- package/templates/mvc/ts/src/controllers/userController.ts.ejs +248 -107
- package/templates/mvc/ts/src/errors/BadRequestError.spec.ts.ejs +22 -21
- package/templates/mvc/ts/src/errors/BadRequestError.ts +9 -8
- package/templates/mvc/ts/src/errors/NotFoundError.spec.ts.ejs +27 -21
- package/templates/mvc/ts/src/errors/NotFoundError.ts +9 -8
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.spec.ts.ejs +68 -51
- package/templates/mvc/ts/src/graphql/resolvers/user.resolvers.ts.ejs +29 -21
- package/templates/mvc/ts/src/graphql/typeDefs/user.types.ts.ejs +17 -15
- package/templates/mvc/ts/src/index.ts.ejs +156 -153
- package/templates/mvc/ts/src/routes/api.spec.ts.ejs +59 -40
- package/templates/mvc/ts/src/routes/api.ts +12 -10
- package/templates/mvc/ts/src/utils/errorMessages.ts +12 -0
- package/templates/clean-architecture/ts/src/infrastructure/repositories/UserRepository.ts.ejs +0 -37
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
const { ApiError } = require('./ApiError');
|
|
2
|
-
const HTTP_STATUS = require('../utils/httpCodes');
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
const { ApiError } = require('./ApiError');
|
|
2
|
+
const HTTP_STATUS = require('../utils/httpCodes');
|
|
3
|
+
const ERROR_MESSAGES = require('../utils/errorMessages');
|
|
4
|
+
|
|
5
|
+
class BadRequestError extends ApiError {
|
|
6
|
+
constructor(message = ERROR_MESSAGES.BAD_REQUEST) {
|
|
7
|
+
super(HTTP_STATUS.BAD_REQUEST, message);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = { BadRequestError };
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
const { BadRequestError } = require('@/errors/BadRequestError');
|
|
2
|
-
const { ApiError } = require('@/errors/ApiError');
|
|
3
|
-
const HTTP_STATUS = require('@/utils/httpCodes');
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
expect(error.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
1
|
+
const { BadRequestError } = require('@/errors/BadRequestError');
|
|
2
|
+
const { ApiError } = require('@/errors/ApiError');
|
|
3
|
+
const HTTP_STATUS = require('@/utils/httpCodes');
|
|
4
|
+
const ERROR_MESSAGES = require('@/utils/errorMessages');
|
|
5
|
+
|
|
6
|
+
describe('BadRequestError', () => {
|
|
7
|
+
it('should extend ApiError', () => {
|
|
8
|
+
const error = new BadRequestError();
|
|
9
|
+
expect(error).toBeInstanceOf(ApiError);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should have default message "Bad Request"', () => {
|
|
13
|
+
const error = new BadRequestError();
|
|
14
|
+
expect(error.message).toBe(ERROR_MESSAGES.BAD_REQUEST);
|
|
15
|
+
expect(error.statusCode).toBe(HTTP_STATUS.BAD_REQUEST);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should accept a custom message', () => {
|
|
19
|
+
const error = new BadRequestError('Custom bad request');
|
|
20
|
+
expect(error.message).toBe('Custom bad request');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
const { ApiError } = require('./ApiError');
|
|
2
|
-
const HTTP_STATUS = require('../utils/httpCodes');
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
const { ApiError } = require('./ApiError');
|
|
2
|
+
const HTTP_STATUS = require('../utils/httpCodes');
|
|
3
|
+
const ERROR_MESSAGES = require('../utils/errorMessages');
|
|
4
|
+
|
|
5
|
+
class NotFoundError extends ApiError {
|
|
6
|
+
constructor(message = ERROR_MESSAGES.RESOURCE_NOT_FOUND) {
|
|
7
|
+
super(HTTP_STATUS.NOT_FOUND, message);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = { NotFoundError };
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
const { NotFoundError } = require('@/errors/NotFoundError');
|
|
2
|
-
const { ApiError } = require('@/errors/ApiError');
|
|
3
|
-
const HTTP_STATUS = require('@/utils/httpCodes');
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
expect(error.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
1
|
+
const { NotFoundError } = require('@/errors/NotFoundError');
|
|
2
|
+
const { ApiError } = require('@/errors/ApiError');
|
|
3
|
+
const HTTP_STATUS = require('@/utils/httpCodes');
|
|
4
|
+
const ERROR_MESSAGES = require('@/utils/errorMessages');
|
|
5
|
+
|
|
6
|
+
describe('NotFoundError', () => {
|
|
7
|
+
it('should extend ApiError', () => {
|
|
8
|
+
const error = new NotFoundError();
|
|
9
|
+
expect(error).toBeInstanceOf(ApiError);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should have default message "Resource not found"', () => {
|
|
13
|
+
const error = new NotFoundError();
|
|
14
|
+
expect(error.message).toBe(ERROR_MESSAGES.RESOURCE_NOT_FOUND);
|
|
15
|
+
expect(error.statusCode).toBe(HTTP_STATUS.NOT_FOUND);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should accept a custom message', () => {
|
|
19
|
+
const error = new NotFoundError(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
20
|
+
expect(error.message).toBe(ERROR_MESSAGES.USER_NOT_FOUND);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
const userController = require('../../controllers/userController');
|
|
2
|
-
|
|
3
|
-
const userResolvers = {
|
|
4
|
-
Query: {
|
|
5
|
-
getAllUsers: async () => {
|
|
6
|
-
return await userController.getUsers();
|
|
7
|
-
}
|
|
8
|
-
},
|
|
9
|
-
Mutation: {
|
|
10
|
-
createUser: async (_, { name, email }) => {
|
|
11
|
-
return await userController.createUser({ name, email });
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
const userController = require('../../controllers/userController');
|
|
2
|
+
|
|
3
|
+
const userResolvers = {
|
|
4
|
+
Query: {
|
|
5
|
+
getAllUsers: async () => {
|
|
6
|
+
return await userController.getUsers();
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
Mutation: {
|
|
10
|
+
createUser: async (_, { name, email }) => {
|
|
11
|
+
return await userController.createUser({ name, email });
|
|
12
|
+
},
|
|
13
|
+
updateUser: async (_, { id, name, email }) => {
|
|
14
|
+
return await userController.updateUser(id, { name, email });
|
|
15
|
+
},
|
|
16
|
+
deleteUser: async (_, { id }) => {
|
|
17
|
+
return await userController.deleteUser(id);
|
|
18
|
+
}
|
|
19
|
+
}<%_ if (database === 'MongoDB') { -%>,
|
|
20
|
+
User: {
|
|
21
|
+
id: (parent) => parent.id || parent._id
|
|
22
|
+
}<%_ } %>
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = { userResolvers };
|
|
@@ -1,47 +1,64 @@
|
|
|
1
|
-
const { userResolvers } = require('@/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('@/controllers/userController', () => ({
|
|
7
|
-
getUsers: (...args) => mockGetUsers(...args),
|
|
8
|
-
createUser: (...args) => mockCreateUser(...args)
|
|
9
|
-
}))
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
expect(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
});
|
|
1
|
+
const { userResolvers } = require('@/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('@/controllers/userController', () => ({
|
|
7
|
+
getUsers: (...args) => mockGetUsers(...args),
|
|
8
|
+
createUser: (...args) => mockCreateUser(...args),
|
|
9
|
+
updateUser: jest.fn().mockImplementation((id, data) => Promise.resolve({ id, ...data })),
|
|
10
|
+
deleteUser: jest.fn().mockImplementation(() => Promise.resolve(true))
|
|
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
|
+
|
|
35
|
+
describe('Mutation.updateUser', () => {
|
|
36
|
+
it('should update and return the user', async () => {
|
|
37
|
+
const payload = { name: 'Updated' };
|
|
38
|
+
const result = await userResolvers.Mutation.updateUser(null, { id: '1', ...payload });
|
|
39
|
+
expect(result).toMatchObject(payload);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('Mutation.deleteUser', () => {
|
|
44
|
+
it('should delete and return true', async () => {
|
|
45
|
+
const result = await userResolvers.Mutation.deleteUser(null, { id: '1' });
|
|
46
|
+
expect(result).toBe(true);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
<%_ if (database === 'MongoDB') { -%>
|
|
50
|
+
describe('User.id', () => {
|
|
51
|
+
it('should return parent.id if available', () => {
|
|
52
|
+
const parent = { id: '123' };
|
|
53
|
+
const result = userResolvers.User.id(parent);
|
|
54
|
+
expect(result).toBe('123');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should fallback to parent._id if id is not available', () => {
|
|
58
|
+
const parent = { _id: '456' };
|
|
59
|
+
const result = userResolvers.User.id(parent);
|
|
60
|
+
expect(result).toBe('456');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
<%_ } -%>
|
|
64
|
+
});
|
|
@@ -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
|
-
|
|
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 };
|
|
@@ -6,7 +6,7 @@ const healthRoutes = require('./routes/healthRoute');
|
|
|
6
6
|
<%_ if (communication === 'Kafka') { -%>const { connectKafka, sendMessage } = require('./services/kafkaService');<%_ } -%>
|
|
7
7
|
<%_ if (communication === 'GraphQL') { -%>
|
|
8
8
|
const { ApolloServer } = require('@apollo/server');
|
|
9
|
-
const { expressMiddleware } = require('@
|
|
9
|
+
const { expressMiddleware } = require('@as-integrations/express4');
|
|
10
10
|
const { ApolloServerPluginLandingPageLocalDefault } = require('@apollo/server/plugin/landingPage/default');
|
|
11
11
|
const { unwrapResolverError } = require('@apollo/server/errors');
|
|
12
12
|
const { ApiError } = require('./errors/ApiError');
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
const express = require('express');
|
|
2
|
-
const router = express.Router();
|
|
3
|
-
const userController = require('../controllers/userController');
|
|
4
|
-
|
|
5
|
-
router.get('/users', userController.getUsers);
|
|
6
|
-
router.post('/users', userController.createUser);
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const userController = require('../controllers/userController');
|
|
4
|
+
|
|
5
|
+
router.get('/users', userController.getUsers);
|
|
6
|
+
router.post('/users', userController.createUser);
|
|
7
|
+
router.patch('/users/:id', userController.updateUser);
|
|
8
|
+
router.delete('/users/:id', userController.deleteUser);
|
|
9
|
+
|
|
10
|
+
module.exports = router;
|
|
@@ -1,36 +1,41 @@
|
|
|
1
|
-
const request = require('supertest');
|
|
2
|
-
const express = require('express');
|
|
3
|
-
const router = require('@/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.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
const request = require('supertest');
|
|
2
|
+
const express = require('express');
|
|
3
|
+
const router = require('@/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
|
+
const mockUpdateUser = jest.fn().mockImplementation((req, res) => res.status(200).json({ id: '1', name: 'Updated' }));
|
|
9
|
+
const mockDeleteUser = jest.fn().mockImplementation((req, res) => res.status(200).json({ message: 'User deleted successfully' }));
|
|
10
|
+
|
|
11
|
+
jest.mock('@/controllers/userController', () => ({
|
|
12
|
+
getUsers: (...args) => mockGetUsers(...args),
|
|
13
|
+
createUser: (...args) => mockCreateUser(...args),
|
|
14
|
+
updateUser: (...args) => mockUpdateUser(...args),
|
|
15
|
+
deleteUser: (...args) => mockDeleteUser(...args)
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
describe('ApiRoutes', () => {
|
|
19
|
+
let app;
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
app = express();
|
|
23
|
+
app.use(express.json());
|
|
24
|
+
app.use('/api', router);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('GET /api/users should call controller.getUsers', async () => {
|
|
28
|
+
await request(app)
|
|
29
|
+
.get('/api/users');
|
|
30
|
+
|
|
31
|
+
expect(mockGetUsers).toHaveBeenCalledTimes(1);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('POST /api/users should call controller.createUser', async () => {
|
|
35
|
+
await request(app)
|
|
36
|
+
.post('/api/users')
|
|
37
|
+
.send({ name: 'Test', email: 'test@example.com' });
|
|
38
|
+
|
|
39
|
+
expect(mockCreateUser).toHaveBeenCalledTimes(1);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const ERROR_MESSAGES = {
|
|
2
|
+
USER_NOT_FOUND: 'User not found',
|
|
3
|
+
RESOURCE_NOT_FOUND: 'Resource not found',
|
|
4
|
+
INVALID_USER_DATA: 'Invalid user event data',
|
|
5
|
+
INTERNAL_SERVER_ERROR: 'Internal Server Error',
|
|
6
|
+
BAD_REQUEST: 'Bad Request',
|
|
7
|
+
FETCH_USERS_ERROR: 'Error fetching users',
|
|
8
|
+
CREATE_USER_ERROR: 'Error creating user',
|
|
9
|
+
UPDATE_USER_ERROR: 'Error updating user',
|
|
10
|
+
DELETE_USER_ERROR: 'Error deleting user',
|
|
11
|
+
DATABASE_PING_FAILED: 'Health Check Database Ping Failed',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
module.exports = ERROR_MESSAGES;
|