feat(frontend): add setup tests
This commit is contained in:
parent
6ed6cf8782
commit
35291a103a
2
frontend/.gitignore
vendored
2
frontend/.gitignore
vendored
@ -14,3 +14,5 @@ dist/
|
|||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
|
coverage
|
||||||
|
|||||||
3
frontend/__mocks__/jest/helpers/index.ts
Normal file
3
frontend/__mocks__/jest/helpers/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export { selectOption } from './selectOption';
|
||||||
|
export { typeDateField } from './typeDateField';
|
||||||
|
export { typeTextField } from './typeTextField';
|
||||||
16
frontend/__mocks__/jest/helpers/selectOption.ts
Normal file
16
frontend/__mocks__/jest/helpers/selectOption.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { screen, within } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
|
export const selectOption = async (selectElement: HTMLElement | null, value: string) => {
|
||||||
|
if (!selectElement) {
|
||||||
|
throw new Error('Не найден элемент выпадающего списка');
|
||||||
|
}
|
||||||
|
|
||||||
|
const bankcardDropdown = within(selectElement).getByRole('combobox');
|
||||||
|
await userEvent.click(bankcardDropdown);
|
||||||
|
const option = screen.getAllByRole('option').find((el) => el.dataset.value === value);
|
||||||
|
if (!option) {
|
||||||
|
throw new Error(`Не найдена опция с value:${value}`);
|
||||||
|
}
|
||||||
|
await userEvent.click(option);
|
||||||
|
};
|
||||||
17
frontend/__mocks__/jest/helpers/typeDateField.ts
Normal file
17
frontend/__mocks__/jest/helpers/typeDateField.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
|
export const typeDateField = async (dateElement: HTMLElement | null, value?: null | string) => {
|
||||||
|
if (!dateElement) {
|
||||||
|
throw new Error('Не найдено поле ввода');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
await userEvent.clear(dateElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
await userEvent.click(dateElement);
|
||||||
|
await userEvent.clear(dateElement);
|
||||||
|
await userEvent.type(dateElement, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
16
frontend/__mocks__/jest/helpers/typeTextField.ts
Normal file
16
frontend/__mocks__/jest/helpers/typeTextField.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
|
export const typeTextField = async (inputElement: HTMLElement | null, value?: null | string) => {
|
||||||
|
if (!inputElement) {
|
||||||
|
throw new Error('Не найдено поле ввода');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value === null) {
|
||||||
|
await userEvent.clear(inputElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
await userEvent.clear(inputElement);
|
||||||
|
await userEvent.type(inputElement, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
17
frontend/__mocks__/jest/wrappers/AppWrapper.tsx
Normal file
17
frontend/__mocks__/jest/wrappers/AppWrapper.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import type { PropsWithChildren } from 'react';
|
||||||
|
|
||||||
|
import { createLocalizationWrapper } from './LocalizationWrapper';
|
||||||
|
import { createReactQueryWrapper } from './ReactQueryWrapper';
|
||||||
|
|
||||||
|
export const createAppWrapper = () => ({ children }: PropsWithChildren) => {
|
||||||
|
const ReactQueryWrapper = createReactQueryWrapper();
|
||||||
|
const LocalizationWrapper = createLocalizationWrapper();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactQueryWrapper>
|
||||||
|
<LocalizationWrapper>
|
||||||
|
{children}
|
||||||
|
</LocalizationWrapper>
|
||||||
|
</ReactQueryWrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
11
frontend/__mocks__/jest/wrappers/LocalizationWrapper.tsx
Normal file
11
frontend/__mocks__/jest/wrappers/LocalizationWrapper.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import type { PropsWithChildren } from 'react';
|
||||||
|
|
||||||
|
import { LocalizationProvider } from '@mui/x-date-pickers';
|
||||||
|
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
|
||||||
|
import { ru } from 'date-fns/locale/ru';
|
||||||
|
|
||||||
|
export const createLocalizationWrapper = () => ({ children }: PropsWithChildren) => (
|
||||||
|
<LocalizationProvider adapterLocale={ru} dateAdapter={AdapterDateFns}>
|
||||||
|
{children}
|
||||||
|
</LocalizationProvider>
|
||||||
|
);
|
||||||
@ -1 +1,3 @@
|
|||||||
|
export { createAppWrapper } from './AppWrapper';
|
||||||
|
export { createLocalizationWrapper } from './LocalizationWrapper';
|
||||||
export { createReactQueryWrapper } from './ReactQueryWrapper';
|
export { createReactQueryWrapper } from './ReactQueryWrapper';
|
||||||
|
|||||||
1
frontend/configs/jest/setupEnv.ts
Normal file
1
frontend/configs/jest/setupEnv.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
process.env.TZ = 'Europe/Moscow';
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
import { server } from '@mocks/jest/server';
|
import { server } from '@mocks/jest/server';
|
||||||
|
|
||||||
|
import './setupEnv';
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
server.listen();
|
server.listen();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,6 +4,7 @@ export default {
|
|||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'@/(.*)': '<rootDir>/src/$1',
|
'@/(.*)': '<rootDir>/src/$1',
|
||||||
'@mocks/(.*)': '<rootDir>/__mocks__/$1',
|
'@mocks/(.*)': '<rootDir>/__mocks__/$1',
|
||||||
|
'@tests/(.*)': '<rootDir>/tests/$1',
|
||||||
'\\.(css|scss|sass|less)$': 'identity-obj-proxy',
|
'\\.(css|scss|sass|less)$': 'identity-obj-proxy',
|
||||||
'\\.(jpg|jpeg|png|gif|webp|svg)$': '<rootDir>/__mocks__/jest/fileMock.js',
|
'\\.(jpg|jpeg|png|gif|webp|svg)$': '<rootDir>/__mocks__/jest/fileMock.js',
|
||||||
},
|
},
|
||||||
@ -20,4 +21,5 @@ export default {
|
|||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
transformIgnorePatterns: ['node_modules/(?!(until-async)/)'],
|
||||||
} as Config;
|
} as Config;
|
||||||
|
|||||||
2475
frontend/package-lock.json
generated
2475
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,42 +9,50 @@
|
|||||||
"dev:mock": "rsbuild dev --env-mode mock",
|
"dev:mock": "rsbuild dev --env-mode mock",
|
||||||
"preview": "rsbuild preview",
|
"preview": "rsbuild preview",
|
||||||
"lint": "eslint --concurrency=auto",
|
"lint": "eslint --concurrency=auto",
|
||||||
"test:unit": "jest",
|
"test:unit": "jest --verbose --silent",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"openapi:gen": "openapi-typescript http://localhost:3000/docs/swagger.json -o src/shared/api/schema.ts"
|
"openapi:gen": "openapi-typescript http://localhost:3000/docs/swagger.json -o src/shared/api/schema.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/react-query": "5.89.0",
|
"@emotion/react": "11.14.0",
|
||||||
|
"@emotion/styled": "11.14.1",
|
||||||
|
"@fontsource/roboto": "5.2.8",
|
||||||
|
"@mui/icons-material": "7.3.4",
|
||||||
|
"@mui/material": "7.3.4",
|
||||||
|
"@mui/x-date-pickers": "8.12.0",
|
||||||
|
"@tanstack/react-query": "5.90.2",
|
||||||
"axios": "1.12.2",
|
"axios": "1.12.2",
|
||||||
"react": "19.1.1",
|
"date-fns": "4.1.0",
|
||||||
"react-dom": "19.1.1",
|
"date-fns-tz": "3.2.0",
|
||||||
"react-router": "7.9.1"
|
"react": "19.2.0",
|
||||||
|
"react-dom": "19.2.0",
|
||||||
|
"react-router": "7.9.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rsbuild/core": "1.5.7",
|
"@rsbuild/core": "1.5.14",
|
||||||
"@rsbuild/plugin-eslint": "1.1.2",
|
"@rsbuild/plugin-eslint": "1.1.2",
|
||||||
"@rsbuild/plugin-react": "1.4.0",
|
"@rsbuild/plugin-react": "1.4.1",
|
||||||
"@rsbuild/plugin-type-check": "1.2.4",
|
"@rsbuild/plugin-type-check": "1.2.4",
|
||||||
"@swc/core": "1.13.5",
|
"@swc/core": "1.13.5",
|
||||||
"@swc/jest": "0.2.39",
|
"@swc/jest": "0.2.39",
|
||||||
"@tanstack/eslint-plugin-query": "5.89.0",
|
"@tanstack/eslint-plugin-query": "5.91.0",
|
||||||
"@testing-library/dom": "10.4.1",
|
"@testing-library/dom": "10.4.1",
|
||||||
"@testing-library/jest-dom": "6.8.0",
|
"@testing-library/jest-dom": "6.9.1",
|
||||||
"@testing-library/react": "16.3.0",
|
"@testing-library/react": "16.3.0",
|
||||||
"@testing-library/user-event": "14.6.1",
|
"@testing-library/user-event": "14.6.1",
|
||||||
"@types/jest": "30.0.0",
|
"@types/jest": "30.0.0",
|
||||||
"@types/react": "19.1.13",
|
"@types/react": "19.2.2",
|
||||||
"@types/react-dom": "19.1.9",
|
"@types/react-dom": "19.2.1",
|
||||||
"eslint": "9.35.0",
|
"eslint": "9.37.0",
|
||||||
"eslint-config-ksv741": "0.3.0",
|
"eslint-config-ksv741": "0.3.0",
|
||||||
"eslint-plugin-perfectionist": "^4.15.0",
|
"eslint-plugin-perfectionist": "4.15.1",
|
||||||
"identity-obj-proxy": "3.0.0",
|
"identity-obj-proxy": "3.0.0",
|
||||||
"jest": "30.1.3",
|
"jest": "30.2.0",
|
||||||
"jest-environment-jsdom": "30.1.2",
|
"jest-environment-jsdom": "30.2.0",
|
||||||
"msw": "2.11.2",
|
"msw": "2.11.3",
|
||||||
"openapi-typescript": "7.9.1",
|
"openapi-typescript": "7.9.1",
|
||||||
"ts-node": "10.9.2",
|
"ts-node": "10.9.2",
|
||||||
"typescript": "5.9.2"
|
"typescript": "5.9.3"
|
||||||
},
|
},
|
||||||
"msw": {
|
"msw": {
|
||||||
"workerDirectory": [
|
"workerDirectory": [
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
* - Please do NOT modify this file.
|
* - Please do NOT modify this file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const PACKAGE_VERSION = '2.11.2'
|
const PACKAGE_VERSION = '2.11.3'
|
||||||
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
|
const INTEGRITY_CHECKSUM = '4db4a41e972cec1b64cc569c66952d82'
|
||||||
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
|
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
|
||||||
const activeClientIds = new Set()
|
const activeClientIds = new Set()
|
||||||
|
|||||||
@ -12,6 +12,8 @@ export default defineConfig({
|
|||||||
pluginEslint({
|
pluginEslint({
|
||||||
eslintPluginOptions: {
|
eslintPluginOptions: {
|
||||||
configType: 'flat',
|
configType: 'flat',
|
||||||
|
emitError: false,
|
||||||
|
emitWarning: false,
|
||||||
failOnError: false,
|
failOnError: false,
|
||||||
failOnWarning: false,
|
failOnWarning: false,
|
||||||
},
|
},
|
||||||
|
|||||||
1
frontend/src/shared/constants/index.ts
Normal file
1
frontend/src/shared/constants/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { DataTestId } from './tests/data-testids';
|
||||||
57
frontend/src/shared/constants/tests/data-testids.ts
Normal file
57
frontend/src/shared/constants/tests/data-testids.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
export enum DataTestId {
|
||||||
|
ADD_BANK_CARD_BUTTON = 'add-bank-card-button',
|
||||||
|
ADD_BANK_CARD_FORM = 'add-bank-card-form',
|
||||||
|
ADD_BANK_CARD_SUBMIT_BUTTON = 'add-bank-card-submit-button',
|
||||||
|
ADD_CASH_BUTTON = 'add-cash-button',
|
||||||
|
ADD_CASH_FORM = 'add-cash-form',
|
||||||
|
ADD_CASH_SUBMIT_BUTTON = 'add-cash-submit-button',
|
||||||
|
ADD_EXPENSE_ITEM_BUTTON = 'add-expense-item-button',
|
||||||
|
ADD_EXPENSE_ITEM_FORM = 'add-expense-item-form',
|
||||||
|
ADD_EXPENSE_ITEM_SUBMIT_BUTTON = 'add-expense-item-submit-button',
|
||||||
|
ADD_EXPENSES_LIST_BUTTON = 'add-expenses-list-button',
|
||||||
|
ADD_EXPENSES_LIST_FORM = 'add-expenses-list-form',
|
||||||
|
ADD_EXPENSES_LIST_SUBMIT_BUTTON = 'add-expenses-list-submit-button',
|
||||||
|
ADD_INCOME_ITEM_BUTTON = 'add-income-item-button',
|
||||||
|
ADD_INCOME_ITEM_FORM = 'add-income-item-form',
|
||||||
|
ADD_INCOME_ITEM_SUBMIT_BUTTON = 'add-income-item-submit-button',
|
||||||
|
ADD_INCOME_LIST_BUTTON = 'add-income-list-button',
|
||||||
|
ADD_INCOME_LIST_FORM = 'add-income-list-form',
|
||||||
|
ADD_INCOME_LIST_SUBMIT_BUTTON = 'add-income-list-submit-button',
|
||||||
|
DELETE_BANK_CARD_BUTTON = 'delete-bank-card-button',
|
||||||
|
DELETE_BANK_CARD_FORM = 'delete-bank-card-form',
|
||||||
|
DELETE_BANK_CARD_SUBMIT_BUTTON = 'delete-bank-card-submit-button',
|
||||||
|
DELETE_CASH_BUTTON = 'delete-cash-button',
|
||||||
|
DELETE_CASH_FORM = 'delete-cash-form',
|
||||||
|
DELETE_CASH_SUBMIT_BUTTON = 'delete-cash-submit-button',
|
||||||
|
DELETE_EXPENSE_ITEM_BUTTON = 'delete-expense-item-button',
|
||||||
|
DELETE_EXPENSE_ITEM_FORM = 'delete-expense-item-form',
|
||||||
|
DELETE_EXPENSE_ITEM_SUBMIT_BUTTON = 'delete-expense-item-submit-button',
|
||||||
|
DELETE_EXPENSES_LIST_BUTTON = 'delete-expenses-list-button',
|
||||||
|
DELETE_EXPENSES_LIST_FORM = 'delete-expenses-list-form',
|
||||||
|
DELETE_EXPENSES_LIST_SUBMIT_BUTTON = 'delete-expenses-list-submit-button',
|
||||||
|
DELETE_INCOME_ITEM_BUTTON = 'delete-income-item-button',
|
||||||
|
DELETE_INCOME_ITEM_FORM = 'delete-income-item-form',
|
||||||
|
DELETE_INCOME_ITEM_SUBMIT_BUTTON = 'delete-income-item-submit-button',
|
||||||
|
DELETE_INCOME_LIST_BUTTON = 'delete-income-list-button',
|
||||||
|
DELETE_INCOME_LIST_FORM = 'delete-income-list-form',
|
||||||
|
DELETE_INCOME_LIST_SUBMIT_BUTTON = 'delete-income-list-submit-button',
|
||||||
|
EDIT_BANK_CARD_BUTTON = 'edit-bank-card-button',
|
||||||
|
EDIT_BANK_CARD_FORM = 'edit-bank-card-form',
|
||||||
|
EDIT_BANK_CARD_SUBMIT_BUTTON = 'edit-bank-card-submit-button',
|
||||||
|
EDIT_CASH_BUTTON = 'edit-cash-button',
|
||||||
|
EDIT_CASH_FORM = 'edit-cash-form',
|
||||||
|
EDIT_CASH_SUBMIT_BUTTON = 'edit-cash-submit-button',
|
||||||
|
EDIT_EXPENSE_ITEM_BUTTON = 'edit-expense-item-button',
|
||||||
|
EDIT_EXPENSE_ITEM_FORM = 'edit-expense-item-form',
|
||||||
|
EDIT_EXPENSE_ITEM_SUBMIT_BUTTON = 'edit-expense-item-submit-button',
|
||||||
|
EDIT_EXPENSES_LIST_BUTTON = 'edit-expenses-list-button',
|
||||||
|
EDIT_EXPENSES_LIST_FORM = 'edit-expenses-list-form',
|
||||||
|
EDIT_EXPENSES_LIST_SUBMIT_BUTTON = 'edit-expenses-list-submit-button',
|
||||||
|
EDIT_INCOME_ITEM_BUTTON = 'edit-income-item-button',
|
||||||
|
EDIT_INCOME_ITEM_FORM = 'edit-income-item-form',
|
||||||
|
EDIT_INCOME_ITEM_SUBMIT_BUTTON = 'edit-income-item-submit-button',
|
||||||
|
EDIT_INCOME_LIST_BUTTON = 'edit-income-list-button',
|
||||||
|
EDIT_INCOME_LIST_FORM = 'edit-income-list-form',
|
||||||
|
EDIT_INCOME_LIST_SUBMIT_BUTTON = 'edit-income-list-submit-button',
|
||||||
|
}
|
||||||
@ -22,13 +22,15 @@
|
|||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"],
|
"@/*": ["./src/*"],
|
||||||
"@mocks/*": ["./__mocks__/*"]
|
"@mocks/*": ["./__mocks__/*"],
|
||||||
|
"@tests/*": ["./tests/*"],
|
||||||
},
|
},
|
||||||
"types": ["jest", "@testing-library/jest-dom"]
|
"types": ["jest", "@testing-library/jest-dom"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src",
|
"src",
|
||||||
"__mocks__",
|
"__mocks__",
|
||||||
|
"tests",
|
||||||
"configs",
|
"configs",
|
||||||
"eslint.config.ts",
|
"eslint.config.ts",
|
||||||
"rsbuild.config.ts",
|
"rsbuild.config.ts",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user