Skip to content

Commit

Permalink
Task/WG-368 improve unit testing of requests (#280)
Browse files Browse the repository at this point in the history
* Update global test setup to check to make sure requests are mocked.

* also ignore some warnings.
* Add nock for request mocking

* Update imports

* Fix linting issues

* Set up nock so we handle CORS

* Add tapisUrl

* Use nock in testing

* Switch from nock to msw

* Remove empty file

* Add missing fixture

* Ingnore warnings

* Refactor into test dir

* Use test render util

* Update comment

* Add missing handlers.ts
  • Loading branch information
nathanfranklin authored Nov 11, 2024
1 parent f5767b2 commit a54b319
Show file tree
Hide file tree
Showing 26 changed files with 782 additions and 209 deletions.
13 changes: 8 additions & 5 deletions react/jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const esModules = [
'@react-leaflet',
'react-leaflet',
'@tacc/core-components',
'uuid',
].join('|');

module.exports = {
Expand All @@ -32,7 +33,6 @@ module.exports = {
'!src/**/*.spec.{js,jsx,ts,tsx}',
// Exclude test utilities
'!src/test/**/*',
'!src/testUtil.ts',
'!src/__fixtures__/**/*',
// Exclude secrets and other files
'!src/secret_local*ts',
Expand Down Expand Up @@ -156,7 +156,7 @@ module.exports = {
// setupFiles: [],

// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],

// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
Expand All @@ -165,11 +165,14 @@ module.exports = {
// snapshotSerializers: [],

// The test environment that will be used for testing
testEnvironment: 'jsdom',
// https://mswjs.io/docs/migrations/1.x-to-2.x#requestresponsetextencoder-is-not-defined-jest; consider moving to vitest
testEnvironment: 'jest-fixed-jsdom',

// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},

// Force JSDOM to import msw/node (see https://stackoverflow.com/questions/77399773/cannot-find-module-msw-node-from)
testEnvironmentOptions: {
customExportConditions: [''],
},
// Adds a location field to test results
// testLocationInResults: false,

Expand Down
86 changes: 86 additions & 0 deletions react/jest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { testDevConfiguration } from '@hazmapper/__fixtures__/appConfigurationFixture';
import { server } from '@hazmapper/test/testUtil';

/***** A) Setup the configuration used for unit testing *****/
jest.mock('@hazmapper/hooks/environment/getLocalAppConfiguration', () => ({
getLocalAppConfiguration: jest.fn(() => testDevConfiguration),
}));

/***** B) Ignore some known warnings/errors *****/

// List of `console.warn` messages that can be ignored
const ignoredWarnings = ['React Router Future Flag Warning'];

// List of component-related errors to ignore
const ignoredErrors = [
// Ignore request code errors as 500 is commong for our testing purposes
/Request failed with status code 500/,
];

// Helper function to determine if a `console.warn` message should be ignored
export function shouldIgnoreWarning(message: string): boolean {
return ignoredWarnings.some((warning) => message.includes(warning));
}

// Helper function to determine if a defaultProps error is from core-components
// Ingnoring till https://tacc-main.atlassian.net/browse/WI-208 is done
function isDefaultPropsErrorFromCoreComponents(args: any[]): boolean {
// Check if this is a defaultProps warning
const isDefaultPropsWarning = args[0]?.includes?.(
'Support for defaultProps will be removed from function components'
);
if (!isDefaultPropsWarning) return false;

// Look through all arguments for stack trace containing @tacc/core-components
return args.some(
(arg) => typeof arg === 'string' && arg.includes('@tacc/core-components')
);
}

// Helper function to determine if a console.error message should be ignored
export function shouldIgnoreError(args: any[]): boolean {
// If it's a defaultProps warning from core-components, ignore it
if (isDefaultPropsErrorFromCoreComponents(args)) {
return true;
}

// Check other error patterns
const messageStr = typeof args[0] === 'string' ? args[0] : args[0]?.message;
return ignoredErrors.some((pattern) => pattern.test(messageStr));
}

/***** C) Setup testing and also ensure that we are mocking things in tests *****/

beforeAll(() => {
// Establish mocking of APIs before all tests
server.listen({ onUnhandledRequest: 'error' });

const originalError = console.error;

jest.spyOn(console, 'error').mockImplementation((...args: any[]) => {
if (shouldIgnoreError(args)) {
return;
}
originalError.apply(console, args);
});

const originalWarn = console.warn;

jest.spyOn(console, 'warn').mockImplementation((...args: any[]) => {
// Check if contains the 500 status message as common for our testing purposes
// so not needed to be logged;
if (typeof args[0] === 'string' && shouldIgnoreWarning(args[0])) {
return;
}
originalWarn.apply(console, args);
});
});

// Reset any runtime request handlers we may add during the tests
afterEach(() => server.resetHandlers());

// Clean up after the tests are finished
afterAll(() => {
server.close();
jest.restoreAllMocks();
});
Loading

0 comments on commit a54b319

Please sign in to comment.