upgrade jest to v28
refs DE-1284 Change-Id: I6f91f5d986d51d73a809cba9fd93355a6f8de7a4 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/296476 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Andrea Cirulli <andrea.cirulli@instructure.com> QA-Review: Aaron Ogata <aogata@instructure.com> Product-Review: Aaron Ogata <aogata@instructure.com>
This commit is contained in:
parent
4bdbe477cf
commit
6afa51a0ef
|
@ -23,6 +23,7 @@ module.exports = {
|
|||
'\\.svg$': '<rootDir>/jest/imageMock.js',
|
||||
'node_modules-version-of-backbone': require.resolve('backbone'),
|
||||
'node_modules-version-of-react-modal': require.resolve('react-modal'),
|
||||
'underscore$': require.resolve('lodash-underscore'),
|
||||
'^Backbone$': '<rootDir>/public/javascripts/Backbone.js',
|
||||
// jest can't import the icons
|
||||
'@instructure/ui-icons/es/svg': '<rootDir>/packages/canvas-rce/src/rce/__tests__/_mockIcons.js',
|
||||
|
@ -33,7 +34,9 @@ module.exports = {
|
|||
'<rootDir>/packages/canvas-rce/lib/rce/plugins/shared/Upload/CategoryProcessor',
|
||||
// mock the tinymce-react Editor react component
|
||||
'@tinymce/tinymce-react': '<rootDir>/packages/canvas-rce/src/rce/__mocks__/tinymceReact.js',
|
||||
'decimal.js/decimal.mjs': 'decimal.js/decimal.js'
|
||||
'decimal.js/decimal.mjs': 'decimal.js/decimal.js',
|
||||
// https://github.com/ai/nanoid/issues/363
|
||||
"^nanoid(/(.*)|$)": "nanoid$1",
|
||||
},
|
||||
roots: ['<rootDir>/ui', 'gems/plugins', 'public/javascripts'],
|
||||
moduleDirectories: ['ui/shims', 'public/javascripts', 'node_modules'],
|
||||
|
@ -78,7 +81,7 @@ module.exports = {
|
|||
transform: {
|
||||
'\\.coffee$': '<rootDir>/jest/coffeeTransformer.js',
|
||||
'\\.handlebars$': '<rootDir>/jest/handlebarsTransformer.js',
|
||||
'\\.graphql$': 'jest-raw-loader',
|
||||
'\\.graphql$': '<rootDir>/jest/rawLoader.js',
|
||||
'\\.[jt]sx?$': [
|
||||
'babel-jest',
|
||||
{
|
||||
|
|
|
@ -21,9 +21,9 @@ const {transform} = require('@babel/core')
|
|||
|
||||
exports.process = (coffee, path) => {
|
||||
const esm = compile(coffee, {bare: true})
|
||||
const cjs = transform(esm, {
|
||||
|
||||
return transform(esm, {
|
||||
filename: path,
|
||||
plugins: ['@babel/plugin-transform-modules-commonjs']
|
||||
}).code
|
||||
return cjs
|
||||
})
|
||||
}
|
||||
|
|
|
@ -24,9 +24,9 @@ exports.process = (source, path) => {
|
|||
// brandable_css assets are not available in test
|
||||
injectBrandableStylesheet: false
|
||||
})
|
||||
const cjs = transform(amd, {
|
||||
|
||||
return transform(amd, {
|
||||
filename: path,
|
||||
plugins: ['@babel/plugin-transform-modules-commonjs']
|
||||
}).code
|
||||
return cjs
|
||||
})
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (C) 2022 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
process: (data) => {
|
||||
return {
|
||||
code: `module.exports = ${JSON.stringify(data)}`
|
||||
}
|
||||
}
|
||||
}
|
|
@ -231,7 +231,7 @@
|
|||
"array-flat-polyfill": "^1.0.1",
|
||||
"axe-core": "~2.1.7",
|
||||
"babel-eslint": "^10",
|
||||
"babel-jest": "^26",
|
||||
"babel-jest": "^28",
|
||||
"babel-loader": "^8",
|
||||
"babel-plugin-transform-react-remove-prop-types": "^0.4",
|
||||
"babel-plugin-typescript-to-proptypes": "^1.4.2",
|
||||
|
@ -282,15 +282,15 @@
|
|||
"imports-loader": "^0.8",
|
||||
"istanbul-instrumenter-loader": "^3",
|
||||
"istanbul-merge": "^1.1.1",
|
||||
"jest": "^27",
|
||||
"jest": "^28",
|
||||
"jest-canvas-mock": "^2",
|
||||
"jest-config": "^27",
|
||||
"jest-config": "^28",
|
||||
"jest-environment-jsdom": "^28",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"jest-html-reporter": "^3",
|
||||
"jest-junit": "^7",
|
||||
"jest-localstorage-mock": "^2",
|
||||
"jest-moxios-utils": "^1",
|
||||
"jest-raw-loader": "^1",
|
||||
"jsdom-global": "^3.0.2",
|
||||
"json-loader": "^0.5.7",
|
||||
"karma": "^3",
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
"esm": "^3.2.25",
|
||||
"format-message-cli": "^6",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^27",
|
||||
"jest": "^28",
|
||||
"jest-canvas-mock": "^2",
|
||||
"jest-junit": "^7",
|
||||
"jest-moxios-utils": "^1",
|
||||
|
|
|
@ -13,6 +13,6 @@
|
|||
"author": "Ahmad Amireh <ahmad@instructure.com>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"jest": "^27"
|
||||
"jest": "^28"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
"timezone": "https://registry.npmjs.org/@brentburgoyne/timezone/-/timezone-1.0.24.tgz"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^27"
|
||||
"jest": "^28"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"jest": "^27"
|
||||
"jest": "^28"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@babel/preset-typescript": "^7.15.0",
|
||||
"@jest/globals": "^27.1.0",
|
||||
"babel-jest": "^27.1.0",
|
||||
"jest": "^27",
|
||||
"jest": "^28",
|
||||
"jest-localstorage-mock": "^2.4.17"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"lint": "prettier bin/**/*.js lib/**/*.json --write"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^27",
|
||||
"jest": "^28",
|
||||
"prettier": "^2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('WebcamCapture', () => {
|
|||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await act(async() => { jest.runOnlyPendingTimers() })
|
||||
await act(async() => { jest.runAllTimers() })
|
||||
delete navigator.mediaDevices
|
||||
})
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import {render, waitFor} from '@testing-library/react'
|
|||
import userEvent from '@testing-library/user-event'
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
|
||||
jest.setTimeout(20000)
|
||||
jest.setTimeout(25000)
|
||||
|
||||
const originalState = store.getState()
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ import * as useGroupDetail from '@canvas/outcomes/react/hooks/useGroupDetail'
|
|||
|
||||
jest.setTimeout(15000)
|
||||
jest.mock('@canvas/rce/RichContentEditor')
|
||||
jest.useFakeTimers('legacy')
|
||||
jest.useFakeTimers({ legacyFakeTimers: true })
|
||||
|
||||
describe('OutcomeManagementPanel', () => {
|
||||
let cache
|
||||
|
|
|
@ -38,7 +38,7 @@ import {clickEl} from '@canvas/outcomes/react/helpers/testHelpers'
|
|||
import resolveProgress from '@canvas/progress/resolve_progress'
|
||||
|
||||
jest.mock('@canvas/progress/resolve_progress')
|
||||
jest.useFakeTimers('legacy')
|
||||
jest.useFakeTimers({ legacyFakeTimers: true })
|
||||
|
||||
const delayImportOutcomesProgress = () => {
|
||||
let realResolve
|
||||
|
|
|
@ -24,6 +24,12 @@ import DirectShareUserModal from '../DirectShareUserModal'
|
|||
|
||||
jest.mock('../../effects/useContentShareUserSearchApi')
|
||||
|
||||
const flushAllTimersAndPromises = async () => {
|
||||
while(jest.getTimerCount() > 0) {
|
||||
await act(async () => { jest.runAllTimers() })
|
||||
}
|
||||
}
|
||||
|
||||
describe('DirectShareUserModal', () => {
|
||||
let ariaLive
|
||||
|
||||
|
@ -51,13 +57,14 @@ describe('DirectShareUserModal', () => {
|
|||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
afterEach(async () => {
|
||||
await flushAllTimersAndPromises()
|
||||
fetchMock.restore()
|
||||
})
|
||||
|
||||
function selectUser(getByText, getByLabelText, name = 'abc') {
|
||||
fireEvent.change(getByLabelText(/send to:/i), {target: {value: name}})
|
||||
act(() => jest.runAllTimers()) // let the debounce happen
|
||||
async function selectUser(getByText, findByLabelText, name = 'abc') {
|
||||
fireEvent.change(await findByLabelText(/send to:/i), {target: {value: name}})
|
||||
await act(async () => jest.runAllTimers()) // let the debounce happen
|
||||
fireEvent.click(getByText(name))
|
||||
}
|
||||
|
||||
|
@ -66,30 +73,30 @@ describe('DirectShareUserModal', () => {
|
|||
expect(getByText('Send').closest('button').getAttribute('disabled')).toBe('')
|
||||
})
|
||||
|
||||
it('enables the send button only when a user is selected', () => {
|
||||
const {getByText, getAllByText, getByLabelText} = render(
|
||||
it('enables the send button only when a user is selected UNDER TEST', async () => {
|
||||
const {getByText, getAllByText, findByLabelText} = render(
|
||||
<DirectShareUserModal open courseId="1" />
|
||||
)
|
||||
selectUser(getByText, getByLabelText)
|
||||
await selectUser(getByText, findByLabelText)
|
||||
expect(getByText('Send').closest('button').getAttribute('disabled')).toBe(null)
|
||||
// remove the selected user from the list
|
||||
fireEvent.click(getAllByText('abc')[1]) // first one is SR alert
|
||||
expect(getByText('Send').closest('button').getAttribute('disabled')).toBe('')
|
||||
})
|
||||
|
||||
it('disables the send button when a search has started', () => {
|
||||
const {getByText, getByLabelText} = render(
|
||||
it('disables the send button when a search has started UNDER TEST', async () => {
|
||||
const {getByText, findByLabelText} = render(
|
||||
<DirectShareUserModal open courseId="1" onDismiss={Function.prototype} />
|
||||
)
|
||||
selectUser(getByText, getByLabelText)
|
||||
await selectUser(getByText, findByLabelText)
|
||||
fireEvent.click(getByText('Send'))
|
||||
expect(getByText('Send').closest('button').getAttribute('disabled')).toBe('')
|
||||
})
|
||||
|
||||
it('starts a share operation and reports status', async () => {
|
||||
it('starts a share operation and reports status UNDER TEST', async () => {
|
||||
fetchMock.postOnce('path:/api/v1/users/self/content_shares', 200)
|
||||
const onDismiss = jest.fn()
|
||||
const {getByText, getAllByText, getByLabelText} = render(
|
||||
const {getByText, getAllByText, findByLabelText} = render(
|
||||
<DirectShareUserModal
|
||||
open
|
||||
courseId="1"
|
||||
|
@ -97,7 +104,7 @@ describe('DirectShareUserModal', () => {
|
|||
onDismiss={onDismiss}
|
||||
/>
|
||||
)
|
||||
selectUser(getByText, getByLabelText)
|
||||
await selectUser(getByText, findByLabelText)
|
||||
fireEvent.click(getByText('Send'))
|
||||
const [, fetchOptions] = fetchMock.lastCall()
|
||||
expect(fetchOptions.method).toBe('POST')
|
||||
|
@ -114,10 +121,10 @@ describe('DirectShareUserModal', () => {
|
|||
|
||||
it('clears user selection when the modal is closed', async () => {
|
||||
fetchMock.get('*', [{id: 'abc', name: 'abc'}])
|
||||
const {queryByText, getByText, getByLabelText, rerender} = render(
|
||||
const {queryByText, getByText, findByLabelText, rerender} = render(
|
||||
<DirectShareUserModal open courseId="1" />
|
||||
)
|
||||
selectUser(getByText, getByLabelText)
|
||||
await selectUser(getByText, findByLabelText)
|
||||
rerender(<DirectShareUserModal open={false} courseId="1" />)
|
||||
rerender(<DirectShareUserModal open courseId="1" />)
|
||||
expect(queryByText('abc')).toBeNull()
|
||||
|
@ -134,14 +141,14 @@ describe('DirectShareUserModal', () => {
|
|||
|
||||
it('reports an error if the fetch fails', async () => {
|
||||
fetchMock.postOnce('path:/api/v1/users/self/content_shares', 400)
|
||||
const {getByText, getByLabelText} = render(
|
||||
const {getByText, findByLabelText} = render(
|
||||
<DirectShareUserModal
|
||||
open
|
||||
courseId="1"
|
||||
contentShare={{content_type: 'discussion_topic', content_id: '42'}}
|
||||
/>
|
||||
)
|
||||
selectUser(getByText, getByLabelText)
|
||||
await selectUser(getByText, findByLabelText)
|
||||
fireEvent.click(getByText('Send'))
|
||||
await act(() => fetchMock.flush(true))
|
||||
expect(getByText(/error/i)).toBeInTheDocument()
|
||||
|
|
|
@ -29,7 +29,7 @@ import * as apiClient from '../apiClient'
|
|||
jest.mock('@canvas/alerts/react/FlashAlert')
|
||||
jest.mock('../apiClient')
|
||||
|
||||
jest.useFakeTimers('legacy')
|
||||
jest.useFakeTimers({ legacyFakeTimers: true })
|
||||
|
||||
const file = sinon.createStubInstance(File)
|
||||
const defaultProps = (props = {}) =>
|
||||
|
|
|
@ -28,6 +28,12 @@ import {FIND_GROUP_OUTCOMES} from '@canvas/outcomes/graphql/Management'
|
|||
|
||||
jest.mock('@canvas/alerts/react/FlashAlert')
|
||||
|
||||
const flushAllTimersAndPromises = async () => {
|
||||
while(jest.getTimerCount() > 0) {
|
||||
await act(async () => { jest.runAllTimers() })
|
||||
}
|
||||
}
|
||||
|
||||
const outcomeTitles = result => result.current.group.outcomes.edges.map(edge => edge.node.title)
|
||||
const outcomeFriendlyDescriptions = result =>
|
||||
result.current.group.outcomes.edges.map(edge => edge.node.friendlyDescription?.description || '')
|
||||
|
@ -176,7 +182,7 @@ describe('groupDetailHook', () => {
|
|||
expect(outcomeTitles(result)).toEqual(['Outcome 1 - Group 1', 'Outcome 2 - Group 1'])
|
||||
expect(outcomeFriendlyDescriptions(result)).toEqual(['', ''])
|
||||
act(() => rerender('200'))
|
||||
await act(async () => jest.runAllTimers())
|
||||
await flushAllTimersAndPromises()
|
||||
expect(result.current.group.title).toBe('Refetched Group 200')
|
||||
expect(outcomeTitles(result)).toEqual([
|
||||
'Refetched Outcome 1 - Group 200',
|
||||
|
|
Loading…
Reference in New Issue