nodejs-quickstart-structure 1.19.0 → 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.
- package/CHANGELOG.md +309 -301
- package/LICENSE +15 -15
- package/lib/generator.js +139 -139
- package/lib/modules/app-setup.js +401 -401
- package/lib/modules/config-files.js +151 -151
- package/lib/modules/database-setup.js +116 -116
- package/lib/modules/project-setup.js +32 -32
- package/lib/prompts.js +100 -100
- package/package.json +78 -78
- package/templates/clean-architecture/js/src/domain/models/User.js +9 -9
- package/templates/clean-architecture/js/src/errors/ApiError.js +14 -14
- package/templates/clean-architecture/js/src/index.js.ejs +55 -55
- package/templates/clean-architecture/js/src/infrastructure/config/env.js.ejs +47 -47
- package/templates/clean-architecture/js/src/infrastructure/log/logger.js +36 -36
- package/templates/clean-architecture/js/src/infrastructure/log/logger.spec.js.ejs +63 -63
- package/templates/clean-architecture/js/src/infrastructure/webserver/middleware/errorMiddleware.js +30 -30
- package/templates/clean-architecture/js/src/infrastructure/webserver/server.js.ejs +89 -89
- package/templates/clean-architecture/js/src/infrastructure/webserver/swagger.js.ejs +6 -6
- package/templates/clean-architecture/js/src/interfaces/graphql/context.js.ejs +13 -13
- package/templates/clean-architecture/js/src/interfaces/graphql/context.spec.js.ejs +31 -31
- package/templates/clean-architecture/js/src/interfaces/graphql/index.js.ejs +5 -5
- package/templates/clean-architecture/js/src/interfaces/graphql/resolvers/index.js.ejs +6 -6
- package/templates/clean-architecture/js/src/interfaces/graphql/typeDefs/index.js.ejs +6 -6
- package/templates/clean-architecture/js/src/interfaces/routes/api.spec.js.ejs +38 -38
- package/templates/clean-architecture/js/src/usecases/CreateUser.js +14 -14
- package/templates/clean-architecture/js/src/usecases/CreateUser.spec.js.ejs +51 -51
- package/templates/clean-architecture/js/src/usecases/GetAllUsers.js +12 -12
- package/templates/clean-architecture/js/src/usecases/GetAllUsers.spec.js.ejs +61 -61
- package/templates/clean-architecture/js/src/utils/httpCodes.js +9 -9
- package/templates/clean-architecture/ts/src/config/env.ts.ejs +46 -46
- package/templates/clean-architecture/ts/src/config/swagger.ts.ejs +6 -6
- package/templates/clean-architecture/ts/src/domain/user.ts +7 -7
- package/templates/clean-architecture/ts/src/errors/ApiError.ts +15 -15
- package/templates/clean-architecture/ts/src/index.ts.ejs +139 -139
- package/templates/clean-architecture/ts/src/infrastructure/log/logger.spec.ts.ejs +63 -63
- package/templates/clean-architecture/ts/src/infrastructure/log/logger.ts +36 -36
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.spec.ts.ejs +32 -32
- package/templates/clean-architecture/ts/src/interfaces/graphql/context.ts.ejs +17 -17
- package/templates/clean-architecture/ts/src/interfaces/graphql/index.ts.ejs +3 -3
- package/templates/clean-architecture/ts/src/interfaces/graphql/resolvers/index.ts.ejs +4 -4
- package/templates/clean-architecture/ts/src/interfaces/graphql/typeDefs/index.ts.ejs +4 -4
- package/templates/clean-architecture/ts/src/interfaces/routes/userRoutes.spec.ts.ejs +40 -40
- package/templates/clean-architecture/ts/src/usecases/createUser.spec.ts.ejs +51 -51
- package/templates/clean-architecture/ts/src/usecases/createUser.ts +13 -13
- package/templates/clean-architecture/ts/src/usecases/getAllUsers.spec.ts.ejs +63 -63
- package/templates/clean-architecture/ts/src/usecases/getAllUsers.ts +10 -10
- package/templates/clean-architecture/ts/src/utils/errorMiddleware.ts.ejs +27 -27
- package/templates/clean-architecture/ts/src/utils/httpCodes.ts +7 -7
- package/templates/common/.cursorrules.ejs +60 -60
- package/templates/common/.dockerignore +12 -12
- package/templates/common/.env.example.ejs +41 -41
- package/templates/common/.gitlab-ci.yml.ejs +86 -86
- package/templates/common/.lintstagedrc +6 -6
- package/templates/common/.prettierrc +7 -7
- package/templates/common/Dockerfile +73 -73
- package/templates/common/Jenkinsfile.ejs +87 -87
- package/templates/common/SECURITY.md +20 -20
- package/templates/common/_github/workflows/ci.yml.ejs +46 -46
- package/templates/common/_github/workflows/security.yml.ejs +36 -36
- package/templates/common/_gitignore +5 -5
- package/templates/common/_husky/pre-commit +4 -4
- package/templates/common/caching/clean/js/CreateUser.js.ejs +29 -29
- package/templates/common/caching/clean/js/GetAllUsers.js.ejs +37 -37
- package/templates/common/caching/clean/ts/createUser.ts.ejs +27 -27
- package/templates/common/caching/clean/ts/getAllUsers.ts.ejs +34 -34
- package/templates/common/caching/js/memoryCache.js.ejs +60 -60
- package/templates/common/caching/js/memoryCache.spec.js.ejs +101 -101
- package/templates/common/caching/js/redisClient.js.ejs +75 -75
- package/templates/common/caching/js/redisClient.spec.js.ejs +147 -147
- package/templates/common/caching/ts/memoryCache.spec.ts.ejs +102 -102
- package/templates/common/caching/ts/redisClient.spec.ts.ejs +157 -157
- package/templates/common/database/js/database.js.ejs +19 -19
- package/templates/common/database/js/database.spec.js.ejs +56 -56
- package/templates/common/database/js/mongoose.js.ejs +33 -33
- package/templates/common/database/js/mongoose.spec.js.ejs +43 -43
- package/templates/common/database/ts/database.spec.ts.ejs +56 -56
- package/templates/common/database/ts/database.ts.ejs +21 -21
- package/templates/common/database/ts/mongoose.spec.ts.ejs +42 -42
- package/templates/common/database/ts/mongoose.ts.ejs +28 -28
- package/templates/common/docker-compose.yml.ejs +159 -159
- package/templates/common/ecosystem.config.js.ejs +40 -40
- package/templates/common/eslint.config.mjs.ejs +77 -77
- package/templates/common/health/js/healthRoute.spec.js.ejs +70 -70
- package/templates/common/health/ts/healthRoute.spec.ts.ejs +76 -76
- package/templates/common/jest.config.js.ejs +32 -32
- package/templates/common/kafka/js/config/kafka.js +9 -9
- package/templates/common/kafka/js/config/kafka.spec.js.ejs +27 -27
- package/templates/common/kafka/js/messaging/baseConsumer.spec.js.ejs +58 -58
- package/templates/common/kafka/js/messaging/userEventSchema.spec.js.ejs +27 -27
- package/templates/common/kafka/js/services/kafkaService.spec.js.ejs +106 -106
- package/templates/common/kafka/ts/config/kafka.spec.ts.ejs +27 -27
- package/templates/common/kafka/ts/config/kafka.ts +7 -7
- package/templates/common/kafka/ts/messaging/baseConsumer.spec.ts.ejs +50 -50
- package/templates/common/kafka/ts/messaging/baseConsumer.ts.ejs +27 -27
- package/templates/common/kafka/ts/services/kafkaService.spec.ts.ejs +81 -81
- package/templates/common/migrate-mongo-config.js.ejs +31 -31
- package/templates/common/migrations/init.js.ejs +23 -23
- package/templates/common/package.json.ejs +119 -118
- package/templates/common/prompts/add-feature.md.ejs +26 -26
- package/templates/common/prompts/project-context.md.ejs +43 -43
- package/templates/common/prompts/troubleshoot.md.ejs +28 -28
- package/templates/common/public/css/style.css +147 -147
- package/templates/common/scripts/run-e2e.js.ejs +63 -63
- package/templates/common/sonar-project.properties.ejs +27 -27
- package/templates/common/src/utils/errorMiddleware.spec.js.ejs +79 -79
- package/templates/common/src/utils/errorMiddleware.spec.ts.ejs +94 -94
- package/templates/common/tsconfig.json +22 -22
- package/templates/common/views/ejs/index.ejs +55 -55
- package/templates/common/views/pug/index.pug +40 -40
- package/templates/mvc/js/src/config/env.js.ejs +46 -46
- package/templates/mvc/js/src/config/swagger.js.ejs +6 -6
- package/templates/mvc/js/src/errors/ApiError.js +14 -14
- package/templates/mvc/js/src/graphql/context.js.ejs +7 -7
- package/templates/mvc/js/src/graphql/context.spec.js.ejs +29 -29
- package/templates/mvc/js/src/graphql/index.js.ejs +5 -5
- package/templates/mvc/js/src/graphql/resolvers/index.js.ejs +6 -6
- package/templates/mvc/js/src/graphql/typeDefs/index.js.ejs +6 -6
- package/templates/mvc/js/src/index.js.ejs +136 -136
- package/templates/mvc/js/src/utils/errorMiddleware.js +29 -29
- package/templates/mvc/js/src/utils/httpCodes.js +9 -9
- package/templates/mvc/js/src/utils/logger.js +40 -40
- package/templates/mvc/js/src/utils/logger.spec.js.ejs +63 -63
- package/templates/mvc/ts/src/config/env.ts.ejs +45 -45
- package/templates/mvc/ts/src/config/swagger.ts.ejs +6 -6
- package/templates/mvc/ts/src/errors/ApiError.ts +15 -15
- package/templates/mvc/ts/src/graphql/context.spec.ts.ejs +30 -30
- package/templates/mvc/ts/src/graphql/context.ts.ejs +12 -12
- package/templates/mvc/ts/src/graphql/index.ts.ejs +3 -3
- package/templates/mvc/ts/src/graphql/resolvers/index.ts.ejs +4 -4
- package/templates/mvc/ts/src/graphql/typeDefs/index.ts.ejs +4 -4
- package/templates/mvc/ts/src/utils/errorMiddleware.ts.ejs +27 -27
- package/templates/mvc/ts/src/utils/httpCodes.ts +7 -7
- package/templates/mvc/ts/src/utils/logger.spec.ts.ejs +63 -63
- package/templates/mvc/ts/src/utils/logger.ts +36 -36
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
jest.mock('sequelize', () => {
|
|
2
|
-
const mSequelize = jest.fn(() => ({
|
|
3
|
-
authenticate: jest.fn().mockResolvedValue(true),
|
|
4
|
-
define: jest.fn(),
|
|
5
|
-
}));
|
|
6
|
-
return { Sequelize: mSequelize };
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
jest.mock('dotenv', () => ({
|
|
10
|
-
config: jest.fn()
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
describe('Database Configuration', () => {
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
jest.clearAllMocks();
|
|
16
|
-
jest.resetModules();
|
|
17
|
-
|
|
18
|
-
// Clean environment
|
|
19
|
-
const envVars = ['DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_PORT'];
|
|
20
|
-
envVars.forEach(v => delete process.env[v]);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should initialize Sequelize with environment variables', () => {
|
|
24
|
-
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
25
|
-
process.env.DB_NAME = 'testdb';
|
|
26
|
-
process.env.DB_USER = 'testuser';
|
|
27
|
-
process.env.DB_PASSWORD = 'testpassword';
|
|
28
|
-
process.env.DB_HOST = 'localhost';
|
|
29
|
-
process.env.DB_PORT = '5432';
|
|
30
|
-
|
|
31
|
-
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
32
|
-
|
|
33
|
-
expect(SequelizeMock).toHaveBeenCalledWith(
|
|
34
|
-
'testdb',
|
|
35
|
-
'testuser',
|
|
36
|
-
'testpassword',
|
|
37
|
-
expect.objectContaining({
|
|
38
|
-
host: 'localhost',
|
|
39
|
-
port: 5432
|
|
40
|
-
})
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should initialize Sequelize with default values when env vars are missing', () => {
|
|
45
|
-
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
46
|
-
delete process.env.DB_NAME;
|
|
47
|
-
delete process.env.DB_USER;
|
|
48
|
-
delete process.env.DB_PASSWORD;
|
|
49
|
-
delete process.env.DB_HOST;
|
|
50
|
-
delete process.env.DB_PORT;
|
|
51
|
-
|
|
52
|
-
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
53
|
-
|
|
54
|
-
expect(SequelizeMock).toHaveBeenCalledTimes(1);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
1
|
+
jest.mock('sequelize', () => {
|
|
2
|
+
const mSequelize = jest.fn(() => ({
|
|
3
|
+
authenticate: jest.fn().mockResolvedValue(true),
|
|
4
|
+
define: jest.fn(),
|
|
5
|
+
}));
|
|
6
|
+
return { Sequelize: mSequelize };
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
jest.mock('dotenv', () => ({
|
|
10
|
+
config: jest.fn()
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
describe('Database Configuration', () => {
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
jest.resetModules();
|
|
17
|
+
|
|
18
|
+
// Clean environment
|
|
19
|
+
const envVars = ['DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_PORT'];
|
|
20
|
+
envVars.forEach(v => delete process.env[v]);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should initialize Sequelize with environment variables', () => {
|
|
24
|
+
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
25
|
+
process.env.DB_NAME = 'testdb';
|
|
26
|
+
process.env.DB_USER = 'testuser';
|
|
27
|
+
process.env.DB_PASSWORD = 'testpassword';
|
|
28
|
+
process.env.DB_HOST = 'localhost';
|
|
29
|
+
process.env.DB_PORT = '5432';
|
|
30
|
+
|
|
31
|
+
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
32
|
+
|
|
33
|
+
expect(SequelizeMock).toHaveBeenCalledWith(
|
|
34
|
+
'testdb',
|
|
35
|
+
'testuser',
|
|
36
|
+
'testpassword',
|
|
37
|
+
expect.objectContaining({
|
|
38
|
+
host: 'localhost',
|
|
39
|
+
port: 5432
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should initialize Sequelize with default values when env vars are missing', () => {
|
|
45
|
+
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
46
|
+
delete process.env.DB_NAME;
|
|
47
|
+
delete process.env.DB_USER;
|
|
48
|
+
delete process.env.DB_PASSWORD;
|
|
49
|
+
delete process.env.DB_HOST;
|
|
50
|
+
delete process.env.DB_PORT;
|
|
51
|
+
|
|
52
|
+
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
53
|
+
|
|
54
|
+
expect(SequelizeMock).toHaveBeenCalledTimes(1);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
const mongoose = require('mongoose');
|
|
2
|
-
|
|
3
|
-
let logger;
|
|
4
|
-
<% if (architecture === 'MVC') { %>
|
|
5
|
-
logger = require('../utils/logger');
|
|
6
|
-
<% } else { %>
|
|
7
|
-
logger = require('../log/logger');
|
|
8
|
-
<% } %>
|
|
9
|
-
const connectDB = async () => {
|
|
10
|
-
const dbHost = process.env.DB_HOST || 'localhost';
|
|
11
|
-
const dbPort = process.env.DB_PORT || '27017';
|
|
12
|
-
const dbName = process.env.DB_NAME || '<%= dbName %>';
|
|
13
|
-
const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:${dbPort}/${dbName}`;
|
|
14
|
-
|
|
15
|
-
let retries = 5;
|
|
16
|
-
while (retries) {
|
|
17
|
-
try {
|
|
18
|
-
await mongoose.connect(mongoURI, {
|
|
19
|
-
useNewUrlParser: true,
|
|
20
|
-
useUnifiedTopology: true
|
|
21
|
-
});
|
|
22
|
-
logger.info('MongoDB Connected...');
|
|
23
|
-
break;
|
|
24
|
-
} catch (err) {
|
|
25
|
-
logger.error('MongoDB connection failed:', err);
|
|
26
|
-
retries -= 1;
|
|
27
|
-
logger.info(`Retries left: ${retries}. Waiting 5s...`);
|
|
28
|
-
await new Promise(res => setTimeout(res, 5000));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
module.exports = connectDB; // Export function to call in index.js
|
|
1
|
+
const mongoose = require('mongoose');
|
|
2
|
+
|
|
3
|
+
let logger;
|
|
4
|
+
<% if (architecture === 'MVC') { %>
|
|
5
|
+
logger = require('../utils/logger');
|
|
6
|
+
<% } else { %>
|
|
7
|
+
logger = require('../log/logger');
|
|
8
|
+
<% } %>
|
|
9
|
+
const connectDB = async () => {
|
|
10
|
+
const dbHost = process.env.DB_HOST || 'localhost';
|
|
11
|
+
const dbPort = process.env.DB_PORT || '27017';
|
|
12
|
+
const dbName = process.env.DB_NAME || '<%= dbName %>';
|
|
13
|
+
const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:${dbPort}/${dbName}`;
|
|
14
|
+
|
|
15
|
+
let retries = 5;
|
|
16
|
+
while (retries) {
|
|
17
|
+
try {
|
|
18
|
+
await mongoose.connect(mongoURI, {
|
|
19
|
+
useNewUrlParser: true,
|
|
20
|
+
useUnifiedTopology: true
|
|
21
|
+
});
|
|
22
|
+
logger.info('MongoDB Connected...');
|
|
23
|
+
break;
|
|
24
|
+
} catch (err) {
|
|
25
|
+
logger.error('MongoDB connection failed:', err);
|
|
26
|
+
retries -= 1;
|
|
27
|
+
logger.info(`Retries left: ${retries}. Waiting 5s...`);
|
|
28
|
+
await new Promise(res => setTimeout(res, 5000));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
module.exports = connectDB; // Export function to call in index.js
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
jest.mock('mongoose', () => ({
|
|
2
|
-
connect: jest.fn().mockResolvedValue(true),
|
|
3
|
-
}));
|
|
4
|
-
|
|
5
|
-
const mockLogger = {
|
|
6
|
-
info: jest.fn(),
|
|
7
|
-
error: jest.fn(),
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
jest.mock('<% if (architecture === "MVC") { %>@/utils/logger<% } else { %>@/infrastructure/log/logger<% } %>', () => mockLogger);
|
|
11
|
-
|
|
12
|
-
describe('Mongoose Configuration', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
jest.resetModules();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should call mongoose.connect with correct parameters', async () => {
|
|
19
|
-
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
20
|
-
const mongoose = require('mongoose');
|
|
21
|
-
await connectDB();
|
|
22
|
-
expect(mongoose.connect).toHaveBeenCalledWith(
|
|
23
|
-
expect.stringContaining('mongodb://'),
|
|
24
|
-
expect.any(Object)
|
|
25
|
-
);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should handle connection failure and retry', async () => {
|
|
29
|
-
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
30
|
-
const mongoose = require('mongoose');
|
|
31
|
-
mongoose.connect
|
|
32
|
-
.mockRejectedValueOnce(new Error('Connection failed'))
|
|
33
|
-
.mockResolvedValueOnce(true);
|
|
34
|
-
|
|
35
|
-
const timeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(cb => cb());
|
|
36
|
-
|
|
37
|
-
await connectDB();
|
|
38
|
-
|
|
39
|
-
expect(mockLogger.error).toHaveBeenCalled();
|
|
40
|
-
expect(mongoose.connect).toHaveBeenCalledTimes(2);
|
|
41
|
-
timeoutSpy.mockRestore();
|
|
42
|
-
});
|
|
43
|
-
});
|
|
1
|
+
jest.mock('mongoose', () => ({
|
|
2
|
+
connect: jest.fn().mockResolvedValue(true),
|
|
3
|
+
}));
|
|
4
|
+
|
|
5
|
+
const mockLogger = {
|
|
6
|
+
info: jest.fn(),
|
|
7
|
+
error: jest.fn(),
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
jest.mock('<% if (architecture === "MVC") { %>@/utils/logger<% } else { %>@/infrastructure/log/logger<% } %>', () => mockLogger);
|
|
11
|
+
|
|
12
|
+
describe('Mongoose Configuration', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.clearAllMocks();
|
|
15
|
+
jest.resetModules();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should call mongoose.connect with correct parameters', async () => {
|
|
19
|
+
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
20
|
+
const mongoose = require('mongoose');
|
|
21
|
+
await connectDB();
|
|
22
|
+
expect(mongoose.connect).toHaveBeenCalledWith(
|
|
23
|
+
expect.stringContaining('mongodb://'),
|
|
24
|
+
expect.any(Object)
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should handle connection failure and retry', async () => {
|
|
29
|
+
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
30
|
+
const mongoose = require('mongoose');
|
|
31
|
+
mongoose.connect
|
|
32
|
+
.mockRejectedValueOnce(new Error('Connection failed'))
|
|
33
|
+
.mockResolvedValueOnce(true);
|
|
34
|
+
|
|
35
|
+
const timeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(cb => cb());
|
|
36
|
+
|
|
37
|
+
await connectDB();
|
|
38
|
+
|
|
39
|
+
expect(mockLogger.error).toHaveBeenCalled();
|
|
40
|
+
expect(mongoose.connect).toHaveBeenCalledTimes(2);
|
|
41
|
+
timeoutSpy.mockRestore();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
jest.mock('sequelize', () => {
|
|
2
|
-
const mSequelize = jest.fn(() => ({
|
|
3
|
-
authenticate: jest.fn().mockResolvedValue(true),
|
|
4
|
-
define: jest.fn(),
|
|
5
|
-
}));
|
|
6
|
-
return { Sequelize: mSequelize };
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
jest.mock('dotenv', () => ({
|
|
10
|
-
config: jest.fn()
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
describe('Database Configuration', () => {
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
jest.clearAllMocks();
|
|
16
|
-
jest.resetModules();
|
|
17
|
-
|
|
18
|
-
// Clean environment
|
|
19
|
-
const envVars = ['DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_PORT'];
|
|
20
|
-
envVars.forEach(v => delete process.env[v]);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should initialize Sequelize with environment variables', () => {
|
|
24
|
-
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
25
|
-
process.env.DB_NAME = 'testdb';
|
|
26
|
-
process.env.DB_USER = 'testuser';
|
|
27
|
-
process.env.DB_PASSWORD = 'testpassword';
|
|
28
|
-
process.env.DB_HOST = 'localhost';
|
|
29
|
-
process.env.DB_PORT = '5432';
|
|
30
|
-
|
|
31
|
-
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
32
|
-
|
|
33
|
-
expect(SequelizeMock).toHaveBeenLastCalledWith(
|
|
34
|
-
'testdb',
|
|
35
|
-
'testuser',
|
|
36
|
-
'testpassword',
|
|
37
|
-
expect.objectContaining({
|
|
38
|
-
host: 'localhost',
|
|
39
|
-
port: 5432
|
|
40
|
-
})
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should initialize Sequelize with default values when env vars are missing', () => {
|
|
45
|
-
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
46
|
-
delete process.env.DB_NAME;
|
|
47
|
-
delete process.env.DB_USER;
|
|
48
|
-
delete process.env.DB_PASSWORD;
|
|
49
|
-
delete process.env.DB_HOST;
|
|
50
|
-
delete process.env.DB_PORT;
|
|
51
|
-
|
|
52
|
-
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
53
|
-
|
|
54
|
-
expect(SequelizeMock).toHaveBeenCalledTimes(1);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
1
|
+
jest.mock('sequelize', () => {
|
|
2
|
+
const mSequelize = jest.fn(() => ({
|
|
3
|
+
authenticate: jest.fn().mockResolvedValue(true),
|
|
4
|
+
define: jest.fn(),
|
|
5
|
+
}));
|
|
6
|
+
return { Sequelize: mSequelize };
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
jest.mock('dotenv', () => ({
|
|
10
|
+
config: jest.fn()
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
describe('Database Configuration', () => {
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
jest.resetModules();
|
|
17
|
+
|
|
18
|
+
// Clean environment
|
|
19
|
+
const envVars = ['DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'DB_PORT'];
|
|
20
|
+
envVars.forEach(v => delete process.env[v]);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should initialize Sequelize with environment variables', () => {
|
|
24
|
+
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
25
|
+
process.env.DB_NAME = 'testdb';
|
|
26
|
+
process.env.DB_USER = 'testuser';
|
|
27
|
+
process.env.DB_PASSWORD = 'testpassword';
|
|
28
|
+
process.env.DB_HOST = 'localhost';
|
|
29
|
+
process.env.DB_PORT = '5432';
|
|
30
|
+
|
|
31
|
+
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
32
|
+
|
|
33
|
+
expect(SequelizeMock).toHaveBeenLastCalledWith(
|
|
34
|
+
'testdb',
|
|
35
|
+
'testuser',
|
|
36
|
+
'testpassword',
|
|
37
|
+
expect.objectContaining({
|
|
38
|
+
host: 'localhost',
|
|
39
|
+
port: 5432
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should initialize Sequelize with default values when env vars are missing', () => {
|
|
45
|
+
const { Sequelize: SequelizeMock } = require('sequelize');
|
|
46
|
+
delete process.env.DB_NAME;
|
|
47
|
+
delete process.env.DB_USER;
|
|
48
|
+
delete process.env.DB_PASSWORD;
|
|
49
|
+
delete process.env.DB_HOST;
|
|
50
|
+
delete process.env.DB_PORT;
|
|
51
|
+
|
|
52
|
+
require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>');
|
|
53
|
+
|
|
54
|
+
expect(SequelizeMock).toHaveBeenCalledTimes(1);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { Sequelize } from 'sequelize';
|
|
2
|
-
import dotenv from 'dotenv';
|
|
3
|
-
|
|
4
|
-
dotenv.config();
|
|
5
|
-
|
|
6
|
-
<% if (database === 'MySQL') { %>const dialect = 'mysql';<% } -%>
|
|
7
|
-
<% if (database === 'PostgreSQL') { %>const dialect = 'postgres';<% } -%>
|
|
8
|
-
|
|
9
|
-
const sequelize = new Sequelize(
|
|
10
|
-
process.env.DB_NAME || '<%= dbName %>',
|
|
11
|
-
process.env.DB_USER || '<% if (database === 'MySQL') { %>root<% } else { %>postgres<% } %>',
|
|
12
|
-
process.env.DB_PASSWORD || '<% if (database === 'MySQL') { %>root<% } else { %>root<% } %>',
|
|
13
|
-
{
|
|
14
|
-
host: process.env.DB_HOST || '127.0.0.1',
|
|
15
|
-
dialect: dialect,
|
|
16
|
-
logging: false,
|
|
17
|
-
port: parseInt(process.env.DB_PORT || '<% if (database === 'MySQL') { %>3306<% } else { %>5432<% } %>')
|
|
18
|
-
}
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
export default sequelize;
|
|
1
|
+
import { Sequelize } from 'sequelize';
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
|
|
4
|
+
dotenv.config();
|
|
5
|
+
|
|
6
|
+
<% if (database === 'MySQL') { %>const dialect = 'mysql';<% } -%>
|
|
7
|
+
<% if (database === 'PostgreSQL') { %>const dialect = 'postgres';<% } -%>
|
|
8
|
+
|
|
9
|
+
const sequelize = new Sequelize(
|
|
10
|
+
process.env.DB_NAME || '<%= dbName %>',
|
|
11
|
+
process.env.DB_USER || '<% if (database === 'MySQL') { %>root<% } else { %>postgres<% } %>',
|
|
12
|
+
process.env.DB_PASSWORD || '<% if (database === 'MySQL') { %>root<% } else { %>root<% } %>',
|
|
13
|
+
{
|
|
14
|
+
host: process.env.DB_HOST || '127.0.0.1',
|
|
15
|
+
dialect: dialect,
|
|
16
|
+
logging: false,
|
|
17
|
+
port: parseInt(process.env.DB_PORT || '<% if (database === 'MySQL') { %>3306<% } else { %>5432<% } %>')
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export default sequelize;
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
jest.mock('mongoose', () => ({
|
|
2
|
-
connect: jest.fn().mockResolvedValue(true),
|
|
3
|
-
}));
|
|
4
|
-
|
|
5
|
-
const logger = {
|
|
6
|
-
info: jest.fn(),
|
|
7
|
-
error: jest.fn(),
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
jest.mock('<% if (architecture === "MVC") { %>@/utils/logger<% } else { %>@/infrastructure/log/logger<% } %>', () => logger);
|
|
11
|
-
|
|
12
|
-
describe('Mongoose Configuration', () => {
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.clearAllMocks();
|
|
15
|
-
jest.resetModules();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('should call mongoose.connect with correct parameters', async () => {
|
|
19
|
-
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>').default;
|
|
20
|
-
const mongoose = require('mongoose');
|
|
21
|
-
await connectDB();
|
|
22
|
-
expect(mongoose.connect).toHaveBeenCalledWith(
|
|
23
|
-
expect.stringContaining('mongodb://')
|
|
24
|
-
);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('should handle connection failure and retry', async () => {
|
|
28
|
-
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>').default;
|
|
29
|
-
const mongoose = require('mongoose');
|
|
30
|
-
(mongoose.connect as jest.Mock)
|
|
31
|
-
.mockRejectedValueOnce(new Error('Connection failed'))
|
|
32
|
-
.mockResolvedValueOnce(true);
|
|
33
|
-
|
|
34
|
-
const timeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(cb => { (cb as any)(); return {} as any; });
|
|
35
|
-
|
|
36
|
-
await connectDB();
|
|
37
|
-
|
|
38
|
-
expect(logger.error).toHaveBeenCalled();
|
|
39
|
-
expect(mongoose.connect).toHaveBeenCalledTimes(2);
|
|
40
|
-
timeoutSpy.mockRestore();
|
|
41
|
-
});
|
|
42
|
-
});
|
|
1
|
+
jest.mock('mongoose', () => ({
|
|
2
|
+
connect: jest.fn().mockResolvedValue(true),
|
|
3
|
+
}));
|
|
4
|
+
|
|
5
|
+
const logger = {
|
|
6
|
+
info: jest.fn(),
|
|
7
|
+
error: jest.fn(),
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
jest.mock('<% if (architecture === "MVC") { %>@/utils/logger<% } else { %>@/infrastructure/log/logger<% } %>', () => logger);
|
|
11
|
+
|
|
12
|
+
describe('Mongoose Configuration', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
jest.clearAllMocks();
|
|
15
|
+
jest.resetModules();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should call mongoose.connect with correct parameters', async () => {
|
|
19
|
+
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>').default;
|
|
20
|
+
const mongoose = require('mongoose');
|
|
21
|
+
await connectDB();
|
|
22
|
+
expect(mongoose.connect).toHaveBeenCalledWith(
|
|
23
|
+
expect.stringContaining('mongodb://')
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should handle connection failure and retry', async () => {
|
|
28
|
+
const connectDB = require('<% if (architecture === "MVC") { %>@/config/database<% } else { %>@/infrastructure/database/database<% } %>').default;
|
|
29
|
+
const mongoose = require('mongoose');
|
|
30
|
+
(mongoose.connect as jest.Mock)
|
|
31
|
+
.mockRejectedValueOnce(new Error('Connection failed'))
|
|
32
|
+
.mockResolvedValueOnce(true);
|
|
33
|
+
|
|
34
|
+
const timeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation(cb => { (cb as any)(); return {} as any; });
|
|
35
|
+
|
|
36
|
+
await connectDB();
|
|
37
|
+
|
|
38
|
+
expect(logger.error).toHaveBeenCalled();
|
|
39
|
+
expect(mongoose.connect).toHaveBeenCalledTimes(2);
|
|
40
|
+
timeoutSpy.mockRestore();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import mongoose from 'mongoose';
|
|
2
|
-
<% if (architecture === 'MVC') { %>
|
|
3
|
-
import logger from '@/utils/logger';
|
|
4
|
-
<% } else { %>
|
|
5
|
-
import logger from '@/infrastructure/log/logger';
|
|
6
|
-
<% } %>
|
|
7
|
-
const connectDB = async (): Promise<void> => {
|
|
8
|
-
const dbHost = process.env.DB_HOST || 'localhost';
|
|
9
|
-
const dbPort = process.env.DB_PORT || '27017';
|
|
10
|
-
const dbName = process.env.DB_NAME || '<%= dbName %>';
|
|
11
|
-
const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:${dbPort}/${dbName}`;
|
|
12
|
-
|
|
13
|
-
let retries = 5;
|
|
14
|
-
while (retries) {
|
|
15
|
-
try {
|
|
16
|
-
await mongoose.connect(mongoURI);
|
|
17
|
-
logger.info('MongoDB Connected...');
|
|
18
|
-
break;
|
|
19
|
-
} catch (err) {
|
|
20
|
-
logger.error('MongoDB connection failed:', err);
|
|
21
|
-
retries -= 1;
|
|
22
|
-
logger.info(`Retries left: ${retries}. Waiting 5s...`);
|
|
23
|
-
await new Promise(res => setTimeout(res, 5000));
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export default connectDB;
|
|
1
|
+
import mongoose from 'mongoose';
|
|
2
|
+
<% if (architecture === 'MVC') { %>
|
|
3
|
+
import logger from '@/utils/logger';
|
|
4
|
+
<% } else { %>
|
|
5
|
+
import logger from '@/infrastructure/log/logger';
|
|
6
|
+
<% } %>
|
|
7
|
+
const connectDB = async (): Promise<void> => {
|
|
8
|
+
const dbHost = process.env.DB_HOST || 'localhost';
|
|
9
|
+
const dbPort = process.env.DB_PORT || '27017';
|
|
10
|
+
const dbName = process.env.DB_NAME || '<%= dbName %>';
|
|
11
|
+
const mongoURI = process.env.MONGO_URI || `mongodb://${dbHost}:${dbPort}/${dbName}`;
|
|
12
|
+
|
|
13
|
+
let retries = 5;
|
|
14
|
+
while (retries) {
|
|
15
|
+
try {
|
|
16
|
+
await mongoose.connect(mongoURI);
|
|
17
|
+
logger.info('MongoDB Connected...');
|
|
18
|
+
break;
|
|
19
|
+
} catch (err) {
|
|
20
|
+
logger.error('MongoDB connection failed:', err);
|
|
21
|
+
retries -= 1;
|
|
22
|
+
logger.info(`Retries left: ${retries}. Waiting 5s...`);
|
|
23
|
+
await new Promise(res => setTimeout(res, 5000));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default connectDB;
|