migrating webapp/channels/src/tests files to typescript (#25016)
* migrating webapp/channels/src/tests files to typescript * Fixing linter errors * Fixing the setup config of the jest.config.js * Fixing CI * fix linter errors * Fixing tests * fixing ci
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
6a7adbe59c
Коммит
5d163d3ae0
@@ -41,7 +41,7 @@ const config = {
|
||||
'node_modules/(?!react-native|react-router|p-queue|p-timeout|@mattermost/compass-components|@mattermost/compass-icons)',
|
||||
],
|
||||
setupFiles: ['jest-canvas-mock'],
|
||||
setupFilesAfterEnv: ['<rootDir>/src/tests/setup.js'],
|
||||
setupFilesAfterEnv: ['<rootDir>/src/tests/setup.ts'],
|
||||
testEnvironment: 'jsdom',
|
||||
testTimeout: 60000,
|
||||
testURL: 'http://localhost:8065',
|
||||
|
||||
@@ -423,7 +423,7 @@ const AdvanceTextEditor = ({
|
||||
|
||||
// listen for line break key combo and insert new line character
|
||||
if (Utils.isUnhandledLineBreakKeyCombo(e)) {
|
||||
onMessageChange(Utils.insertLineBreakFromKeyEvent(e));
|
||||
onMessageChange(Utils.insertLineBreakFromKeyEvent(e.nativeEvent));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import React from 'react';
|
||||
import type {Channel, ChannelType} from '@mattermost/types/channels';
|
||||
|
||||
import EditChannelHeaderModal from 'components/edit_channel_header_modal/edit_channel_header_modal';
|
||||
import type {default as EditChannelHeaderModalClass} from 'components/edit_channel_header_modal/edit_channel_header_modal';
|
||||
import Textbox from 'components/textbox';
|
||||
|
||||
import {testComponentForLineBreak} from 'tests/helpers/line_break_helpers';
|
||||
@@ -275,7 +274,7 @@ describe('components/EditChannelHeaderModal', () => {
|
||||
}}
|
||||
/>
|
||||
),
|
||||
(instance: EditChannelHeaderModalClass) => instance.state.header,
|
||||
(instance: React.Component<any, any>) => instance.state.header,
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -157,7 +157,7 @@ export default class EditChannelHeaderModal extends React.PureComponent<Props, S
|
||||
|
||||
// listen for line break key combo and insert new line character
|
||||
if (isUnhandledLineBreakKeyCombo(e)) {
|
||||
this.setState({header: insertLineBreakFromKeyEvent(e as React.KeyboardEvent<HTMLTextAreaElement>)});
|
||||
this.setState({header: insertLineBreakFromKeyEvent(e.nativeEvent)});
|
||||
} else if (ctrlSend && isKeyPressed(e, KeyCodes.ENTER) && e.ctrlKey === true) {
|
||||
this.handleKeyPress(e);
|
||||
}
|
||||
|
||||
@@ -261,5 +261,5 @@ describe('comoponents/EditChannelPurposeModal', () => {
|
||||
onExited={jest.fn()}
|
||||
actions={{patchChannel: jest.fn()}}
|
||||
/>
|
||||
), (instance: EditChannelPurposeModalClass) => instance.state.purpose);
|
||||
), (instance: React.Component<any, any>) => instance.state.purpose);
|
||||
});
|
||||
|
||||
@@ -71,7 +71,7 @@ export class EditChannelPurposeModal extends React.PureComponent<Props, State> {
|
||||
// listen for line break key combo and insert new line character
|
||||
if (Utils.isUnhandledLineBreakKeyCombo(e)) {
|
||||
e.preventDefault();
|
||||
this.setState({purpose: Utils.insertLineBreakFromKeyEvent(e as React.KeyboardEvent<HTMLTextAreaElement>)});
|
||||
this.setState({purpose: Utils.insertLineBreakFromKeyEvent(e.nativeEvent)});
|
||||
} else if (ctrlSend && Keyboard.isKeyPressed(e, Constants.KeyCodes.ENTER) && e.ctrlKey) {
|
||||
e.preventDefault();
|
||||
this.handleSave();
|
||||
|
||||
@@ -332,7 +332,7 @@ const EditPost = ({editingPost, actions, canEditPost, config, channelId, draft,
|
||||
// listen for line break key combo and insert new line character
|
||||
if (Utils.isUnhandledLineBreakKeyCombo(e)) {
|
||||
e.stopPropagation(); // perhaps this should happen in all of these cases? or perhaps Modal should not be listening?
|
||||
setEditText(Utils.insertLineBreakFromKeyEvent(e as React.KeyboardEvent<HTMLTextAreaElement>));
|
||||
setEditText(Utils.insertLineBreakFromKeyEvent(e.nativeEvent));
|
||||
} else if (ctrlEnterKeyCombo) {
|
||||
handleEdit();
|
||||
} else if (Keyboard.isKeyPressed(e, KeyCodes.ESCAPE) && !showEmojiPicker) {
|
||||
|
||||
@@ -86,7 +86,7 @@ const ForwardPostCommentInput = ({channelId, canForwardPost, comment, permaLinkL
|
||||
|
||||
// listen for line break key combo and insert new line character
|
||||
if (Utils.isUnhandledLineBreakKeyCombo(e)) {
|
||||
onChange(Utils.insertLineBreakFromKeyEvent(e));
|
||||
onChange(Utils.insertLineBreakFromKeyEvent(e.nativeEvent));
|
||||
} else if (ctrlAltCombo && markdownLinkKey) {
|
||||
applyMarkdownMode({
|
||||
markdownMode: 'link',
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
* consolidate testing of similar behavior across components
|
||||
*/
|
||||
|
||||
import type {ShallowWrapper} from 'enzyme';
|
||||
import {shallow} from 'enzyme';
|
||||
import type React from 'react';
|
||||
|
||||
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
import Constants from 'utils/constants';
|
||||
@@ -16,29 +18,32 @@ export const OUTPUT_APPEND = 'Hello world!\n';
|
||||
export const OUTPUT_REPLACE = 'Hello\norld!';
|
||||
const REPLACE_START = 5;
|
||||
const REPLACE_END = 7;
|
||||
export const BASE_EVENT = {
|
||||
|
||||
export const BASE_EVENT: KeyboardEvent = {...new KeyboardEvent('keyDown'),
|
||||
preventDefault: jest.fn(),
|
||||
stopPropagation: jest.fn(),
|
||||
ctrlKey: true,
|
||||
key: Constants.KeyCodes.ENTER[0],
|
||||
keyCode: Constants.KeyCodes.ENTER[1],
|
||||
currentTarget: document.createElement('input'),
|
||||
target: document.createElement('input'),
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {object} [e={}] keydown event object
|
||||
* @return {object} keydown event object
|
||||
*/
|
||||
export function getAppendEvent(e = {}) {
|
||||
export function getAppendEvent(e?: KeyboardEvent): KeyboardEvent {
|
||||
return {
|
||||
...BASE_EVENT,
|
||||
...e,
|
||||
target: {
|
||||
...e || {},
|
||||
target: {...BASE_EVENT.target,
|
||||
selectionStart: INPUT.length,
|
||||
selectionEnd: INPUT.length,
|
||||
value: INPUT,
|
||||
focus: jest.fn(),
|
||||
setSelectionRange: jest.fn(),
|
||||
},
|
||||
} as EventTarget,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,17 +51,17 @@ export function getAppendEvent(e = {}) {
|
||||
* @param {object} [e={}] keydown event object
|
||||
* @return {object} keydown event object
|
||||
*/
|
||||
export function getReplaceEvent(e = {}) {
|
||||
export function getReplaceEvent(e?: KeyboardEvent): KeyboardEvent {
|
||||
return {
|
||||
...BASE_EVENT,
|
||||
...e,
|
||||
target: {
|
||||
...e || {},
|
||||
target: {...BASE_EVENT.target,
|
||||
selectionStart: REPLACE_START,
|
||||
selectionEnd: REPLACE_END,
|
||||
value: INPUT,
|
||||
focus: jest.fn(),
|
||||
setSelectionRange: jest.fn(),
|
||||
},
|
||||
} as EventTarget,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,10 +69,10 @@ export function getReplaceEvent(e = {}) {
|
||||
* @param {object} [e={}] keydown event object
|
||||
* @return {object} keydown event object
|
||||
*/
|
||||
export const getAltKeyEvent = (e = {}) => ({...BASE_EVENT, ...e, altKey: true});
|
||||
export const getCtrlKeyEvent = (e = {}) => ({...BASE_EVENT, ...e, ctrlKey: true});
|
||||
export const getMetaKeyEvent = (e = {}) => ({...BASE_EVENT, ...e, metaKey: true});
|
||||
export const getShiftKeyEvent = (e = {}) => ({...BASE_EVENT, ...e, shiftKey: true});
|
||||
export const getAltKeyEvent = (e?: KeyboardEvent): KeyboardEvent => ({...BASE_EVENT, ...e || {}, altKey: true});
|
||||
export const getCtrlKeyEvent = (e?: KeyboardEvent): KeyboardEvent => ({...BASE_EVENT, ...e || {}, ctrlKey: true});
|
||||
export const getMetaKeyEvent = (e?: KeyboardEvent): KeyboardEvent => ({...BASE_EVENT, ...e || {}, metaKey: true});
|
||||
export const getShiftKeyEvent = (e?: KeyboardEvent): KeyboardEvent => ({...BASE_EVENT, ...e || {}, shiftKey: true});
|
||||
|
||||
/**
|
||||
* helper to test line break on key down behavior common to many textarea inputs
|
||||
@@ -76,16 +81,16 @@ export const getShiftKeyEvent = (e = {}) => ({...BASE_EVENT, ...e, shiftKey: tru
|
||||
* @param {boolean} intlInhected -
|
||||
* NOTE: runs Jest tests
|
||||
*/
|
||||
export function testComponentForLineBreak(generateInstance, getValue, intlInjected = true) {
|
||||
const shallowRender = intlInjected ? shallowWithIntl : shallow;
|
||||
export function testComponentForLineBreak(generateInstance: (input: string) => JSX.Element, getValue: (instance: React.Component<any, any>) => string, intlInjected = true) {
|
||||
const shallowRender: (instance: JSX.Element) => ShallowWrapper = intlInjected ? shallowWithIntl : shallow;
|
||||
|
||||
test('component appends line break to input on shift + enter', () => {
|
||||
const event = getAppendEvent(getShiftKeyEvent());
|
||||
const instance = shallowRender(generateInstance(INPUT));
|
||||
instance.simulate('keyDown', event);
|
||||
setTimeout(() => {
|
||||
expect(getValue(instance)).toBe(OUTPUT_APPEND);
|
||||
expect(event.target.value).toBe(OUTPUT_APPEND);
|
||||
expect(getValue(instance.instance())).toBe(OUTPUT_APPEND);
|
||||
expect((event.target as any).value).toBe(OUTPUT_APPEND);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
@@ -94,8 +99,8 @@ export function testComponentForLineBreak(generateInstance, getValue, intlInject
|
||||
const instance = shallowRender(generateInstance(INPUT));
|
||||
instance.simulate('keyDown', event);
|
||||
setTimeout(() => {
|
||||
expect(getValue(instance)).toBe(OUTPUT_APPEND);
|
||||
expect(event.target.value).toBe(OUTPUT_APPEND);
|
||||
expect(getValue(instance.instance())).toBe(OUTPUT_APPEND);
|
||||
expect((event.target as any).value).toBe(OUTPUT_APPEND);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
@@ -104,8 +109,8 @@ export function testComponentForLineBreak(generateInstance, getValue, intlInject
|
||||
const instance = shallowRender(generateInstance(INPUT));
|
||||
instance.simulate('keyDown', event);
|
||||
setTimeout(() => {
|
||||
expect(getValue(instance)).toBe(OUTPUT_REPLACE);
|
||||
expect(event.target.value).toBe(OUTPUT_REPLACE);
|
||||
expect(getValue(instance.instance())).toBe(OUTPUT_REPLACE);
|
||||
expect((event.target as any).value).toBe(OUTPUT_REPLACE);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
@@ -114,8 +119,8 @@ export function testComponentForLineBreak(generateInstance, getValue, intlInject
|
||||
const instance = shallowRender(generateInstance(INPUT));
|
||||
instance.simulate('keyDown', event);
|
||||
setTimeout(() => {
|
||||
expect(getValue(instance)).toBe(OUTPUT_REPLACE);
|
||||
expect(event.target.value).toBe(OUTPUT_REPLACE);
|
||||
expect(getValue(instance.instance())).toBe(OUTPUT_REPLACE);
|
||||
expect((event.target as any).value).toBe(OUTPUT_REPLACE);
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
@@ -20,3 +20,5 @@ jest.mock('react-intl', function() {
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default {};
|
||||
@@ -5,8 +5,5 @@ import React from 'react';
|
||||
|
||||
jest.mock('@tippyjs/react', () => ({
|
||||
__esModule: true,
|
||||
default: () => (
|
||||
<div
|
||||
id='tippyMock'
|
||||
/>),
|
||||
default: () => (<div id='tippyMock'/>),
|
||||
}));
|
||||
@@ -12,7 +12,7 @@ jest.mock('redux-persist', () => {
|
||||
},
|
||||
|
||||
persistReducer: jest.fn().mockImplementation((config, reducers) => reducers),
|
||||
persistCombineReducers: (persistConfig, reducers) => combineReducers(reducers),
|
||||
persistCombineReducers: (persistConfig: any, reducers: any) => combineReducers(reducers),
|
||||
persistStore: () => {
|
||||
return {
|
||||
pause: () => {},
|
||||
@@ -22,3 +22,5 @@ jest.mock('redux-persist', () => {
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export default {};
|
||||
@@ -13,10 +13,10 @@ import './react-intl_mock';
|
||||
import './react-router-dom_mock';
|
||||
import './react-tippy_mock';
|
||||
|
||||
global.performance = {};
|
||||
global.performance = {} as any;
|
||||
require('isomorphic-fetch');
|
||||
|
||||
configure({adapter: new Adapter()});
|
||||
configure({adapter: new (Adapter as any)()});
|
||||
|
||||
global.window = Object.create(window);
|
||||
Object.defineProperty(window, 'location', {
|
||||
@@ -32,11 +32,11 @@ Object.defineProperty(window, 'location', {
|
||||
const supportedCommands = ['copy', 'insertText'];
|
||||
|
||||
Object.defineProperty(document, 'queryCommandSupported', {
|
||||
value: (cmd) => supportedCommands.includes(cmd),
|
||||
value: (cmd: string) => supportedCommands.includes(cmd),
|
||||
});
|
||||
|
||||
Object.defineProperty(document, 'execCommand', {
|
||||
value: (cmd) => supportedCommands.includes(cmd),
|
||||
value: (cmd: string) => supportedCommands.includes(cmd),
|
||||
});
|
||||
|
||||
document.documentElement.style.fontSize = '12px';
|
||||
@@ -49,8 +49,8 @@ jest.mock('@mui/styled-engine', () => {
|
||||
|
||||
// isDependencyWarning returns true when the given console.warn message is coming from a dependency using deprecated
|
||||
// React lifecycle methods.
|
||||
function isDependencyWarning(params) {
|
||||
function paramsHasComponent(name) {
|
||||
function isDependencyWarning(params: string[]) {
|
||||
function paramsHasComponent(name: string) {
|
||||
return params.some((param) => param.includes(name));
|
||||
}
|
||||
|
||||
@@ -67,23 +67,23 @@ function isDependencyWarning(params) {
|
||||
);
|
||||
}
|
||||
|
||||
let warns;
|
||||
let errors;
|
||||
let warns: string[][];
|
||||
let errors: string[][];
|
||||
beforeAll(() => {
|
||||
console.originalWarn = console.warn;
|
||||
const originalWarn = console.warn;
|
||||
console.warn = jest.fn((...params) => {
|
||||
// Ignore any deprecation warnings coming from dependencies
|
||||
if (isDependencyWarning(params)) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.originalWarn(...params);
|
||||
originalWarn(...params);
|
||||
warns.push(params);
|
||||
});
|
||||
|
||||
console.originalError = console.error;
|
||||
const originalError = console.error;
|
||||
console.error = jest.fn((...params) => {
|
||||
console.originalError(...params);
|
||||
originalError(...params);
|
||||
errors.push(params);
|
||||
});
|
||||
});
|
||||
@@ -1,15 +1,13 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type React from 'react';
|
||||
|
||||
import type {UserProfile} from '@mattermost/types/users';
|
||||
|
||||
import {GeneralTypes} from 'mattermost-redux/action_types';
|
||||
|
||||
import store from 'stores/redux_store';
|
||||
|
||||
import * as lineBreakHelpers from 'tests/helpers/line_break_helpers.js';
|
||||
import * as lineBreakHelpers from 'tests/helpers/line_break_helpers';
|
||||
import * as ua from 'tests/helpers/user_agent_mocks';
|
||||
import Constants, {ValidationErrors} from 'utils/constants';
|
||||
import * as Utils from 'utils/utils';
|
||||
@@ -379,25 +377,25 @@ describe('Utils.imageURLForUser', () => {
|
||||
describe('Utils.isUnhandledLineBreakKeyCombo', () => {
|
||||
test('isUnhandledLineBreakKeyCombo returns true for alt + enter for Chrome UA', () => {
|
||||
ua.mockChrome();
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getAltKeyEvent() as KeyboardEvent)).toBe(true);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getAltKeyEvent())).toBe(true);
|
||||
});
|
||||
|
||||
test('isUnhandledLineBreakKeyCombo returns false for alt + enter for Safari UA', () => {
|
||||
ua.mockSafari();
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getAltKeyEvent() as KeyboardEvent)).toBe(false);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getAltKeyEvent())).toBe(false);
|
||||
});
|
||||
|
||||
test('isUnhandledLineBreakKeyCombo returns false for shift + enter', () => {
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getShiftKeyEvent() as unknown as KeyboardEvent)).toBe(false);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getShiftKeyEvent())).toBe(false);
|
||||
});
|
||||
|
||||
test('isUnhandledLineBreakKeyCombo returns false for ctrl/command + enter', () => {
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getCtrlKeyEvent() as unknown as KeyboardEvent)).toBe(false);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getMetaKeyEvent() as unknown as KeyboardEvent)).toBe(false);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getCtrlKeyEvent())).toBe(false);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.getMetaKeyEvent())).toBe(false);
|
||||
});
|
||||
|
||||
test('isUnhandledLineBreakKeyCombo returns false for just enter', () => {
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.BASE_EVENT as unknown as KeyboardEvent)).toBe(false);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(lineBreakHelpers.BASE_EVENT)).toBe(false);
|
||||
});
|
||||
|
||||
test('isUnhandledLineBreakKeyCombo returns false for f (random key)', () => {
|
||||
@@ -406,7 +404,7 @@ describe('Utils.isUnhandledLineBreakKeyCombo', () => {
|
||||
key: Constants.KeyCodes.F[0],
|
||||
keyCode: Constants.KeyCodes.F[1],
|
||||
};
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(e as unknown as KeyboardEvent)).toBe(false);
|
||||
expect(Utils.isUnhandledLineBreakKeyCombo(e)).toBe(false);
|
||||
});
|
||||
|
||||
// restore initial user agent
|
||||
@@ -415,10 +413,10 @@ describe('Utils.isUnhandledLineBreakKeyCombo', () => {
|
||||
|
||||
describe('Utils.insertLineBreakFromKeyEvent', () => {
|
||||
test('insertLineBreakFromKeyEvent returns with line break appending (no selection range)', () => {
|
||||
expect(Utils.insertLineBreakFromKeyEvent(lineBreakHelpers.getAppendEvent() as React.KeyboardEvent<HTMLInputElement>)).toBe(lineBreakHelpers.OUTPUT_APPEND);
|
||||
expect(Utils.insertLineBreakFromKeyEvent(lineBreakHelpers.getAppendEvent())).toBe(lineBreakHelpers.OUTPUT_APPEND);
|
||||
});
|
||||
test('insertLineBreakFromKeyEvent returns with line break replacing (with selection range)', () => {
|
||||
expect(Utils.insertLineBreakFromKeyEvent(lineBreakHelpers.getReplaceEvent() as React.KeyboardEvent<HTMLInputElement>)).toBe(lineBreakHelpers.OUTPUT_REPLACE);
|
||||
expect(Utils.insertLineBreakFromKeyEvent(lineBreakHelpers.getReplaceEvent())).toBe(lineBreakHelpers.OUTPUT_REPLACE);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ export function isUnhandledLineBreakKeyCombo(e: React.KeyboardEvent | KeyboardEv
|
||||
* insert a new line character at keyboard cursor (or overwrites selection)
|
||||
* WARNING: HAS DOM SIDE EFFECTS
|
||||
*/
|
||||
export function insertLineBreakFromKeyEvent(e: React.KeyboardEvent<TextboxElement>): string {
|
||||
export function insertLineBreakFromKeyEvent(e: KeyboardEvent): string {
|
||||
const el = e.target as TextboxElement;
|
||||
const {selectionEnd, selectionStart, value} = el;
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user