Setup jest to run API/notification tests in isolation (#146)

* remove unused testUtils

* update jest, rename .babelrc to babel.config.js

renaming babel config is required for jest to be able to transform es6 libs (like solana/wallet-adapter-phantom) https://stackoverflow.com/a/54656593

* test: update jest to handle tsconfig baseUrl/paths settings

* test: set jest testEnvironment to jsdom (rather than node)

* test: let `babel-jest` handle js(x) as well as ts(x) files

* test: add simple test to verify test settings

* test: simplify jest/babel setup

was able to be simplified after #149 was merged

* test: faster tests with swc/jest vs babel-jest

* test: use `next/jest`

- remove manual file mocks as they're handled by next/jest
- create test/setup.js file
- remove target config https://nextjs.org/docs/messages/deprecated-target-config

* test: test homepage redirects
This commit is contained in:
John Rees 2021-12-23 01:58:02 +00:00 committed by GitHub
parent b241da4187
commit ba3b04a87e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 989 additions and 1476 deletions

View File

@ -12,7 +12,3 @@
],
"plugins": ["@emotion/babel-plugin", "babel-plugin-macros"]
}
// {
// "presets": ["next/babel"]
// }

View File

@ -1,17 +1,25 @@
module.exports = {
roots: ['<rootDir>'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'json', 'jsx'],
testPathIgnorePatterns: ['<rootDir>[/\\\\](node_modules|.next)[/\\\\]'],
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(ts|tsx)$'],
transform: {
'^.+\\.(ts|tsx)$': 'babel-jest',
},
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
moduleNameMapper: {
'\\.(css|less|sass|scss)$': 'identity-obj-proxy',
'\\.(gif|ttf|eot|svg|png)$': '<rootDir>/test/__mocks__/fileMock.js',
},
const nextJest = require('next/jest')
const { resolve } = require('path')
const { readdirSync } = require('fs')
// XXX: hack to deal with tsconfig.baseUrl: "." and tsconfig.paths
const directories = readdirSync(__dirname, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map(({ name }) => name)
.filter((dir) => !dir.startsWith('.') && dir !== 'node_modules')
.reduce(
(acc, dir) => ({
...acc,
[`^${dir}/(.*)$`]: resolve(__dirname, `./${dir}/$1`),
[`^@${dir}/(.*)$`]: resolve(__dirname, `./${dir}/$1`),
}),
{}
)
const customConfig = {
moduleNameMapper: directories,
setupFilesAfterEnv: ['<rootDir>/test/setup.js'],
moduleDirectories: ['node_modules', '<rootDir>/'],
}
module.exports = nextJest({ dir: './' })(customConfig)

View File

@ -8,7 +8,6 @@ const withTM = require('next-transpile-modules')([
])
module.exports = withTM({
target: 'serverless',
webpack: (config, { isServer }) => {
config.module.rules.push({
test: /\.svg$/,

View File

@ -59,21 +59,20 @@
},
"devDependencies": {
"@emotion/babel-preset-css-prop": "^11.2.0",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^11.2.5",
"@types/jest": "^26.0.20",
"@types/jest": "^27.0.3",
"@types/node": "^14.14.25",
"@types/react": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^5.7.0",
"@typescript-eslint/parser": "^5.7.0",
"babel-jest": "^26.6.3",
"eslint": "^8.4.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"husky": "^6.0.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^26.6.3",
"jest-watch-typeahead": "^0.6.1",
"jest": "^27.4.5",
"lint-staged": "^10.0.10",
"next-router-mock": "^0.6.3",
"postcss": "^8.2.12",

View File

@ -6,10 +6,10 @@ const Index = () => {
useEffect(() => {
const { REALM } = process.env
const mainUrl = REALM ? `/dao/${REALM}` : '/realms'
router.push(mainUrl)
router.replace(mainUrl)
}, [])
return <></>
return null
}
export default Index

View File

@ -1 +0,0 @@
module.exports = 'test-file-stub'

View File

@ -0,0 +1,14 @@
import { getCertifiedRealmInfo } from 'models/registry/api'
import { getConnectionContext } from 'utils/connection'
import realms from 'public/realms/mainnet-beta.json'
test('getCertifiedRealmInfo', async () => {
const mango = realms.find(({ symbol }) => symbol === 'MNGO')!
const realmInfo = await getCertifiedRealmInfo(
mango.symbol,
getConnectionContext('mainnet')
)
expect(realmInfo!.realmId.toBase58()).toEqual(mango.realmId)
})

View File

@ -1,10 +1,39 @@
/**
* @jest-environment jsdom
*/
import React from 'react'
import { render } from '../testUtils'
import Home from '../../pages/index'
import { render, waitFor } from '@testing-library/react'
import singletonRouter from 'next/router'
describe('Home page', () => {
it('renders', () => {
render(<Home />, {})
expect(true).toBe(true)
const originalRealm = process.env.REALM
describe('Home page redirects to', () => {
afterEach(() => {
process.env.REALM = originalRealm
})
test('/realms when process.env.REALM is not set', async () => {
delete process.env.REALM
render(<Home />)
await waitFor(() => {
expect(singletonRouter).toMatchObject({
pathname: '/realms',
})
})
})
test(`/dao/MNGO when process.env.REALM = 'MNGO'`, async () => {
process.env.REALM = 'MNGO'
render(<Home />)
await waitFor(() => {
expect(singletonRouter).toMatchObject({
pathname: '/dao/MNGO',
})
})
})
test.todo(`/realms when process.env.REALM is not a valid realm symbol`)
})

3
test/setup.js Normal file
View File

@ -0,0 +1,3 @@
import '@testing-library/jest-dom/extend-expect'
jest.mock('next/router', () => require('next-router-mock'))

View File

@ -1,26 +0,0 @@
import { render } from '@testing-library/react'
// import { ThemeProvider } from "my-ui-lib"
// import { TranslationProvider } from "my-i18n-lib"
// import defaultStrings from "i18n/en-x-default"
jest.mock('next/router', () => require('next-router-mock'))
const Providers = ({ children }) => {
return children
// return (
// <ThemeProvider theme="light">
// <TranslationProvider messages={defaultStrings}>
// {children}
// </TranslationProvider>
// </ThemeProvider>
// )
}
const customRender = (ui, options = {}) =>
render(ui, { wrapper: Providers, ...options })
// re-export everything
export * from '@testing-library/react'
// override render method
export { customRender as render }

2326
yarn.lock

File diff suppressed because it is too large Load Diff