Skip to content

Commit 26059fe

Browse files
authored
Merge pull request #4 from HEET-Group/edwinTEST
Adding Unit Testing for chronos.config - Edwin
2 parents f5f6f3d + a88833c commit 26059fe

20 files changed

+2072
-544
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
const { EcoTwoTone } = require('@material-ui/icons');
2+
const Chronos = require('../chronos_npm_package/chronos.js');
3+
const helpers = require('../chronos_npm_package/controllers/utilities.js');
4+
const hpropagate = require('hpropagate');
5+
const mongo = require('../chronos_npm_package/controllers/mongo.js');
6+
const postgres = require('../chronos_npm_package/controllers/postgres.js');
7+
8+
// Mock the utilities module functions
9+
jest.mock('../chronos_npm_package/controllers/utilities.js', () => ({
10+
validateInput: jest.fn(config => config),
11+
addNotifications: jest.fn(config => config),
12+
testMetricsQuery: jest.fn(config => config),
13+
getMetricsURI: jest.fn(config => config),
14+
}));
15+
16+
// mock propogate from Chronos
17+
jest.mock('hpropagate');
18+
19+
//mock fns found in track
20+
jest.mock('../chronos_npm_package/controllers/mongo.js', () => ({
21+
connect: jest.fn(config => config),
22+
services: jest.fn(config => config),
23+
docker: jest.fn(config => config),
24+
health: jest.fn(config => config),
25+
communications: jest.fn(config => config),
26+
serverQuery: jest.fn(config => config),
27+
}));
28+
29+
jest.mock('../chronos_npm_package/controllers/postgres.js', () => ({
30+
connect: jest.fn(config => config),
31+
services: jest.fn(config => config),
32+
docker: jest.fn(config => config),
33+
health: jest.fn(config => config),
34+
communications: jest.fn(config => config),
35+
serverQuery: jest.fn(config => config),
36+
}));
37+
38+
describe('Chronos Config', () => {
39+
afterEach(() => {
40+
// Clear mock function calls after each test
41+
jest.clearAllMocks();
42+
});
43+
44+
test('should throw an error if config is undefined', () => {
45+
expect(() => new Chronos()).toThrow('Chronos config is undefined');
46+
});
47+
48+
test('should call utilities functions with the correct parm', () => {
49+
const config = {
50+
microservice: 'test',
51+
interval: 300,
52+
mode: 'micro',
53+
dockerized: false,
54+
database: {
55+
connection: 'REST',
56+
type: process.env.CHRONOS_DB,
57+
URI: process.env.CHRONOS_URI,
58+
},
59+
notifications: [],
60+
};
61+
62+
const chronos = new Chronos(config);
63+
64+
// Ensure the config property is correctly set in the instance
65+
expect(chronos.config).toEqual(config);
66+
// Ensure the constructor called the validateInput and addNotifications functions
67+
expect(helpers.validateInput).toHaveBeenCalledWith(config);
68+
expect(helpers.addNotifications).toHaveBeenCalledWith(config);
69+
});
70+
71+
describe('propagate', () => {
72+
test('should check if propagate func properply calls hpropagate', () => {
73+
const config = {
74+
microservice: 'test',
75+
interval: 300,
76+
mode: 'micro',
77+
dockerized: false,
78+
database: {
79+
connection: 'REST',
80+
type: process.env.CHRONOS_DB,
81+
URI: process.env.CHRONOS_URI,
82+
},
83+
notifications: [],
84+
};
85+
86+
const chronos = new Chronos(config);
87+
chronos.propagate();
88+
expect(hpropagate).toHaveBeenCalledWith({ propagateInResponses: true });
89+
});
90+
});
91+
92+
describe('track', () => {
93+
test('should check if track function for MongoDB works', () => {
94+
//check if we can destructure database and dockerized from config
95+
const config = {
96+
microservice: 'test',
97+
interval: 300,
98+
mode: 'micro',
99+
dockerized: true,
100+
database: {
101+
connection: 'REST',
102+
type: 'MongoDB',
103+
URI: process.env.CHRONOS_URI,
104+
},
105+
notifications: [],
106+
};
107+
const { database, dockerized } = config;
108+
const falseDock = { dockerized: false };
109+
const chronos = new Chronos(config);
110+
chronos.track();
111+
if (database.type === 'MongoDB') {
112+
expect(mongo.connect).toHaveBeenCalledWith(config);
113+
expect(mongo.services).toHaveBeenCalledWith(config);
114+
if (dockerized) expect(mongo.docker).toHaveBeenCalledWith(config);
115+
if (!falseDock) expect(mongo.health).toHaveBeenCalledWith(config);
116+
if (database.connection === 'REST') expect(mongo.communications).not.toBeUndefined();
117+
}
118+
});
119+
test('should check if track function for Postgres works', () => {
120+
//check if we can destructure database and dockerized from config
121+
const config = {
122+
microservice: 'test',
123+
interval: 300,
124+
mode: 'micro',
125+
dockerized: true,
126+
database: {
127+
connection: 'REST',
128+
type: 'PostgreSQL',
129+
URI: process.env.CHRONOS_URI,
130+
},
131+
notifications: [],
132+
};
133+
const { database, dockerized } = config;
134+
const falseDock = { dockerized: false };
135+
const chronos = new Chronos(config);
136+
chronos.track();
137+
if (database.type === 'PostgreSQL') {
138+
expect(postgres.connect).toHaveBeenCalledWith(config);
139+
expect(postgres.services).toHaveBeenCalledWith(config);
140+
if (dockerized) expect(postgres.docker).toHaveBeenCalledWith(config);
141+
if (!falseDock) expect(postgres.health).toHaveBeenCalledWith(config);
142+
if (database.connection === 'REST') expect(postgres.communications).not.toBeUndefined();
143+
}
144+
});
145+
});
146+
describe('kafka', () => {
147+
test('should check if kafka is functional', async () => {
148+
const config = {
149+
microservice: 'test',
150+
interval: 300,
151+
mode: 'micro',
152+
dockerized: true,
153+
database: {
154+
connection: 'REST',
155+
type: 'MongoDB',
156+
URI: process.env.CHRONOS_URI,
157+
},
158+
notifications: [],
159+
};
160+
const { database, dockerized } = config;
161+
const falseDock = { dockerized: false };
162+
const chronos = new Chronos(config);
163+
chronos.kafka();
164+
await helpers.testMetricsQuery(config);
165+
if (database.type === 'MongoDB') {
166+
expect(mongo.connect).toHaveBeenCalledWith(config);
167+
expect(mongo.serverQuery).toHaveBeenCalledWith(config);
168+
}
169+
if (database.type === 'PostgreSQL') {
170+
expect(postgres.connect).toHaveBeenCalledWith(config);
171+
expect(postgres.serverQuery).toHaveBeenCalledWith(config);
172+
}
173+
});
174+
});
175+
176+
describe('kubernetes', () => {
177+
test('should check if kubernetes is functional', async () => {
178+
const config = {
179+
microservice: 'test',
180+
interval: 300,
181+
mode: 'micro',
182+
dockerized: true,
183+
database: {
184+
connection: 'REST',
185+
type: 'MongoDB',
186+
URI: process.env.CHRONOS_URI,
187+
},
188+
notifications: [],
189+
};
190+
const { database, dockerized } = config;
191+
const falseDock = { dockerized: false };
192+
const chronos = new Chronos(config);
193+
chronos.kubernetes();
194+
await helpers.testMetricsQuery(config);
195+
if (database.type === 'MongoDB') {
196+
expect(mongo.connect).toHaveBeenCalledWith(config);
197+
expect(mongo.serverQuery).toHaveBeenCalledWith(config);
198+
}
199+
if (database.type === 'PostgreSQL') {
200+
expect(postgres.connect).toHaveBeenCalledWith(config);
201+
expect(postgres.serverQuery).toHaveBeenCalledWith(config);
202+
}
203+
});
204+
});
205+
});

__backend-tests__/controllers/alert.test.js

Whitespace-only changes.

__backend-tests__/controllers/dockerHelper.test.js

Whitespace-only changes.

__backend-tests__/controllers/healthHelpers.test.js

Whitespace-only changes.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//const mongoose = require('mongoose');
2+
const mongo = require('../../chronos_npm_package/controllers/mongo');
3+
const ServicesModel = require('../../chronos_npm_package/models/ServicesModel');
4+
require('dotenv').config();
5+
6+
jest.mock('mongoose', () => {
7+
return {
8+
connect: jest.fn().mockResolvedValue(undefined),
9+
};
10+
});
11+
12+
jest.spyOn(console, 'log').mockImplementation(() => {});
13+
14+
describe('mongo.connect', () => {
15+
beforeEach(() => {
16+
jest.clearAllMocks();
17+
});
18+
19+
test('should connect to MongoDB database', async () => {
20+
const databaseURI = 'mongodb://localhost:27017/testdb';
21+
await mongo.connect({ databaseURI });
22+
expect(mongoose.connect).toHaveBeenCalledWith(databaseURI);
23+
expect(console.log).toHaveBeenCalledWith(
24+
expect.stringContaining('MongoDB database connected at')
25+
);
26+
});
27+
28+
test('should handle connection error', async () => {
29+
const errorMessage = 'Connection failed';
30+
const databaseURI = 'mongodb://localhost:27017/testdb';
31+
32+
jest.spyOn(mongoose, 'connect').mockRejectedValueOnce(new Error(errorMessage));
33+
34+
await mongo.connect({ databaseURI });
35+
expect(mongoose.connect).toHaveBeenCalledWith(databaseURI);
36+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining(errorMessage));
37+
});
38+
});
39+
40+
describe('mongo.services', () => {
41+
beforeEach(() => {
42+
jest.clearAllMocks();
43+
});
44+
45+
test('should create a new document', async () => {});
46+
});

__backend-tests__/controllers/postgres.test.js

Whitespace-only changes.

__backend-tests__/controllers/utilities.test.js

Whitespace-only changes.

__backend-tests__/jest.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
testEnvironment: 'node', // Use the Node.js environment for testing
3+
roots: ['<rootDir>'], // Set the root directory for test files (adjust this path to your test folder)
4+
5+
testRegex: '(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$',
6+
7+
// Code coverage settings
8+
collectCoverage: true,
9+
coverageDirectory: 'coverage',
10+
11+
// Specify the test path patterns to ignore (frontend tests)
12+
testPathIgnorePatterns: ['/node_modules/', '/__tests__/'],
13+
};

app/context/HealthContext.tsx

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -53,43 +53,50 @@ const HealthContextProvider: React.FC<Props> = React.memo(({ children }) => {
5353
* Data is then parsed and setHealthData is called with the transformed information.
5454
*/
5555

56-
const fetchHealthData = useCallback(async (serv) => {
56+
const fetchHealthData = useCallback(async serv => {
5757
ipcRenderer.removeAllListeners('healthResponse');
5858

5959
let temp: HealthDataObject[] = [];
6060
//Promise.all(
61-
let promises = await Promise.all(serv.map( async (service: string) => {
62-
63-
try {
64-
const newPromise = await new Promise((resolve, reject) => {
65-
ipcRenderer.send('healthRequest', `${service}-containerinfos`);
66-
ipcRenderer.on('healthResponse', (event: Electron.Event, data: string) => {
67-
let result: object[];
68-
if (JSON.stringify(data) !== '{}' && tryParseJSON(data)) {
69-
result = JSON.parse(data);
70-
console.log('HealthContext.tsx line 68 result: ', result, 'service', service, 'Obj key', Object.keys(result[0])[0]);
71-
// if (result && result.length && service === Object.keys(result[0])[0]) {
72-
resolve(result[0]);
73-
// }
61+
let promises = await Promise.all(
62+
serv.map(async (service: string) => {
63+
try {
64+
const newPromise = await new Promise((resolve, reject) => {
65+
ipcRenderer.send('healthRequest', `${service}-containerinfos`);
66+
ipcRenderer.on('healthResponse', (event: Electron.Event, data: string) => {
67+
let result: object[];
68+
if (JSON.stringify(data) !== '{}' && tryParseJSON(data)) {
69+
result = JSON.parse(data);
70+
console.log(
71+
'HealthContext.tsx line 68 result: ',
72+
result,
73+
'service',
74+
service,
75+
'Obj key',
76+
Object.keys(result[0])[0]
77+
);
78+
if (result && result.length && service === Object.keys(result[0])[0]) {
79+
resolve(result[0]);
7480
}
75-
});
76-
})
77-
console.log('HealthContext.tsx line 75 newPromise: ', newPromise);
78-
// temp.push(newPromise);
79-
// if (checkServicesComplete(temp, serv)) {
80-
// setServices(serv);
81-
// let transformedData: any = {};
82-
// console.log('original healthData before transformation: ', temp);
83-
// transformedData = healthTransformer(temp);
84-
// console.log('healthData after tranformation: ', transformedData);
85-
// setHealthData(transformedData);
86-
// }
87-
} catch (err) {
88-
console.log("healthcontext.tsx ERROR: ", err);
89-
};
81+
}
82+
});
83+
});
84+
console.log('HealthContext.tsx line 75 newPromise: ', newPromise);
85+
// temp.push(newPromise);
86+
// if (checkServicesComplete(temp, serv)) {
87+
// setServices(serv);
88+
// let transformedData: any = {};
89+
// console.log('original healthData before transformation: ', temp);
90+
// transformedData = healthTransformer(temp);
91+
// console.log('healthData after tranformation: ', transformedData);
92+
// setHealthData(transformedData);
93+
// }
94+
} catch (err) {
95+
console.log('healthcontext.tsx ERROR: ', err);
9096
}
91-
));
92-
}, []);
97+
})
98+
);
99+
}, []);
93100
// const fetchHealthData = useCallback(serv => {
94101
// ipcRenderer.removeAllListeners('healthResponse');
95102

0 commit comments

Comments
 (0)