Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build!: use node 18 #383

Merged
merged 18 commits into from
Mar 13, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test: fix environment
beawar committed Jan 29, 2024
commit d2693985431806e703da6994cf3729fc190ac8cd
38 changes: 27 additions & 11 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { Config } from 'jest';

export default {
const config: Config = {
// All imported modules in your tests should be mocked automatically
// automock: false,

@@ -48,14 +49,14 @@ export default {
coverageReporters: ['text', 'cobertura'],

// An object that configures minimum threshold enforcement for coverage results
coverageThreshold: {
// global: {
// branches: 75,
// functions: 75,
// lines: 75,
// statements: 75
// }
},
// coverageThreshold: {
// global: {
// branches: 75,
// functions: 75,
// lines: 75,
// statements: 75
// }
// },

// A path to a custom dependency extractor
// dependencyExtractor: undefined,
@@ -65,7 +66,8 @@ export default {

// The default configuration for fake timers
fakeTimers: {
enableGlobally: true
enableGlobally: true,
doNotFake: ['queueMicrotask']
},

// Force coverage collection from ignored files using an array of glob patterns
@@ -163,7 +165,19 @@ export default {
testEnvironment: 'jsdom',

// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
testEnvironmentOptions: {
/**
* @note Opt-out from JSDOM using browser-style resolution
* for dependencies. This is simply incorrect, as JSDOM is
* not a browser, and loading browser-oriented bundles in
* Node.js will break things.
*
* Consider migrating to a more modern test runner if you
* don't want to deal with this.
* @see https://mswjs.io/docs/migrations/1.x-to-2.x#cannot-find-module-mswnode-jsdom
*/
customExportConditions: ['']
},

// Adds a location field to test results
// testLocationInResults: false,
@@ -208,3 +222,5 @@ export default {
// Whether to use watchman for file crawling
// watchman: true,
};

export default config;
61 changes: 49 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -92,6 +92,7 @@
"postcss-loader": "^8.0.0",
"ts-node": "^10.9.1",
"typescript": "^5.2.2",
"undici": "^5.28.2",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1",
13 changes: 8 additions & 5 deletions src/boot/loader.test.tsx
Original file line number Diff line number Diff line change
@@ -47,14 +47,17 @@ describe('Loader', () => {

test('If only getInfo request fails, the LoaderFailureModal appears', async () => {
// TODO remove when SHELL-117 will be implemented
controlConsoleError('Unexpected end of JSON input');
controlConsoleError("Cannot read properties of undefined (reading 'Fault')");
// using getComponents and loginConfig default handlers
server.use(
http.post('/service/soap/GetInfoRequest', () =>
HttpResponse.json(null, {
status: 503,
statusText: 'Controlled error: fail getInfo request'
})
HttpResponse.json(
{},
{
status: 503,
statusText: 'Controlled error: fail getInfo request'
}
)
)
);
const loginRes = waitForResponse('get', LOGIN_V3_CONFIG_PATH);
44 changes: 40 additions & 4 deletions src/jest-polyfills.ts
Original file line number Diff line number Diff line change
@@ -4,13 +4,49 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import 'whatwg-fetch';
import { noop } from 'lodash';
import { TextEncoder, TextDecoder } from 'node:util';

// define browser objects not available in jest
// Define browser objects not available in jest
// https://jestjs.io/docs/en/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
// if it's necessary to use a jest mock, place the definition in the beforeEach, because the restoreMock
// config restore all mocks to the initial value (undefined if the object is not present at all)

// If it's necessary to use a jest mock,
// place the definition in the beforeEach,
// because the restoreMock config restore all mocks to the initial value
// (undefined if the object is not present at all)

/**
* @note The block below contains polyfills for Node.js globals
* required for Jest to function when running JSDOM tests.
* These HAVE to be "require" and HAVE to be in this exact
* order, since "undici" depends on the "TextEncoder" global API.
*
* Consider migrating to a more modern test runner if
* you don't want to deal with this.
*
* @see https://mswjs.io/docs/migrations/1.x-to-2.x#requestresponsetextencoder-is-not-defined-jest
*/

Object.defineProperties(global, {
TextEncoder: { value: TextEncoder },
TextDecoder: { value: TextDecoder }
});

// undici requires TextDecoder to be defined,
// so import must occur after the definition of TextDecoder
// Make sure to have undici@5 to make fetch work (see https://github.com/mswjs/msw/issues/1931)
// eslint-disable-next-line @typescript-eslint/no-var-requires,global-require
const { fetch, Headers, FormData, Request, Response } = require('undici');

Object.defineProperties(global, {
fetch: { value: fetch, writable: true },
Blob: { value: Blob },
File: { value: File },
Headers: { value: Headers },
FormData: { value: FormData },
Request: { value: Request },
Response: { value: Response }
});

window.matchMedia = function matchMedia(query: string): MediaQueryList {
return {
15 changes: 9 additions & 6 deletions src/mocks/handlers/logout.ts
Original file line number Diff line number Diff line change
@@ -6,10 +6,13 @@
import { HttpResponse, HttpResponseResolver } from 'msw';

export const logout: HttpResponseResolver<never, never, never> = () =>
HttpResponse.json(null, {
status: 304,
statusText: 'Temporary Redirect',
headers: {
location: 'https://localhost/static/login/'
HttpResponse.json(
{},
{
status: 307,
statusText: 'Temporary Redirect',
headers: {
Location: 'https://localhost/static/login/'
}
}
});
);
2 changes: 1 addition & 1 deletion src/network/fetch.ts
Original file line number Diff line number Diff line change
@@ -176,7 +176,7 @@ export const getSoapFetch =
}
: undefined,
session: session ?? {},
account: getAccount(account as Account, otherAccount),
account: getAccount(account, otherAccount),
userAgent: {
name: userAgent,
version: zimbraVersion
13 changes: 10 additions & 3 deletions src/settings/accounts-settings.test.tsx
Original file line number Diff line number Diff line change
@@ -26,7 +26,9 @@ import { setup } from '../test/utils';

describe('Account setting', () => {
async function waitForGetRightsRequest(): Promise<void> {
await waitForRequest('post', '/service/soap/GetRightsRequest');
// wait for the main UI to render
await screen.findByText('Accounts');
// then wait for the delegates section to render
await screen.findByText('sendAs');
}
const defaultFirstName = faker.person.firstName();
@@ -49,6 +51,7 @@ describe('Account setting', () => {
const persona3FullName = 'New Persona 3';
const persona3Email = '[email protected]';
const persona3Id = faker.string.uuid();

test('When saving the order should not change', async () => {
setupAccountStore(
createAccount(defaultEmail, defaultId, [
@@ -923,7 +926,9 @@ describe('Account setting', () => {
await user.click(screen.getByRole('button', { name: /save/i }));

await pendingBatchRequest;

await act(async () => {
await jest.advanceTimersToNextTimerAsync();
});
const successSnackbar = await screen.findByText('Edits saved correctly');
expect(successSnackbar).toBeVisible();

@@ -984,7 +989,9 @@ describe('Account setting', () => {
await user.click(screen.getByRole('button', { name: /save/i }));

await pendingBatchRequest;

await act(async () => {
await jest.advanceTimersToNextTimerAsync();
});
const successSnackbar = await screen.findByText('Edits saved correctly');
expect(successSnackbar).toBeVisible();