Skip to content

Commit cc6a5e2

Browse files
committed
test(auth-server): migrate remaining Mocha tests to Jest, freeze Mocha files, and fix CI artifact uploads (FXA-12562)
1 parent 1b419d7 commit cc6a5e2

25 files changed

Lines changed: 5323 additions & 78 deletions

.circleci/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ workflows:
987987
- integration-test:
988988
name: Integration Test Jest - Servers - Auth (PR)
989989
nx_run: affected --base=main --head=$CIRCLE_SHA1
990-
projects: --exclude '*,!tag:scope:server:auth,!fxa-profile-server'
990+
projects: --exclude '*,!tag:scope:server:auth'
991991
start_customs: true
992992
target: -t test-integration-jest
993993
test_suite: servers-auth-jest-integration
@@ -1208,7 +1208,7 @@ workflows:
12081208
- Build
12091209
- integration-test:
12101210
name: Integration Test Jest - Servers - Auth
1211-
projects: --exclude '*,!tag:scope:server:auth,!fxa-profile-server'
1211+
projects: --exclude '*,!tag:scope:server:auth'
12121212
start_customs: true
12131213
target: -t test-integration-jest
12141214
test_suite: servers-auth-jest-integration
@@ -1327,7 +1327,7 @@ workflows:
13271327
- Build (nightly)
13281328
- integration-test:
13291329
name: Integration Test Jest - Servers - Auth (nightly)
1330-
projects: --exclude '*,!tag:scope:server:auth,!fxa-profile-server'
1330+
projects: --exclude '*,!tag:scope:server:auth'
13311331
start_customs: true
13321332
target: -t test-integration-jest
13331333
test_suite: servers-auth-jest-integration

_scripts/check-frozen.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ const frozen: Array<{ pattern: string; reason: string }> = [
1616
pattern: 'packages/fxa-auth-server/lib/senders/(emails|renderer)/.*',
1717
reason: 'Files moved to libs/accounts/email-renderer',
1818
},
19+
{
20+
pattern: 'packages/fxa-auth-server/test/local/.*\\.(js|ts)$',
21+
reason:
22+
'Mocha unit tests are frozen. Add new tests as co-located Jest specs (lib/**/*.spec.ts)',
23+
},
24+
{
25+
pattern: 'packages/fxa-auth-server/test/remote/.*_tests\\.js$',
26+
reason:
27+
'Mocha integration tests are frozen. Add new tests as Jest specs (test/remote/*.in.spec.ts)',
28+
},
29+
{
30+
pattern: 'packages/fxa-auth-server/test/oauth/.*\\.(js|ts)$',
31+
reason:
32+
'Mocha OAuth tests are frozen. Add new tests as Jest specs (lib/oauth/*.spec.ts)',
33+
},
1934
];
2035

2136
export const getChangedFiles = () => {

nx.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
"dependsOn": ["build", "gen-keys"],
103103
"inputs": ["test", "^test"],
104104
"outputs": [
105-
"{workspaceRoot}/artifacts/tests",
105+
"{workspaceRoot}/artifacts/tests/{projectName}",
106106
"{projectRoot}/coverage",
107107
"{projectRoot}/.nyc_output",
108108
"{projectRoot}/test-results.xml",
@@ -114,7 +114,7 @@
114114
"dependsOn": ["build", "gen-keys"],
115115
"inputs": ["test", "^test"],
116116
"outputs": [
117-
"{workspaceRoot}/artifacts/tests",
117+
"{workspaceRoot}/artifacts/tests/{projectName}",
118118
"{projectRoot}/coverage",
119119
"{projectRoot}/.nyc_output",
120120
"{projectRoot}/test-results.xml",
@@ -126,7 +126,7 @@
126126
"dependsOn": ["build", "gen-keys"],
127127
"inputs": ["test", "^test"],
128128
"outputs": [
129-
"{workspaceRoot}/artifacts/tests",
129+
"{workspaceRoot}/artifacts/tests/{projectName}",
130130
"{projectRoot}/coverage",
131131
"{projectRoot}/.nyc_output",
132132
"{projectRoot}/test-results.xml"
@@ -137,7 +137,7 @@
137137
"dependsOn": ["build", "gen-keys"],
138138
"inputs": ["test", "^test"],
139139
"outputs": [
140-
"{workspaceRoot}/artifacts/tests",
140+
"{workspaceRoot}/artifacts/tests/{projectName}",
141141
"{projectRoot}/coverage",
142142
"{projectRoot}/.nyc_output",
143143
"{projectRoot}/test-results.xml"

packages/fxa-auth-server/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module.exports = {
2424
clearMocks: true,
2525
workerIdleMemoryLimit: '512MB',
2626
setupFiles: ['<rootDir>/jest.setup.js', '<rootDir>/jest.setup-proxyquire.js'],
27-
testPathIgnorePatterns: ['/node_modules/'],
27+
testPathIgnorePatterns: ['\\.in\\.spec\\.ts$'],
2828
// Coverage configuration (enabled via --coverage flag)
2929
collectCoverageFrom: [
3030
'lib/**/*.{ts,js}',

packages/fxa-auth-server/jest.integration.config.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ module.exports = {
1818
'^fxa-shared$': '<rootDir>/../fxa-shared/index',
1919
},
2020

21-
testMatch: [
22-
'<rootDir>/test/remote/**/*.spec.ts',
23-
'<rootDir>/test/integration/**/*.spec.ts',
24-
],
21+
testMatch: ['<rootDir>/**/*.in.spec.ts'],
2522

2623
// oauth_api.in.spec.ts uses its own in-process server (server.inject)
2724
// and must run separately to avoid client-config DB race conditions

packages/fxa-auth-server/jest.oauth-api.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ module.exports = {
2121
},
2222

2323
testMatch: ['<rootDir>/test/remote/oauth_api.in.spec.ts'],
24+
// Override base config's .in.spec.ts ignore since this targets one
25+
testPathIgnorePatterns: [],
2426

2527
testTimeout: 120000,
2628
maxWorkers: 1,
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4+
5+
const REMINDERS = ['first', 'second', 'third'];
6+
const EXPECTED_CREATE_DELETE_RESULT = REMINDERS.reduce(
7+
(expected: any, reminder) => {
8+
expected[reminder] = 1;
9+
return expected;
10+
},
11+
{} as Record<string, number>
12+
);
13+
14+
const config = require('../config').default.getProperties();
15+
const mocks = require('../test/mocks');
16+
17+
describe('#integration - lib/cad-reminders', () => {
18+
let log: any, mockConfig: any, redis: any, cadReminders: any;
19+
20+
beforeEach(() => {
21+
jest.resetModules();
22+
log = mocks.mockLog();
23+
mockConfig = {
24+
redis: config.redis,
25+
cadReminders: {
26+
rolloutRate: 1,
27+
firstInterval: 1,
28+
secondInterval: 2,
29+
thirdInterval: 60000,
30+
redis: {
31+
maxConnections: 1,
32+
minConnections: 1,
33+
prefix: 'test-cad-reminders:',
34+
},
35+
},
36+
};
37+
redis = require('./redis')(
38+
{
39+
...config.redis,
40+
...mockConfig.cadReminders.redis,
41+
enabled: true,
42+
},
43+
mocks.mockLog()
44+
);
45+
cadReminders = require('./cad-reminders')(mockConfig, log);
46+
});
47+
48+
afterEach(async () => {
49+
await redis.close();
50+
await cadReminders.close();
51+
});
52+
53+
it('returned the expected interface', () => {
54+
expect(cadReminders).toBeDefined();
55+
expect(Object.keys(cadReminders)).toHaveLength(5);
56+
expect(cadReminders.keys).toEqual(['first', 'second', 'third']);
57+
expect(typeof cadReminders.create).toBe('function');
58+
expect(cadReminders.create).toHaveLength(1);
59+
expect(typeof cadReminders.delete).toBe('function');
60+
expect(cadReminders.delete).toHaveLength(1);
61+
expect(typeof cadReminders.process).toBe('function');
62+
expect(cadReminders.process).toHaveLength(0);
63+
expect(typeof cadReminders.get).toBe('function');
64+
expect(cadReminders.get).toHaveLength(1);
65+
expect(typeof cadReminders.close).toBe('function');
66+
expect(cadReminders.close).toHaveLength(0);
67+
});
68+
69+
describe('create', () => {
70+
let before: number, createResult: any;
71+
72+
beforeEach(async () => {
73+
before = Date.now();
74+
createResult = await cadReminders.create('wibble', before - 1);
75+
});
76+
77+
afterEach(async () => {
78+
await cadReminders.delete('wibble');
79+
});
80+
81+
it('returned the correct result', () => {
82+
expect(createResult).toEqual(EXPECTED_CREATE_DELETE_RESULT);
83+
});
84+
85+
it.each(REMINDERS)('wrote %s reminder to redis', async (reminder) => {
86+
const reminders = await redis.zrange(reminder, 0, -1);
87+
expect(reminders).toEqual(['wibble']);
88+
});
89+
90+
describe('delete', () => {
91+
let deleteResult: any;
92+
93+
beforeEach(async () => {
94+
deleteResult = await cadReminders.delete('wibble');
95+
});
96+
97+
it('returned the correct result', () => {
98+
expect(deleteResult).toEqual(EXPECTED_CREATE_DELETE_RESULT);
99+
});
100+
101+
it.each(REMINDERS)(
102+
'removed %s reminder from redis',
103+
async (reminder) => {
104+
const reminders = await redis.zrange(reminder, 0, -1);
105+
expect(reminders).toHaveLength(0);
106+
}
107+
);
108+
109+
it('did not call log.error', () => {
110+
expect(log.error.callCount).toBe(0);
111+
});
112+
});
113+
114+
describe('get', () => {
115+
let result: any;
116+
117+
beforeEach(async () => {
118+
result = await cadReminders.get('wibble');
119+
});
120+
121+
it('returned the correct result', () => {
122+
expect(result).toEqual({ first: 0, second: 0, third: 0 });
123+
});
124+
125+
it('did not call log.error', () => {
126+
expect(log.error.callCount).toBe(0);
127+
});
128+
});
129+
130+
describe('process', () => {
131+
let processResult: any;
132+
133+
beforeEach(async () => {
134+
await cadReminders.create('blee', before);
135+
processResult = await cadReminders.process(before + 2);
136+
});
137+
138+
afterEach(async () => {
139+
await cadReminders.delete('blee');
140+
});
141+
142+
it('returned the correct result', () => {
143+
expect(processResult).toBeDefined();
144+
145+
expect(processResult.first).toHaveLength(2);
146+
expect(processResult.first[0].uid).toBe('wibble');
147+
expect(parseInt(processResult.first[0].timestamp)).toBeGreaterThan(
148+
before - 1000
149+
);
150+
expect(parseInt(processResult.first[0].timestamp)).toBeLessThan(
151+
before
152+
);
153+
expect(processResult.first[1].uid).toBe('blee');
154+
expect(parseInt(processResult.first[1].timestamp)).toBeGreaterThanOrEqual(
155+
before
156+
);
157+
expect(parseInt(processResult.first[1].timestamp)).toBeLessThan(
158+
before + 1000
159+
);
160+
161+
expect(processResult.second).toHaveLength(2);
162+
expect(processResult.second[0].uid).toBe('wibble');
163+
expect(processResult.second[0].timestamp).toBe(
164+
processResult.first[0].timestamp
165+
);
166+
expect(processResult.second[1].uid).toBe('blee');
167+
expect(processResult.second[1].timestamp).toBe(
168+
processResult.first[1].timestamp
169+
);
170+
171+
expect(processResult.third).toEqual([]);
172+
});
173+
174+
it.each(['first', 'second'])(
175+
'removed %s reminder from redis correctly',
176+
async (reminder) => {
177+
const reminders = await redis.zrange(reminder, 0, -1);
178+
expect(reminders).toHaveLength(0);
179+
}
180+
);
181+
182+
it('left the third reminders in redis', async () => {
183+
const reminders = await redis.zrange('third', 0, -1);
184+
expect(new Set(reminders)).toEqual(new Set(['wibble', 'blee']));
185+
});
186+
187+
it('did not call log.error', () => {
188+
expect(log.error.callCount).toBe(0);
189+
});
190+
});
191+
});
192+
});

0 commit comments

Comments
 (0)