Skip to content

Commit b06025a

Browse files
committed
fxa-12621: Migrate integration tests from Mocha to Jest and unify CI job
1 parent 9172ae7 commit b06025a

26 files changed

Lines changed: 3777 additions & 71 deletions

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module.exports = {
2626
},
2727
testTimeout: 10000,
2828
clearMocks: true,
29+
workerIdleMemoryLimit: '512MB',
2930
setupFiles: ['<rootDir>/jest.setup.js', '<rootDir>/jest.setup-proxyquire.js'],
3031
testPathIgnorePatterns: ['/node_modules/'],
3132
// Coverage configuration (enabled via --coverage flag)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module.exports = {
2020
],
2121

2222
testTimeout: 120000,
23+
maxWorkers: 4,
2324

2425
globalSetup: '<rootDir>/test/support/jest-global-setup.ts',
2526
globalTeardown: '<rootDir>/test/support/jest-global-teardown.ts',

packages/fxa-auth-server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"test-unit": "VERIFIER_VERSION=0 TEST_TYPE=unit scripts/test-ci.sh",
4646
"test-integration": "VERIFIER_VERSION=0 TEST_TYPE=integration scripts/test-ci.sh",
4747
"test-integration-v2": "VERIFIER_VERSION=0 TEST_TYPE=integration-v2 scripts/test-ci.sh",
48-
"test-integration-jest": "JEST_JUNIT_OUTPUT_DIR='../../artifacts/tests/fxa-auth-server' JEST_JUNIT_OUTPUT_NAME='jest-integration-results.xml' npx jest --config jest.integration.config.js --forceExit --ci --reporters=default --reporters=jest-junit",
48+
"test-integration-jest": "VERIFIER_VERSION=0 TEST_TYPE=integration-jest scripts/test-ci.sh",
4949
"populate-firestore-customers": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/populate-firestore-customers.ts",
5050
"populate-vat-taxes": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/populate-vat-taxes.ts",
5151
"paypal-processor": "CONFIG_FILES='config/secrets.json' node -r esbuild-register ./scripts/paypal-processor.ts",

packages/fxa-auth-server/scripts/test-ci.sh

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,23 @@ if [ "$TEST_TYPE" == 'integration' ]; then GREP_TESTS="--grep /#integration\s-/"
1212
if [ "$TEST_TYPE" == 'integration-v2' ]; then GREP_TESTS="--grep /#integrationV2\s-/"; fi;
1313

1414

15-
TESTS=(local oauth remote scripts)
16-
if [ -z "$1" ]; then
15+
# Skip mocha tests for integration-jest — only run Jest tests
16+
if [ "$TEST_TYPE" != 'integration-jest' ]; then
1717
TESTS=(local oauth remote scripts)
18-
else
19-
TESTS=($1)
18+
if [ -z "$1" ]; then
19+
TESTS=(local oauth remote scripts)
20+
else
21+
TESTS=($1)
22+
fi
23+
24+
for t in "${TESTS[@]}"; do
25+
echo -e "\n\nTesting: $t"
26+
27+
#./scripts/mocha-coverage.js $DEFAULT_ARGS $GREP_TESTS --reporter-options mochaFile="../../artifacts/tests/fxa-auth-server/$t/test-results.xml" "test/$t"
28+
MOCHA_FILE=../../artifacts/tests/$npm_package_name/fxa-auth-server-mocha-$TEST_TYPE-$t-results.xml mocha $DEFAULT_ARGS $GREP_TESTS test/$t
29+
done
2030
fi
2131

22-
for t in "${TESTS[@]}"; do
23-
echo -e "\n\nTesting: $t"
24-
25-
#./scripts/mocha-coverage.js $DEFAULT_ARGS $GREP_TESTS --reporter-options mochaFile="../../artifacts/tests/fxa-auth-server/$t/test-results.xml" "test/$t"
26-
MOCHA_FILE=../../artifacts/tests/$npm_package_name/fxa-auth-server-mocha-$TEST_TYPE-$t-results.xml mocha $DEFAULT_ARGS $GREP_TESTS test/$t
27-
done
28-
2932
if [ "$TEST_TYPE" == 'integration' ]; then
3033
yarn run clean-up-old-ci-stripe-customers;
3134
fi;
@@ -42,6 +45,16 @@ elif [ "$TEST_TYPE" == 'integration' ]; then
4245
JEST_JUNIT_OUTPUT_DIR="../../artifacts/tests/fxa-auth-server" \
4346
JEST_JUNIT_OUTPUT_NAME="fxa-auth-server-jest-integration-results.xml" \
4447
npx jest --coverage --forceExit --ci --reporters=default --reporters=jest-junit --testPathPattern='verification-reminders'
48+
elif [ "$TEST_TYPE" == 'integration-jest' ]; then
49+
echo -e "\n\nRunning Jest verification-reminders tests"
50+
JEST_JUNIT_OUTPUT_DIR="../../artifacts/tests/fxa-auth-server" \
51+
JEST_JUNIT_OUTPUT_NAME="fxa-auth-server-jest-verification-reminders-results.xml" \
52+
npx jest --coverage --forceExit --ci --reporters=default --reporters=jest-junit --testPathPattern='verification-reminders'
53+
54+
echo -e "\n\nRunning Jest migrated integration tests"
55+
JEST_JUNIT_OUTPUT_DIR="../../artifacts/tests/fxa-auth-server" \
56+
JEST_JUNIT_OUTPUT_NAME="fxa-auth-server-jest-integration-jest-results.xml" \
57+
npx jest --config jest.integration.config.js --forceExit --ci --reporters=default --reporters=jest-junit
4558
elif [ -z "$TEST_TYPE" ]; then
4659
echo -e "\n\nRunning all Jest tests"
4760
JEST_JUNIT_OUTPUT_DIR="../../artifacts/tests/fxa-auth-server" \

packages/fxa-auth-server/test/remote/account_create.spec.ts renamed to packages/fxa-auth-server/test/remote/account_create.in.spec.ts

Lines changed: 202 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,19 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import { createTestServer, TestServerInstance } from '../support/helpers/test-server';
65
import crypto from 'crypto';
76

8-
interface AuthServerError extends Error {
9-
errno: number;
10-
code: number;
11-
email: string;
12-
}
7+
import * as jwt from '../../lib/oauth/jwt';
8+
import { createTestServer, TestServerInstance } from '../support/helpers/test-server';
9+
import { AuthServerError, generateMetricsContext } from '../support/helpers/test-utils';
1310

1411
interface TestConfig extends Record<string, unknown> {
1512
smtp: { syncUrl: string };
1613
publicUrl: string;
1714
}
1815

16+
// eslint-disable-next-line @typescript-eslint/no-require-imports
1917
const Client = require('../client')();
20-
const mocks = require('../mocks');
2118

2219
let server: TestServerInstance;
2320
let config: TestConfig;
@@ -167,7 +164,6 @@ describe.each(testVersions)(
167164

168165
const stubResponse = await client.stubAccount('dcdb5ae7add825d2');
169166

170-
const jwt = require('../../lib/oauth/jwt');
171167
const setupToken = jwt.sign(
172168
{ uid: stubResponse.uid, iat: Date.now() },
173169
{ header: { typ: 'fin+JWT' } }
@@ -236,7 +232,6 @@ describe.each(testVersions)(
236232

237233
const stubResponse = await client.stubAccount('dcdb5ae7add825d2');
238234

239-
const jwt = require('../../lib/oauth/jwt');
240235
const setupToken = jwt.sign(
241236
{
242237
uid: stubResponse.uid,
@@ -431,6 +426,195 @@ describe.each(testVersions)(
431426
}
432427
});
433428

429+
it('invalid entrypointExperiment', async () => {
430+
const api = new Client.Api(server.publicUrl, testOptions);
431+
const email = server.uniqueEmail();
432+
const authPW =
433+
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF';
434+
const options = {
435+
...testOptions,
436+
metricsContext: {
437+
entrypoint: 'foo',
438+
entrypointExperiment: ';',
439+
entrypointVariation: 'var',
440+
utmCampaign: 'bar',
441+
utmContent: 'baz',
442+
utmMedium: 'qux',
443+
utmSource: 'wibble',
444+
utmTerm: 'blee',
445+
},
446+
};
447+
448+
try {
449+
await api.accountCreate(email, authPW, options);
450+
fail('should have thrown');
451+
} catch (err: unknown) {
452+
expect((err as AuthServerError).errno).toBe(107);
453+
}
454+
});
455+
456+
it('invalid entrypointVariation', async () => {
457+
const api = new Client.Api(server.publicUrl, testOptions);
458+
const email = server.uniqueEmail();
459+
const authPW =
460+
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF';
461+
const options = {
462+
...testOptions,
463+
metricsContext: {
464+
entrypoint: 'foo',
465+
entrypointExperiment: 'exp',
466+
entrypointVariation: ';',
467+
utmCampaign: 'bar',
468+
utmContent: 'baz',
469+
utmMedium: 'qux',
470+
utmSource: 'wibble',
471+
utmTerm: 'blee',
472+
},
473+
};
474+
475+
try {
476+
await api.accountCreate(email, authPW, options);
477+
fail('should have thrown');
478+
} catch (err: unknown) {
479+
expect((err as AuthServerError).errno).toBe(107);
480+
}
481+
});
482+
483+
it('invalid utmCampaign', async () => {
484+
const api = new Client.Api(server.publicUrl, testOptions);
485+
const email = server.uniqueEmail();
486+
const authPW =
487+
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF';
488+
const options = {
489+
...testOptions,
490+
metricsContext: {
491+
entrypoint: 'foo',
492+
entrypointExperiment: 'exp',
493+
entrypointVariation: 'var',
494+
utmCampaign: ';',
495+
utmContent: 'bar',
496+
utmMedium: 'baz',
497+
utmSource: 'qux',
498+
utmTerm: 'wibble',
499+
},
500+
};
501+
502+
try {
503+
await api.accountCreate(email, authPW, options);
504+
fail('should have thrown');
505+
} catch (err: unknown) {
506+
expect((err as AuthServerError).errno).toBe(107);
507+
}
508+
});
509+
510+
it('invalid utmContent', async () => {
511+
const api = new Client.Api(server.publicUrl, testOptions);
512+
const email = server.uniqueEmail();
513+
const authPW =
514+
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF';
515+
const options = {
516+
...testOptions,
517+
metricsContext: {
518+
entrypoint: 'foo',
519+
entrypointExperiment: 'exp',
520+
entrypointVariation: 'var',
521+
utmCampaign: 'bar',
522+
utmContent: ';',
523+
utmMedium: 'baz',
524+
utmSource: 'qux',
525+
utmTerm: 'wibble',
526+
},
527+
};
528+
529+
try {
530+
await api.accountCreate(email, authPW, options);
531+
fail('should have thrown');
532+
} catch (err: unknown) {
533+
expect((err as AuthServerError).errno).toBe(107);
534+
}
535+
});
536+
537+
it('invalid utmMedium', async () => {
538+
const api = new Client.Api(server.publicUrl, testOptions);
539+
const email = server.uniqueEmail();
540+
const authPW =
541+
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF';
542+
const options = {
543+
...testOptions,
544+
metricsContext: {
545+
entrypoint: 'foo',
546+
entrypointExperiment: 'exp',
547+
entrypointVariation: 'var',
548+
utmCampaign: 'bar',
549+
utmContent: 'baz',
550+
utmMedium: ';',
551+
utmSource: 'qux',
552+
utmTerm: 'wibble',
553+
},
554+
};
555+
556+
try {
557+
await api.accountCreate(email, authPW, options);
558+
fail('should have thrown');
559+
} catch (err: unknown) {
560+
expect((err as AuthServerError).errno).toBe(107);
561+
}
562+
});
563+
564+
it('invalid utmSource', async () => {
565+
const api = new Client.Api(server.publicUrl, testOptions);
566+
const email = server.uniqueEmail();
567+
const authPW =
568+
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF';
569+
const options = {
570+
...testOptions,
571+
metricsContext: {
572+
entrypoint: 'foo',
573+
entrypointExperiment: 'exp',
574+
entrypointVariation: 'var',
575+
utmCampaign: 'bar',
576+
utmContent: 'baz',
577+
utmMedium: 'qux',
578+
utmSource: ';',
579+
utmTerm: 'wibble',
580+
},
581+
};
582+
583+
try {
584+
await api.accountCreate(email, authPW, options);
585+
fail('should have thrown');
586+
} catch (err: unknown) {
587+
expect((err as AuthServerError).errno).toBe(107);
588+
}
589+
});
590+
591+
it('invalid utmTerm', async () => {
592+
const api = new Client.Api(server.publicUrl, testOptions);
593+
const email = server.uniqueEmail();
594+
const authPW =
595+
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF';
596+
const options = {
597+
...testOptions,
598+
metricsContext: {
599+
entrypoint: 'foo',
600+
entrypointExperiment: 'exp',
601+
entrypointVariation: 'var',
602+
utmCampaign: 'bar',
603+
utmContent: 'baz',
604+
utmMedium: 'qux',
605+
utmSource: 'wibble',
606+
utmTerm: ';',
607+
},
608+
};
609+
610+
try {
611+
await api.accountCreate(email, authPW, options);
612+
fail('should have thrown');
613+
} catch (err: unknown) {
614+
expect((err as AuthServerError).errno).toBe(107);
615+
}
616+
});
617+
434618
it('create account with service query parameter', async () => {
435619
const email = server.uniqueEmail();
436620

@@ -470,8 +654,8 @@ describe.each(testVersions)(
470654
},
471655
});
472656
fail('account creation should have failed');
473-
} catch (err) {
474-
expect(err).toBeTruthy();
657+
} catch (err: unknown) {
658+
expect((err as AuthServerError).errno).toBe(107);
475659
}
476660
});
477661

@@ -488,16 +672,16 @@ describe.each(testVersions)(
488672
},
489673
});
490674
fail('account creation should have failed');
491-
} catch (err) {
492-
expect(err).toBeTruthy();
675+
} catch (err: unknown) {
676+
expect((err as AuthServerError).errno).toBe(107);
493677
}
494678
});
495679

496680
it('account creation works with maximal metricsContext metadata', async () => {
497681
const email = server.uniqueEmail();
498682
const options = {
499683
...testOptions,
500-
metricsContext: mocks.generateMetricsContext(),
684+
metricsContext: generateMetricsContext(),
501685
};
502686

503687
const client = await Client.create(server.publicUrl, email, 'foo', options);
@@ -532,8 +716,8 @@ describe.each(testVersions)(
532716
},
533717
});
534718
fail('account creation should have failed');
535-
} catch (err) {
536-
expect(err).toBeTruthy();
719+
} catch (err: unknown) {
720+
expect((err as AuthServerError).errno).toBe(107);
537721
}
538722
});
539723

@@ -548,8 +732,8 @@ describe.each(testVersions)(
548732
},
549733
});
550734
fail('account creation should have failed');
551-
} catch (err) {
552-
expect(err).toBeTruthy();
735+
} catch (err: unknown) {
736+
expect((err as AuthServerError).errno).toBe(107);
553737
}
554738
});
555739

0 commit comments

Comments
 (0)