i-darrshan commited on
Commit
1626af8
·
1 Parent(s): a0e61bf
Files changed (32) hide show
  1. backend/__tests__/config/googleOAuth.test.js +0 -77
  2. backend/__tests__/config/refreshTokens.test.js +0 -101
  3. backend/__tests__/controller/applicantController.test.js +0 -132
  4. backend/__tests__/controller/authController.test.js +0 -81
  5. backend/__tests__/controller/contactController.test.js +0 -198
  6. backend/__tests__/controller/demo/dateAvailability.test.js +0 -81
  7. backend/__tests__/controller/demo/holidays.test.js +0 -128
  8. backend/__tests__/controller/demo/slots.test.js +0 -142
  9. backend/__tests__/controller/demo/utils.test.js +0 -77
  10. backend/__tests__/controller/demoRequestController.test.js +0 -293
  11. backend/__tests__/controller/subscriptionController.test.js +0 -131
  12. backend/__tests__/db.test.js +0 -64
  13. backend/__tests__/db/addSubscriber.test.js +0 -95
  14. backend/__tests__/db/contactRequestDB.test.js +0 -90
  15. backend/__tests__/db/demoRequestDB.test.js +0 -120
  16. backend/__tests__/db/jobRequestDB.test.js +0 -105
  17. backend/__tests__/routes/applicantRoutes.test.js +0 -73
  18. backend/__tests__/testSetup.js +0 -0
  19. backend/controller/applicantController.js +2 -2
  20. backend/controller/contactController.js +2 -2
  21. backend/controller/demoRequestController.js +2 -2
  22. backend/demo-event.ics +0 -21
  23. backend/genomatics-logo.png +0 -0
  24. backend/jest/mediaFileTransformer.js +0 -9
  25. backend/test-report/index.html +0 -203
  26. backend/test-report/teststyle.css +0 -259
  27. backend/utils/sendEmail.js +1 -0
  28. frontend/jest/mediaFileTransformer.js +0 -9
  29. frontend/src/sections/contact/Forms.jsx +7 -8
  30. frontend/src/sections/jobs/JobPageSection.jsx +8 -2
  31. frontend/test-report/index.html +0 -459
  32. 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
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
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
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
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: 'Failed to send job application emails, but the application was received!' });
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('Failed to send Contact request confirmation email, however request registered successfully!', error);
95
- res.status(200).send({ error: 'Failed to send Contact request confirmation email, however request registered successfully!' });
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('Failed to send demo request confirmation email, however request registered successfully!', error);
171
- res.status(200).send({ error: 'Failed to send demo request confirmation email, however the demo request has been registered successfully!' });
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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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
- &gt; 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.&lt;anonymous&gt; (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.&lt;anonymous&gt; (/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 (&lt;anonymous&gt;)
29
- at Object.&lt;anonymous&gt; (/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 (&lt;anonymous&gt;)
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 &gt; 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 &gt; 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 &gt; 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 &gt; 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.&lt;anonymous&gt; (/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 (&lt;anonymous&gt;)
55
- at Object.&lt;anonymous&gt; (/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 (&lt;anonymous&gt;)
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 &gt; 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.&lt;anonymous&gt; (/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 &gt; 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 &gt; 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 &gt; 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.&lt;anonymous&gt; (/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 &gt; 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 &gt; 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.&lt;anonymous&gt; (/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 &gt; 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.&lt;anonymous&gt; (/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.&lt;anonymous&gt; (/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.&lt;anonymous&gt; (/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.&lt;anonymous&gt; (/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.&lt;anonymous&gt; (/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.&lt;anonymous&gt; (/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.&lt;anonymous&gt; (/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.&lt;anonymous&gt; (/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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 &gt; 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 === "Failed to send demo request confirmation email, however the demo request has been registered successfully!") {
277
  showCustomAlert(response.data.error);
278
- }else if (response.data.error === 'Failed to send Contact request confirmation email, however request registered successfully!') {
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
- <div htmlFor="gdpr-consent">
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
- </div>
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
- <div htmlFor="gdpr-consent">
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
- </div>
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
- showCustomError(error.response.data.error || "An unexpected error occurred. Please try again.");
 
 
 
 
 
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 &gt; General Enquiry &gt; 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 &gt; General Enquiry &gt; 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 &gt; General Enquiry &gt; 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 &gt; General Enquiry &gt; 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
- &lt;html&gt;
10
- &lt;head /&gt;
11
- &lt;body&gt;
12
- &lt;div&gt;
13
- &lt;form
14
- aria-label="general"
15
- class="sc-blHHSb hUXMOf"
16
- data-testid="formFields"
17
- &gt;
18
- &lt;input
19
- class="sc-gtLWhw jSyAJc"
20
- placeholder="Your Name"
21
- required=""
22
- type="text"
23
- value="John Doe"
24
- /&gt;
25
- &lt;input
26
- class="sc-gtLWhw jSyAJc"
27
- placeholder="Your Email"
28
- required=""
29
- type="email"
30
- value="[email protected]"
31
- /&gt;
32
- &lt;div
33
- class="iti iti--allow-dropdown iti--show-flags iti--inline-dropdown"
34
- &gt;
35
- &lt;div
36
- class="iti__country-container"
37
- style="left: 0px;"
38
- &gt;
39
- &lt;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
- &gt;
49
- &lt;div
50
- class="iti__selected-country-primary"
51
- &gt;
52
- &lt;div
53
- class="iti__flag iti__in"
54
- &gt;
55
- &lt;span
56
- class="iti__a11y-text"
57
- &gt;
58
- India +91
59
- &lt;/span&gt;
60
- &lt;/div&gt;
61
- &lt;div
62
- aria-hidden="true"
63
- class="iti__arrow"
64
- /&gt;
65
- &lt;/div&gt;
66
- &lt;div
67
- class="iti__selected-dial-code"
68
- &gt;
69
- +91
70
- &lt;/div&gt;
71
- &lt;/button&gt;
72
- &lt;div
73
- class="iti__dropdown-content iti__hide "
74
- id="iti-3__dropdown-content"
75
- &gt;
76
- &lt;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
- /&gt;
87
- &lt;span
88
- class="iti__a11y-text"
89
- &gt;
90
- 244 results found
91
- &lt;/span&gt;
92
- &lt;ul
93
- aria-label="List of countries"
94
- class="iti__country-list"
95
- id="iti-3__country-listbox"
96
- role="listbox"
97
- &gt;
98
- &lt;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
- &gt;
107
- &lt;div
108
- class="iti__flag iti__af"
109
- /&gt;
110
- &lt;span
111
- class="iti__country-name"
112
- &gt;
113
- Afghanistan
114
- &lt;/span&gt;
115
- &lt;span
116
- class="iti__dial-code"
117
- &gt;
118
- +93
119
- &lt;/span&gt;
120
- &lt;/li&gt;
121
- &lt;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
- &gt;
130
- &lt;div
131
- class="iti__flag iti__ax"
132
- /&gt;
133
- &lt;span
134
- class="iti__country-name"
135
- &gt;
136
- Åland Islands
137
- &lt;/span&gt;
138
- &lt;span
139
- class="iti__dial-code"
140
- &gt;
141
- +358
142
- &lt;/span&gt;
143
- &lt;/li&gt;
144
- &lt;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
- &gt;
153
- &lt;div
154
- class="iti__flag iti__al"
155
- /&gt;
156
- &lt;span
157
- class="iti__country-name"
158
- &gt;
159
- Albania
160
- &lt;/span&gt;
161
- &lt;span
162
- class="iti__dial-code"
163
- &gt;
164
- +355
165
- &lt;/span&gt;
166
- &lt;/li&gt;
167
- &lt;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 &gt; General Enquiry &gt; 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
- &lt;html&gt;
184
- &lt;head /&gt;
185
- &lt;body&gt;
186
- &lt;div&gt;
187
- &lt;form
188
- aria-label="general"
189
- class="sc-blHHSb hUXMOf"
190
- data-testid="formFields"
191
- &gt;
192
- &lt;input
193
- class="sc-gtLWhw jSyAJc"
194
- placeholder="Your Name"
195
- required=""
196
- type="text"
197
- value="John Doe"
198
- /&gt;
199
- &lt;input
200
- class="sc-gtLWhw jSyAJc"
201
- placeholder="Your Email"
202
- required=""
203
- type="email"
204
- value="[email protected]"
205
- /&gt;
206
- &lt;div
207
- class="iti iti--allow-dropdown iti--show-flags iti--inline-dropdown"
208
- &gt;
209
- &lt;div
210
- class="iti__country-container"
211
- style="left: 0px;"
212
- &gt;
213
- &lt;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
- &gt;
223
- &lt;div
224
- class="iti__selected-country-primary"
225
- &gt;
226
- &lt;div
227
- class="iti__flag iti__in"
228
- &gt;
229
- &lt;span
230
- class="iti__a11y-text"
231
- &gt;
232
- India +91
233
- &lt;/span&gt;
234
- &lt;/div&gt;
235
- &lt;div
236
- aria-hidden="true"
237
- class="iti__arrow"
238
- /&gt;
239
- &lt;/div&gt;
240
- &lt;div
241
- class="iti__selected-dial-code"
242
- &gt;
243
- +91
244
- &lt;/div&gt;
245
- &lt;/button&gt;
246
- &lt;div
247
- class="iti__dropdown-content iti__hide "
248
- id="iti-4__dropdown-content"
249
- &gt;
250
- &lt;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
- /&gt;
261
- &lt;span
262
- class="iti__a11y-text"
263
- &gt;
264
- 244 results found
265
- &lt;/span&gt;
266
- &lt;ul
267
- aria-label="List of countries"
268
- class="iti__country-list"
269
- id="iti-4__country-listbox"
270
- role="listbox"
271
- &gt;
272
- &lt;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
- &gt;
281
- &lt;div
282
- class="iti__flag iti__af"
283
- /&gt;
284
- &lt;span
285
- class="iti__country-name"
286
- &gt;
287
- Afghanistan
288
- &lt;/span&gt;
289
- &lt;span
290
- class="iti__dial-code"
291
- &gt;
292
- +93
293
- &lt;/span&gt;
294
- &lt;/li&gt;
295
- &lt;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
- &gt;
304
- &lt;div
305
- class="iti__flag iti__ax"
306
- /&gt;
307
- &lt;span
308
- class="iti__country-name"
309
- &gt;
310
- Åland Islands
311
- &lt;/span&gt;
312
- &lt;span
313
- class="iti__dial-code"
314
- &gt;
315
- +358
316
- &lt;/span&gt;
317
- &lt;/li&gt;
318
- &lt;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
- &gt;
327
- &lt;div
328
- class="iti__flag iti__al"
329
- /&gt;
330
- &lt;span
331
- class="iti__country-name"
332
- &gt;
333
- Albania
334
- &lt;/span&gt;
335
- &lt;span
336
- class="iti__dial-code"
337
- &gt;
338
- +355
339
- &lt;/span&gt;
340
- &lt;/li&gt;
341
- &lt;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 &gt; Demo Request &gt; 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 &gt; Demo Request &gt; 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 &gt; Demo Request &gt; 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 &gt; Demo Request &gt; 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 &gt; Demo Request &gt; 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.&lt;computed&gt; [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
- }