Commit
·
1626af8
1
Parent(s):
a0e61bf
update
Browse files- backend/__tests__/config/googleOAuth.test.js +0 -77
- backend/__tests__/config/refreshTokens.test.js +0 -101
- backend/__tests__/controller/applicantController.test.js +0 -132
- backend/__tests__/controller/authController.test.js +0 -81
- backend/__tests__/controller/contactController.test.js +0 -198
- backend/__tests__/controller/demo/dateAvailability.test.js +0 -81
- backend/__tests__/controller/demo/holidays.test.js +0 -128
- backend/__tests__/controller/demo/slots.test.js +0 -142
- backend/__tests__/controller/demo/utils.test.js +0 -77
- backend/__tests__/controller/demoRequestController.test.js +0 -293
- backend/__tests__/controller/subscriptionController.test.js +0 -131
- backend/__tests__/db.test.js +0 -64
- backend/__tests__/db/addSubscriber.test.js +0 -95
- backend/__tests__/db/contactRequestDB.test.js +0 -90
- backend/__tests__/db/demoRequestDB.test.js +0 -120
- backend/__tests__/db/jobRequestDB.test.js +0 -105
- backend/__tests__/routes/applicantRoutes.test.js +0 -73
- backend/__tests__/testSetup.js +0 -0
- backend/controller/applicantController.js +2 -2
- backend/controller/contactController.js +2 -2
- backend/controller/demoRequestController.js +2 -2
- backend/demo-event.ics +0 -21
- backend/genomatics-logo.png +0 -0
- backend/jest/mediaFileTransformer.js +0 -9
- backend/test-report/index.html +0 -203
- backend/test-report/teststyle.css +0 -259
- backend/utils/sendEmail.js +1 -0
- frontend/jest/mediaFileTransformer.js +0 -9
- frontend/src/sections/contact/Forms.jsx +7 -8
- frontend/src/sections/jobs/JobPageSection.jsx +8 -2
- frontend/test-report/index.html +0 -459
- frontend/test-report/teststyle.css +0 -259
backend/__tests__/config/googleOAuth.test.js
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
const { google } = require('googleapis'); // Import googleapis here
|
2 |
-
jest.mock('googleapis', () => ({
|
3 |
-
google: {
|
4 |
-
auth: {
|
5 |
-
OAuth2: jest.fn().mockImplementation(() => ({
|
6 |
-
setCredentials: jest.fn(),
|
7 |
-
isTokenExpiring: jest.fn(),
|
8 |
-
refreshAccessToken: jest.fn(),
|
9 |
-
})),
|
10 |
-
},
|
11 |
-
},
|
12 |
-
}));
|
13 |
-
|
14 |
-
describe('googleOAuth client', () => {
|
15 |
-
beforeEach(() => {
|
16 |
-
// Clear all mocks before each test
|
17 |
-
jest.clearAllMocks();
|
18 |
-
process.env.CLIENT_ID = 'test-client-id';
|
19 |
-
process.env.CLIENT_SECRET = 'test-client-secret';
|
20 |
-
process.env.REDIRECT_URI = 'http://localhost';
|
21 |
-
});
|
22 |
-
|
23 |
-
it('should initialize OAuth2 client with credentials from .env', () => {
|
24 |
-
// Import the oAuth2Client after setting environment variables and mocks
|
25 |
-
const { oAuth2Client } = require('../../config/googleOAuth');
|
26 |
-
|
27 |
-
// Test if OAuth2 constructor was called with the expected parameters
|
28 |
-
expect(google.auth.OAuth2).toHaveBeenCalledWith(
|
29 |
-
'test-client-id',
|
30 |
-
'test-client-secret',
|
31 |
-
'http://localhost'
|
32 |
-
);
|
33 |
-
expect(oAuth2Client).toBeDefined();
|
34 |
-
});
|
35 |
-
|
36 |
-
it('should call setCredentials on OAuth2 client with proper tokens', async () => {
|
37 |
-
const tokens = { access_token: 'access-token', refresh_token: 'refresh-token' };
|
38 |
-
|
39 |
-
const { oAuth2Client } = require('../../config/googleOAuth'); // Ensure this is required here
|
40 |
-
oAuth2Client.setCredentials(tokens);
|
41 |
-
|
42 |
-
expect(oAuth2Client.setCredentials).toHaveBeenCalledWith(tokens);
|
43 |
-
});
|
44 |
-
|
45 |
-
it('should call refreshAccessToken and handle success', async () => {
|
46 |
-
const mockRefreshResponse = {
|
47 |
-
credentials: {
|
48 |
-
access_token: 'new-access-token',
|
49 |
-
refresh_token: 'new-refresh-token',
|
50 |
-
},
|
51 |
-
};
|
52 |
-
|
53 |
-
const { oAuth2Client } = require('../../config/googleOAuth'); // Ensure this is required here
|
54 |
-
oAuth2Client.refreshAccessToken.mockResolvedValueOnce(mockRefreshResponse);
|
55 |
-
|
56 |
-
const response = await oAuth2Client.refreshAccessToken();
|
57 |
-
expect(response.credentials.access_token).toBe('new-access-token');
|
58 |
-
expect(oAuth2Client.refreshAccessToken).toHaveBeenCalled();
|
59 |
-
});
|
60 |
-
|
61 |
-
it('should call refreshAccessToken and handle error', async () => {
|
62 |
-
const { oAuth2Client } = require('../../config/googleOAuth'); // Ensure this is required here
|
63 |
-
oAuth2Client.refreshAccessToken.mockRejectedValueOnce(new Error('Token refresh failed'));
|
64 |
-
|
65 |
-
await expect(oAuth2Client.refreshAccessToken()).rejects.toThrow('Token refresh failed');
|
66 |
-
expect(oAuth2Client.refreshAccessToken).toHaveBeenCalled();
|
67 |
-
});
|
68 |
-
|
69 |
-
it('should correctly check if the token is expiring', () => {
|
70 |
-
const { oAuth2Client } = require('../../config/googleOAuth'); // Ensure this is required here
|
71 |
-
oAuth2Client.isTokenExpiring.mockReturnValue(true);
|
72 |
-
|
73 |
-
const isExpiring = oAuth2Client.isTokenExpiring();
|
74 |
-
expect(isExpiring).toBe(true);
|
75 |
-
expect(oAuth2Client.isTokenExpiring).toHaveBeenCalled();
|
76 |
-
});
|
77 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/config/refreshTokens.test.js
DELETED
@@ -1,101 +0,0 @@
|
|
1 |
-
const { checkAndRefreshAccessToken } = require('../../utils/refreshToken');
|
2 |
-
const { oAuth2Client } = require('../../config/googleOAuth');
|
3 |
-
|
4 |
-
jest.mock('../../config/googleOAuth', () => ({
|
5 |
-
oAuth2Client: {
|
6 |
-
setCredentials: jest.fn(),
|
7 |
-
isTokenExpiring: jest.fn(),
|
8 |
-
refreshAccessToken: jest.fn(),
|
9 |
-
},
|
10 |
-
}));
|
11 |
-
|
12 |
-
describe('checkAndRefreshAccessToken', () => {
|
13 |
-
beforeEach(() => {
|
14 |
-
jest.clearAllMocks();
|
15 |
-
// Set mock tokens in environment before each test
|
16 |
-
process.env.ACCESS_TOKEN = 'test-access-token';
|
17 |
-
process.env.REFRESH_TOKEN = 'test-refresh-token';
|
18 |
-
});
|
19 |
-
|
20 |
-
afterEach(() => {
|
21 |
-
// Clear the environment variables after each test
|
22 |
-
delete process.env.ACCESS_TOKEN;
|
23 |
-
delete process.env.REFRESH_TOKEN;
|
24 |
-
});
|
25 |
-
|
26 |
-
it('should use tokens from .env and set credentials', async () => {
|
27 |
-
oAuth2Client.isTokenExpiring.mockReturnValue(false);
|
28 |
-
|
29 |
-
const tokens = await checkAndRefreshAccessToken();
|
30 |
-
|
31 |
-
expect(oAuth2Client.setCredentials).toHaveBeenCalledWith({
|
32 |
-
access_token: 'test-access-token',
|
33 |
-
refresh_token: 'test-refresh-token',
|
34 |
-
});
|
35 |
-
expect(tokens).toEqual({
|
36 |
-
access_token: 'test-access-token',
|
37 |
-
refresh_token: 'test-refresh-token',
|
38 |
-
});
|
39 |
-
});
|
40 |
-
|
41 |
-
it('should refresh tokens if the access token is expiring', async () => {
|
42 |
-
oAuth2Client.isTokenExpiring.mockReturnValue(true);
|
43 |
-
oAuth2Client.refreshAccessToken.mockResolvedValueOnce({
|
44 |
-
credentials: {
|
45 |
-
access_token: 'new-access-token',
|
46 |
-
refresh_token: 'new-refresh-token',
|
47 |
-
},
|
48 |
-
});
|
49 |
-
|
50 |
-
const tokens = await checkAndRefreshAccessToken();
|
51 |
-
|
52 |
-
expect(oAuth2Client.refreshAccessToken).toHaveBeenCalled();
|
53 |
-
expect(oAuth2Client.setCredentials).toHaveBeenCalledWith({
|
54 |
-
access_token: 'new-access-token',
|
55 |
-
refresh_token: 'new-refresh-token',
|
56 |
-
});
|
57 |
-
expect(tokens).toEqual({
|
58 |
-
access_token: 'new-access-token',
|
59 |
-
refresh_token: 'new-refresh-token',
|
60 |
-
});
|
61 |
-
});
|
62 |
-
|
63 |
-
it('should log an error if token refresh fails', async () => {
|
64 |
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
65 |
-
oAuth2Client.isTokenExpiring.mockReturnValue(true);
|
66 |
-
oAuth2Client.refreshAccessToken.mockRejectedValueOnce(new Error('Refresh failed'));
|
67 |
-
|
68 |
-
const tokens = await checkAndRefreshAccessToken();
|
69 |
-
|
70 |
-
expect(oAuth2Client.refreshAccessToken).toHaveBeenCalled();
|
71 |
-
expect(consoleErrorSpy).toHaveBeenCalledWith('Error refreshing access token:', expect.any(Error));
|
72 |
-
expect(tokens).toEqual({
|
73 |
-
access_token: 'test-access-token',
|
74 |
-
refresh_token: 'test-refresh-token',
|
75 |
-
});
|
76 |
-
|
77 |
-
consoleErrorSpy.mockRestore();
|
78 |
-
});
|
79 |
-
|
80 |
-
it('should log a message if no tokens are found in .env', async () => {
|
81 |
-
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
82 |
-
|
83 |
-
// Set the environment variables to undefined to simulate missing tokens
|
84 |
-
delete process.env.ACCESS_TOKEN;
|
85 |
-
delete process.env.REFRESH_TOKEN;
|
86 |
-
|
87 |
-
const tokens = await checkAndRefreshAccessToken();
|
88 |
-
|
89 |
-
// Ensure the log message was printed
|
90 |
-
expect(consoleLogSpy).toHaveBeenCalledWith('No tokens found in .env file. Please authenticate.');
|
91 |
-
|
92 |
-
// Ensure that setCredentials is NOT called because no tokens were provided
|
93 |
-
expect(oAuth2Client.setCredentials).not.toHaveBeenCalled();
|
94 |
-
|
95 |
-
// Check that the returned tokens are empty as expected
|
96 |
-
expect(tokens).toEqual({});
|
97 |
-
|
98 |
-
// Clean up the spy
|
99 |
-
consoleLogSpy.mockRestore();
|
100 |
-
});
|
101 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/applicantController.test.js
DELETED
@@ -1,132 +0,0 @@
|
|
1 |
-
const { submitJobApplication } = require('../../controller/applicantController');
|
2 |
-
const { checkExistingJobApplication, insertJobApplication } = require('../../utils/jobRequestDB');
|
3 |
-
const { checkAndRefreshAccessToken } = require('../../utils/refreshToken');
|
4 |
-
const { google } = require('googleapis');
|
5 |
-
const { oAuth2Client } = require('../../config/googleOAuth');
|
6 |
-
|
7 |
-
// Mock the dependencies
|
8 |
-
jest.mock('../../utils/jobRequestDB', () => ({
|
9 |
-
checkExistingJobApplication: jest.fn(),
|
10 |
-
insertJobApplication: jest.fn(),
|
11 |
-
}));
|
12 |
-
|
13 |
-
jest.mock('../../utils/refreshToken', () => ({
|
14 |
-
checkAndRefreshAccessToken: jest.fn(),
|
15 |
-
}));
|
16 |
-
|
17 |
-
// Mock googleapis and oAuth2Client setup
|
18 |
-
jest.mock('googleapis', () => ({
|
19 |
-
google: {
|
20 |
-
auth: {
|
21 |
-
OAuth2: jest.fn().mockImplementation(() => ({
|
22 |
-
setCredentials: jest.fn(),
|
23 |
-
})),
|
24 |
-
},
|
25 |
-
gmail: jest.fn().mockReturnValue({
|
26 |
-
users: {
|
27 |
-
messages: {
|
28 |
-
send: jest.fn(),
|
29 |
-
},
|
30 |
-
},
|
31 |
-
}),
|
32 |
-
},
|
33 |
-
}));
|
34 |
-
|
35 |
-
describe('submitJobApplication', () => {
|
36 |
-
let req;
|
37 |
-
let res;
|
38 |
-
|
39 |
-
beforeEach(() => {
|
40 |
-
// Mock request and response objects
|
41 |
-
req = {
|
42 |
-
body: {
|
43 |
-
name: 'John Doe',
|
44 |
-
email: '[email protected]',
|
45 |
-
phone: '1234567890',
|
46 |
-
experience: '5 years',
|
47 |
-
role: 'Software Engineer',
|
48 |
-
linkedin: 'https://linkedin.com/in/johndoe',
|
49 |
-
},
|
50 |
-
file: {
|
51 |
-
originalname: 'resume.pdf',
|
52 |
-
buffer: Buffer.from('file data'),
|
53 |
-
},
|
54 |
-
};
|
55 |
-
res = {
|
56 |
-
status: jest.fn().mockReturnThis(), // Mocking status method to return 'res' object itself
|
57 |
-
send: jest.fn().mockReturnThis(), // Mocking send method
|
58 |
-
json: jest.fn().mockReturnThis(), // Mocking json method
|
59 |
-
};
|
60 |
-
|
61 |
-
// Clear previous mocks
|
62 |
-
jest.clearAllMocks();
|
63 |
-
});
|
64 |
-
|
65 |
-
it('should return an error if any required fields are missing', async () => {
|
66 |
-
req.body.email = ''; // Missing email
|
67 |
-
|
68 |
-
await submitJobApplication(req, res);
|
69 |
-
|
70 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
71 |
-
expect(res.json).toHaveBeenCalledWith({ error: 'Please fill in all required fields.' });
|
72 |
-
});
|
73 |
-
|
74 |
-
it('should return an error if email format is invalid', async () => {
|
75 |
-
req.body.email = 'invalid-email'; // Invalid email format
|
76 |
-
|
77 |
-
await submitJobApplication(req, res);
|
78 |
-
|
79 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
80 |
-
expect(res.json).toHaveBeenCalledWith({ error: 'Please enter a valid email address.' });
|
81 |
-
});
|
82 |
-
|
83 |
-
it('should refresh access token if needed', async () => {
|
84 |
-
await submitJobApplication(req, res);
|
85 |
-
|
86 |
-
expect(checkAndRefreshAccessToken).toHaveBeenCalled();
|
87 |
-
});
|
88 |
-
|
89 |
-
it('should return an error if job application already exists', async () => {
|
90 |
-
checkExistingJobApplication.mockResolvedValueOnce(true); // Simulate an existing job application
|
91 |
-
|
92 |
-
await submitJobApplication(req, res);
|
93 |
-
|
94 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
95 |
-
expect(res.send).toHaveBeenCalledWith({
|
96 |
-
error: 'Your Job request for the role Software Engineer is already in queue'
|
97 |
-
});
|
98 |
-
});
|
99 |
-
|
100 |
-
it('should successfully submit job application and send an email', async () => {
|
101 |
-
checkExistingJobApplication.mockResolvedValueOnce(false); // Simulate no existing application
|
102 |
-
insertJobApplication.mockResolvedValueOnce(); // Simulate successful insertion
|
103 |
-
|
104 |
-
// Mocking Gmail API call
|
105 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({
|
106 |
-
data: { id: 'message-id' },
|
107 |
-
});
|
108 |
-
|
109 |
-
await submitJobApplication(req, res);
|
110 |
-
|
111 |
-
expect(res.status).toHaveBeenCalledWith(200);
|
112 |
-
expect(res.json).toHaveBeenCalledWith({ message: 'Application submitted successfully!', response: { data: { id: 'message-id' } } });
|
113 |
-
|
114 |
-
// Check if email was sent
|
115 |
-
expect(google.gmail().users.messages.send).toHaveBeenCalled();
|
116 |
-
});
|
117 |
-
|
118 |
-
it('should handle errors while sending the email', async () => {
|
119 |
-
checkExistingJobApplication.mockResolvedValueOnce(false); // Simulate no existing application
|
120 |
-
insertJobApplication.mockResolvedValueOnce(); // Simulate successful insertion
|
121 |
-
|
122 |
-
// Simulate email sending failure
|
123 |
-
google.gmail().users.messages.send.mockRejectedValueOnce(new Error('Email sending failed'));
|
124 |
-
|
125 |
-
await submitJobApplication(req, res);
|
126 |
-
|
127 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
128 |
-
expect(res.json).toHaveBeenCalledWith({
|
129 |
-
error: 'Failed to send job application reception email, however your job application has been received successfully!',
|
130 |
-
});
|
131 |
-
});
|
132 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/authController.test.js
DELETED
@@ -1,81 +0,0 @@
|
|
1 |
-
const { redirectToGoogleOAuth, handleOAuthCallback } = require('../../controller/authController');
|
2 |
-
const { oAuth2Client } = require('../../config/googleOAuth');
|
3 |
-
|
4 |
-
// Mock dependencies
|
5 |
-
jest.mock('../../config/googleOAuth', () => ({
|
6 |
-
oAuth2Client: {
|
7 |
-
generateAuthUrl: jest.fn(),
|
8 |
-
getToken: jest.fn(),
|
9 |
-
setCredentials: jest.fn(),
|
10 |
-
}
|
11 |
-
}));
|
12 |
-
|
13 |
-
describe('Google OAuth Controller', () => {
|
14 |
-
|
15 |
-
// Test for redirectToGoogleOAuth
|
16 |
-
it('should redirect to Google OAuth URL', async () => {
|
17 |
-
const req = {}; // Mock the request if needed
|
18 |
-
const res = {
|
19 |
-
redirect: jest.fn() // Mock the redirect method
|
20 |
-
};
|
21 |
-
|
22 |
-
// Simulate generating the auth URL
|
23 |
-
const expectedAuthUrl = 'https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=https://www.googleapis.com/auth/gmail.send+https://www.googleapis.com/auth/calendar.readonly';
|
24 |
-
oAuth2Client.generateAuthUrl.mockReturnValueOnce(expectedAuthUrl);
|
25 |
-
|
26 |
-
// Call the function
|
27 |
-
redirectToGoogleOAuth(req, res);
|
28 |
-
|
29 |
-
// Verify the redirect URL
|
30 |
-
expect(res.redirect).toHaveBeenCalledWith(expectedAuthUrl);
|
31 |
-
});
|
32 |
-
|
33 |
-
// Test for handleOAuthCallback (success)
|
34 |
-
it('should handle OAuth callback successfully and send a success message', async () => {
|
35 |
-
const req = { query: { code: 'valid-code' } }; // Simulate the query parameter with a valid code
|
36 |
-
const res = {
|
37 |
-
send: jest.fn(), // Mock the send method
|
38 |
-
status: jest.fn().mockReturnThis(), // Mock status to chain calls
|
39 |
-
};
|
40 |
-
|
41 |
-
// Mock the oAuth2Client methods
|
42 |
-
const mockTokens = {
|
43 |
-
access_token: 'access-token',
|
44 |
-
refresh_token: 'refresh-token',
|
45 |
-
};
|
46 |
-
|
47 |
-
// Mock the getToken method to resolve with mock tokens
|
48 |
-
oAuth2Client.getToken.mockResolvedValueOnce({
|
49 |
-
tokens: mockTokens,
|
50 |
-
});
|
51 |
-
|
52 |
-
// Mock the setCredentials method to resolve
|
53 |
-
oAuth2Client.setCredentials.mockImplementationOnce(() => {});
|
54 |
-
|
55 |
-
// Call the function
|
56 |
-
await handleOAuthCallback(req, res);
|
57 |
-
|
58 |
-
// Check if the send method was called with the expected success message
|
59 |
-
expect(res.send).toHaveBeenCalledWith('Authorization successful! You can now send emails.');
|
60 |
-
});
|
61 |
-
|
62 |
-
// Test for handleOAuthCallback (error scenario)
|
63 |
-
it('should handle OAuth callback error and send failure message', async () => {
|
64 |
-
const req = { query: { code: 'invalid-code' } }; // Simulate an invalid code
|
65 |
-
const res = {
|
66 |
-
send: jest.fn(),
|
67 |
-
status: jest.fn().mockReturnThis(),
|
68 |
-
};
|
69 |
-
|
70 |
-
// Mock the oAuth2Client methods to throw an error
|
71 |
-
oAuth2Client.getToken.mockRejectedValueOnce(new Error('OAuth error'));
|
72 |
-
|
73 |
-
// Call the function
|
74 |
-
await handleOAuthCallback(req, res);
|
75 |
-
|
76 |
-
// Check if the status was set to 500 and send was called with the failure message
|
77 |
-
expect(res.status).toHaveBeenCalledWith(500);
|
78 |
-
expect(res.send).toHaveBeenCalledWith('Failed to authenticate with Google');
|
79 |
-
});
|
80 |
-
|
81 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/contactController.test.js
DELETED
@@ -1,198 +0,0 @@
|
|
1 |
-
// Importing dependencies once to avoid re-declaration errors
|
2 |
-
const { submitContactForm } = require('../../controller/contactController');
|
3 |
-
const { checkAndRefreshAccessToken } = require('../../utils/refreshToken');
|
4 |
-
const { checkExistingContactRequest, insertContactRequest } = require('../../utils/contactRequestDB');
|
5 |
-
const fetch = require('node-fetch');
|
6 |
-
const { google } = require('googleapis');
|
7 |
-
|
8 |
-
// Mock dependencies
|
9 |
-
jest.mock('../../utils/refreshToken', () => ({
|
10 |
-
checkAndRefreshAccessToken: jest.fn(),
|
11 |
-
}));
|
12 |
-
|
13 |
-
jest.mock('../../utils/contactRequestDB', () => ({
|
14 |
-
checkExistingContactRequest: jest.fn(),
|
15 |
-
insertContactRequest: jest.fn(),
|
16 |
-
}));
|
17 |
-
|
18 |
-
jest.mock('node-fetch', () => jest.fn().mockResolvedValue({
|
19 |
-
json: jest.fn().mockResolvedValue({ success: true })
|
20 |
-
}));
|
21 |
-
|
22 |
-
// Mock googleapis and oAuth2Client setup
|
23 |
-
jest.mock('googleapis', () => ({
|
24 |
-
google: {
|
25 |
-
auth: {
|
26 |
-
OAuth2: jest.fn().mockImplementation(() => ({
|
27 |
-
setCredentials: jest.fn(),
|
28 |
-
})),
|
29 |
-
},
|
30 |
-
gmail: jest.fn().mockReturnValue({
|
31 |
-
users: {
|
32 |
-
messages: {
|
33 |
-
send: jest.fn(),
|
34 |
-
},
|
35 |
-
},
|
36 |
-
}),
|
37 |
-
},
|
38 |
-
}));
|
39 |
-
|
40 |
-
describe('Contact Controller', () => {
|
41 |
-
|
42 |
-
afterEach(() => {
|
43 |
-
jest.clearAllMocks();
|
44 |
-
});
|
45 |
-
|
46 |
-
it('should handle contact form submission successfully', async () => {
|
47 |
-
const req = {
|
48 |
-
body: {
|
49 |
-
name: 'John Doe',
|
50 |
-
email: '[email protected]',
|
51 |
-
phone: '1234567890',
|
52 |
-
subject: 'Inquiry',
|
53 |
-
message: 'Hello, I have a question.',
|
54 |
-
},
|
55 |
-
};
|
56 |
-
|
57 |
-
const res = {
|
58 |
-
send: jest.fn(),
|
59 |
-
status: jest.fn().mockReturnThis(),
|
60 |
-
};
|
61 |
-
|
62 |
-
// Mock dependencies
|
63 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce();
|
64 |
-
checkExistingContactRequest.mockResolvedValueOnce(null); // Simulate no existing request
|
65 |
-
insertContactRequest.mockResolvedValueOnce();
|
66 |
-
|
67 |
-
// Mock the Gmail API response
|
68 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({
|
69 |
-
data: {
|
70 |
-
id: '123',
|
71 |
-
threadId: '456',
|
72 |
-
},
|
73 |
-
});
|
74 |
-
|
75 |
-
|
76 |
-
// Call the controller function
|
77 |
-
await submitContactForm(req, res);
|
78 |
-
|
79 |
-
// Check the successful response
|
80 |
-
expect(res.status).toHaveBeenCalledWith(200);
|
81 |
-
expect(res.send).toHaveBeenCalledWith({
|
82 |
-
message: 'Contact message sent successfully!',
|
83 |
-
response: {data: { id: '123', threadId: '456' }},
|
84 |
-
});
|
85 |
-
|
86 |
-
// Check if the required functions were called
|
87 |
-
expect(checkAndRefreshAccessToken).toHaveBeenCalledTimes(1);
|
88 |
-
expect(checkExistingContactRequest).toHaveBeenCalledWith('John Doe', '[email protected]', 'Inquiry');
|
89 |
-
expect(insertContactRequest).toHaveBeenCalledWith('John Doe', '[email protected]', '1234567890', 'Inquiry', 'Hello, I have a question.');
|
90 |
-
expect(google.gmail().users.messages.send).toHaveBeenCalledTimes(1);
|
91 |
-
expect(fetch).toHaveBeenCalledTimes(1);
|
92 |
-
});
|
93 |
-
|
94 |
-
it('should return error if contact request with same subject exists', async () => {
|
95 |
-
const req = {
|
96 |
-
body: {
|
97 |
-
name: 'John Doe',
|
98 |
-
email: '[email protected]',
|
99 |
-
phone: '1234567890',
|
100 |
-
subject: 'Inquiry',
|
101 |
-
message: 'Hello, I have a question.',
|
102 |
-
},
|
103 |
-
};
|
104 |
-
|
105 |
-
const res = {
|
106 |
-
send: jest.fn(),
|
107 |
-
status: jest.fn().mockReturnThis(),
|
108 |
-
};
|
109 |
-
|
110 |
-
// Mock dependencies
|
111 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce();
|
112 |
-
checkExistingContactRequest.mockResolvedValueOnce(true); // Simulate an existing request
|
113 |
-
insertContactRequest.mockResolvedValueOnce();
|
114 |
-
|
115 |
-
// Call the function
|
116 |
-
await submitContactForm(req, res);
|
117 |
-
|
118 |
-
// Check if it returned the error message for existing request
|
119 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
120 |
-
expect(res.send).toHaveBeenCalledWith({
|
121 |
-
error: 'Your contact request with same subject is in queue',
|
122 |
-
});
|
123 |
-
|
124 |
-
// Check if insertContactRequest wasn't called
|
125 |
-
expect(insertContactRequest).not.toHaveBeenCalled();
|
126 |
-
});
|
127 |
-
|
128 |
-
it('should return an error if required fields are missing', async () => {
|
129 |
-
const req = {
|
130 |
-
body: {
|
131 |
-
name: 'John Doe',
|
132 |
-
email: '[email protected]',
|
133 |
-
phone: '', // Missing phone
|
134 |
-
subject: 'Inquiry',
|
135 |
-
message: 'Hello, I have a question.',
|
136 |
-
},
|
137 |
-
};
|
138 |
-
|
139 |
-
const res = {
|
140 |
-
send: jest.fn(),
|
141 |
-
status: jest.fn().mockReturnThis(),
|
142 |
-
};
|
143 |
-
|
144 |
-
// Call the function
|
145 |
-
await submitContactForm(req, res);
|
146 |
-
|
147 |
-
// Check if the response was the correct error message
|
148 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
149 |
-
expect(res.send).toHaveBeenCalledWith({ error: 'All fields are required.' });
|
150 |
-
|
151 |
-
// Check if any other functions were called (they shouldn't have been)
|
152 |
-
expect(checkAndRefreshAccessToken).not.toHaveBeenCalled();
|
153 |
-
expect(checkExistingContactRequest).not.toHaveBeenCalled();
|
154 |
-
expect(insertContactRequest).not.toHaveBeenCalled();
|
155 |
-
expect(fetch).not.toHaveBeenCalled();
|
156 |
-
});
|
157 |
-
|
158 |
-
it('should handle error when sending email fails', async () => {
|
159 |
-
const req = {
|
160 |
-
body: {
|
161 |
-
name: 'John Doe',
|
162 |
-
email: '[email protected]',
|
163 |
-
phone: '1234567890',
|
164 |
-
subject: 'Inquiry',
|
165 |
-
message: 'Hello, I have a question.',
|
166 |
-
},
|
167 |
-
};
|
168 |
-
|
169 |
-
const res = {
|
170 |
-
send: jest.fn(),
|
171 |
-
status: jest.fn().mockReturnThis(),
|
172 |
-
};
|
173 |
-
|
174 |
-
// Mock dependencies
|
175 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce();
|
176 |
-
checkExistingContactRequest.mockResolvedValueOnce(null); // Simulate no existing request
|
177 |
-
insertContactRequest.mockResolvedValueOnce();
|
178 |
-
|
179 |
-
// Simulate Gmail API failure
|
180 |
-
google.gmail().users.messages.send.mockRejectedValueOnce(new Error('Email send failed'));
|
181 |
-
|
182 |
-
// Call the controller function
|
183 |
-
await submitContactForm(req, res);
|
184 |
-
|
185 |
-
// Check the error response
|
186 |
-
expect(res.status).toHaveBeenCalledWith(200);
|
187 |
-
expect(res.send).toHaveBeenCalledWith({
|
188 |
-
error: 'Failed to send Contact request confirmation email, however request registered successfully!',
|
189 |
-
});
|
190 |
-
|
191 |
-
// Check if other functions were called
|
192 |
-
expect(checkAndRefreshAccessToken).toHaveBeenCalledTimes(1);
|
193 |
-
expect(checkExistingContactRequest).toHaveBeenCalledWith('John Doe', '[email protected]', 'Inquiry');
|
194 |
-
expect(insertContactRequest).toHaveBeenCalledWith('John Doe', '[email protected]', '1234567890', 'Inquiry', 'Hello, I have a question.');
|
195 |
-
expect(google.gmail().users.messages.send).toHaveBeenCalledTimes(1);
|
196 |
-
});
|
197 |
-
|
198 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/demo/dateAvailability.test.js
DELETED
@@ -1,81 +0,0 @@
|
|
1 |
-
const { checkDateAvailability, getAvailableDates } = require('../../../controller/dateAvailability');
|
2 |
-
const { runSelectQuery } = require('../../../utils/queries');
|
3 |
-
const { isHoliday } = require('../../../controller/holidays');
|
4 |
-
const { DateTime } = require('luxon');
|
5 |
-
|
6 |
-
// Mock dependencies
|
7 |
-
jest.mock('../../../utils/queries', () => ({
|
8 |
-
runSelectQuery: jest.fn(),
|
9 |
-
}));
|
10 |
-
|
11 |
-
jest.mock('../../../controller/holidays', () => ({
|
12 |
-
isHoliday: jest.fn(),
|
13 |
-
}));
|
14 |
-
|
15 |
-
describe('Date Availability Module', () => {
|
16 |
-
afterEach(() => {
|
17 |
-
jest.clearAllMocks();
|
18 |
-
});
|
19 |
-
|
20 |
-
describe('checkDateAvailability', () => {
|
21 |
-
it('should return true if the date is available (less than 11 bookings)', async () => {
|
22 |
-
runSelectQuery.mockResolvedValue([{ count: 5 }]);
|
23 |
-
|
24 |
-
const result = await checkDateAvailability('2025-01-01');
|
25 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
26 |
-
'SELECT COUNT(*) AS count FROM demo_requests WHERE demo_date = ?;',
|
27 |
-
['2025-01-01']
|
28 |
-
);
|
29 |
-
expect(result).toBe(true);
|
30 |
-
});
|
31 |
-
|
32 |
-
it('should return false if the date is fully booked (11 or more bookings)', async () => {
|
33 |
-
runSelectQuery.mockResolvedValue([{ count: 11 }]);
|
34 |
-
|
35 |
-
const result = await checkDateAvailability('2025-01-01');
|
36 |
-
expect(result).toBe(false);
|
37 |
-
});
|
38 |
-
|
39 |
-
it('should handle empty results gracefully', async () => {
|
40 |
-
runSelectQuery.mockResolvedValue([]);
|
41 |
-
|
42 |
-
const result = await checkDateAvailability('2025-01-01');
|
43 |
-
expect(result).toBe(true); // No bookings mean the date is available
|
44 |
-
});
|
45 |
-
});
|
46 |
-
|
47 |
-
describe('getAvailableDates', () => {
|
48 |
-
it('should return 14 available dates excluding holidays and weekends', async () => {
|
49 |
-
const currentDate = DateTime.fromISO('2025-01-01', { zone: 'Asia/Kolkata' });
|
50 |
-
|
51 |
-
// Mock isHoliday to return false for all dates
|
52 |
-
isHoliday.mockImplementation(async () => false);
|
53 |
-
|
54 |
-
// Mock runSelectQuery to simulate all dates have <11 bookings
|
55 |
-
runSelectQuery.mockImplementation(async () => [{ count: 0 }]);
|
56 |
-
|
57 |
-
const result = await getAvailableDates(currentDate);
|
58 |
-
|
59 |
-
// Check that 14 dates are returned
|
60 |
-
expect(result.length).toBe(14);
|
61 |
-
});
|
62 |
-
|
63 |
-
it('should skip holidays, Sundays, and 1st/3rd/5th Saturdays', async () => {
|
64 |
-
const currentDate = DateTime.fromISO('2025-01-01', { zone: 'Asia/Kolkata' });
|
65 |
-
|
66 |
-
// Mock isHoliday to return true for specific dates
|
67 |
-
isHoliday.mockImplementation(async date =>
|
68 |
-
['2025-01-02', '2025-01-05'].includes(date)
|
69 |
-
);
|
70 |
-
|
71 |
-
// Mock runSelectQuery to simulate availability
|
72 |
-
runSelectQuery.mockImplementation(async () => [{ count: 0 }]);
|
73 |
-
|
74 |
-
const result = await getAvailableDates(currentDate);
|
75 |
-
|
76 |
-
// Ensure skipped dates are not in the result
|
77 |
-
expect(result).not.toContain('2025-01-02');
|
78 |
-
expect(result).not.toContain('2025-01-05');
|
79 |
-
});
|
80 |
-
});
|
81 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/demo/holidays.test.js
DELETED
@@ -1,128 +0,0 @@
|
|
1 |
-
const { getIndiaTamilHolidays, refreshHolidays, isHoliday } = require('../../../controller/holidays');
|
2 |
-
const { google } = require('googleapis');
|
3 |
-
const { oAuth2Client } = require('../../../config/googleOAuth');
|
4 |
-
const { checkAndRefreshAccessToken } = require('../../../utils/refreshToken');
|
5 |
-
|
6 |
-
// Mock the dependencies
|
7 |
-
jest.mock('googleapis', () => ({
|
8 |
-
google: {
|
9 |
-
calendar: jest.fn().mockReturnValue({
|
10 |
-
events: {
|
11 |
-
list: jest.fn(),
|
12 |
-
},
|
13 |
-
}),
|
14 |
-
},
|
15 |
-
}));
|
16 |
-
|
17 |
-
jest.mock('../../../utils/refreshToken', () => ({
|
18 |
-
checkAndRefreshAccessToken: jest.fn(),
|
19 |
-
}));
|
20 |
-
|
21 |
-
jest.mock('../../../config/googleOAuth', () => ({
|
22 |
-
oAuth2Client: {
|
23 |
-
setCredentials: jest.fn(),
|
24 |
-
},
|
25 |
-
}));
|
26 |
-
|
27 |
-
describe('Holidays Controller', () => {
|
28 |
-
let mockResponse;
|
29 |
-
let consoleLogSpy;
|
30 |
-
let setTimeoutSpy;
|
31 |
-
|
32 |
-
beforeEach(() => {
|
33 |
-
jest.clearAllMocks();
|
34 |
-
|
35 |
-
// Mock response to return a list of holiday events
|
36 |
-
mockResponse = {
|
37 |
-
data: {
|
38 |
-
items: [
|
39 |
-
{
|
40 |
-
summary: 'Holiday 1',
|
41 |
-
start: { date: '2025-01-01' },
|
42 |
-
end: { date: '2025-01-01' },
|
43 |
-
},
|
44 |
-
{
|
45 |
-
summary: 'Holiday 2',
|
46 |
-
start: { date: '2025-02-01' },
|
47 |
-
end: { date: '2025-02-02' },
|
48 |
-
},
|
49 |
-
],
|
50 |
-
},
|
51 |
-
};
|
52 |
-
|
53 |
-
checkAndRefreshAccessToken.mockResolvedValue({ access_token: 'valid-token' });
|
54 |
-
google.calendar().events.list.mockResolvedValue(mockResponse);
|
55 |
-
|
56 |
-
// Spy on console.log to suppress output during tests
|
57 |
-
consoleLogSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
58 |
-
|
59 |
-
// Spy on setTimeout to suppress interval during tests
|
60 |
-
setTimeoutSpy = jest.spyOn(global, 'setTimeout').mockImplementation((fn, delay) => fn());
|
61 |
-
});
|
62 |
-
|
63 |
-
afterEach(() => {
|
64 |
-
consoleLogSpy.mockRestore();
|
65 |
-
setTimeoutSpy.mockRestore();
|
66 |
-
});
|
67 |
-
|
68 |
-
describe('getIndiaTamilHolidays', () => {
|
69 |
-
it('should return a list of holidays', async () => {
|
70 |
-
const holidays = await getIndiaTamilHolidays();
|
71 |
-
|
72 |
-
expect(holidays).toEqual([
|
73 |
-
{ festival: 'Holiday 1', date: '2025-01-01' },
|
74 |
-
{ festival: 'Holiday 2', date: '2025-02-01' },
|
75 |
-
{ festival: 'Holiday 2', date: '2025-02-02' },
|
76 |
-
]);
|
77 |
-
expect(google.calendar().events.list).toHaveBeenCalledTimes(1);
|
78 |
-
expect(checkAndRefreshAccessToken).toHaveBeenCalledTimes(1);
|
79 |
-
});
|
80 |
-
|
81 |
-
it('should return an error if OAuth credentials are missing', async () => {
|
82 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce(null);
|
83 |
-
|
84 |
-
const result = await getIndiaTamilHolidays();
|
85 |
-
expect(result).toEqual({ error: 'OAuth credentials missing. Please authorize the app first.' });
|
86 |
-
});
|
87 |
-
|
88 |
-
it('should handle errors properly', async () => {
|
89 |
-
google.calendar().events.list.mockRejectedValueOnce(new Error('API Error'));
|
90 |
-
|
91 |
-
await expect(getIndiaTamilHolidays()).rejects.toThrow('API Error');
|
92 |
-
});
|
93 |
-
});
|
94 |
-
|
95 |
-
describe('refreshHolidays', () => {
|
96 |
-
it('should refresh holidays and log them', async () => {
|
97 |
-
await refreshHolidays();
|
98 |
-
|
99 |
-
expect(consoleLogSpy).toHaveBeenCalledWith('India Holidays:', expect.any(Array));
|
100 |
-
expect(consoleLogSpy).toHaveBeenCalledWith('Total holidays:', 3);
|
101 |
-
expect(consoleLogSpy).toHaveBeenCalledWith('Last holiday:', expect.any(Object));
|
102 |
-
});
|
103 |
-
|
104 |
-
it('should handle retrying on error', async () => {
|
105 |
-
google.calendar().events.list.mockRejectedValueOnce(new Error('API Error'));
|
106 |
-
|
107 |
-
await refreshHolidays();
|
108 |
-
|
109 |
-
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 10000);
|
110 |
-
});
|
111 |
-
});
|
112 |
-
|
113 |
-
describe('isHoliday', () => {
|
114 |
-
it('should return true if the date is a holiday', async () => {
|
115 |
-
await refreshHolidays();
|
116 |
-
|
117 |
-
const result = await isHoliday('2025-01-01');
|
118 |
-
expect(result).toBe(true);
|
119 |
-
});
|
120 |
-
|
121 |
-
it('should return false if the date is not a holiday', async () => {
|
122 |
-
await refreshHolidays();
|
123 |
-
|
124 |
-
const result = await isHoliday('2025-01-03');
|
125 |
-
expect(result).toBe(false);
|
126 |
-
});
|
127 |
-
});
|
128 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/demo/slots.test.js
DELETED
@@ -1,142 +0,0 @@
|
|
1 |
-
const { getAvailableSlots, getBookedSlots } = require('../../../controller/slots');
|
2 |
-
const { runSelectQuery } = require('../../../utils/queries');
|
3 |
-
|
4 |
-
// Mock the runSelectQuery function
|
5 |
-
jest.mock('../../../utils/queries', () => ({
|
6 |
-
runSelectQuery: jest.fn(),
|
7 |
-
}));
|
8 |
-
|
9 |
-
describe('Slots Controller', () => {
|
10 |
-
beforeEach(() => {
|
11 |
-
jest.clearAllMocks();
|
12 |
-
});
|
13 |
-
|
14 |
-
describe('getBookedSlots', () => {
|
15 |
-
it('should throw an error if no date is provided', async () => {
|
16 |
-
await expect(getBookedSlots()).rejects.toThrow('Date is required');
|
17 |
-
});
|
18 |
-
|
19 |
-
|
20 |
-
it('should return an empty array if no slots are found for a valid date', async () => {
|
21 |
-
const date = '2025-01-01';
|
22 |
-
runSelectQuery.mockResolvedValueOnce([]); // Simulate no booked slots
|
23 |
-
|
24 |
-
const slots = await getBookedSlots(date);
|
25 |
-
|
26 |
-
expect(slots).toEqual([]); // No booked slots
|
27 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
28 |
-
expect.any(String),
|
29 |
-
date
|
30 |
-
);
|
31 |
-
});
|
32 |
-
|
33 |
-
it('should return a list of booked slots for a given date', async () => {
|
34 |
-
const date = '2025-01-01';
|
35 |
-
const mockBookedSlots = [
|
36 |
-
{ slot: '10:00 - 10:30' },
|
37 |
-
{ slot: '11:30 - 12:00' },
|
38 |
-
];
|
39 |
-
runSelectQuery.mockResolvedValueOnce(mockBookedSlots);
|
40 |
-
|
41 |
-
const slots = await getBookedSlots(date);
|
42 |
-
|
43 |
-
expect(slots).toEqual(['10:00 - 10:30', '11:30 - 12:00']);
|
44 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
45 |
-
expect.any(String),
|
46 |
-
date
|
47 |
-
);
|
48 |
-
});
|
49 |
-
|
50 |
-
it('should handle missing slot property gracefully', async () => {
|
51 |
-
const date = '2025-01-01';
|
52 |
-
const mockBookedSlots = [
|
53 |
-
{ slot: '10:00 - 10:30' },
|
54 |
-
{ /* missing slot property */ },
|
55 |
-
];
|
56 |
-
runSelectQuery.mockResolvedValueOnce(mockBookedSlots);
|
57 |
-
|
58 |
-
const slots = await getBookedSlots(date);
|
59 |
-
|
60 |
-
expect(slots).toEqual(['10:00 - 10:30']); // Ignore the entry without a slot
|
61 |
-
});
|
62 |
-
});
|
63 |
-
|
64 |
-
describe('getAvailableSlots', () => {
|
65 |
-
it('should throw an error if no date is provided', async () => {
|
66 |
-
await expect(getAvailableSlots()).rejects.toThrow('Date is required');
|
67 |
-
});
|
68 |
-
|
69 |
-
it('should throw an error for invalid date format', async () => {
|
70 |
-
const invalidDate = '2025-01-32';
|
71 |
-
await expect(getAvailableSlots(invalidDate)).rejects.toThrow('Invalid date format. Expected YYYY-MM-DD');
|
72 |
-
});
|
73 |
-
|
74 |
-
it('should return all general slots if no slots are booked for a given date', async () => {
|
75 |
-
const date = '2025-01-01';
|
76 |
-
runSelectQuery.mockResolvedValueOnce([]); // Simulate no booked slots
|
77 |
-
|
78 |
-
const availableSlots = await getAvailableSlots(date);
|
79 |
-
|
80 |
-
expect(availableSlots).toEqual([
|
81 |
-
'10:00 - 10:30', '10:45 - 11:15', '11:30 - 12:00', '12:15 - 12:45', '13:00 - 13:30',
|
82 |
-
'13:45 - 14:15', '14:30 - 15:00', '15:15 - 15:45', '16:00 - 16:30', '16:45 - 17:15', '17:30 - 18:00'
|
83 |
-
]);
|
84 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
85 |
-
expect.any(String),
|
86 |
-
date
|
87 |
-
);
|
88 |
-
});
|
89 |
-
|
90 |
-
it('should return available slots after removing booked slots', async () => {
|
91 |
-
const date = '2025-01-01';
|
92 |
-
const mockBookedSlots = [
|
93 |
-
{ slot: '10:00 - 10:30' },
|
94 |
-
{ slot: '11:30 - 12:00' },
|
95 |
-
];
|
96 |
-
runSelectQuery.mockResolvedValueOnce(mockBookedSlots);
|
97 |
-
|
98 |
-
const availableSlots = await getAvailableSlots(date);
|
99 |
-
|
100 |
-
expect(availableSlots).toEqual([
|
101 |
-
'10:45 - 11:15', '12:15 - 12:45', '13:00 - 13:30', '13:45 - 14:15',
|
102 |
-
'14:30 - 15:00', '15:15 - 15:45', '16:00 - 16:30', '16:45 - 17:15', '17:30 - 18:00'
|
103 |
-
]);
|
104 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
105 |
-
expect.any(String),
|
106 |
-
date
|
107 |
-
);
|
108 |
-
});
|
109 |
-
|
110 |
-
it('should handle empty results gracefully', async () => {
|
111 |
-
const date = '2025-01-01';
|
112 |
-
const mockBookedSlots = []; // No booked slots
|
113 |
-
runSelectQuery.mockResolvedValueOnce(mockBookedSlots);
|
114 |
-
|
115 |
-
const availableSlots = await getAvailableSlots(date);
|
116 |
-
|
117 |
-
expect(availableSlots).toEqual([
|
118 |
-
'10:00 - 10:30', '10:45 - 11:15', '11:30 - 12:00', '12:15 - 12:45', '13:00 - 13:30',
|
119 |
-
'13:45 - 14:15', '14:30 - 15:00', '15:15 - 15:45', '16:00 - 16:30', '16:45 - 17:15', '17:30 - 18:00'
|
120 |
-
]);
|
121 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
122 |
-
expect.any(String),
|
123 |
-
date
|
124 |
-
);
|
125 |
-
});
|
126 |
-
|
127 |
-
it('should throw an error if general slots are not properly defined', async () => {
|
128 |
-
const date = '2025-01-01';
|
129 |
-
const mockBookedSlots = [{ slot: '10:00 - 10:30' }];
|
130 |
-
runSelectQuery.mockResolvedValueOnce(mockBookedSlots);
|
131 |
-
|
132 |
-
// Temporarily break the generalSlots array
|
133 |
-
const originalGeneralSlots = [...global.generalSlots];
|
134 |
-
global.generalSlots = undefined;
|
135 |
-
|
136 |
-
await expect(getAvailableSlots(date)).rejects.toThrow('General slots are not properly defined');
|
137 |
-
|
138 |
-
// Restore the general slots for other tests
|
139 |
-
global.generalSlots = originalGeneralSlots;
|
140 |
-
});
|
141 |
-
});
|
142 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/demo/utils.test.js
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
const { createDateTimeSlotMapping, slotsInUserZone, getDatesSlots } = require('../../../controller/utils');
|
2 |
-
const { DateTime } = require('luxon');
|
3 |
-
|
4 |
-
describe('Utils Controller', () => {
|
5 |
-
|
6 |
-
describe('createDateTimeSlotMapping', () => {
|
7 |
-
it('should map date-time to slots correctly', () => {
|
8 |
-
const data = [
|
9 |
-
{ '2025-01-01': ['10:00 - 10:30', '11:00 - 11:30'] },
|
10 |
-
{ '2025-01-02': ['12:00 - 12:30'] }
|
11 |
-
];
|
12 |
-
const expected = {
|
13 |
-
'2025-01-01T10:00': '10:00 - 10:30',
|
14 |
-
'2025-01-01T11:00': '11:00 - 11:30',
|
15 |
-
'2025-01-02T12:00': '12:00 - 12:30'
|
16 |
-
};
|
17 |
-
const result = createDateTimeSlotMapping(data);
|
18 |
-
expect(result).toEqual(expected);
|
19 |
-
});
|
20 |
-
|
21 |
-
it('should return an empty object if no data is provided', () => {
|
22 |
-
const result = createDateTimeSlotMapping([]);
|
23 |
-
expect(result).toEqual({});
|
24 |
-
});
|
25 |
-
|
26 |
-
it('should handle invalid date format gracefully', () => {
|
27 |
-
const data = [
|
28 |
-
{ '2025-01-01': ['10:00 - 10:30'] },
|
29 |
-
{ '2025-31-31': ['11:00 - 11:30'] } // Invalid date format
|
30 |
-
];
|
31 |
-
const result = createDateTimeSlotMapping(data);
|
32 |
-
expect(result['2025-31-31T11:00']).toBeUndefined(); // Should not map an invalid date
|
33 |
-
});
|
34 |
-
});
|
35 |
-
|
36 |
-
describe('slotsInUserZone', () => {
|
37 |
-
it('should convert slot times correctly for user timezone', async () => {
|
38 |
-
const inter = {
|
39 |
-
'2025-01-01T10:00': '10:00 - 10:30',
|
40 |
-
'2025-01-01T11:00': '11:00 - 11:30'
|
41 |
-
};
|
42 |
-
const timezone = 'America/New_York';
|
43 |
-
const result = await slotsInUserZone(inter, timezone);
|
44 |
-
console.log(result);
|
45 |
-
expect(result['2024-12-31T23:30:00.000-05:00']).toBe('23:30 - 00:00 (America/New_York)');
|
46 |
-
});
|
47 |
-
});
|
48 |
-
|
49 |
-
describe('getDatesSlots', () => {
|
50 |
-
it('should organize slots by date correctly', async () => {
|
51 |
-
const input = {
|
52 |
-
'2025-01-01T10:00': '10:00 - 10:30',
|
53 |
-
'2025-01-01T11:00': '11:00 - 11:30',
|
54 |
-
'2025-01-02T12:00': '12:00 - 12:30'
|
55 |
-
};
|
56 |
-
const result = await getDatesSlots(input);
|
57 |
-
expect(result).toEqual({
|
58 |
-
'2025-01-01': ['10:00 - 10:30', '11:00 - 11:30'],
|
59 |
-
'2025-01-02': ['12:00 - 12:30']
|
60 |
-
});
|
61 |
-
});
|
62 |
-
|
63 |
-
it('should handle empty input', async () => {
|
64 |
-
const input = {};
|
65 |
-
const result = await getDatesSlots(input);
|
66 |
-
expect(result).toEqual({});
|
67 |
-
});
|
68 |
-
|
69 |
-
it('should handle invalid timestamp formats', async () => {
|
70 |
-
const input = {
|
71 |
-
'invalid-date': '10:00 - 10:30'
|
72 |
-
};
|
73 |
-
const result = await getDatesSlots(input);
|
74 |
-
expect(result).toEqual({});
|
75 |
-
});
|
76 |
-
});
|
77 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/demoRequestController.test.js
DELETED
@@ -1,293 +0,0 @@
|
|
1 |
-
const { demoRequest } = require('../../controller/demoRequestController');
|
2 |
-
const { checkExistingDemoRequest, insertDemoRequest } = require('../../utils/demoRequestDB');
|
3 |
-
const { checkAndRefreshAccessToken } = require('../../utils/refreshToken');
|
4 |
-
const { oAuth2Client } = require('../../config/googleOAuth');
|
5 |
-
const { google } = require('googleapis');
|
6 |
-
const fetch = require('node-fetch');
|
7 |
-
const { DateTime } = require('luxon');
|
8 |
-
|
9 |
-
jest.mock('../../utils/demoRequestDB', () => ({
|
10 |
-
checkExistingDemoRequest: jest.fn(),
|
11 |
-
insertDemoRequest: jest.fn(),
|
12 |
-
}));
|
13 |
-
|
14 |
-
jest.mock('../../utils/refreshToken', () => ({
|
15 |
-
checkAndRefreshAccessToken: jest.fn(),
|
16 |
-
}));
|
17 |
-
|
18 |
-
jest.mock('../../config/googleOAuth', () => ({
|
19 |
-
oAuth2Client: {
|
20 |
-
setCredentials: jest.fn(),
|
21 |
-
},
|
22 |
-
}));
|
23 |
-
|
24 |
-
jest.mock('node-fetch', () => jest.fn());
|
25 |
-
|
26 |
-
jest.mock('googleapis', () => ({
|
27 |
-
google: {
|
28 |
-
gmail: jest.fn().mockReturnValue({
|
29 |
-
users: {
|
30 |
-
messages: {
|
31 |
-
send: jest.fn(),
|
32 |
-
},
|
33 |
-
},
|
34 |
-
}),
|
35 |
-
},
|
36 |
-
}));
|
37 |
-
|
38 |
-
describe('demoRequest Controller', () => {
|
39 |
-
let req, res;
|
40 |
-
|
41 |
-
beforeEach(() => {
|
42 |
-
jest.clearAllMocks();
|
43 |
-
|
44 |
-
req = {
|
45 |
-
body: {
|
46 |
-
name: 'John Doe',
|
47 |
-
email: '[email protected]',
|
48 |
-
company: 'Example Corp',
|
49 |
-
product: 'Test Product',
|
50 |
-
demoDate: '2025-02-01',
|
51 |
-
selectedSlot: '10:00 - 11:00 (IST)',
|
52 |
-
phone: '+1234567890',
|
53 |
-
additionalComments: 'Looking forward to it!',
|
54 |
-
timezone: 'America/New_York',
|
55 |
-
},
|
56 |
-
};
|
57 |
-
|
58 |
-
res = {
|
59 |
-
status: jest.fn().mockReturnThis(),
|
60 |
-
send: jest.fn(),
|
61 |
-
};
|
62 |
-
});
|
63 |
-
|
64 |
-
it('should return 400 if required fields are missing', async () => {
|
65 |
-
req.body = {}; // Missing fields
|
66 |
-
|
67 |
-
await demoRequest(req, res);
|
68 |
-
|
69 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
70 |
-
expect(res.send).toHaveBeenCalledWith({ error: 'Please fill in all required fields.' });
|
71 |
-
});
|
72 |
-
|
73 |
-
it('should return 400 if demo request already exists within 15 days', async () => {
|
74 |
-
checkExistingDemoRequest.mockResolvedValueOnce(true);
|
75 |
-
|
76 |
-
await demoRequest(req, res);
|
77 |
-
|
78 |
-
expect(checkExistingDemoRequest).toHaveBeenCalledWith(
|
79 |
-
'John Doe',
|
80 |
-
'[email protected]',
|
81 |
-
'Test Product',
|
82 |
-
'2025-02-01',
|
83 |
-
'+1234567890'
|
84 |
-
);
|
85 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
86 |
-
expect(res.send).toHaveBeenCalledWith({
|
87 |
-
error: 'You have already requested a demo for this product within 15 days. Our team will get back to you shortly.',
|
88 |
-
});
|
89 |
-
});
|
90 |
-
|
91 |
-
it('should insert a new demo request if no existing request is found', async () => {
|
92 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
93 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
94 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({}); // Mock email sending
|
95 |
-
|
96 |
-
await demoRequest(req, res);
|
97 |
-
|
98 |
-
const convertedDemoDate = DateTime.fromISO(req.body.demoDate, { zone: 'utc' })
|
99 |
-
.setZone('Asia/Kolkata')
|
100 |
-
.toFormat('yyyy-MM-dd');
|
101 |
-
|
102 |
-
expect(insertDemoRequest).toHaveBeenCalledWith(
|
103 |
-
'John Doe',
|
104 |
-
'[email protected]',
|
105 |
-
'Example Corp',
|
106 |
-
'Test Product',
|
107 |
-
convertedDemoDate,
|
108 |
-
'10:00 - 11:00',
|
109 |
-
'+1234567890',
|
110 |
-
'Looking forward to it!'
|
111 |
-
);
|
112 |
-
expect(res.status).toHaveBeenCalledWith(200);
|
113 |
-
expect(res.send).toHaveBeenCalledWith({
|
114 |
-
message: 'Demo request submitted successfully! Our team will get in touch with you soon.',
|
115 |
-
response: {},
|
116 |
-
});
|
117 |
-
});
|
118 |
-
|
119 |
-
it('should send an email via Gmail API', async () => {
|
120 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
121 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
122 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({}); // Mock email sending
|
123 |
-
|
124 |
-
await demoRequest(req, res);
|
125 |
-
|
126 |
-
expect(google.gmail().users.messages.send).toHaveBeenCalledWith({
|
127 |
-
userId: 'me',
|
128 |
-
requestBody: {
|
129 |
-
raw: expect.any(String),
|
130 |
-
},
|
131 |
-
});
|
132 |
-
});
|
133 |
-
|
134 |
-
it('should handle email sending failure gracefully', async () => {
|
135 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
136 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
137 |
-
google.gmail().users.messages.send.mockRejectedValueOnce(new Error('Email API Error'));
|
138 |
-
|
139 |
-
await demoRequest(req, res);
|
140 |
-
|
141 |
-
expect(res.status).toHaveBeenCalledWith(200);
|
142 |
-
expect(res.send).toHaveBeenCalledWith({
|
143 |
-
error: 'Failed to send demo request confirmation email, however the demo request has been registered successfully!',
|
144 |
-
});
|
145 |
-
});
|
146 |
-
|
147 |
-
it('should call VAPI API with correct data', async () => {
|
148 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
149 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
150 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({}); // Mock email sending
|
151 |
-
|
152 |
-
// Mock fetch response for the VAPI API call
|
153 |
-
fetch.mockResolvedValueOnce({
|
154 |
-
json: jest.fn().mockResolvedValueOnce({ success: true }),
|
155 |
-
});
|
156 |
-
|
157 |
-
await demoRequest(req, res);
|
158 |
-
|
159 |
-
expect(fetch).toHaveBeenCalledWith('https://api.vapi.ai/call', {
|
160 |
-
method: 'POST',
|
161 |
-
headers: {
|
162 |
-
'Content-Type': 'application/json',
|
163 |
-
Authorization: `Bearer ${process.env.VAPI_KEY}`,
|
164 |
-
},
|
165 |
-
body: JSON.stringify({
|
166 |
-
name: '+1234567890_2025-01-28_DRC',
|
167 |
-
assistantId: `${process.env.DEMO_ASSISTANT_ID}`,
|
168 |
-
assistantOverrides: {
|
169 |
-
variableValues: {
|
170 |
-
name: 'John Doe',
|
171 |
-
product_name: 'Test Product',
|
172 |
-
demo_date: '2025-02-01',
|
173 |
-
slot: '10:00 - 11:00 (IST)',
|
174 |
-
comments: 'Looking forward to it!',
|
175 |
-
},
|
176 |
-
},
|
177 |
-
customer: {
|
178 |
-
number: '+1234567890',
|
179 |
-
},
|
180 |
-
phoneNumberId: `${process.env.PHONE_NUMBER_ID}`,
|
181 |
-
}),
|
182 |
-
});
|
183 |
-
});
|
184 |
-
|
185 |
-
it('should correctly convert the selected time slot to Asia/Kolkata timezone', async () => {
|
186 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
187 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
188 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({}); // Mock email sending
|
189 |
-
|
190 |
-
await demoRequest(req, res);
|
191 |
-
|
192 |
-
// Ensure the demo date and time are converted to Asia/Kolkata timezone
|
193 |
-
const convertedTime = '10:00 - 11:00'; // Expected converted time
|
194 |
-
expect(insertDemoRequest).toHaveBeenCalledWith(
|
195 |
-
'John Doe',
|
196 |
-
'[email protected]',
|
197 |
-
'Example Corp',
|
198 |
-
'Test Product',
|
199 |
-
expect.any(String), // Date will be formatted and converted
|
200 |
-
convertedTime,
|
201 |
-
'+1234567890',
|
202 |
-
'Looking forward to it!'
|
203 |
-
);
|
204 |
-
});
|
205 |
-
|
206 |
-
it('should return 400 if product field is missing', async () => {
|
207 |
-
req.body.product = ''; // Missing product
|
208 |
-
|
209 |
-
await demoRequest(req, res);
|
210 |
-
|
211 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
212 |
-
expect(res.send).toHaveBeenCalledWith({ error: 'Please fill in all required fields.' });
|
213 |
-
});
|
214 |
-
|
215 |
-
it('should generate correctly formatted HTML email content', async () => {
|
216 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
217 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
218 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({}); // Mock email sending
|
219 |
-
|
220 |
-
await demoRequest(req, res);
|
221 |
-
|
222 |
-
const expectedHtmlMessage = `
|
223 |
-
<div style="font-family: Arial, sans-serif; color: #333;">
|
224 |
-
<img src="https://www.genomatics.in/wp-content/uploads/2020/01/cropped-LOGO-1-1.png" alt="Genomatics Logo">
|
225 |
-
<h2 style="color: #0056b3;">Hello John Doe,</h2>
|
226 |
-
<p>Thank you for requesting a demo of our <strong>Genomatics</strong> product: <strong>Test Product</strong>. We're excited to showcase how our solutions can benefit your team at <strong>Example Corp</strong>.</p>
|
227 |
-
<p><strong>Requested demo date:</strong> 2025-02-01 - Time zone: America/New_York</p>
|
228 |
-
<p><strong>Preferred time slot:</strong> 10:00 - 11:00 (IST)</p>
|
229 |
-
<p>We'll be in touch soon to confirm the details. In the meantime, please feel free to reach out with any specific questions or topics you’d like us to cover during the demo.</p>
|
230 |
-
<h3 style="color: #0056b3;">Additional Message from You:</h3>
|
231 |
-
<p>Looking forward to it!</p>
|
232 |
-
<p style="margin-top: 20px;">Best regards,</p>
|
233 |
-
<p><strong>The Genomatics Team</strong></p>
|
234 |
-
<hr style="border: 0; height: 1px; background: #ddd; margin: 20px 0;">
|
235 |
-
<p style="font-size: 12px; color: #666;">
|
236 |
-
This email was sent in response to your request for a demo on the Genomatics platform.
|
237 |
-
</p>
|
238 |
-
</div>`;
|
239 |
-
|
240 |
-
expect(google.gmail().users.messages.send).toHaveBeenCalledWith({
|
241 |
-
userId: 'me',
|
242 |
-
requestBody: {
|
243 |
-
raw: expect.any(String),
|
244 |
-
},
|
245 |
-
});
|
246 |
-
|
247 |
-
// Verify that email content matches the expected content
|
248 |
-
const emailContent = google.gmail().users.messages.send.mock.calls[0][0].requestBody.raw;
|
249 |
-
expect(emailContent).toContain(expectedHtmlMessage);
|
250 |
-
});
|
251 |
-
|
252 |
-
it('should handle fetch API error during VAPI call', async () => {
|
253 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
254 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
255 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({}); // Mock email sending
|
256 |
-
|
257 |
-
// Mock fetch to throw an error during VAPI API call
|
258 |
-
fetch.mockRejectedValueOnce(new Error('VAPI call failed'));
|
259 |
-
|
260 |
-
await demoRequest(req, res);
|
261 |
-
|
262 |
-
expect(res.status).toHaveBeenCalledWith(200);
|
263 |
-
expect(res.send).toHaveBeenCalledWith({
|
264 |
-
error: 'Failed to send demo request confirmation email, however the demo request has been registered successfully!',
|
265 |
-
});
|
266 |
-
});
|
267 |
-
|
268 |
-
it('should correctly handle daylight saving time transitions for timezones', async () => {
|
269 |
-
req.body.timezone = 'America/New_York'; // A timezone with daylight saving time transition
|
270 |
-
|
271 |
-
checkExistingDemoRequest.mockResolvedValueOnce(false);
|
272 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce({});
|
273 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({}); // Mock email sending
|
274 |
-
|
275 |
-
await demoRequest(req, res);
|
276 |
-
|
277 |
-
// Test if the correct timezone is applied
|
278 |
-
const convertedDemoDate = DateTime.fromISO(req.body.demoDate, { zone: 'utc' })
|
279 |
-
.setZone('America/New_York')
|
280 |
-
.toFormat('yyyy-MM-dd');
|
281 |
-
|
282 |
-
expect(insertDemoRequest).toHaveBeenCalledWith(
|
283 |
-
'John Doe',
|
284 |
-
'[email protected]',
|
285 |
-
'Example Corp',
|
286 |
-
'Test Product',
|
287 |
-
convertedDemoDate,
|
288 |
-
'10:00 - 11:00',
|
289 |
-
'+1234567890',
|
290 |
-
'Looking forward to it!'
|
291 |
-
);
|
292 |
-
});
|
293 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/controller/subscriptionController.test.js
DELETED
@@ -1,131 +0,0 @@
|
|
1 |
-
const { handleSubscriptionEmail } = require('../../controller/subscriptionController');
|
2 |
-
const { addSubscriber } = require('../../utils/addSubscriber');
|
3 |
-
const { checkAndRefreshAccessToken } = require('../../utils/refreshToken');
|
4 |
-
const { google } = require('googleapis');
|
5 |
-
const { oAuth2Client } = require('../../config/googleOAuth');
|
6 |
-
|
7 |
-
// Mock the dependencies
|
8 |
-
jest.mock('../../utils/addSubscriber', () => ({
|
9 |
-
addSubscriber: jest.fn(),
|
10 |
-
}));
|
11 |
-
|
12 |
-
jest.mock('../../utils/refreshToken', () => ({
|
13 |
-
checkAndRefreshAccessToken: jest.fn(),
|
14 |
-
}));
|
15 |
-
|
16 |
-
// Mock googleapis and oAuth2Client setup
|
17 |
-
jest.mock('googleapis', () => ({
|
18 |
-
google: {
|
19 |
-
auth: {
|
20 |
-
OAuth2: jest.fn().mockImplementation(() => ({
|
21 |
-
setCredentials: jest.fn(),
|
22 |
-
})),
|
23 |
-
},
|
24 |
-
gmail: jest.fn().mockReturnValue({
|
25 |
-
users: {
|
26 |
-
messages: {
|
27 |
-
send: jest.fn(),
|
28 |
-
},
|
29 |
-
},
|
30 |
-
}),
|
31 |
-
},
|
32 |
-
}));
|
33 |
-
|
34 |
-
describe('handleSubscriptionEmail', () => {
|
35 |
-
let req;
|
36 |
-
let res;
|
37 |
-
let userTokens;
|
38 |
-
|
39 |
-
beforeEach(() => {
|
40 |
-
// Mock request and response objects
|
41 |
-
req = {
|
42 |
-
body: {
|
43 |
-
email: '[email protected]',
|
44 |
-
},
|
45 |
-
};
|
46 |
-
res = {
|
47 |
-
status: jest.fn().mockReturnThis(), // Mocking status method to return 'res' object itself
|
48 |
-
send: jest.fn().mockReturnThis(), // Mocking send method
|
49 |
-
json: jest.fn().mockReturnThis(), // Mocking json method
|
50 |
-
};
|
51 |
-
|
52 |
-
oAuth2Client.credentials = { access_token: 'fake-access-token', refresh_token: `fake-refresh-token` }; // Mocked OAuth tokens
|
53 |
-
|
54 |
-
// Clear previous mocks
|
55 |
-
jest.clearAllMocks();
|
56 |
-
});
|
57 |
-
|
58 |
-
it('should return an error if email is missing', async () => {
|
59 |
-
req.body.email = ''; // Missing email
|
60 |
-
|
61 |
-
await handleSubscriptionEmail(req, res);
|
62 |
-
|
63 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
64 |
-
expect(res.send).toHaveBeenCalledWith({ error: 'Email is required' });
|
65 |
-
});
|
66 |
-
|
67 |
-
it('should return an error if OAuth credentials are missing', async () => {
|
68 |
-
req.body.email = '[email protected]'; // Valid email
|
69 |
-
oAuth2Client.credentials = null; // Mocked OAuth tokens
|
70 |
-
|
71 |
-
addSubscriber.mockResolvedValueOnce({ status: 200, message: 'Subscriber added' });
|
72 |
-
|
73 |
-
await handleSubscriptionEmail(req, res);
|
74 |
-
|
75 |
-
expect(res.status).toHaveBeenCalledWith(500);
|
76 |
-
expect(res.send).toHaveBeenCalledWith({ error: 'OAuth credentials missing. Please authorize the app first.' });
|
77 |
-
});
|
78 |
-
|
79 |
-
it('should successfully subscribe a user and send a subscription email', async () => {
|
80 |
-
addSubscriber.mockResolvedValueOnce({ status: 200, message: 'Subscriber added' }); // Mock success
|
81 |
-
checkAndRefreshAccessToken.mockResolvedValueOnce(); // Mock successful token refresh
|
82 |
-
|
83 |
-
oAuth2Client.credentials = { access_token: 'fake-access-token', refresh_token: `fake-refresh-token` }; // Mocked OAuth tokens
|
84 |
-
|
85 |
-
google.gmail().users.messages.send.mockResolvedValueOnce({
|
86 |
-
data: { id: '123', threadId: '456' }, // Mock successful email sending
|
87 |
-
});
|
88 |
-
|
89 |
-
await handleSubscriptionEmail(req, res);
|
90 |
-
|
91 |
-
expect(res.status).toHaveBeenCalledWith(200);
|
92 |
-
expect(res.send).toHaveBeenCalledWith({
|
93 |
-
message: 'Subscription email sent!',
|
94 |
-
response: { data: { id: '123', threadId: '456' } },
|
95 |
-
});
|
96 |
-
|
97 |
-
expect(addSubscriber).toHaveBeenCalledWith('[email protected]');
|
98 |
-
expect(checkAndRefreshAccessToken).toHaveBeenCalledTimes(1);
|
99 |
-
expect(google.gmail().users.messages.send).toHaveBeenCalledTimes(1);
|
100 |
-
});
|
101 |
-
|
102 |
-
it('should return an error if email is already in the database', async () => {
|
103 |
-
const result = {
|
104 |
-
error: 'Email already exists',
|
105 |
-
status: 400,
|
106 |
-
};
|
107 |
-
addSubscriber.mockResolvedValueOnce(result); // Simulate email already existing
|
108 |
-
|
109 |
-
await handleSubscriptionEmail(req, res);
|
110 |
-
|
111 |
-
expect(res.status).toHaveBeenCalledWith(400);
|
112 |
-
expect(res.send).toHaveBeenCalledWith({ error: 'Email already exists' });
|
113 |
-
|
114 |
-
expect(addSubscriber).toHaveBeenCalledWith('[email protected]');
|
115 |
-
});
|
116 |
-
|
117 |
-
it('should handle error when sending email fails', async () => {
|
118 |
-
addSubscriber.mockResolvedValueOnce({ status: 200, message: 'Subscriber added' }); // Mock success
|
119 |
-
google.gmail().users.messages.send.mockRejectedValueOnce(new Error('Failed to send email')); // Mock email send failure
|
120 |
-
|
121 |
-
await handleSubscriptionEmail(req, res);
|
122 |
-
|
123 |
-
expect(res.status).toHaveBeenCalledWith(500);
|
124 |
-
expect(res.send).toHaveBeenCalledWith({
|
125 |
-
error: 'Failed to send subscription confirmation email, however you are subscribed and will receive newsletters',
|
126 |
-
});
|
127 |
-
|
128 |
-
expect(addSubscriber).toHaveBeenCalledWith('[email protected]');
|
129 |
-
expect(google.gmail().users.messages.send).toHaveBeenCalledTimes(1);
|
130 |
-
});
|
131 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/db.test.js
DELETED
@@ -1,64 +0,0 @@
|
|
1 |
-
// initializeDatabase.test.js
|
2 |
-
const { initializeDatabase } = require('../utils/setupDB'); // Import the function
|
3 |
-
const { runQuery } = require('../utils/queries'); // Import the runQuery function
|
4 |
-
|
5 |
-
jest.mock('../utils/queries'); // Mock the runQuery function
|
6 |
-
|
7 |
-
describe('initializeDatabase', () => {
|
8 |
-
beforeEach(() => {
|
9 |
-
// Clear all previous mocks before each test
|
10 |
-
jest.clearAllMocks();
|
11 |
-
});
|
12 |
-
|
13 |
-
it('should call runQuery for each table creation query', async () => {
|
14 |
-
// Arrange: Simulate the successful execution of runQuery
|
15 |
-
runQuery.mockResolvedValueOnce({}); // Mocking a successful query execution
|
16 |
-
|
17 |
-
// Act: Call the initializeDatabase function
|
18 |
-
await initializeDatabase();
|
19 |
-
|
20 |
-
// Assert: Check that runQuery was called once for each table creation query
|
21 |
-
const tableCreationQueries = [
|
22 |
-
expect.stringContaining('CREATE TABLE IF NOT EXISTS subscribers'),
|
23 |
-
expect.stringContaining('CREATE TABLE IF NOT EXISTS applicants'),
|
24 |
-
expect.stringContaining('CREATE TABLE IF NOT EXISTS demo_requests'),
|
25 |
-
expect.stringContaining('CREATE TABLE IF NOT EXISTS contact_requests'),
|
26 |
-
expect.stringContaining('CREATE TABLE IF NOT EXISTS purchases'),
|
27 |
-
expect.stringContaining('CREATE TABLE IF NOT EXISTS jobs')
|
28 |
-
];
|
29 |
-
|
30 |
-
tableCreationQueries.forEach((query, index) => {
|
31 |
-
expect(runQuery).toHaveBeenNthCalledWith(index + 1, query);
|
32 |
-
});
|
33 |
-
});
|
34 |
-
|
35 |
-
it('should handle errors properly if runQuery fails', async () => {
|
36 |
-
// Arrange: Simulate a failure when runQuery is called
|
37 |
-
runQuery.mockRejectedValueOnce(new Error('Database error'));
|
38 |
-
|
39 |
-
// Act & Assert: Call the function and expect it to log the error
|
40 |
-
await expect(initializeDatabase()).resolves.not.toThrow(); // Since error is logged but not re-thrown
|
41 |
-
expect(runQuery).toHaveBeenCalled();
|
42 |
-
});
|
43 |
-
|
44 |
-
it('should log successful table creation', async () => {
|
45 |
-
// Arrange: Mock successful query responses
|
46 |
-
runQuery.mockResolvedValueOnce({}); // Mocking a successful query execution
|
47 |
-
|
48 |
-
// Act: Call the function and capture the console log output
|
49 |
-
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); // Spy on console.log
|
50 |
-
|
51 |
-
await initializeDatabase();
|
52 |
-
|
53 |
-
// Assert: Check that each table creation success message is logged
|
54 |
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("Table 'subscribers' is checked/created successfully."));
|
55 |
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("Table 'applicants' is checked/created successfully."));
|
56 |
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("Table 'demo_requests' is checked/created successfully."));
|
57 |
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("Table 'contact_requests' is checked/created successfully."));
|
58 |
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("Table 'purchases' is checked/created successfully."));
|
59 |
-
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining("Table 'jobs' is checked/created successfully."));
|
60 |
-
|
61 |
-
// Cleanup the spy
|
62 |
-
logSpy.mockRestore();
|
63 |
-
});
|
64 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/db/addSubscriber.test.js
DELETED
@@ -1,95 +0,0 @@
|
|
1 |
-
const { addSubscriber } = require('../../utils/addSubscriber'); // Import the addSubscriber function
|
2 |
-
const { runQuery, runSelectQuery } = require('../../utils/queries'); // Import the functions that interact with the DB
|
3 |
-
|
4 |
-
jest.mock('../../utils/queries'); // Mock the runQuery and runSelectQuery functions
|
5 |
-
|
6 |
-
describe('addSubscriber', () => {
|
7 |
-
beforeEach(() => {
|
8 |
-
// Clear all previous mocks before each test
|
9 |
-
jest.clearAllMocks();
|
10 |
-
});
|
11 |
-
|
12 |
-
it('should return an error if the email already exists', async () => {
|
13 |
-
// Arrange: Mock the result of runSelectQuery to simulate that the email already exists
|
14 |
-
const email = '[email protected]';
|
15 |
-
runSelectQuery.mockResolvedValueOnce([{ email }]); // Simulate an existing email in the database
|
16 |
-
|
17 |
-
// Act: Call the addSubscriber function
|
18 |
-
const result = await addSubscriber(email);
|
19 |
-
|
20 |
-
// Assert: Ensure the function returns the correct error response
|
21 |
-
expect(result).toEqual({ status: 400, error: 'You have already subscribed!!' });
|
22 |
-
expect(runSelectQuery).toHaveBeenCalledWith('SELECT * FROM subscribers WHERE email = ?', [email]);
|
23 |
-
expect(runQuery).not.toHaveBeenCalled(); // Ensure runQuery was not called since email already exists
|
24 |
-
});
|
25 |
-
|
26 |
-
it('should add a new subscriber if the email does not exist', async () => {
|
27 |
-
// Arrange: Mock the result of runSelectQuery to simulate that the email does not exist
|
28 |
-
const email = '[email protected]';
|
29 |
-
runSelectQuery.mockResolvedValueOnce([]); // Simulate no matching email in the database
|
30 |
-
runQuery.mockResolvedValueOnce({}); // Mock the successful insert query
|
31 |
-
|
32 |
-
// Act: Call the addSubscriber function
|
33 |
-
const result = await addSubscriber(email);
|
34 |
-
|
35 |
-
// Assert: Ensure the subscriber was added and a success message is returned
|
36 |
-
expect(result).toEqual({ status: 200, message: 'Subscriber added' });
|
37 |
-
expect(runSelectQuery).toHaveBeenCalledWith('SELECT * FROM subscribers WHERE email = ?', [email]);
|
38 |
-
expect(runQuery).toHaveBeenCalledWith(
|
39 |
-
'INSERT INTO subscribers (date, time, email) VALUES (DATE("now"), TIME("now"), ?)',
|
40 |
-
[email]
|
41 |
-
);
|
42 |
-
});
|
43 |
-
|
44 |
-
it('should handle errors properly if there is a database error', async () => {
|
45 |
-
// Arrange: Simulate an error in the database operation
|
46 |
-
const email = '[email protected]';
|
47 |
-
runSelectQuery.mockResolvedValueOnce([]); // Simulate no matching email
|
48 |
-
runQuery.mockRejectedValueOnce(new Error('Database error')); // Simulate an error during the insert
|
49 |
-
|
50 |
-
// Act: Call the addSubscriber function
|
51 |
-
const result = await addSubscriber(email);
|
52 |
-
|
53 |
-
// Assert: Ensure the error is logged and the error response is returned
|
54 |
-
expect(result).toEqual({ status: 500, error: 'Failed to add subscriber' });
|
55 |
-
expect(runSelectQuery).toHaveBeenCalledWith('SELECT * FROM subscribers WHERE email = ?', [email]);
|
56 |
-
expect(runQuery).toHaveBeenCalledWith(
|
57 |
-
'INSERT INTO subscribers (date, time, email) VALUES (DATE("now"), TIME("now"), ?)',
|
58 |
-
[email]
|
59 |
-
);
|
60 |
-
});
|
61 |
-
|
62 |
-
it('should log success message when a new subscriber is added', async () => {
|
63 |
-
// Arrange: Mock the result of runSelectQuery to simulate that the email does not exist
|
64 |
-
const email = '[email protected]';
|
65 |
-
runSelectQuery.mockResolvedValueOnce([]); // Simulate no matching email
|
66 |
-
runQuery.mockResolvedValueOnce({}); // Mock successful insert
|
67 |
-
|
68 |
-
const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); // Spy on console.log
|
69 |
-
|
70 |
-
// Act: Call the addSubscriber function
|
71 |
-
await addSubscriber(email);
|
72 |
-
|
73 |
-
// Assert: Ensure the success message is logged
|
74 |
-
expect(logSpy).toHaveBeenCalledWith('Subscriber added successfully');
|
75 |
-
|
76 |
-
logSpy.mockRestore(); // Clean up the spy
|
77 |
-
});
|
78 |
-
|
79 |
-
it('should log an error message if there is a database error', async () => {
|
80 |
-
// Arrange: Simulate an error scenario
|
81 |
-
const email = '[email protected]';
|
82 |
-
runSelectQuery.mockResolvedValueOnce([]); // Simulate no matching email
|
83 |
-
runQuery.mockRejectedValueOnce(new Error('Database error')); // Simulate insert error
|
84 |
-
|
85 |
-
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); // Spy on console.error
|
86 |
-
|
87 |
-
// Act: Call the addSubscriber function
|
88 |
-
await addSubscriber(email);
|
89 |
-
|
90 |
-
// Assert: Ensure the error message is logged
|
91 |
-
expect(errorSpy).toHaveBeenCalledWith('Database error:', expect.any(Error));
|
92 |
-
|
93 |
-
errorSpy.mockRestore(); // Clean up the spy
|
94 |
-
});
|
95 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/db/contactRequestDB.test.js
DELETED
@@ -1,90 +0,0 @@
|
|
1 |
-
const { checkExistingContactRequest, insertContactRequest } = require('../../utils/contactRequestDB');
|
2 |
-
const { runQuery, runSelectQuery } = require('../../utils/queries');
|
3 |
-
|
4 |
-
jest.mock('../../utils/queries');
|
5 |
-
|
6 |
-
describe('checkExistingContactRequest', () => {
|
7 |
-
beforeEach(() => {
|
8 |
-
jest.clearAllMocks();
|
9 |
-
});
|
10 |
-
|
11 |
-
it('should return true if a contact request with the same name, email, and subject exists', async () => {
|
12 |
-
const name = 'John Doe';
|
13 |
-
const email = '[email protected]';
|
14 |
-
const subject = 'Inquiry';
|
15 |
-
runSelectQuery.mockResolvedValueOnce([{ name, email, subject }]);
|
16 |
-
|
17 |
-
const result = await checkExistingContactRequest(name, email, subject);
|
18 |
-
|
19 |
-
expect(result).toBe(true);
|
20 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
21 |
-
expect.stringContaining(`SELECT * FROM contact_requests WHERE name = ? AND email = ? AND subject = ?;`),
|
22 |
-
[name, email, subject]
|
23 |
-
);
|
24 |
-
});
|
25 |
-
|
26 |
-
it('should return false if no contact request with the same name, email, and subject exists', async () => {
|
27 |
-
const name = 'Jane Doe';
|
28 |
-
const email = '[email protected]';
|
29 |
-
const subject = 'Support';
|
30 |
-
runSelectQuery.mockResolvedValueOnce([]);
|
31 |
-
|
32 |
-
const result = await checkExistingContactRequest(name, email, subject);
|
33 |
-
|
34 |
-
expect(result).toBe(false);
|
35 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
36 |
-
expect.stringContaining(`SELECT * FROM contact_requests WHERE name = ? AND email = ? AND subject = ?;`),
|
37 |
-
[name, email, subject]
|
38 |
-
);
|
39 |
-
});
|
40 |
-
|
41 |
-
it('should handle database errors gracefully when checking existing contact requests', async () => {
|
42 |
-
const name = 'John Doe';
|
43 |
-
const email = '[email protected]';
|
44 |
-
const subject = 'Inquiry';
|
45 |
-
runSelectQuery.mockRejectedValueOnce(new Error('Database error'));
|
46 |
-
|
47 |
-
await expect(checkExistingContactRequest(name, email, subject)).rejects.toThrow('Database error');
|
48 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
49 |
-
expect.stringContaining(`SELECT * FROM contact_requests WHERE name = ? AND email = ? AND subject = ?;`),
|
50 |
-
[name, email, subject]
|
51 |
-
);
|
52 |
-
});
|
53 |
-
});
|
54 |
-
|
55 |
-
describe('insertContactRequest', () => {
|
56 |
-
beforeEach(() => {
|
57 |
-
jest.clearAllMocks();
|
58 |
-
});
|
59 |
-
|
60 |
-
it('should insert a contact request successfully', async () => {
|
61 |
-
const name = 'John Doe';
|
62 |
-
const email = '[email protected]';
|
63 |
-
const phone = '1234567890';
|
64 |
-
const subject = 'Inquiry';
|
65 |
-
const message = 'Hello, I have a question.';
|
66 |
-
runQuery.mockResolvedValueOnce({});
|
67 |
-
|
68 |
-
await insertContactRequest(name, email, phone, subject, message);
|
69 |
-
|
70 |
-
expect(runQuery).toHaveBeenCalledWith(
|
71 |
-
expect.stringContaining(`INSERT INTO contact_requests (date, time, name, email, phone, subject, message) VALUES (DATE("now"), TIME("now"), ?, ?, ?, ?, ?);`),
|
72 |
-
[name, email, phone, subject, message]
|
73 |
-
);
|
74 |
-
});
|
75 |
-
|
76 |
-
it('should handle errors properly if the insert query fails', async () => {
|
77 |
-
const name = 'John Doe';
|
78 |
-
const email = '[email protected]';
|
79 |
-
const phone = '1234567890';
|
80 |
-
const subject = 'Inquiry';
|
81 |
-
const message = 'Hello, I have a question.';
|
82 |
-
runQuery.mockRejectedValueOnce(new Error('Database error'));
|
83 |
-
|
84 |
-
await expect(insertContactRequest(name, email, phone, subject, message)).rejects.toThrow('Database error');
|
85 |
-
expect(runQuery).toHaveBeenCalledWith(
|
86 |
-
expect.stringContaining(`INSERT INTO contact_requests (date, time, name, email, phone, subject, message) VALUES (DATE("now"), TIME("now"), ?, ?, ?, ?, ?);`),
|
87 |
-
[name, email, phone, subject, message]
|
88 |
-
);
|
89 |
-
});
|
90 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/db/demoRequestDB.test.js
DELETED
@@ -1,120 +0,0 @@
|
|
1 |
-
const { checkExistingDemoRequest, insertDemoRequest } = require('../../utils/demoRequestDB');
|
2 |
-
const { runQuery, runSelectQuery } = require('../../utils/queries');
|
3 |
-
|
4 |
-
jest.mock('../../utils/queries');
|
5 |
-
|
6 |
-
describe('checkExistingDemoRequest', () => {
|
7 |
-
beforeEach(() => {
|
8 |
-
jest.clearAllMocks();
|
9 |
-
});
|
10 |
-
|
11 |
-
it('should return true if a demo request with the same name, email, product, demoDate, and phone exists', async () => {
|
12 |
-
const name = 'John Doe';
|
13 |
-
const email = '[email protected]';
|
14 |
-
const product = 'Software XYZ';
|
15 |
-
const demoDate = '2025-02-15';
|
16 |
-
const phone = '1234567890';
|
17 |
-
runSelectQuery.mockResolvedValueOnce([{ name, email, product, demo_date: demoDate, phone }]);
|
18 |
-
|
19 |
-
const result = await checkExistingDemoRequest(name, email, product, demoDate, phone);
|
20 |
-
|
21 |
-
expect(result).toBe(true);
|
22 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
23 |
-
expect.stringContaining(`
|
24 |
-
SELECT * FROM demo_requests
|
25 |
-
WHERE name = ? AND email = ? AND product = ?
|
26 |
-
AND ABS(julianday(demo_date) - julianday(?)) <= 15 AND phone = ?;
|
27 |
-
`),
|
28 |
-
[name, email, product, demoDate, phone]
|
29 |
-
);
|
30 |
-
});
|
31 |
-
|
32 |
-
it('should return false if no demo request with the same name, email, product, demoDate, and phone exists', async () => {
|
33 |
-
const name = 'Jane Doe';
|
34 |
-
const email = '[email protected]';
|
35 |
-
const product = 'Software XYZ';
|
36 |
-
const demoDate = '2025-02-15';
|
37 |
-
const phone = '9876543210';
|
38 |
-
runSelectQuery.mockResolvedValueOnce([]);
|
39 |
-
|
40 |
-
const result = await checkExistingDemoRequest(name, email, product, demoDate, phone);
|
41 |
-
|
42 |
-
expect(result).toBe(false);
|
43 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
44 |
-
expect.stringContaining(`
|
45 |
-
SELECT * FROM demo_requests
|
46 |
-
WHERE name = ? AND email = ? AND product = ?
|
47 |
-
AND ABS(julianday(demo_date) - julianday(?)) <= 15 AND phone = ?;
|
48 |
-
`),
|
49 |
-
[name, email, product, demoDate, phone]
|
50 |
-
);
|
51 |
-
});
|
52 |
-
|
53 |
-
it('should handle database errors gracefully when checking existing demo requests', async () => {
|
54 |
-
const name = 'John Doe';
|
55 |
-
const email = '[email protected]';
|
56 |
-
const product = 'Software XYZ';
|
57 |
-
const demoDate = '2025-02-15';
|
58 |
-
const phone = '1234567890';
|
59 |
-
runSelectQuery.mockRejectedValueOnce(new Error('Database error'));
|
60 |
-
|
61 |
-
await expect(checkExistingDemoRequest(name, email, product, demoDate, phone)).rejects.toThrow('Database error');
|
62 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
63 |
-
expect.stringContaining(`
|
64 |
-
SELECT * FROM demo_requests
|
65 |
-
WHERE name = ? AND email = ? AND product = ?
|
66 |
-
AND ABS(julianday(demo_date) - julianday(?)) <= 15 AND phone = ?;
|
67 |
-
`),
|
68 |
-
[name, email, product, demoDate, phone]
|
69 |
-
);
|
70 |
-
});
|
71 |
-
});
|
72 |
-
|
73 |
-
describe('insertDemoRequest', () => {
|
74 |
-
beforeEach(() => {
|
75 |
-
jest.clearAllMocks();
|
76 |
-
});
|
77 |
-
|
78 |
-
it('should insert a demo request successfully', async () => {
|
79 |
-
const name = 'John Doe';
|
80 |
-
const email = '[email protected]';
|
81 |
-
const company = 'ABC Corp';
|
82 |
-
const product = 'Software XYZ';
|
83 |
-
const demoDate = '2025-02-15';
|
84 |
-
const slot = '10:00 AM';
|
85 |
-
const phone = '1234567890';
|
86 |
-
const message = 'Looking forward to the demo!';
|
87 |
-
runQuery.mockResolvedValueOnce({});
|
88 |
-
|
89 |
-
await insertDemoRequest(name, email, company, product, demoDate, slot, phone, message);
|
90 |
-
|
91 |
-
expect(runQuery).toHaveBeenCalledWith(
|
92 |
-
expect.stringContaining(`
|
93 |
-
INSERT INTO demo_requests (date, time, name, email, company, product, demo_date, slot, phone, comments)
|
94 |
-
VALUES (DATE("now"), TIME("now"), ?, ?, ?, ?, ?, ?, ?, ?);
|
95 |
-
`),
|
96 |
-
[name, email, company, product, demoDate, slot, phone, message]
|
97 |
-
);
|
98 |
-
});
|
99 |
-
|
100 |
-
it('should handle errors properly if the insert query fails', async () => {
|
101 |
-
const name = 'John Doe';
|
102 |
-
const email = '[email protected]';
|
103 |
-
const company = 'ABC Corp';
|
104 |
-
const product = 'Software XYZ';
|
105 |
-
const demoDate = '2025-02-15';
|
106 |
-
const slot = '10:00 AM';
|
107 |
-
const phone = '1234567890';
|
108 |
-
const message = 'Looking forward to the demo!';
|
109 |
-
runQuery.mockRejectedValueOnce(new Error('Database error'));
|
110 |
-
|
111 |
-
await expect(insertDemoRequest(name, email, company, product, demoDate, slot, phone, message)).rejects.toThrow('Database error');
|
112 |
-
expect(runQuery).toHaveBeenCalledWith(
|
113 |
-
expect.stringContaining(`
|
114 |
-
INSERT INTO demo_requests (date, time, name, email, company, product, demo_date, slot, phone, comments)
|
115 |
-
VALUES (DATE("now"), TIME("now"), ?, ?, ?, ?, ?, ?, ?, ?);
|
116 |
-
`),
|
117 |
-
[name, email, company, product, demoDate, slot, phone, message]
|
118 |
-
);
|
119 |
-
});
|
120 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/db/jobRequestDB.test.js
DELETED
@@ -1,105 +0,0 @@
|
|
1 |
-
const { checkExistingJobApplication, insertJobApplication } = require('../../utils/jobRequestDB');
|
2 |
-
const { runQuery, runSelectQuery } = require('../../utils/queries');
|
3 |
-
|
4 |
-
jest.mock('../../utils/queries');
|
5 |
-
|
6 |
-
describe('checkExistingJobApplication', () => {
|
7 |
-
beforeEach(() => {
|
8 |
-
jest.clearAllMocks();
|
9 |
-
});
|
10 |
-
|
11 |
-
it('should return true if a job application with the same name, email, and role exists', async () => {
|
12 |
-
const name = 'John Doe';
|
13 |
-
const email = '[email protected]';
|
14 |
-
const role = 'Developer';
|
15 |
-
|
16 |
-
runSelectQuery.mockResolvedValueOnce([{ name, email, role }]);
|
17 |
-
|
18 |
-
const result = await checkExistingJobApplication(name, email, role);
|
19 |
-
|
20 |
-
expect(result).toBe(true);
|
21 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
22 |
-
expect.stringContaining(`SELECT * FROM applicants WHERE name = ? AND email = ? AND role = ?;`),
|
23 |
-
[name, email, role]
|
24 |
-
);
|
25 |
-
});
|
26 |
-
|
27 |
-
it('should return false if no job application with the same name, email, and role exists', async () => {
|
28 |
-
const name = 'Jane Doe';
|
29 |
-
const email = '[email protected]';
|
30 |
-
const role = 'Designer';
|
31 |
-
|
32 |
-
runSelectQuery.mockResolvedValueOnce([]);
|
33 |
-
|
34 |
-
const result = await checkExistingJobApplication(name, email, role);
|
35 |
-
|
36 |
-
expect(result).toBe(false);
|
37 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
38 |
-
expect.stringContaining(`SELECT * FROM applicants WHERE name = ? AND email = ? AND role = ?;`),
|
39 |
-
[name, email, role]
|
40 |
-
);
|
41 |
-
});
|
42 |
-
|
43 |
-
it('should handle database errors gracefully when checking for existing job applications', async () => {
|
44 |
-
const name = 'John Doe';
|
45 |
-
const email = '[email protected]';
|
46 |
-
const role = 'Developer';
|
47 |
-
|
48 |
-
runSelectQuery.mockRejectedValueOnce(new Error('Database error'));
|
49 |
-
|
50 |
-
await expect(checkExistingJobApplication(name, email, role)).rejects.toThrow('Database error');
|
51 |
-
expect(runSelectQuery).toHaveBeenCalledWith(
|
52 |
-
expect.stringContaining(`SELECT * FROM applicants WHERE name = ? AND email = ? AND role = ?;`),
|
53 |
-
[name, email, role]
|
54 |
-
);
|
55 |
-
});
|
56 |
-
});
|
57 |
-
|
58 |
-
describe('insertJobApplication', () => {
|
59 |
-
beforeEach(() => {
|
60 |
-
jest.clearAllMocks();
|
61 |
-
});
|
62 |
-
|
63 |
-
it('should insert a job application successfully', async () => {
|
64 |
-
const name = 'John Doe';
|
65 |
-
const email = '[email protected]';
|
66 |
-
const phone = '1234567890';
|
67 |
-
const experience = '5 years';
|
68 |
-
const role = 'Developer';
|
69 |
-
const linkedin = 'https://linkedin.com/johndoe';
|
70 |
-
const resume = Buffer.from('resume data');
|
71 |
-
const filename = 'resume.pdf';
|
72 |
-
|
73 |
-
runQuery.mockResolvedValueOnce({});
|
74 |
-
|
75 |
-
await insertJobApplication(name, email, phone, experience, role, linkedin, resume, filename);
|
76 |
-
|
77 |
-
expect(runQuery).toHaveBeenCalledWith(
|
78 |
-
expect.stringContaining(
|
79 |
-
`INSERT INTO applicants (date, time, name, email, phone, experience, role, linkedin, resume, filename) VALUES (DATE("now"), TIME("now"), ?, ?, ?, ?, ?, ?, ?, ?);`
|
80 |
-
),
|
81 |
-
[name, email, phone, experience, role, linkedin, resume, filename]
|
82 |
-
);
|
83 |
-
});
|
84 |
-
|
85 |
-
it('should handle errors properly if the insert query fails', async () => {
|
86 |
-
const name = 'John Doe';
|
87 |
-
const email = '[email protected]';
|
88 |
-
const phone = '1234567890';
|
89 |
-
const experience = '5 years';
|
90 |
-
const role = 'Developer';
|
91 |
-
const linkedin = 'https://linkedin.com/johndoe';
|
92 |
-
const resume = Buffer.from('resume data');
|
93 |
-
const filename = 'resume.pdf';
|
94 |
-
|
95 |
-
runQuery.mockRejectedValueOnce(new Error('Database error'));
|
96 |
-
|
97 |
-
await expect(insertJobApplication(name, email, phone, experience, role, linkedin, resume, filename)).rejects.toThrow('Database error');
|
98 |
-
expect(runQuery).toHaveBeenCalledWith(
|
99 |
-
expect.stringContaining(
|
100 |
-
`INSERT INTO applicants (date, time, name, email, phone, experience, role, linkedin, resume, filename) VALUES (DATE("now"), TIME("now"), ?, ?, ?, ?, ?, ?, ?, ?);`
|
101 |
-
),
|
102 |
-
[name, email, phone, experience, role, linkedin, resume, filename]
|
103 |
-
);
|
104 |
-
});
|
105 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/routes/applicantRoutes.test.js
DELETED
@@ -1,73 +0,0 @@
|
|
1 |
-
const request = require('supertest');
|
2 |
-
const express = require('express');
|
3 |
-
const app = express();
|
4 |
-
const { submitJobApplication } = require('../../controller/applicantController');
|
5 |
-
const applicantRoutes = require('../../routes/applicantRoutes');
|
6 |
-
|
7 |
-
// Jest timeout increased to prevent timeouts
|
8 |
-
jest.setTimeout(10000);
|
9 |
-
|
10 |
-
// Middleware to parse JSON and form data
|
11 |
-
app.use(express.json());
|
12 |
-
app.use(express.urlencoded({ extended: true }));
|
13 |
-
|
14 |
-
// Mocking the controller function
|
15 |
-
jest.mock('../../controller/applicantController', () => ({
|
16 |
-
submitJobApplication: jest.fn(),
|
17 |
-
}));
|
18 |
-
|
19 |
-
// Use the route in the app
|
20 |
-
app.use('/api', applicantRoutes);
|
21 |
-
|
22 |
-
describe('Applicant Routes', () => {
|
23 |
-
beforeEach(() => {
|
24 |
-
jest.clearAllMocks();
|
25 |
-
});
|
26 |
-
|
27 |
-
it('should successfully submit a job application', async () => {
|
28 |
-
const mockFile = Buffer.from('fake file content');
|
29 |
-
|
30 |
-
// Mock successful response
|
31 |
-
submitJobApplication.mockImplementation((req, res) => {
|
32 |
-
res.status(200).json({ message: 'Application submitted successfully' });
|
33 |
-
});
|
34 |
-
|
35 |
-
const response = await request(app)
|
36 |
-
.post('/api/submit-job-application')
|
37 |
-
.attach('resume', mockFile, 'test_resume.pdf')
|
38 |
-
.field('name', 'John Doe')
|
39 |
-
.field('email', '[email protected]')
|
40 |
-
.expect(200);
|
41 |
-
|
42 |
-
expect(response.body.message).toBe('Application submitted successfully');
|
43 |
-
});
|
44 |
-
|
45 |
-
it('should return 400 if no resume is provided', async () => {
|
46 |
-
submitJobApplication.mockImplementation((req, res) => {
|
47 |
-
res.status(400).json({ error: 'No resume uploaded' });
|
48 |
-
});
|
49 |
-
|
50 |
-
const response = await request(app)
|
51 |
-
.post('/api/submit-job-application')
|
52 |
-
.field('name', 'John Doe')
|
53 |
-
.field('email', '[email protected]')
|
54 |
-
.expect(400);
|
55 |
-
|
56 |
-
expect(response.body.error).toBe('No resume uploaded');
|
57 |
-
});
|
58 |
-
|
59 |
-
it('should handle errors gracefully', async () => {
|
60 |
-
submitJobApplication.mockImplementation((req, res) => {
|
61 |
-
res.status(500).json({ error: 'Something went wrong' });
|
62 |
-
});
|
63 |
-
|
64 |
-
const response = await request(app)
|
65 |
-
.post('/api/submit-job-application')
|
66 |
-
.attach('resume', Buffer.from('fake file content'), 'test_resume.pdf')
|
67 |
-
.field('name', 'John Doe')
|
68 |
-
.field('email', '[email protected]')
|
69 |
-
.expect(500);
|
70 |
-
|
71 |
-
expect(response.body.error).toBe('Something went wrong');
|
72 |
-
});
|
73 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/__tests__/testSetup.js
DELETED
File without changes
|
backend/controller/applicantController.js
CHANGED
@@ -107,10 +107,10 @@ const submitJobApplication = async (req, res) => {
|
|
107 |
|
108 |
await sendEmail(authorityEmail, authoritySubject, authorityHtmlMessage, resume, filename);
|
109 |
|
110 |
-
res.status(200).json({ message: 'Application submitted successfully!' });
|
111 |
}catch (error) {
|
112 |
console.error('Error sending emails:', error);
|
113 |
-
res.status(400).json({ error: '
|
114 |
}
|
115 |
};
|
116 |
|
|
|
107 |
|
108 |
await sendEmail(authorityEmail, authoritySubject, authorityHtmlMessage, resume, filename);
|
109 |
|
110 |
+
res.status(200).json({ message: 'Your Job Application has been submitted successfully!' });
|
111 |
}catch (error) {
|
112 |
console.error('Error sending emails:', error);
|
113 |
+
res.status(400).json({ error: 'Unable to send email for the confirmation of submission, but the application was received suvvessfully!' });
|
114 |
}
|
115 |
};
|
116 |
|
backend/controller/contactController.js
CHANGED
@@ -91,8 +91,8 @@ const submitContactForm = async (req, res) => {
|
|
91 |
|
92 |
res.status(200).send({ message: 'Contact message sent successfully!' });
|
93 |
} catch (error) {
|
94 |
-
console.error('
|
95 |
-
res.status(200).send({ error: '
|
96 |
}
|
97 |
|
98 |
// 🔹 Vapi AI Call
|
|
|
91 |
|
92 |
res.status(200).send({ message: 'Contact message sent successfully!' });
|
93 |
} catch (error) {
|
94 |
+
console.error('Unable to send Contact request confirmation email, however request registered successfully!', error);
|
95 |
+
res.status(200).send({ error: 'Unable to send Contact request confirmation email, however request registered successfully!' });
|
96 |
}
|
97 |
|
98 |
// 🔹 Vapi AI Call
|
backend/controller/demoRequestController.js
CHANGED
@@ -167,8 +167,8 @@ const demoRequest = async (req, res) => {
|
|
167 |
|
168 |
res.status(200).send({ message: 'Demo request submitted successfully! Our team will get in touch with you soon.' });
|
169 |
} catch (error) {
|
170 |
-
console.error('
|
171 |
-
res.status(200).send({ error: '
|
172 |
}
|
173 |
|
174 |
// 🔹 Vapi AI Call
|
|
|
167 |
|
168 |
res.status(200).send({ message: 'Demo request submitted successfully! Our team will get in touch with you soon.' });
|
169 |
} catch (error) {
|
170 |
+
console.error('Unable to send demo request confirmation email, however request registered successfully!', error);
|
171 |
+
res.status(200).send({ error: 'Unable to send demo request confirmation email, however the demo request has been registered successfully!' });
|
172 |
}
|
173 |
|
174 |
// 🔹 Vapi AI Call
|
backend/demo-event.ics
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
BEGIN:VCALENDAR
|
2 |
-
VERSION:2.0
|
3 |
-
CALSCALE:GREGORIAN
|
4 |
-
PRODID:adamgibbons/ics
|
5 |
-
METHOD:PUBLISH
|
6 |
-
X-PUBLISHED-TTL:PT1H
|
7 |
-
BEGIN:VEVENT
|
8 |
-
UID:ruGRSbfUjVeOCSrlKvoWs
|
9 |
-
SUMMARY:Demo for VarDiG SaaS
|
10 |
-
DTSTAMP:20250202T145649Z
|
11 |
-
DTSTART:20250212T060000Z
|
12 |
-
DESCRIPTION:Product demonstration for VarDiG SaaS
|
13 |
-
URL:https://meet.google.com/nzg-ptcm-abm
|
14 |
-
STATUS:CONFIRMED
|
15 |
-
CATEGORIES:Product Demo
|
16 |
-
X-MICROSOFT-CDO-BUSYSTATUS:BUSY
|
17 |
-
ATTENDEE;RSVP=TRUE;ROLE="REQ-PARTICIPANT";PARTSTAT="ACCEPTED";CN="DarrshanS
|
18 |
-
esha":mailto:[email protected]
|
19 |
-
DURATION:PT30M
|
20 |
-
END:VEVENT
|
21 |
-
END:VCALENDAR
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/genomatics-logo.png
DELETED
Binary file (1.56 kB)
|
|
backend/jest/mediaFileTransformer.js
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
const path = require('path');
|
2 |
-
|
3 |
-
// Mocks every media file to return its filename.
|
4 |
-
// Return just the file name without wrapping in an object
|
5 |
-
module.exports = {
|
6 |
-
process: (_, filename) => {
|
7 |
-
return `module.exports = '${path.basename(filename)}'`; // Return the filename as a string
|
8 |
-
},
|
9 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/test-report/index.html
DELETED
@@ -1,203 +0,0 @@
|
|
1 |
-
<html><head><meta charset="utf-8"/><title>Backend Unit tests</title><link rel="stylesheet" type="text/css" href="teststyle.css"/></head><body><div class="jesthtml-content"><header><h1 id="title">Backend Unit tests</h1></header><div id="metadata-container"><div id="timestamp">Started: 2025-01-29 12:35:57</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (18)</div><div class="summary-passed ">14 passed</div><div class="summary-failed ">4 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (93)</div><div class="summary-passed ">80 passed</div><div class="summary-failed ">13 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><input id="collapsible-0" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-0"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/slots.test.js</div><div class="suite-time">2.596s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getBookedSlots</div><div class="test-title">should throw an error if no date is provided</div><div class="test-status">passed</div><div class="test-duration">0.043s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getBookedSlots</div><div class="test-title">should return an empty array if no slots are found for a valid date</div><div class="test-status">passed</div><div class="test-duration">0.008s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getBookedSlots</div><div class="test-title">should return a list of booked slots for a given date</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getBookedSlots</div><div class="test-title">should handle missing slot property gracefully</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getAvailableSlots</div><div class="test-title">should throw an error if no date is provided</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">Slots Controller > getAvailableSlots</div><div class="test-title">should throw an error for invalid date format</div><div class="test-status">failed</div><div class="test-duration">0.023s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(received).rejects.toThrow(expected)
|
2 |
-
|
3 |
-
Expected substring: "Invalid date format. Expected YYYY-MM-DD"
|
4 |
-
Received message: "Cannot read properties of undefined (reading 'length')"
|
5 |
-
|
6 |
-
24 | const results = await runSelectQuery(query, date);
|
7 |
-
25 |
|
8 |
-
> 26 | console.log(`Fetched ${results.length} slots for date: ${date}`);
|
9 |
-
| ^
|
10 |
-
27 |
|
11 |
-
28 | // Check if results are empty
|
12 |
-
29 | if (!results || results.length === 0) {
|
13 |
-
|
14 |
-
at length (controller/slots.js:26:40)
|
15 |
-
at tryCatch (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
16 |
-
at Generator.<anonymous> (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
17 |
-
at Generator.next (node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
18 |
-
at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
19 |
-
at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
20 |
-
at Object.toThrow (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/expect/build/index.js:218:22)
|
21 |
-
at toThrow (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/slots.test.js:71:66)
|
22 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
23 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
24 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
25 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
26 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
27 |
-
at /data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7
|
28 |
-
at new Promise (<anonymous>)
|
29 |
-
at Object.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12)
|
30 |
-
at Promise.then.completed (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/utils.js:298:28)
|
31 |
-
at new Promise (<anonymous>)
|
32 |
-
at callAsyncCircusFn (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/utils.js:231:10)
|
33 |
-
at _callCircusTest (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:316:40)
|
34 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)
|
35 |
-
at _runTest (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:252:3)
|
36 |
-
at _runTestsForDescribeBlock (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:126:9)
|
37 |
-
at _runTestsForDescribeBlock (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:121:9)
|
38 |
-
at _runTestsForDescribeBlock (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:121:9)
|
39 |
-
at run (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:71:3)
|
40 |
-
at runAndTransformResultsToJestFormat (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
|
41 |
-
at jestAdapter (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
|
42 |
-
at runTestInternal (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-runner/build/runTest.js:367:16)
|
43 |
-
at runTest (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-runner/build/runTest.js:444:34)
|
44 |
-
at Object.worker (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-runner/build/testWorker.js:106:12)</pre></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getAvailableSlots</div><div class="test-title">should return all general slots if no slots are booked for a given date</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getAvailableSlots</div><div class="test-title">should return available slots after removing booked slots</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Slots Controller > getAvailableSlots</div><div class="test-title">should handle empty results gracefully</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">Slots Controller > getAvailableSlots</div><div class="test-title">should throw an error if general slots are not properly defined</div><div class="test-status">failed</div><div class="test-duration">0.002s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
|
45 |
-
at _iterableToArray (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/iterableToArray.js:2:48)
|
46 |
-
at _toConsumableArray (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/toConsumableArray.js:6:34)
|
47 |
-
at _callee10$ (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/slots.test.js:133:39)
|
48 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
49 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
50 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
51 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
52 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
53 |
-
at /data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7
|
54 |
-
at new Promise (<anonymous>)
|
55 |
-
at Object.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12)
|
56 |
-
at Promise.then.completed (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/utils.js:298:28)
|
57 |
-
at new Promise (<anonymous>)
|
58 |
-
at callAsyncCircusFn (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/utils.js:231:10)
|
59 |
-
at _callCircusTest (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:316:40)
|
60 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)
|
61 |
-
at _runTest (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:252:3)
|
62 |
-
at _runTestsForDescribeBlock (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:126:9)
|
63 |
-
at _runTestsForDescribeBlock (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:121:9)
|
64 |
-
at _runTestsForDescribeBlock (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:121:9)
|
65 |
-
at run (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/run.js:71:3)
|
66 |
-
at runAndTransformResultsToJestFormat (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
|
67 |
-
at jestAdapter (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
|
68 |
-
at runTestInternal (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-runner/build/runTest.js:367:16)
|
69 |
-
at runTest (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-runner/build/runTest.js:444:34)
|
70 |
-
at Object.worker (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/jest-runner/build/testWorker.js:106:12)</pre></div></div></div></div><div id="suite-2" class="suite-container"><input id="collapsible-1" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-1"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/holidays.test.js</div><div class="suite-time">2.658s</div></div></label><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename">Holidays Controller > getIndiaTamilHolidays</div><div class="test-title">should return a list of holidays</div><div class="test-status">failed</div><div class="test-duration">0.049s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(received).toEqual(expected) // deep equality
|
71 |
-
|
72 |
-
- Expected - 8
|
73 |
-
+ Received + 0
|
74 |
-
|
75 |
-
Array [
|
76 |
-
Object {
|
77 |
-
- "date": "2025-01-01",
|
78 |
-
- "festival": "Holiday 1",
|
79 |
-
- },
|
80 |
-
- Object {
|
81 |
-
"date": "2025-02-01",
|
82 |
-
- "festival": "Holiday 2",
|
83 |
-
- },
|
84 |
-
- Object {
|
85 |
-
- "date": "2025-02-02",
|
86 |
-
"festival": "Holiday 2",
|
87 |
-
},
|
88 |
-
]
|
89 |
-
at toEqual (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/holidays.test.js:72:30)
|
90 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
91 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
92 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
93 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
94 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
95 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Holidays Controller > getIndiaTamilHolidays</div><div class="test-title">should return an error if OAuth credentials are missing</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Holidays Controller > getIndiaTamilHolidays</div><div class="test-title">should handle errors properly</div><div class="test-status">passed</div><div class="test-duration">0.011s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">Holidays Controller > refreshHolidays</div><div class="test-title">should refresh holidays and log them</div><div class="test-status">failed</div><div class="test-duration">0.013s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(jest.fn()).toHaveBeenCalledWith(...expected)
|
96 |
-
|
97 |
-
Expected: "Total holidays:", 3
|
98 |
-
Received
|
99 |
-
1: "Holiday:", "Holiday 2", 2025-02-02T00:00:00.000Z
|
100 |
-
2: "India Holidays:", [{"date": "2025-02-01", "festival": "Holiday 2"}]
|
101 |
-
3: "Total holidays:", 1
|
102 |
-
|
103 |
-
Number of calls: 5
|
104 |
-
at toHaveBeenCalledWith (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/holidays.test.js:100:35)
|
105 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
106 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
107 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
108 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
109 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
110 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Holidays Controller > refreshHolidays</div><div class="test-title">should handle retrying on error</div><div class="test-status">passed</div><div class="test-duration">0.006s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">Holidays Controller > isHoliday</div><div class="test-title">should return true if the date is a holiday</div><div class="test-status">failed</div><div class="test-duration">0.011s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(received).toBe(expected) // Object.is equality
|
111 |
-
|
112 |
-
Expected: true
|
113 |
-
Received: false
|
114 |
-
at toBe (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/holidays.test.js:118:28)
|
115 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
116 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
117 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
118 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
119 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
120 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Holidays Controller > isHoliday</div><div class="test-title">should return false if the date is not a holiday</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div></div></div><div id="suite-3" class="suite-container"><input id="collapsible-2" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-2"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demoRequestController.test.js</div><div class="suite-time">2.897s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should return 400 if required fields are missing</div><div class="test-status">passed</div><div class="test-duration">0.064s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should return 400 if demo request already exists within 15 days</div><div class="test-status">passed</div><div class="test-duration">0.037s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should insert a new demo request if no existing request is found</div><div class="test-status">failed</div><div class="test-duration">0.045s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'then')
|
121 |
-
at _callee$ (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/controller/demoRequestController.js:150:7)
|
122 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
123 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
124 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
125 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
126 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
127 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should send an email via Gmail API</div><div class="test-status">failed</div><div class="test-duration">0.01s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'then')
|
128 |
-
at _callee$ (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/controller/demoRequestController.js:150:7)
|
129 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
130 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
131 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
132 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
133 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
134 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should handle email sending failure gracefully</div><div class="test-status">failed</div><div class="test-duration">0.014s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'then')
|
135 |
-
at _callee$ (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/controller/demoRequestController.js:150:7)
|
136 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
137 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
138 |
-
at Generator.throw (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
139 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
140 |
-
at _throw (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:20:9)
|
141 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should call VAPI API with correct data</div><div class="test-status">failed</div><div class="test-duration">0.017s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(jest.fn()).toHaveBeenCalledWith(...expected)
|
142 |
-
|
143 |
-
- Expected
|
144 |
-
+ Received
|
145 |
-
|
146 |
-
"https://api.vapi.ai/call",
|
147 |
-
@@ -1,7 +1,7 @@
|
148 |
-
Object {
|
149 |
-
- "body": "{\"name\":\"+1234567890_2025-01-28_DRC\",\"assistantId\":\"undefined\",\"assistantOverrides\":{\"variableValues\":{\"name\":\"John Doe\",\"product_name\":\"Test Product\",\"demo_date\":\"2025-02-01\",\"slot\":\"10:00 - 11:00 (IST)\",\"comments\":\"Looking forward to it!\"}},\"customer\":{\"number\":\"+1234567890\"},\"phoneNumberId\":\"undefined\"}",
|
150 |
-
+ "body": "{\"name\":\"+1234567890_2025-01-29_DRC\",\"assistantId\":\"undefined\",\"assistantOverrides\":{\"variableValues\":{\"name\":\"John Doe\",\"product_name\":\"Test Product\",\"demo_date\":\"2025-02-01\",\"slot\":\"10:00 - 11:00 (IST)\",\"comments\":\"Looking forward to it!\"}},\"customer\":{\"number\":\"+1234567890\"},\"phoneNumberId\":\"undefined\"}",
|
151 |
-
"headers": Object {
|
152 |
-
"Authorization": "Bearer undefined",
|
153 |
-
"Content-Type": "application/json",
|
154 |
-
},
|
155 |
-
"method": "POST",,
|
156 |
-
|
157 |
-
Number of calls: 1
|
158 |
-
at toHaveBeenCalledWith (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demoRequestController.test.js:159:23)
|
159 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
160 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
161 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
162 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
163 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
164 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should correctly convert the selected time slot to Asia/Kolkata timezone</div><div class="test-status">failed</div><div class="test-duration">0.005s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'then')
|
165 |
-
at _callee$ (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/controller/demoRequestController.js:150:7)
|
166 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
167 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
168 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
169 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
170 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
171 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should return 400 if product field is missing</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should generate correctly formatted HTML email content</div><div class="test-status">failed</div><div class="test-duration">0.007s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'then')
|
172 |
-
at _callee$ (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/controller/demoRequestController.js:150:7)
|
173 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
174 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
175 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
176 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
177 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
178 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should handle fetch API error during VAPI call</div><div class="test-status">failed</div><div class="test-duration">0.047s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(jest.fn()).toHaveBeenCalledWith(...expected)
|
179 |
-
|
180 |
-
- Expected
|
181 |
-
+ Received
|
182 |
-
|
183 |
-
Object {
|
184 |
-
- "error": "Failed to send demo request confirmation email, however the demo request has been registered successfully!",
|
185 |
-
+ "message": "Demo request submitted successfully! Our team will get in touch with you soon.",
|
186 |
-
+ "response": Object {},
|
187 |
-
},
|
188 |
-
|
189 |
-
Number of calls: 1
|
190 |
-
at toHaveBeenCalledWith (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demoRequestController.test.js:263:26)
|
191 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
192 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
193 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
194 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
195 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
196 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">demoRequest Controller</div><div class="test-title">should correctly handle daylight saving time transitions for timezones</div><div class="test-status">failed</div><div class="test-duration">0.038s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'then')
|
197 |
-
at _callee$ (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/controller/demoRequestController.js:150:7)
|
198 |
-
at tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
199 |
-
at Generator.<anonymous> (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
200 |
-
at Generator.next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
201 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
202 |
-
at _next (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
203 |
-
at processTicksAndRejections (node:internal/process/task_queues:96:5)</pre></div></div></div></div><div id="suite-4" class="suite-container"><input id="collapsible-3" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-3"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/routes/applicantRoutes.test.js</div><div class="suite-time">0.87s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Applicant Routes</div><div class="test-title">should successfully submit a job application</div><div class="test-status">passed</div><div class="test-duration">0.056s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Applicant Routes</div><div class="test-title">should return 400 if no resume is provided</div><div class="test-status">passed</div><div class="test-duration">0.01s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Applicant Routes</div><div class="test-title">should handle errors gracefully</div><div class="test-status">passed</div><div class="test-duration">0.008s</div></div></div></div></div><div id="suite-5" class="suite-container"><input id="collapsible-4" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-4"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/contactController.test.js</div><div class="suite-time">0.741s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Contact Controller</div><div class="test-title">should handle contact form submission successfully</div><div class="test-status">passed</div><div class="test-duration">0.041s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Contact Controller</div><div class="test-title">should return error if contact request with same subject exists</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Contact Controller</div><div class="test-title">should return an error if required fields are missing</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Contact Controller</div><div class="test-title">should handle error when sending email fails</div><div class="test-status">passed</div><div class="test-duration">0.006s</div></div></div></div></div><div id="suite-6" class="suite-container"><input id="collapsible-5" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-5"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/applicantController.test.js</div><div class="suite-time">0.608s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">submitJobApplication</div><div class="test-title">should return an error if any required fields are missing</div><div class="test-status">passed</div><div class="test-duration">0.065s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">submitJobApplication</div><div class="test-title">should return an error if email format is invalid</div><div class="test-status">passed</div><div class="test-duration">0.009s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">submitJobApplication</div><div class="test-title">should refresh access token if needed</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">submitJobApplication</div><div class="test-title">should return an error if job application already exists</div><div class="test-status">passed</div><div class="test-duration">0.023s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">submitJobApplication</div><div class="test-title">should successfully submit job application and send an email</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">submitJobApplication</div><div class="test-title">should handle errors while sending the email</div><div class="test-status">passed</div><div class="test-duration">0.013s</div></div></div></div></div><div id="suite-7" class="suite-container"><input id="collapsible-6" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-6"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/db/jobRequestDB.test.js</div><div class="suite-time">0.529s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingJobApplication</div><div class="test-title">should return true if a job application with the same name, email, and role exists</div><div class="test-status">passed</div><div class="test-duration">0.022s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingJobApplication</div><div class="test-title">should return false if no job application with the same name, email, and role exists</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingJobApplication</div><div class="test-title">should handle database errors gracefully when checking for existing job applications</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">insertJobApplication</div><div class="test-title">should insert a job application successfully</div><div class="test-status">passed</div><div class="test-duration">0.015s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">insertJobApplication</div><div class="test-title">should handle errors properly if the insert query fails</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div></div></div><div id="suite-8" class="suite-container"><input id="collapsible-7" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-7"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/db/demoRequestDB.test.js</div><div class="suite-time">0.379s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingDemoRequest</div><div class="test-title">should return true if a demo request with the same name, email, product, demoDate, and phone exists</div><div class="test-status">passed</div><div class="test-duration">0.018s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingDemoRequest</div><div class="test-title">should return false if no demo request with the same name, email, product, demoDate, and phone exists</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingDemoRequest</div><div class="test-title">should handle database errors gracefully when checking existing demo requests</div><div class="test-status">passed</div><div class="test-duration">0.011s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">insertDemoRequest</div><div class="test-title">should insert a demo request successfully</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">insertDemoRequest</div><div class="test-title">should handle errors properly if the insert query fails</div><div class="test-status">passed</div><div class="test-duration">0.006s</div></div></div></div></div><div id="suite-9" class="suite-container"><input id="collapsible-8" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-8"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/dateAvailability.test.js</div><div class="suite-time">0.632s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Date Availability Module > checkDateAvailability</div><div class="test-title">should return true if the date is available (less than 11 bookings)</div><div class="test-status">passed</div><div class="test-duration">0.026s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Date Availability Module > checkDateAvailability</div><div class="test-title">should return false if the date is fully booked (11 or more bookings)</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Date Availability Module > checkDateAvailability</div><div class="test-title">should handle empty results gracefully</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Date Availability Module > getAvailableDates</div><div class="test-title">should return 14 available dates excluding holidays and weekends</div><div class="test-status">passed</div><div class="test-duration">0.079s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Date Availability Module > getAvailableDates</div><div class="test-title">should skip holidays, Sundays, and 1st/3rd/5th Saturdays</div><div class="test-status">passed</div><div class="test-duration">0.079s</div></div></div></div></div><div id="suite-10" class="suite-container"><input id="collapsible-9" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-9"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/db/contactRequestDB.test.js</div><div class="suite-time">0.429s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingContactRequest</div><div class="test-title">should return true if a contact request with the same name, email, and subject exists</div><div class="test-status">passed</div><div class="test-duration">0.025s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingContactRequest</div><div class="test-title">should return false if no contact request with the same name, email, and subject exists</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkExistingContactRequest</div><div class="test-title">should handle database errors gracefully when checking existing contact requests</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">insertContactRequest</div><div class="test-title">should insert a contact request successfully</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">insertContactRequest</div><div class="test-title">should handle errors properly if the insert query fails</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div></div></div><div id="suite-11" class="suite-container"><input id="collapsible-10" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-10"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/authController.test.js</div><div class="suite-time">2.675s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Google OAuth Controller</div><div class="test-title">should redirect to Google OAuth URL</div><div class="test-status">passed</div><div class="test-duration">0.025s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Google OAuth Controller</div><div class="test-title">should handle OAuth callback successfully and send a success message</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Google OAuth Controller</div><div class="test-title">should handle OAuth callback error and send failure message</div><div class="test-status">passed</div><div class="test-duration">0.014s</div></div></div></div></div><div id="suite-12" class="suite-container"><input id="collapsible-11" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-11"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/demo/utils.test.js</div><div class="suite-time">0.617s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Utils Controller > createDateTimeSlotMapping</div><div class="test-title">should map date-time to slots correctly</div><div class="test-status">passed</div><div class="test-duration">0.013s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Utils Controller > createDateTimeSlotMapping</div><div class="test-title">should return an empty object if no data is provided</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Utils Controller > createDateTimeSlotMapping</div><div class="test-title">should handle invalid date format gracefully</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Utils Controller > slotsInUserZone</div><div class="test-title">should convert slot times correctly for user timezone</div><div class="test-status">passed</div><div class="test-duration">0.053s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Utils Controller > getDatesSlots</div><div class="test-title">should organize slots by date correctly</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Utils Controller > getDatesSlots</div><div class="test-title">should handle empty input</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Utils Controller > getDatesSlots</div><div class="test-title">should handle invalid timestamp formats</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div></div></div><div id="suite-13" class="suite-container"><input id="collapsible-12" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-12"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/db.test.js</div><div class="suite-time">0.407s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">initializeDatabase</div><div class="test-title">should call runQuery for each table creation query</div><div class="test-status">passed</div><div class="test-duration">0.039s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">initializeDatabase</div><div class="test-title">should handle errors properly if runQuery fails</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">initializeDatabase</div><div class="test-title">should log successful table creation</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div></div></div><div id="suite-14" class="suite-container"><input id="collapsible-13" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-13"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/db/addSubscriber.test.js</div><div class="suite-time">0.418s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">addSubscriber</div><div class="test-title">should return an error if the email already exists</div><div class="test-status">passed</div><div class="test-duration">0.022s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">addSubscriber</div><div class="test-title">should add a new subscriber if the email does not exist</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">addSubscriber</div><div class="test-title">should handle errors properly if there is a database error</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">addSubscriber</div><div class="test-title">should log success message when a new subscriber is added</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">addSubscriber</div><div class="test-title">should log an error message if there is a database error</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div></div></div><div id="suite-15" class="suite-container"><input id="collapsible-14" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-14"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/controller/subscriptionController.test.js</div><div class="suite-time">0.503s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">handleSubscriptionEmail</div><div class="test-title">should return an error if email is missing</div><div class="test-status">passed</div><div class="test-duration">0.027s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">handleSubscriptionEmail</div><div class="test-title">should return an error if OAuth credentials are missing</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">handleSubscriptionEmail</div><div class="test-title">should successfully subscribe a user and send a subscription email</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">handleSubscriptionEmail</div><div class="test-title">should return an error if email is already in the database</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">handleSubscriptionEmail</div><div class="test-title">should handle error when sending email fails</div><div class="test-status">passed</div><div class="test-duration">0.007s</div></div></div></div></div><div id="suite-16" class="suite-container"><input id="collapsible-15" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-15"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/config/googleOAuth.test.js</div><div class="suite-time">0.303s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">googleOAuth client</div><div class="test-title">should initialize OAuth2 client with credentials from .env</div><div class="test-status">passed</div><div class="test-duration">0.024s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">googleOAuth client</div><div class="test-title">should call setCredentials on OAuth2 client with proper tokens</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">googleOAuth client</div><div class="test-title">should call refreshAccessToken and handle success</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">googleOAuth client</div><div class="test-title">should call refreshAccessToken and handle error</div><div class="test-status">passed</div><div class="test-duration">0.009s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">googleOAuth client</div><div class="test-title">should correctly check if the token is expiring</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div></div></div><div id="suite-17" class="suite-container"><input id="collapsible-16" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-16"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/testSetup.js</div><div class="suite-time">0s</div></div></label><div class="suite-tests"/></div><div id="suite-18" class="suite-container"><input id="collapsible-17" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-17"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/backend/__tests__/config/refreshTokens.test.js</div><div class="suite-time">0.38s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkAndRefreshAccessToken</div><div class="test-title">should use tokens from .env and set credentials</div><div class="test-status">passed</div><div class="test-duration">0.014s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkAndRefreshAccessToken</div><div class="test-title">should refresh tokens if the access token is expiring</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkAndRefreshAccessToken</div><div class="test-title">should log an error if token refresh fails</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">checkAndRefreshAccessToken</div><div class="test-title">should log a message if no tokens are found in .env</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div></div></div></div></body></html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/test-report/teststyle.css
DELETED
@@ -1,259 +0,0 @@
|
|
1 |
-
html,
|
2 |
-
body {
|
3 |
-
font-family: Arial, Helvetica, sans-serif;
|
4 |
-
font-size: 1rem;
|
5 |
-
margin: 0;
|
6 |
-
padding: 0;
|
7 |
-
color: #333;
|
8 |
-
}
|
9 |
-
body {
|
10 |
-
padding: 2rem 1rem;
|
11 |
-
font-size: 0.85rem;
|
12 |
-
}
|
13 |
-
.jesthtml-content {
|
14 |
-
margin: 0 auto;
|
15 |
-
max-width: 70rem;
|
16 |
-
}
|
17 |
-
header {
|
18 |
-
display: flex;
|
19 |
-
align-items: center;
|
20 |
-
}
|
21 |
-
#title {
|
22 |
-
margin: 0;
|
23 |
-
flex-grow: 1;
|
24 |
-
}
|
25 |
-
#logo {
|
26 |
-
height: 4rem;
|
27 |
-
}
|
28 |
-
#timestamp {
|
29 |
-
color: #777;
|
30 |
-
margin-top: 0.5rem;
|
31 |
-
}
|
32 |
-
|
33 |
-
/** SUMMARY */
|
34 |
-
#summary {
|
35 |
-
color: #333;
|
36 |
-
margin: 2rem 0;
|
37 |
-
display: flex;
|
38 |
-
font-family: monospace;
|
39 |
-
font-size: 1rem;
|
40 |
-
}
|
41 |
-
#summary > div {
|
42 |
-
margin-right: 2rem;
|
43 |
-
background: #eee;
|
44 |
-
padding: 1rem;
|
45 |
-
min-width: 15rem;
|
46 |
-
}
|
47 |
-
#summary > div:last-child {
|
48 |
-
margin-right: 0;
|
49 |
-
}
|
50 |
-
@media only screen and (max-width: 720px) {
|
51 |
-
#summary {
|
52 |
-
flex-direction: column;
|
53 |
-
}
|
54 |
-
#summary > div {
|
55 |
-
margin-right: 0;
|
56 |
-
margin-top: 2rem;
|
57 |
-
}
|
58 |
-
#summary > div:first-child {
|
59 |
-
margin-top: 0;
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
.summary-total {
|
64 |
-
font-weight: bold;
|
65 |
-
margin-bottom: 0.5rem;
|
66 |
-
}
|
67 |
-
.summary-passed {
|
68 |
-
color: #4f8a10;
|
69 |
-
border-left: 0.4rem solid #4f8a10;
|
70 |
-
padding-left: 0.5rem;
|
71 |
-
}
|
72 |
-
.summary-failed,
|
73 |
-
.summary-obsolete-snapshots {
|
74 |
-
color: #d8000c;
|
75 |
-
border-left: 0.4rem solid #d8000c;
|
76 |
-
padding-left: 0.5rem;
|
77 |
-
}
|
78 |
-
.summary-pending {
|
79 |
-
color: #9f6000;
|
80 |
-
border-left: 0.4rem solid #9f6000;
|
81 |
-
padding-left: 0.5rem;
|
82 |
-
}
|
83 |
-
.summary-empty {
|
84 |
-
color: #999;
|
85 |
-
border-left: 0.4rem solid #999;
|
86 |
-
}
|
87 |
-
|
88 |
-
.test-result {
|
89 |
-
padding: 1rem;
|
90 |
-
margin-bottom: 0.25rem;
|
91 |
-
}
|
92 |
-
.test-result:last-child {
|
93 |
-
border: 0;
|
94 |
-
}
|
95 |
-
.test-result.passed {
|
96 |
-
background-color: #dff2bf;
|
97 |
-
color: #4f8a10;
|
98 |
-
}
|
99 |
-
.test-result.failed {
|
100 |
-
background-color: #ffbaba;
|
101 |
-
color: #d8000c;
|
102 |
-
}
|
103 |
-
.test-result.pending {
|
104 |
-
background-color: #ffdf61;
|
105 |
-
color: #9f6000;
|
106 |
-
}
|
107 |
-
|
108 |
-
.test-info {
|
109 |
-
display: flex;
|
110 |
-
justify-content: space-between;
|
111 |
-
}
|
112 |
-
.test-suitename {
|
113 |
-
width: 20%;
|
114 |
-
text-align: left;
|
115 |
-
font-weight: bold;
|
116 |
-
word-break: break-word;
|
117 |
-
}
|
118 |
-
.test-title {
|
119 |
-
width: 40%;
|
120 |
-
text-align: left;
|
121 |
-
font-style: italic;
|
122 |
-
}
|
123 |
-
.test-status {
|
124 |
-
width: 20%;
|
125 |
-
text-align: right;
|
126 |
-
}
|
127 |
-
.test-duration {
|
128 |
-
width: 10%;
|
129 |
-
text-align: right;
|
130 |
-
font-size: 0.75rem;
|
131 |
-
}
|
132 |
-
|
133 |
-
.failureMessages {
|
134 |
-
padding: 0 1rem;
|
135 |
-
margin-top: 1rem;
|
136 |
-
border-top: 1px dashed #d8000c;
|
137 |
-
}
|
138 |
-
.failureMessages.suiteFailure {
|
139 |
-
border-top: none;
|
140 |
-
}
|
141 |
-
.failureMsg {
|
142 |
-
white-space: pre-wrap;
|
143 |
-
white-space: -moz-pre-wrap;
|
144 |
-
white-space: -pre-wrap;
|
145 |
-
white-space: -o-pre-wrap;
|
146 |
-
word-wrap: break-word;
|
147 |
-
}
|
148 |
-
|
149 |
-
.suite-container {
|
150 |
-
margin-bottom: 2rem;
|
151 |
-
}
|
152 |
-
.suite-container > input[type="checkbox"] {
|
153 |
-
position: absolute;
|
154 |
-
left: -100vw;
|
155 |
-
}
|
156 |
-
.suite-container label {
|
157 |
-
display: block;
|
158 |
-
}
|
159 |
-
.suite-container .suite-tests {
|
160 |
-
overflow-y: hidden;
|
161 |
-
height: 0;
|
162 |
-
}
|
163 |
-
.suite-container > input[type="checkbox"]:checked ~ .suite-tests {
|
164 |
-
height: auto;
|
165 |
-
overflow: visible;
|
166 |
-
}
|
167 |
-
.suite-info {
|
168 |
-
padding: 1rem;
|
169 |
-
background-color: #eee;
|
170 |
-
color: #777;
|
171 |
-
display: flex;
|
172 |
-
align-items: center;
|
173 |
-
margin-bottom: 0.25rem;
|
174 |
-
}
|
175 |
-
.suite-info:hover {
|
176 |
-
background-color: #ddd;
|
177 |
-
cursor: pointer;
|
178 |
-
}
|
179 |
-
.suite-info .suite-path {
|
180 |
-
word-break: break-all;
|
181 |
-
flex-grow: 1;
|
182 |
-
font-family: monospace;
|
183 |
-
font-size: 1rem;
|
184 |
-
}
|
185 |
-
.suite-info .suite-time {
|
186 |
-
margin-left: 0.5rem;
|
187 |
-
padding: 0.2rem 0.3rem;
|
188 |
-
font-size: 0.75rem;
|
189 |
-
}
|
190 |
-
.suite-info .suite-time.warn {
|
191 |
-
background-color: #d8000c;
|
192 |
-
color: #fff;
|
193 |
-
}
|
194 |
-
.suite-info:before {
|
195 |
-
content: "\2303";
|
196 |
-
display: inline-block;
|
197 |
-
margin-right: 0.5rem;
|
198 |
-
transform: rotate(0deg);
|
199 |
-
}
|
200 |
-
.suite-container > input[type="checkbox"]:checked ~ label .suite-info:before {
|
201 |
-
transform: rotate(180deg);
|
202 |
-
}
|
203 |
-
|
204 |
-
/* CONSOLE LOGS */
|
205 |
-
.suite-consolelog {
|
206 |
-
margin-bottom: 0.25rem;
|
207 |
-
padding: 1rem;
|
208 |
-
background-color: #efefef;
|
209 |
-
}
|
210 |
-
.suite-consolelog-header {
|
211 |
-
font-weight: bold;
|
212 |
-
}
|
213 |
-
.suite-consolelog-item {
|
214 |
-
padding: 0.5rem;
|
215 |
-
}
|
216 |
-
.suite-consolelog-item pre {
|
217 |
-
margin: 0.5rem 0;
|
218 |
-
white-space: pre-wrap;
|
219 |
-
white-space: -moz-pre-wrap;
|
220 |
-
white-space: -pre-wrap;
|
221 |
-
white-space: -o-pre-wrap;
|
222 |
-
word-wrap: break-word;
|
223 |
-
}
|
224 |
-
.suite-consolelog-item-origin {
|
225 |
-
color: #777;
|
226 |
-
font-weight: bold;
|
227 |
-
}
|
228 |
-
.suite-consolelog-item-message {
|
229 |
-
color: #000;
|
230 |
-
font-size: 1rem;
|
231 |
-
padding: 0 0.5rem;
|
232 |
-
}
|
233 |
-
|
234 |
-
/* OBSOLETE SNAPSHOTS */
|
235 |
-
.suite-obsolete-snapshots {
|
236 |
-
margin-bottom: 0.25rem;
|
237 |
-
padding: 1rem;
|
238 |
-
background-color: #ffbaba;
|
239 |
-
color: #d8000c;
|
240 |
-
}
|
241 |
-
.suite-obsolete-snapshots-header {
|
242 |
-
font-weight: bold;
|
243 |
-
}
|
244 |
-
.suite-obsolete-snapshots-item {
|
245 |
-
padding: 0.5rem;
|
246 |
-
}
|
247 |
-
.suite-obsolete-snapshots-item pre {
|
248 |
-
margin: 0.5rem 0;
|
249 |
-
white-space: pre-wrap;
|
250 |
-
white-space: -moz-pre-wrap;
|
251 |
-
white-space: -pre-wrap;
|
252 |
-
white-space: -o-pre-wrap;
|
253 |
-
word-wrap: break-word;
|
254 |
-
}
|
255 |
-
.suite-obsolete-snapshots-item-message {
|
256 |
-
color: #000;
|
257 |
-
font-size: 1rem;
|
258 |
-
padding: 0 0.5rem;
|
259 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backend/utils/sendEmail.js
CHANGED
@@ -55,6 +55,7 @@ const sendEmail = async (recipient, subject, htmlContent, attachment = null, att
|
|
55 |
console.log(`✅ Email sent successfully to ${recipient}`);
|
56 |
} catch (error) {
|
57 |
console.log(`❌ Failed to send email to ${recipient}:`, error);
|
|
|
58 |
}
|
59 |
};
|
60 |
|
|
|
55 |
console.log(`✅ Email sent successfully to ${recipient}`);
|
56 |
} catch (error) {
|
57 |
console.log(`❌ Failed to send email to ${recipient}:`, error);
|
58 |
+
throw error;
|
59 |
}
|
60 |
};
|
61 |
|
frontend/jest/mediaFileTransformer.js
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
const path = require('path');
|
2 |
-
|
3 |
-
// Mocks every media file to return its filename.
|
4 |
-
// Return just the file name without wrapping in an object
|
5 |
-
module.exports = {
|
6 |
-
process: (_, filename) => {
|
7 |
-
return `module.exports = '${path.basename(filename)}'`; // Return the filename as a string
|
8 |
-
},
|
9 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frontend/src/sections/contact/Forms.jsx
CHANGED
@@ -270,14 +270,13 @@ const ContactForm = ({ formType, demoProduct }) => {
|
|
270 |
? '/submit-contact-form'
|
271 |
: '/demo-request';
|
272 |
|
|
|
273 |
const response = await axios.post(endpoint, formData);
|
274 |
|
275 |
if (response.status >= 200 && response.status < 300) {
|
276 |
-
if (response.data.error === "
|
277 |
showCustomAlert(response.data.error);
|
278 |
-
}else if (response.data.error === '
|
279 |
-
showCustomAlert(response.data.error);
|
280 |
-
}else if (response.data.error === "Failed to send job application reception email, however your job application has been received successfully!") {
|
281 |
showCustomAlert(response.data.error);
|
282 |
}else if (response.data.error === "You have already requested a demo for this product within 15 days. Our team will get back to you shortly.") {
|
283 |
showCustomAlert(response.data.error);
|
@@ -428,10 +427,10 @@ const ContactForm = ({ formType, demoProduct }) => {
|
|
428 |
onChange={() => setConsent(!consent)}
|
429 |
required
|
430 |
/>
|
431 |
-
<
|
432 |
I consent to the processing of my submitted data in accordance with the{' '}
|
433 |
<a href="/privacy-policy" target="_blank" rel="noopener noreferrer"><i style={{color:"#00AA00"}}>Privacy Policy</i></a>.
|
434 |
-
</
|
435 |
</ConsentWrapper>
|
436 |
|
437 |
<SubmitButton type="submit">Submit Message</SubmitButton>
|
@@ -536,10 +535,10 @@ const ContactForm = ({ formType, demoProduct }) => {
|
|
536 |
onChange={() => setConsent(!consent)}
|
537 |
required
|
538 |
/>
|
539 |
-
<
|
540 |
I consent to the processing of my submitted data in accordance with the{' '}
|
541 |
<a href="/privacy-policy" target="_blank" rel="noopener noreferrer"><i style={{color:"#00AA00"}}>Privacy Policy</i></a>.
|
542 |
-
</
|
543 |
</ConsentWrapper>
|
544 |
|
545 |
<SubmitButton type="submit">Submit Demo Request</SubmitButton>
|
|
|
270 |
? '/submit-contact-form'
|
271 |
: '/demo-request';
|
272 |
|
273 |
+
showCustomAlert("Please wait.... Your submission is in progress");
|
274 |
const response = await axios.post(endpoint, formData);
|
275 |
|
276 |
if (response.status >= 200 && response.status < 300) {
|
277 |
+
if (response.data.error === "Unable to send demo request confirmation email, however the demo request has been registered successfully!") {
|
278 |
showCustomAlert(response.data.error);
|
279 |
+
}else if (response.data.error === 'Unable to send Contact request confirmation email, however request registered successfully!') {
|
|
|
|
|
280 |
showCustomAlert(response.data.error);
|
281 |
}else if (response.data.error === "You have already requested a demo for this product within 15 days. Our team will get back to you shortly.") {
|
282 |
showCustomAlert(response.data.error);
|
|
|
427 |
onChange={() => setConsent(!consent)}
|
428 |
required
|
429 |
/>
|
430 |
+
<label htmlFor="gdpr-consent">
|
431 |
I consent to the processing of my submitted data in accordance with the{' '}
|
432 |
<a href="/privacy-policy" target="_blank" rel="noopener noreferrer"><i style={{color:"#00AA00"}}>Privacy Policy</i></a>.
|
433 |
+
</label>
|
434 |
</ConsentWrapper>
|
435 |
|
436 |
<SubmitButton type="submit">Submit Message</SubmitButton>
|
|
|
535 |
onChange={() => setConsent(!consent)}
|
536 |
required
|
537 |
/>
|
538 |
+
<label htmlFor="gdpr-consent">
|
539 |
I consent to the processing of my submitted data in accordance with the{' '}
|
540 |
<a href="/privacy-policy" target="_blank" rel="noopener noreferrer"><i style={{color:"#00AA00"}}>Privacy Policy</i></a>.
|
541 |
+
</label>
|
542 |
</ConsentWrapper>
|
543 |
|
544 |
<SubmitButton type="submit">Submit Demo Request</SubmitButton>
|
frontend/src/sections/jobs/JobPageSection.jsx
CHANGED
@@ -5,7 +5,7 @@ import { createGlobalStyle } from 'styled-components';
|
|
5 |
import IntlTelInput from 'intl-tel-input/reactWithUtils';
|
6 |
import 'intl-tel-input/styles';
|
7 |
import axios from 'axios';
|
8 |
-
import { showCustomError, showCustomSuccess } from '../../utils/showalerts';
|
9 |
|
10 |
const GlobalStyles = createGlobalStyle`
|
11 |
.iti__country {
|
@@ -312,6 +312,7 @@ const JobPageSection = ({ job }) => {
|
|
312 |
formData.append('role', role); // Add role to the form data
|
313 |
formData.append('resume', document.getElementById('fileInput').files[0]);
|
314 |
|
|
|
315 |
const response = await axios.post('/submit-job-application', formData, {
|
316 |
headers: { 'Content-Type': 'multipart/form-data' }
|
317 |
});
|
@@ -349,7 +350,12 @@ const JobPageSection = ({ job }) => {
|
|
349 |
setFileName('');
|
350 |
setLinkedin('');
|
351 |
setConsent(false);
|
352 |
-
|
|
|
|
|
|
|
|
|
|
|
353 |
}
|
354 |
};
|
355 |
|
|
|
5 |
import IntlTelInput from 'intl-tel-input/reactWithUtils';
|
6 |
import 'intl-tel-input/styles';
|
7 |
import axios from 'axios';
|
8 |
+
import { showCustomAlert, showCustomError, showCustomSuccess } from '../../utils/showalerts';
|
9 |
|
10 |
const GlobalStyles = createGlobalStyle`
|
11 |
.iti__country {
|
|
|
312 |
formData.append('role', role); // Add role to the form data
|
313 |
formData.append('resume', document.getElementById('fileInput').files[0]);
|
314 |
|
315 |
+
showCustomAlert("Please wait.... Your submission is in progress");
|
316 |
const response = await axios.post('/submit-job-application', formData, {
|
317 |
headers: { 'Content-Type': 'multipart/form-data' }
|
318 |
});
|
|
|
350 |
setFileName('');
|
351 |
setLinkedin('');
|
352 |
setConsent(false);
|
353 |
+
if (error.response.data.error ==="Unable to send email for the confirmation of submission, but the application was received suvvessfully!"){
|
354 |
+
showCustomAlert("Unable to send email for the confirmation of submission, but the application was received suvvessfully!");
|
355 |
+
}else{
|
356 |
+
showCustomError(error.response.data.error || "An unexpected error occurred. Please try again.");
|
357 |
+
}
|
358 |
+
|
359 |
}
|
360 |
};
|
361 |
|
frontend/test-report/index.html
DELETED
@@ -1,459 +0,0 @@
|
|
1 |
-
<html><head><meta charset="utf-8"/><title>Unit tests</title><link rel="stylesheet" type="text/css" href="teststyle.css"/></head><body><div class="jesthtml-content"><header><h1 id="title">Unit tests</h1></header><div id="metadata-container"><div id="timestamp">Started: 2025-01-29 12:43:25</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (17)</div><div class="summary-passed ">16 passed</div><div class="summary-failed ">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (95)</div><div class="summary-passed ">89 passed</div><div class="summary-failed ">6 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><input id="collapsible-0" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-0"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/blogs/BlogPage.test.jsx</div><div class="suite-time warn">33.28s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPage Component</div><div class="test-title">renders blog post when valid slug is provided</div><div class="test-status">passed</div><div class="test-duration">0.311s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPage Component</div><div class="test-title">shows error and redirects for invalid slug</div><div class="test-status">passed</div><div class="test-duration">2.015s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPage Component</div><div class="test-title">redirects to blogs page when post not found</div><div class="test-status">passed</div><div class="test-duration">2.009s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPageSection Component</div><div class="test-title">renders all content types correctly</div><div class="test-status">passed</div><div class="test-duration">0.054s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPageSection Component</div><div class="test-title">handles missing post data gracefully</div><div class="test-status">passed</div><div class="test-duration">0.036s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPageSection Component</div><div class="test-title">renders social sharing buttons with correct hrefs</div><div class="test-status">passed</div><div class="test-duration">0.042s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPageSection Component</div><div class="test-title">handles empty content array gracefully</div><div class="test-status">passed</div><div class="test-duration">0.016s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BlogPageSection Component</div><div class="test-title">handles missing optional content fields gracefully</div><div class="test-status">passed</div><div class="test-duration">0.026s</div></div></div></div></div><div id="suite-2" class="suite-container"><input id="collapsible-1" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-1"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/jobs/JobPage.test.jsx</div><div class="suite-time warn">48.191s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPage Component</div><div class="test-title">should render job data correctly when a valid slug is provided</div><div class="test-status">passed</div><div class="test-duration">1.481s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPage Component</div><div class="test-title">should display an error message when an invalid slug is provided</div><div class="test-status">passed</div><div class="test-duration">0.031s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPage Component</div><div class="test-title">should redirect to /jobs if job data is not found</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPageSection Component</div><div class="test-title">should render job description correctly</div><div class="test-status">passed</div><div class="test-duration">0.355s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPageSection Component</div><div class="test-title">should show error if email is invalid</div><div class="test-status">passed</div><div class="test-duration">5.282s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPageSection Component</div><div class="test-title">should show error if phone number is invalid</div><div class="test-status">passed</div><div class="test-duration">5.268s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPageSection Component</div><div class="test-title">should show success message on valid form submission</div><div class="test-status">passed</div><div class="test-duration">5.319s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPageSection Component</div><div class="test-title">should show error when the file type is invalid</div><div class="test-status">passed</div><div class="test-duration">5.137s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobPageSection Component</div><div class="test-title">should reset the form fields after successful submission</div><div class="test-status">passed</div><div class="test-duration">5.279s</div></div></div></div></div><div id="suite-3" class="suite-container"><input id="collapsible-2" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-2"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactForm.test.jsx</div><div class="suite-time warn">86.826s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">ContactForm Component > General Enquiry > Form Rendering</div><div class="test-title">renders general enquiry form fields correctly</div><div class="test-status">passed</div><div class="test-duration">0.736s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">ContactForm Component > General Enquiry > Validation Tests</div><div class="test-title">validates email format correctly</div><div class="test-status">passed</div><div class="test-duration">7.031s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">ContactForm Component > General Enquiry > Validation Tests</div><div class="test-title">validates phone number correctly</div><div class="test-status">passed</div><div class="test-duration">7.281s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">ContactForm Component > General Enquiry > Form Submission</div><div class="test-title">submits the form with valid input</div><div class="test-status">failed</div><div class="test-duration">3.997s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(element).toHaveTextContent()
|
2 |
-
|
3 |
-
Expected element to have text content:
|
4 |
-
Contact message sent successfully!
|
5 |
-
Received:
|
6 |
-
Please enter a valid phone number.
|
7 |
-
|
8 |
-
Ignored nodes: comments, script, style
|
9 |
-
<html>
|
10 |
-
<head />
|
11 |
-
<body>
|
12 |
-
<div>
|
13 |
-
<form
|
14 |
-
aria-label="general"
|
15 |
-
class="sc-blHHSb hUXMOf"
|
16 |
-
data-testid="formFields"
|
17 |
-
>
|
18 |
-
<input
|
19 |
-
class="sc-gtLWhw jSyAJc"
|
20 |
-
placeholder="Your Name"
|
21 |
-
required=""
|
22 |
-
type="text"
|
23 |
-
value="John Doe"
|
24 |
-
/>
|
25 |
-
<input
|
26 |
-
class="sc-gtLWhw jSyAJc"
|
27 |
-
placeholder="Your Email"
|
28 |
-
required=""
|
29 |
-
type="email"
|
30 |
-
value="[email protected]"
|
31 |
-
/>
|
32 |
-
<div
|
33 |
-
class="iti iti--allow-dropdown iti--show-flags iti--inline-dropdown"
|
34 |
-
>
|
35 |
-
<div
|
36 |
-
class="iti__country-container"
|
37 |
-
style="left: 0px;"
|
38 |
-
>
|
39 |
-
<button
|
40 |
-
aria-controls="iti-3__dropdown-content"
|
41 |
-
aria-expanded="false"
|
42 |
-
aria-haspopup="true"
|
43 |
-
aria-label="Selected country"
|
44 |
-
class="iti__selected-country"
|
45 |
-
role="combobox"
|
46 |
-
title="India"
|
47 |
-
type="button"
|
48 |
-
>
|
49 |
-
<div
|
50 |
-
class="iti__selected-country-primary"
|
51 |
-
>
|
52 |
-
<div
|
53 |
-
class="iti__flag iti__in"
|
54 |
-
>
|
55 |
-
<span
|
56 |
-
class="iti__a11y-text"
|
57 |
-
>
|
58 |
-
India +91
|
59 |
-
</span>
|
60 |
-
</div>
|
61 |
-
<div
|
62 |
-
aria-hidden="true"
|
63 |
-
class="iti__arrow"
|
64 |
-
/>
|
65 |
-
</div>
|
66 |
-
<div
|
67 |
-
class="iti__selected-dial-code"
|
68 |
-
>
|
69 |
-
+91
|
70 |
-
</div>
|
71 |
-
</button>
|
72 |
-
<div
|
73 |
-
class="iti__dropdown-content iti__hide "
|
74 |
-
id="iti-3__dropdown-content"
|
75 |
-
>
|
76 |
-
<input
|
77 |
-
aria-autocomplete="list"
|
78 |
-
aria-controls="iti-3__country-listbox"
|
79 |
-
aria-expanded="true"
|
80 |
-
aria-label="Search"
|
81 |
-
autocomplete="off"
|
82 |
-
class="iti__search-input"
|
83 |
-
placeholder="Search"
|
84 |
-
role="combobox"
|
85 |
-
type="text"
|
86 |
-
/>
|
87 |
-
<span
|
88 |
-
class="iti__a11y-text"
|
89 |
-
>
|
90 |
-
244 results found
|
91 |
-
</span>
|
92 |
-
<ul
|
93 |
-
aria-label="List of countries"
|
94 |
-
class="iti__country-list"
|
95 |
-
id="iti-3__country-listbox"
|
96 |
-
role="listbox"
|
97 |
-
>
|
98 |
-
<li
|
99 |
-
aria-selected="false"
|
100 |
-
class="iti__country iti__highlight"
|
101 |
-
data-country-code="af"
|
102 |
-
data-dial-code="93"
|
103 |
-
id="iti-3__item-af"
|
104 |
-
role="option"
|
105 |
-
tabindex="-1"
|
106 |
-
>
|
107 |
-
<div
|
108 |
-
class="iti__flag iti__af"
|
109 |
-
/>
|
110 |
-
<span
|
111 |
-
class="iti__country-name"
|
112 |
-
>
|
113 |
-
Afghanistan
|
114 |
-
</span>
|
115 |
-
<span
|
116 |
-
class="iti__dial-code"
|
117 |
-
>
|
118 |
-
+93
|
119 |
-
</span>
|
120 |
-
</li>
|
121 |
-
<li
|
122 |
-
aria-selected="false"
|
123 |
-
class="iti__country "
|
124 |
-
data-country-code="ax"
|
125 |
-
data-dial-code="358"
|
126 |
-
id="iti-3__item-ax"
|
127 |
-
role="option"
|
128 |
-
tabindex="-1"
|
129 |
-
>
|
130 |
-
<div
|
131 |
-
class="iti__flag iti__ax"
|
132 |
-
/>
|
133 |
-
<span
|
134 |
-
class="iti__country-name"
|
135 |
-
>
|
136 |
-
Åland Islands
|
137 |
-
</span>
|
138 |
-
<span
|
139 |
-
class="iti__dial-code"
|
140 |
-
>
|
141 |
-
+358
|
142 |
-
</span>
|
143 |
-
</li>
|
144 |
-
<li
|
145 |
-
aria-selected="false"
|
146 |
-
class="iti__country "
|
147 |
-
data-country-code="al"
|
148 |
-
data-dial-code="355"
|
149 |
-
id="iti-3__item-al"
|
150 |
-
role="option"
|
151 |
-
tabindex="-1"
|
152 |
-
>
|
153 |
-
<div
|
154 |
-
class="iti__flag iti__al"
|
155 |
-
/>
|
156 |
-
<span
|
157 |
-
class="iti__country-name"
|
158 |
-
>
|
159 |
-
Albania
|
160 |
-
</span>
|
161 |
-
<span
|
162 |
-
class="iti__dial-code"
|
163 |
-
>
|
164 |
-
+355
|
165 |
-
</span>
|
166 |
-
</li>
|
167 |
-
<li
|
168 |
-
aria-selected="false...
|
169 |
-
at toHaveTextContent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactForm.test.jsx:146:51)
|
170 |
-
at callback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/config.js:47:12)
|
171 |
-
at _checkCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/wait-for.js:124:76)
|
172 |
-
at checkCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/wait-for.js:118:16)
|
173 |
-
at Timeout.task [as _onTimeout] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
|
174 |
-
at listOnTimeout (node:internal/timers:559:17)
|
175 |
-
at processTimers (node:internal/timers:502:7)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">ContactForm Component > General Enquiry > Form Submission</div><div class="test-title">shows error when API request fails</div><div class="test-status">failed</div><div class="test-duration">2.692s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: expect(element).toHaveTextContent()
|
176 |
-
|
177 |
-
Expected element to have text content:
|
178 |
-
Something went wrong
|
179 |
-
Received:
|
180 |
-
Please enter a valid phone number.
|
181 |
-
|
182 |
-
Ignored nodes: comments, script, style
|
183 |
-
<html>
|
184 |
-
<head />
|
185 |
-
<body>
|
186 |
-
<div>
|
187 |
-
<form
|
188 |
-
aria-label="general"
|
189 |
-
class="sc-blHHSb hUXMOf"
|
190 |
-
data-testid="formFields"
|
191 |
-
>
|
192 |
-
<input
|
193 |
-
class="sc-gtLWhw jSyAJc"
|
194 |
-
placeholder="Your Name"
|
195 |
-
required=""
|
196 |
-
type="text"
|
197 |
-
value="John Doe"
|
198 |
-
/>
|
199 |
-
<input
|
200 |
-
class="sc-gtLWhw jSyAJc"
|
201 |
-
placeholder="Your Email"
|
202 |
-
required=""
|
203 |
-
type="email"
|
204 |
-
value="[email protected]"
|
205 |
-
/>
|
206 |
-
<div
|
207 |
-
class="iti iti--allow-dropdown iti--show-flags iti--inline-dropdown"
|
208 |
-
>
|
209 |
-
<div
|
210 |
-
class="iti__country-container"
|
211 |
-
style="left: 0px;"
|
212 |
-
>
|
213 |
-
<button
|
214 |
-
aria-controls="iti-4__dropdown-content"
|
215 |
-
aria-expanded="false"
|
216 |
-
aria-haspopup="true"
|
217 |
-
aria-label="Selected country"
|
218 |
-
class="iti__selected-country"
|
219 |
-
role="combobox"
|
220 |
-
title="India"
|
221 |
-
type="button"
|
222 |
-
>
|
223 |
-
<div
|
224 |
-
class="iti__selected-country-primary"
|
225 |
-
>
|
226 |
-
<div
|
227 |
-
class="iti__flag iti__in"
|
228 |
-
>
|
229 |
-
<span
|
230 |
-
class="iti__a11y-text"
|
231 |
-
>
|
232 |
-
India +91
|
233 |
-
</span>
|
234 |
-
</div>
|
235 |
-
<div
|
236 |
-
aria-hidden="true"
|
237 |
-
class="iti__arrow"
|
238 |
-
/>
|
239 |
-
</div>
|
240 |
-
<div
|
241 |
-
class="iti__selected-dial-code"
|
242 |
-
>
|
243 |
-
+91
|
244 |
-
</div>
|
245 |
-
</button>
|
246 |
-
<div
|
247 |
-
class="iti__dropdown-content iti__hide "
|
248 |
-
id="iti-4__dropdown-content"
|
249 |
-
>
|
250 |
-
<input
|
251 |
-
aria-autocomplete="list"
|
252 |
-
aria-controls="iti-4__country-listbox"
|
253 |
-
aria-expanded="true"
|
254 |
-
aria-label="Search"
|
255 |
-
autocomplete="off"
|
256 |
-
class="iti__search-input"
|
257 |
-
placeholder="Search"
|
258 |
-
role="combobox"
|
259 |
-
type="text"
|
260 |
-
/>
|
261 |
-
<span
|
262 |
-
class="iti__a11y-text"
|
263 |
-
>
|
264 |
-
244 results found
|
265 |
-
</span>
|
266 |
-
<ul
|
267 |
-
aria-label="List of countries"
|
268 |
-
class="iti__country-list"
|
269 |
-
id="iti-4__country-listbox"
|
270 |
-
role="listbox"
|
271 |
-
>
|
272 |
-
<li
|
273 |
-
aria-selected="false"
|
274 |
-
class="iti__country iti__highlight"
|
275 |
-
data-country-code="af"
|
276 |
-
data-dial-code="93"
|
277 |
-
id="iti-4__item-af"
|
278 |
-
role="option"
|
279 |
-
tabindex="-1"
|
280 |
-
>
|
281 |
-
<div
|
282 |
-
class="iti__flag iti__af"
|
283 |
-
/>
|
284 |
-
<span
|
285 |
-
class="iti__country-name"
|
286 |
-
>
|
287 |
-
Afghanistan
|
288 |
-
</span>
|
289 |
-
<span
|
290 |
-
class="iti__dial-code"
|
291 |
-
>
|
292 |
-
+93
|
293 |
-
</span>
|
294 |
-
</li>
|
295 |
-
<li
|
296 |
-
aria-selected="false"
|
297 |
-
class="iti__country "
|
298 |
-
data-country-code="ax"
|
299 |
-
data-dial-code="358"
|
300 |
-
id="iti-4__item-ax"
|
301 |
-
role="option"
|
302 |
-
tabindex="-1"
|
303 |
-
>
|
304 |
-
<div
|
305 |
-
class="iti__flag iti__ax"
|
306 |
-
/>
|
307 |
-
<span
|
308 |
-
class="iti__country-name"
|
309 |
-
>
|
310 |
-
Åland Islands
|
311 |
-
</span>
|
312 |
-
<span
|
313 |
-
class="iti__dial-code"
|
314 |
-
>
|
315 |
-
+358
|
316 |
-
</span>
|
317 |
-
</li>
|
318 |
-
<li
|
319 |
-
aria-selected="false"
|
320 |
-
class="iti__country "
|
321 |
-
data-country-code="al"
|
322 |
-
data-dial-code="355"
|
323 |
-
id="iti-4__item-al"
|
324 |
-
role="option"
|
325 |
-
tabindex="-1"
|
326 |
-
>
|
327 |
-
<div
|
328 |
-
class="iti__flag iti__al"
|
329 |
-
/>
|
330 |
-
<span
|
331 |
-
class="iti__country-name"
|
332 |
-
>
|
333 |
-
Albania
|
334 |
-
</span>
|
335 |
-
<span
|
336 |
-
class="iti__dial-code"
|
337 |
-
>
|
338 |
-
+355
|
339 |
-
</span>
|
340 |
-
</li>
|
341 |
-
<li
|
342 |
-
aria-selected="false...
|
343 |
-
at toHaveTextContent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactForm.test.jsx:174:51)
|
344 |
-
at callback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/config.js:47:12)
|
345 |
-
at _checkCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/wait-for.js:124:76)
|
346 |
-
at checkCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/wait-for.js:118:16)
|
347 |
-
at Timeout.task [as _onTimeout] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
|
348 |
-
at listOnTimeout (node:internal/timers:559:17)
|
349 |
-
at processTimers (node:internal/timers:502:7)</pre></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">ContactForm Component > Demo Request > Form Rendering</div><div class="test-title">renders demo request form fields correctly</div><div class="test-status">passed</div><div class="test-duration">0.149s</div></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">ContactForm Component > Demo Request > Validation Tests</div><div class="test-title">validates email format correctly</div><div class="test-status">failed</div><div class="test-duration">24.197s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'includes')
|
350 |
-
at includes (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/sections/contact/Forms.jsx:173:27)
|
351 |
-
at filterDate (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/date_utils.ts:810:21)
|
352 |
-
at Day.isDayDisabled [as isDisabled] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:204:5)
|
353 |
-
at Day.isDisabled [as getClassNames] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:417:49)
|
354 |
-
at Day.getClassNames [as render] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:562:23)
|
355 |
-
at render (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19781:31)
|
356 |
-
at finishClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19727:24)
|
357 |
-
at updateClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:21650:16)
|
358 |
-
at beginWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:27465:14)
|
359 |
-
at beginWork$1 (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26599:12)
|
360 |
-
at performUnitOfWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26505:5)
|
361 |
-
at workLoopSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26473:7)
|
362 |
-
at renderRootSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25889:20)
|
363 |
-
at recoverFromConcurrentError (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25789:22)
|
364 |
-
at callback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:266:34)
|
365 |
-
at workLoop (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:239:14)
|
366 |
-
at scheduledHostCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:533:21)
|
367 |
-
at Timeout.task [as _onTimeout] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
|
368 |
-
at listOnTimeout (node:internal/timers:559:17)
|
369 |
-
at processTimers (node:internal/timers:502:7)</pre><pre class="failureMsg">TypeError: Cannot read properties of null (reading 'querySelectorAll')
|
370 |
-
at querySelectorAll (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactForm.test.jsx:219:36)
|
371 |
-
at call (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
372 |
-
at Generator.tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
373 |
-
at Generator._invoke [as next] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
374 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
375 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
|
376 |
-
at runNextTicks (node:internal/process/task_queues:61:5)
|
377 |
-
at processTimers (node:internal/timers:499:9)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">ContactForm Component > Demo Request > Validation Tests</div><div class="test-title">validates phone number correctly</div><div class="test-status">failed</div><div class="test-duration">4.77s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'includes')
|
378 |
-
at includes (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/sections/contact/Forms.jsx:173:27)
|
379 |
-
at filterDate (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/date_utils.ts:810:21)
|
380 |
-
at Day.isDayDisabled [as isDisabled] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:204:5)
|
381 |
-
at Day.isDisabled [as getClassNames] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:417:49)
|
382 |
-
at Day.getClassNames [as render] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:562:23)
|
383 |
-
at render (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19781:31)
|
384 |
-
at finishClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19727:24)
|
385 |
-
at updateClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:21650:16)
|
386 |
-
at beginWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:27465:14)
|
387 |
-
at beginWork$1 (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26599:12)
|
388 |
-
at performUnitOfWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26505:5)
|
389 |
-
at workLoopSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26473:7)
|
390 |
-
at renderRootSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25889:20)
|
391 |
-
at recoverFromConcurrentError (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25789:22)
|
392 |
-
at callback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:266:34)
|
393 |
-
at workLoop (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:239:14)
|
394 |
-
at scheduledHostCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:533:21)
|
395 |
-
at Timeout.task [as _onTimeout] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
|
396 |
-
at listOnTimeout (node:internal/timers:559:17)
|
397 |
-
at processTimers (node:internal/timers:502:7)</pre><pre class="failureMsg">TypeError: Cannot read properties of null (reading 'querySelectorAll')
|
398 |
-
at querySelectorAll (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactForm.test.jsx:275:36)
|
399 |
-
at call (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
400 |
-
at Generator.tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
401 |
-
at Generator._invoke [as next] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
402 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
403 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">ContactForm Component > Demo Request > Form Submission</div><div class="test-title">submits the demo request form with valid input</div><div class="test-status">failed</div><div class="test-duration">0.24s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'includes')
|
404 |
-
at includes (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/sections/contact/Forms.jsx:173:27)
|
405 |
-
at filterDate (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/date_utils.ts:810:21)
|
406 |
-
at Day.isDayDisabled [as isDisabled] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:204:5)
|
407 |
-
at Day.isDisabled [as getClassNames] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:417:49)
|
408 |
-
at Day.getClassNames [as render] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:562:23)
|
409 |
-
at render (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19781:31)
|
410 |
-
at finishClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19727:24)
|
411 |
-
at updateClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:21650:16)
|
412 |
-
at beginWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:27465:14)
|
413 |
-
at beginWork$1 (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26599:12)
|
414 |
-
at performUnitOfWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26505:5)
|
415 |
-
at workLoopSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26473:7)
|
416 |
-
at renderRootSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25889:20)
|
417 |
-
at recoverFromConcurrentError (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25789:22)
|
418 |
-
at callback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:266:34)
|
419 |
-
at workLoop (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:239:14)
|
420 |
-
at scheduledHostCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:533:21)
|
421 |
-
at Timeout.task [as _onTimeout] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
|
422 |
-
at listOnTimeout (node:internal/timers:559:17)
|
423 |
-
at processTimers (node:internal/timers:502:7)</pre><pre class="failureMsg">TypeError: Cannot read properties of null (reading 'querySelectorAll')
|
424 |
-
at querySelectorAll (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactForm.test.jsx:334:36)
|
425 |
-
at call (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
426 |
-
at Generator.tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
427 |
-
at Generator._invoke [as next] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
428 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
429 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)</pre></div></div><div class="test-result failed"><div class="test-info"><div class="test-suitename">ContactForm Component > Demo Request > Form Submission</div><div class="test-title">shows error when API request fails</div><div class="test-status">failed</div><div class="test-duration">0.251s</div></div><div class="failureMessages"> <pre class="failureMsg">TypeError: Cannot read properties of undefined (reading 'includes')
|
430 |
-
at includes (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/sections/contact/Forms.jsx:173:27)
|
431 |
-
at filterDate (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/date_utils.ts:810:21)
|
432 |
-
at Day.isDayDisabled [as isDisabled] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:204:5)
|
433 |
-
at Day.isDisabled [as getClassNames] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:417:49)
|
434 |
-
at Day.getClassNames [as render] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-datepicker/src/day.tsx:562:23)
|
435 |
-
at render (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19781:31)
|
436 |
-
at finishClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:19727:24)
|
437 |
-
at updateClassComponent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:21650:16)
|
438 |
-
at beginWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:27465:14)
|
439 |
-
at beginWork$1 (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26599:12)
|
440 |
-
at performUnitOfWork (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26505:5)
|
441 |
-
at workLoopSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:26473:7)
|
442 |
-
at renderRootSync (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25889:20)
|
443 |
-
at recoverFromConcurrentError (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/react-dom/cjs/react-dom.development.js:25789:22)
|
444 |
-
at callback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:266:34)
|
445 |
-
at workLoop (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:239:14)
|
446 |
-
at scheduledHostCallback (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/scheduler/cjs/scheduler.development.js:533:21)
|
447 |
-
at Timeout.task [as _onTimeout] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/jsdom/lib/jsdom/browser/Window.js:520:19)
|
448 |
-
at listOnTimeout (node:internal/timers:559:17)
|
449 |
-
at processTimers (node:internal/timers:502:7)</pre><pre class="failureMsg">Error: Unable to fire a "click" event - please provide a DOM element.
|
450 |
-
at createEvent (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/events.js:27:11)
|
451 |
-
at Function.createEvent [as click] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/events.js:106:38)
|
452 |
-
at Function.fireEvent.<computed> [as click] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/dom/dist/events.js:110:68)
|
453 |
-
at Function.apply (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@testing-library/react/dist/fire-event.js:15:52)
|
454 |
-
at click (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactForm.test.jsx:402:19)
|
455 |
-
at call (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:45:16)
|
456 |
-
at Generator.tryCatch (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:133:17)
|
457 |
-
at Generator._invoke [as next] (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:74:21)
|
458 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
|
459 |
-
at asyncGeneratorStep (/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)</pre></div></div></div></div><div id="suite-4" class="suite-container"><input id="collapsible-3" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-3"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/about/VarDiGSection.test.jsx</div><div class="suite-time warn">38.089s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">renders the VarDiGSection component</div><div class="test-status">passed</div><div class="test-duration">0.063s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">applies the correct styles to the title</div><div class="test-status">passed</div><div class="test-duration">0.081s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">justifies the text in the paragraph</div><div class="test-status">passed</div><div class="test-duration">0.015s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">displays bullet points in two columns for larger screens</div><div class="test-status">passed</div><div class="test-duration">0.059s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">displays the check circle icon in each bullet point</div><div class="test-status">passed</div><div class="test-duration">0.035s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">displays the image with correct styles</div><div class="test-status">passed</div><div class="test-duration">0.014s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">adjusts layout for small screens</div><div class="test-status">passed</div><div class="test-duration">0.013s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VarDiGSection</div><div class="test-title">applies the correct background color to the container</div><div class="test-status">passed</div><div class="test-duration">0.017s</div></div></div></div></div><div id="suite-5" class="suite-container"><input id="collapsible-4" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-4"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/vardig/VideoCarousel.test.jsx</div><div class="suite-time warn">79.662s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">VideoCarousel Component</div><div class="test-title">renders the video carousel with videos</div><div class="test-status">passed</div><div class="test-duration">0.057s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VideoCarousel Component</div><div class="test-title">handles the end of a video and moves to the next one</div><div class="test-status">passed</div><div class="test-duration">0.3s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VideoCarousel Component</div><div class="test-title">resets the carousel when the last video ends</div><div class="test-status">passed</div><div class="test-duration">0.031s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VideoCarousel Component</div><div class="test-title">moves to the next video after the current one ends</div><div class="test-status">passed</div><div class="test-duration">0.106s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">VideoCarousel Component</div><div class="test-title">calls GSAP context animations on render</div><div class="test-status">passed</div><div class="test-duration">0.012s</div></div></div></div></div><div id="suite-6" class="suite-container"><input id="collapsible-5" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-5"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/Header.test.jsx</div><div class="suite-time warn">93.198s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">renders Header with logo</div><div class="test-status">passed</div><div class="test-duration">0.063s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">renders desktop navigation links</div><div class="test-status">passed</div><div class="test-duration">0.104s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">renders mobile menu button</div><div class="test-status">passed</div><div class="test-duration">0.024s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">opens and closes mobile menu when button is clicked</div><div class="test-status">passed</div><div class="test-duration">0.054s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">opens and closes mobile menu when button is clicked</div><div class="test-status">passed</div><div class="test-duration">0.029s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">closes mobile menu when clicking outside</div><div class="test-status">passed</div><div class="test-duration">0.026s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">closes mobile menu when navigating to a new route</div><div class="test-status">passed</div><div class="test-duration">0.065s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">closes the menu when clicking outside in mobile view</div><div class="test-status">passed</div><div class="test-duration">0.021s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">navigates to correct paths on link click</div><div class="test-status">passed</div><div class="test-duration">0.046s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">renders home link correctly in the mobile menu</div><div class="test-status">passed</div><div class="test-duration">0.042s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Header component</div><div class="test-title">mobile menu links close the menu when clicked</div><div class="test-status">passed</div><div class="test-duration">0.055s</div></div></div></div></div><div id="suite-7" class="suite-container"><input id="collapsible-6" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-6"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/blogs/Blogsection.test.jsx</div><div class="suite-time">2.659s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Blogsection Component</div><div class="test-title">should render correct number of BlogCard components</div><div class="test-status">passed</div><div class="test-duration">0.092s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Blogsection Component</div><div class="test-title">should display blog data correctly</div><div class="test-status">passed</div><div class="test-duration">0.058s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Blogsection Component</div><div class="test-title">should adjust grid layout based on screen size</div><div class="test-status">passed</div><div class="test-duration">0.14s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Blogsection Component</div><div class="test-title">should apply correct grid styles</div><div class="test-status">passed</div><div class="test-duration">0.031s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Blogsection Component</div><div class="test-title">should render BlogCards with correct data</div><div class="test-status">passed</div><div class="test-duration">0.019s</div></div></div></div></div><div id="suite-8" class="suite-container"><input id="collapsible-7" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-7"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/vardig/Pricing.test.jsx</div><div class="suite-time">2.12s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Pricing Component</div><div class="test-title">renders the Pricing component with title and toggle buttons</div><div class="test-status">passed</div><div class="test-duration">0.608s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Pricing Component</div><div class="test-title">renders all pricing cards with correct data</div><div class="test-status">passed</div><div class="test-duration">0.046s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Pricing Component</div><div class="test-title">toggles between monthly and yearly pricing</div><div class="test-status">passed</div><div class="test-duration">0.061s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Pricing Component</div><div class="test-title">displays the correct features for each plan</div><div class="test-status">passed</div><div class="test-duration">0.048s</div></div></div></div></div><div id="suite-9" class="suite-container"><input id="collapsible-8" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-8"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/jobs/Jobsection.test.jsx</div><div class="suite-time">2.997s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobSection Component</div><div class="test-title">should render correct number of JobCard components</div><div class="test-status">passed</div><div class="test-duration">0.186s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobSection Component</div><div class="test-title">should display job data correctly</div><div class="test-status">passed</div><div class="test-duration">0.029s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobSection Component</div><div class="test-title">should adjust grid layout based on screen size</div><div class="test-status">passed</div><div class="test-duration">0.023s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">JobSection Component</div><div class="test-title">should apply correct grid styles</div><div class="test-status">passed</div><div class="test-duration">0.021s</div></div></div></div></div><div id="suite-10" class="suite-container"><input id="collapsible-9" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-9"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/showAlerts.test.jsx</div><div class="suite-time">0.443s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Alert Functions</div><div class="test-title">should create a custom alert with the correct styles</div><div class="test-status">passed</div><div class="test-duration">0.016s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Alert Functions</div><div class="test-title">should create a custom error with the correct styles</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Alert Functions</div><div class="test-title">should create a custom success with the correct styles</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Alert Functions</div><div class="test-title">should fade out the alert after 3 seconds</div><div class="test-status">passed</div><div class="test-duration">0.006s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Alert Functions</div><div class="test-title">should remove the alert after 5 seconds</div><div class="test-status">passed</div><div class="test-duration">0.005s</div></div></div></div></div><div id="suite-11" class="suite-container"><input id="collapsible-10" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-10"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactInfo.test.jsx</div><div class="suite-time">1.901s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">CompanyInfo Component</div><div class="test-title">renders without errors</div><div class="test-status">passed</div><div class="test-duration">0.031s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">CompanyInfo Component</div><div class="test-title">renders the correct address</div><div class="test-status">passed</div><div class="test-duration">0.01s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">CompanyInfo Component</div><div class="test-title">renders the phone number with the correct link</div><div class="test-status">passed</div><div class="test-duration">0.032s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">CompanyInfo Component</div><div class="test-title">renders the email with the correct link</div><div class="test-status">passed</div><div class="test-duration">0.017s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">CompanyInfo Component</div><div class="test-title">renders all icons correctly</div><div class="test-status">passed</div><div class="test-duration">0.012s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">CompanyInfo Component</div><div class="test-title">applies the correct styles to the container</div><div class="test-status">passed</div><div class="test-duration">0.017s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">CompanyInfo Component</div><div class="test-title">applies correct icon styles</div><div class="test-status">passed</div><div class="test-duration">0.017s</div></div></div></div></div><div id="suite-12" class="suite-container"><input id="collapsible-11" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-11"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/about/Leaders.test.jsx</div><div class="suite-time">0.836s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">OrganizationLeaders</div><div class="test-title">renders the leaders section with a title</div><div class="test-status">passed</div><div class="test-duration">0.046s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">OrganizationLeaders</div><div class="test-title">renders leader cards with correct data</div><div class="test-status">passed</div><div class="test-duration">0.022s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">OrganizationLeaders</div><div class="test-title">renders social media links if available</div><div class="test-status">passed</div><div class="test-duration">0.011s</div></div></div></div></div><div id="suite-13" class="suite-container"><input id="collapsible-12" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-12"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/about/AboutUs.test.jsx</div><div class="suite-time">0.648s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">AboutUs Component</div><div class="test-title">renders the AboutUs component without crashing</div><div class="test-status">passed</div><div class="test-duration">0.037s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">AboutUs Component</div><div class="test-title">renders the main paragraph with expected text</div><div class="test-status">passed</div><div class="test-duration">0.008s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">AboutUs Component</div><div class="test-title">renders all bullet points correctly</div><div class="test-status">passed</div><div class="test-duration">0.011s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">AboutUs Component</div><div class="test-title">renders the image with correct src and alt attributes</div><div class="test-status">passed</div><div class="test-duration">0.007s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">AboutUs Component</div><div class="test-title">applies the correct styles to the title</div><div class="test-status">passed</div><div class="test-duration">0.013s</div></div></div></div></div><div id="suite-14" class="suite-container"><input id="collapsible-13" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-13"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/Footer.test.jsx</div><div class="suite-time">0.612s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Footer component</div><div class="test-title">renders Twitter and LinkedIn icons</div><div class="test-status">passed</div><div class="test-duration">0.047s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Footer component</div><div class="test-title">contains correct social media links</div><div class="test-status">passed</div><div class="test-duration">0.019s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Footer component</div><div class="test-title">icons have proper aria-labels for accessibility</div><div class="test-status">passed</div><div class="test-duration">0.017s</div></div></div></div></div><div id="suite-15" class="suite-container"><input id="collapsible-14" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-14"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/vardig/Highlights.test.jsx</div><div class="suite-time">4.371s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">Highlights Component</div><div class="test-title">renders the highlights section</div><div class="test-status">passed</div><div class="test-duration">0.037s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">Highlights Component</div><div class="test-title">should trigger gsap animations on render</div><div class="test-status">passed</div><div class="test-duration">0.008s</div></div></div></div></div><div id="suite-16" class="suite-container"><input id="collapsible-15" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-15"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/vardig/Bookdemo.test.jsx</div><div class="suite-time warn">19.816s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">BookDemo Component</div><div class="test-title">renders the title and button</div><div class="test-status">passed</div><div class="test-duration">0.15s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BookDemo Component</div><div class="test-title">navigates to the contact page on button click</div><div class="test-status">passed</div><div class="test-duration">1.367s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">BookDemo Component</div><div class="test-title">passes state to contact page and renders correctly</div><div class="test-status">passed</div><div class="test-duration">1.235s</div></div></div></div></div><div id="suite-17" class="suite-container"><input id="collapsible-16" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-16"><div class="suite-info"><div class="suite-path">/data/darshan/data/genomatics-site-react-tailwind/versions/geno-react-modularised/frontend/src/__test__/contact/ContactPage.test.jsx</div><div class="suite-time warn">20.703s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">ContactPage</div><div class="test-title">renders the contact form and company info</div><div class="test-status">passed</div><div class="test-duration">3.738s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">ContactPage</div><div class="test-title">should display grid layout properly</div><div class="test-status">passed</div><div class="test-duration">0.148s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">ContactPage</div><div class="test-title">should adjust grid for mobile screen</div><div class="test-status">passed</div><div class="test-duration">0.142s</div></div></div></div></div></div></body></html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
frontend/test-report/teststyle.css
DELETED
@@ -1,259 +0,0 @@
|
|
1 |
-
html,
|
2 |
-
body {
|
3 |
-
font-family: Arial, Helvetica, sans-serif;
|
4 |
-
font-size: 1rem;
|
5 |
-
margin: 0;
|
6 |
-
padding: 0;
|
7 |
-
color: #333;
|
8 |
-
}
|
9 |
-
body {
|
10 |
-
padding: 2rem 1rem;
|
11 |
-
font-size: 0.85rem;
|
12 |
-
}
|
13 |
-
.jesthtml-content {
|
14 |
-
margin: 0 auto;
|
15 |
-
max-width: 70rem;
|
16 |
-
}
|
17 |
-
header {
|
18 |
-
display: flex;
|
19 |
-
align-items: center;
|
20 |
-
}
|
21 |
-
#title {
|
22 |
-
margin: 0;
|
23 |
-
flex-grow: 1;
|
24 |
-
}
|
25 |
-
#logo {
|
26 |
-
height: 4rem;
|
27 |
-
}
|
28 |
-
#timestamp {
|
29 |
-
color: #777;
|
30 |
-
margin-top: 0.5rem;
|
31 |
-
}
|
32 |
-
|
33 |
-
/** SUMMARY */
|
34 |
-
#summary {
|
35 |
-
color: #333;
|
36 |
-
margin: 2rem 0;
|
37 |
-
display: flex;
|
38 |
-
font-family: monospace;
|
39 |
-
font-size: 1rem;
|
40 |
-
}
|
41 |
-
#summary > div {
|
42 |
-
margin-right: 2rem;
|
43 |
-
background: #eee;
|
44 |
-
padding: 1rem;
|
45 |
-
min-width: 15rem;
|
46 |
-
}
|
47 |
-
#summary > div:last-child {
|
48 |
-
margin-right: 0;
|
49 |
-
}
|
50 |
-
@media only screen and (max-width: 720px) {
|
51 |
-
#summary {
|
52 |
-
flex-direction: column;
|
53 |
-
}
|
54 |
-
#summary > div {
|
55 |
-
margin-right: 0;
|
56 |
-
margin-top: 2rem;
|
57 |
-
}
|
58 |
-
#summary > div:first-child {
|
59 |
-
margin-top: 0;
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
.summary-total {
|
64 |
-
font-weight: bold;
|
65 |
-
margin-bottom: 0.5rem;
|
66 |
-
}
|
67 |
-
.summary-passed {
|
68 |
-
color: #4f8a10;
|
69 |
-
border-left: 0.4rem solid #4f8a10;
|
70 |
-
padding-left: 0.5rem;
|
71 |
-
}
|
72 |
-
.summary-failed,
|
73 |
-
.summary-obsolete-snapshots {
|
74 |
-
color: #d8000c;
|
75 |
-
border-left: 0.4rem solid #d8000c;
|
76 |
-
padding-left: 0.5rem;
|
77 |
-
}
|
78 |
-
.summary-pending {
|
79 |
-
color: #9f6000;
|
80 |
-
border-left: 0.4rem solid #9f6000;
|
81 |
-
padding-left: 0.5rem;
|
82 |
-
}
|
83 |
-
.summary-empty {
|
84 |
-
color: #999;
|
85 |
-
border-left: 0.4rem solid #999;
|
86 |
-
}
|
87 |
-
|
88 |
-
.test-result {
|
89 |
-
padding: 1rem;
|
90 |
-
margin-bottom: 0.25rem;
|
91 |
-
}
|
92 |
-
.test-result:last-child {
|
93 |
-
border: 0;
|
94 |
-
}
|
95 |
-
.test-result.passed {
|
96 |
-
background-color: #dff2bf;
|
97 |
-
color: #4f8a10;
|
98 |
-
}
|
99 |
-
.test-result.failed {
|
100 |
-
background-color: #ffbaba;
|
101 |
-
color: #d8000c;
|
102 |
-
}
|
103 |
-
.test-result.pending {
|
104 |
-
background-color: #ffdf61;
|
105 |
-
color: #9f6000;
|
106 |
-
}
|
107 |
-
|
108 |
-
.test-info {
|
109 |
-
display: flex;
|
110 |
-
justify-content: space-between;
|
111 |
-
}
|
112 |
-
.test-suitename {
|
113 |
-
width: 20%;
|
114 |
-
text-align: left;
|
115 |
-
font-weight: bold;
|
116 |
-
word-break: break-word;
|
117 |
-
}
|
118 |
-
.test-title {
|
119 |
-
width: 40%;
|
120 |
-
text-align: left;
|
121 |
-
font-style: italic;
|
122 |
-
}
|
123 |
-
.test-status {
|
124 |
-
width: 20%;
|
125 |
-
text-align: right;
|
126 |
-
}
|
127 |
-
.test-duration {
|
128 |
-
width: 10%;
|
129 |
-
text-align: right;
|
130 |
-
font-size: 0.75rem;
|
131 |
-
}
|
132 |
-
|
133 |
-
.failureMessages {
|
134 |
-
padding: 0 1rem;
|
135 |
-
margin-top: 1rem;
|
136 |
-
border-top: 1px dashed #d8000c;
|
137 |
-
}
|
138 |
-
.failureMessages.suiteFailure {
|
139 |
-
border-top: none;
|
140 |
-
}
|
141 |
-
.failureMsg {
|
142 |
-
white-space: pre-wrap;
|
143 |
-
white-space: -moz-pre-wrap;
|
144 |
-
white-space: -pre-wrap;
|
145 |
-
white-space: -o-pre-wrap;
|
146 |
-
word-wrap: break-word;
|
147 |
-
}
|
148 |
-
|
149 |
-
.suite-container {
|
150 |
-
margin-bottom: 2rem;
|
151 |
-
}
|
152 |
-
.suite-container > input[type="checkbox"] {
|
153 |
-
position: absolute;
|
154 |
-
left: -100vw;
|
155 |
-
}
|
156 |
-
.suite-container label {
|
157 |
-
display: block;
|
158 |
-
}
|
159 |
-
.suite-container .suite-tests {
|
160 |
-
overflow-y: hidden;
|
161 |
-
height: 0;
|
162 |
-
}
|
163 |
-
.suite-container > input[type="checkbox"]:checked ~ .suite-tests {
|
164 |
-
height: auto;
|
165 |
-
overflow: visible;
|
166 |
-
}
|
167 |
-
.suite-info {
|
168 |
-
padding: 1rem;
|
169 |
-
background-color: #eee;
|
170 |
-
color: #777;
|
171 |
-
display: flex;
|
172 |
-
align-items: center;
|
173 |
-
margin-bottom: 0.25rem;
|
174 |
-
}
|
175 |
-
.suite-info:hover {
|
176 |
-
background-color: #ddd;
|
177 |
-
cursor: pointer;
|
178 |
-
}
|
179 |
-
.suite-info .suite-path {
|
180 |
-
word-break: break-all;
|
181 |
-
flex-grow: 1;
|
182 |
-
font-family: monospace;
|
183 |
-
font-size: 1rem;
|
184 |
-
}
|
185 |
-
.suite-info .suite-time {
|
186 |
-
margin-left: 0.5rem;
|
187 |
-
padding: 0.2rem 0.3rem;
|
188 |
-
font-size: 0.75rem;
|
189 |
-
}
|
190 |
-
.suite-info .suite-time.warn {
|
191 |
-
background-color: #d8000c;
|
192 |
-
color: #fff;
|
193 |
-
}
|
194 |
-
.suite-info:before {
|
195 |
-
content: "\2303";
|
196 |
-
display: inline-block;
|
197 |
-
margin-right: 0.5rem;
|
198 |
-
transform: rotate(0deg);
|
199 |
-
}
|
200 |
-
.suite-container > input[type="checkbox"]:checked ~ label .suite-info:before {
|
201 |
-
transform: rotate(180deg);
|
202 |
-
}
|
203 |
-
|
204 |
-
/* CONSOLE LOGS */
|
205 |
-
.suite-consolelog {
|
206 |
-
margin-bottom: 0.25rem;
|
207 |
-
padding: 1rem;
|
208 |
-
background-color: #efefef;
|
209 |
-
}
|
210 |
-
.suite-consolelog-header {
|
211 |
-
font-weight: bold;
|
212 |
-
}
|
213 |
-
.suite-consolelog-item {
|
214 |
-
padding: 0.5rem;
|
215 |
-
}
|
216 |
-
.suite-consolelog-item pre {
|
217 |
-
margin: 0.5rem 0;
|
218 |
-
white-space: pre-wrap;
|
219 |
-
white-space: -moz-pre-wrap;
|
220 |
-
white-space: -pre-wrap;
|
221 |
-
white-space: -o-pre-wrap;
|
222 |
-
word-wrap: break-word;
|
223 |
-
}
|
224 |
-
.suite-consolelog-item-origin {
|
225 |
-
color: #777;
|
226 |
-
font-weight: bold;
|
227 |
-
}
|
228 |
-
.suite-consolelog-item-message {
|
229 |
-
color: #000;
|
230 |
-
font-size: 1rem;
|
231 |
-
padding: 0 0.5rem;
|
232 |
-
}
|
233 |
-
|
234 |
-
/* OBSOLETE SNAPSHOTS */
|
235 |
-
.suite-obsolete-snapshots {
|
236 |
-
margin-bottom: 0.25rem;
|
237 |
-
padding: 1rem;
|
238 |
-
background-color: #ffbaba;
|
239 |
-
color: #d8000c;
|
240 |
-
}
|
241 |
-
.suite-obsolete-snapshots-header {
|
242 |
-
font-weight: bold;
|
243 |
-
}
|
244 |
-
.suite-obsolete-snapshots-item {
|
245 |
-
padding: 0.5rem;
|
246 |
-
}
|
247 |
-
.suite-obsolete-snapshots-item pre {
|
248 |
-
margin: 0.5rem 0;
|
249 |
-
white-space: pre-wrap;
|
250 |
-
white-space: -moz-pre-wrap;
|
251 |
-
white-space: -pre-wrap;
|
252 |
-
white-space: -o-pre-wrap;
|
253 |
-
word-wrap: break-word;
|
254 |
-
}
|
255 |
-
.suite-obsolete-snapshots-item-message {
|
256 |
-
color: #000;
|
257 |
-
font-size: 1rem;
|
258 |
-
padding: 0 0.5rem;
|
259 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|