Skip to content

Commit b1a34a7

Browse files
committed
fix: convert test infrastructure from ES6 modules to CommonJS
- Convert all test files from ES6 import/export to CommonJS require/module.exports - Remove babel transform configuration from jest.config.js - Expose NotificationManager to window for testing - Add mock for FavoritesManager dependency - Tests now run successfully in Jest/Node environment
1 parent f6fcaf6 commit b1a34a7

File tree

7 files changed

+65
-27
lines changed

7 files changed

+65
-27
lines changed

jest.config.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ module.exports = {
6969
'**/tests/frontend/**/*.spec.js'
7070
],
7171

72-
// Transform files
73-
transform: {
74-
'^.+\\.js$': ['<rootDir>/tests/frontend/utils/jsTransform.js']
75-
},
7672

7773
// Global variables available in tests
7874
globals: {

static/js/notifications.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,8 @@ const NotificationManager = {
466466
$(document).ready(function() {
467467
NotificationManager.init();
468468
});
469+
470+
// Expose for testing
471+
if (typeof window !== 'undefined') {
472+
window.NotificationManager = NotificationManager;
473+
}

tests/frontend/setup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44

55
// Add custom matchers from jest-dom
6-
import '@testing-library/jest-dom';
6+
require('@testing-library/jest-dom');
77

88
// Set up global jQuery
99
global.$ = global.jQuery = require('../../static/js/jquery.min.js');

tests/frontend/unit/countdown-simple.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
* Tests for countdown-simple.js
33
*/
44

5-
import { TimerController, mockLuxonDateTime } from '../utils/mockHelpers';
6-
import { createConferenceWithDeadline, setupConferenceDOM } from '../utils/dataHelpers';
5+
const { TimerController, mockLuxonDateTime } = require('../utils/mockHelpers');
6+
const { createConferenceWithDeadline, setupConferenceDOM } = require('../utils/dataHelpers');
77

88
describe('Countdown Timer System', () => {
99
let timerController;

tests/frontend/unit/notifications.test.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
* Tests for NotificationManager
33
*/
44

5-
import {
5+
const {
66
mockNotificationAPI,
77
mockStore,
88
TimerController,
99
mockBootstrapModal,
1010
mockPageVisibility
11-
} from '../utils/mockHelpers';
11+
} = require('../utils/mockHelpers');
1212

13-
import {
13+
const {
1414
createConferenceWithDeadline,
1515
createSavedConferences,
1616
setupConferenceDOM,
1717
createConferenceSet
18-
} from '../utils/dataHelpers';
18+
} = require('../utils/dataHelpers');
1919

2020
// We'll load the actual file in the test
2121
let NotificationManager;
@@ -37,11 +37,25 @@ describe('NotificationManager', () => {
3737
// Set current time
3838
timerController.setCurrentTime('2024-01-15 12:00:00');
3939

40-
// Load NotificationManager (it's an IIFE so it auto-initializes)
40+
// Mock FavoritesManager (dependency of NotificationManager)
41+
window.FavoritesManager = {
42+
getSavedConferences: jest.fn(() => ({})),
43+
showToast: jest.fn(),
44+
init: jest.fn()
45+
};
46+
47+
// Mock jQuery ready to prevent auto-init
48+
const originalReady = $.fn.ready;
49+
$.fn.ready = jest.fn();
50+
51+
// Load NotificationManager (it exposes itself to window)
4152
jest.isolateModules(() => {
4253
require('../../../static/js/notifications.js');
4354
NotificationManager = window.NotificationManager;
4455
});
56+
57+
// Restore jQuery ready
58+
$.fn.ready = originalReady;
4559
});
4660

4761
afterEach(() => {

tests/frontend/utils/dataHelpers.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* Generate mock conference data
77
*/
8-
export function createMockConference(overrides = {}) {
8+
function createMockConference(overrides = {}) {
99
const baseDate = new Date();
1010
const cfpDate = new Date(baseDate);
1111
cfpDate.setDate(cfpDate.getDate() + 30); // CFP 30 days from now
@@ -42,7 +42,7 @@ export function createMockConference(overrides = {}) {
4242
/**
4343
* Create conference with specific days until deadline
4444
*/
45-
export function createConferenceWithDeadline(daysUntilDeadline, overrides = {}) {
45+
function createConferenceWithDeadline(daysUntilDeadline, overrides = {}) {
4646
const cfpDate = new Date();
4747
cfpDate.setDate(cfpDate.getDate() + daysUntilDeadline);
4848
cfpDate.setHours(23, 59, 59, 0);
@@ -56,7 +56,7 @@ export function createConferenceWithDeadline(daysUntilDeadline, overrides = {})
5656
/**
5757
* Create past conference
5858
*/
59-
export function createPastConference(daysPast = 30, overrides = {}) {
59+
function createPastConference(daysPast = 30, overrides = {}) {
6060
const cfpDate = new Date();
6161
cfpDate.setDate(cfpDate.getDate() - daysPast);
6262

@@ -69,7 +69,7 @@ export function createPastConference(daysPast = 30, overrides = {}) {
6969
/**
7070
* Create DOM element for conference
7171
*/
72-
export function createConferenceDOM(conference) {
72+
function createConferenceDOM(conference) {
7373
const div = document.createElement('div');
7474
div.className = 'ConfItem';
7575
div.id = conference.id;
@@ -127,7 +127,7 @@ export function createConferenceDOM(conference) {
127127
/**
128128
* Create multiple conferences with varied deadlines
129129
*/
130-
export function createConferenceSet() {
130+
function createConferenceSet() {
131131
return {
132132
upcoming7Days: createConferenceWithDeadline(7, {
133133
id: 'conf-7days',
@@ -155,7 +155,7 @@ export function createConferenceSet() {
155155
/**
156156
* Create saved conferences structure for localStorage
157157
*/
158-
export function createSavedConferences(conferences) {
158+
function createSavedConferences(conferences) {
159159
const saved = {};
160160
conferences.forEach(conf => {
161161
saved[conf.id] = {
@@ -170,7 +170,7 @@ export function createSavedConferences(conferences) {
170170
/**
171171
* Create series subscription data
172172
*/
173-
export function createSeriesSubscription(seriesName, settings = {}) {
173+
function createSeriesSubscription(seriesName, settings = {}) {
174174
return {
175175
[seriesName.toLowerCase()]: {
176176
name: seriesName,
@@ -185,7 +185,7 @@ export function createSeriesSubscription(seriesName, settings = {}) {
185185
/**
186186
* Setup DOM with multiple conferences
187187
*/
188-
export function setupConferenceDOM(conferences) {
188+
function setupConferenceDOM(conferences) {
189189
const container = document.createElement('div');
190190
container.id = 'conference-list';
191191
container.className = 'conference-list';
@@ -208,3 +208,15 @@ export function setupConferenceDOM(conferences) {
208208

209209
return container;
210210
}
211+
212+
// Export all data helpers
213+
module.exports = {
214+
createMockConference,
215+
createConferenceWithDeadline,
216+
createPastConference,
217+
createConferenceDOM,
218+
createConferenceSet,
219+
createSavedConferences,
220+
createSeriesSubscription,
221+
setupConferenceDOM
222+
};

tests/frontend/utils/mockHelpers.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* Mock Notification API
77
*/
8-
export function mockNotificationAPI(permission = 'default') {
8+
function mockNotificationAPI(permission = 'default') {
99
const NotificationMock = jest.fn().mockImplementation(function(title, options) {
1010
this.title = title;
1111
this.body = options?.body;
@@ -40,7 +40,7 @@ export function mockNotificationAPI(permission = 'default') {
4040
/**
4141
* Mock localStorage with persistence within test
4242
*/
43-
export function mockLocalStorage() {
43+
function mockLocalStorage() {
4444
const storage = {};
4545

4646
const localStorageMock = {
@@ -76,7 +76,7 @@ export function mockLocalStorage() {
7676
/**
7777
* Mock store.js library
7878
*/
79-
export function mockStore() {
79+
function mockStore() {
8080
const storage = new Map();
8181

8282
const storeMock = {
@@ -98,7 +98,7 @@ export function mockStore() {
9898
/**
9999
* Mock timers with control
100100
*/
101-
export class TimerController {
101+
class TimerController {
102102
constructor() {
103103
this.currentTime = new Date();
104104
jest.useFakeTimers();
@@ -148,7 +148,7 @@ export class TimerController {
148148
/**
149149
* Mock Bootstrap modal
150150
*/
151-
export function mockBootstrapModal() {
151+
function mockBootstrapModal() {
152152
$.fn.modal = jest.fn(function(action) {
153153
if (action === 'show') {
154154
$(this).addClass('show');
@@ -181,7 +181,7 @@ export function mockBootstrapModal() {
181181
/**
182182
* Mock window.focus and document.hidden
183183
*/
184-
export function mockPageVisibility(isVisible = true) {
184+
function mockPageVisibility(isVisible = true) {
185185
Object.defineProperty(document, 'hidden', {
186186
configurable: true,
187187
get: () => !isVisible
@@ -214,7 +214,7 @@ export function mockPageVisibility(isVisible = true) {
214214
/**
215215
* Mock Luxon DateTime
216216
*/
217-
export function mockLuxonDateTime() {
217+
function mockLuxonDateTime() {
218218
if (!window.luxon) {
219219
// Simple mock if Luxon not loaded
220220
window.luxon = {
@@ -255,3 +255,14 @@ export function mockLuxonDateTime() {
255255
}
256256
return window.luxon;
257257
}
258+
259+
// Export all mock helpers
260+
module.exports = {
261+
mockNotificationAPI,
262+
mockLocalStorage,
263+
mockStore,
264+
TimerController,
265+
mockBootstrapModal,
266+
mockPageVisibility,
267+
mockLuxonDateTime
268+
};

0 commit comments

Comments
 (0)