From 51d9caecf632543dbcc5fb948eb9f58edb47a724 Mon Sep 17 00:00:00 2001 From: "Leon.kov" Date: Mon, 4 Dec 2023 19:36:06 +0300 Subject: [PATCH] fix: add ts strict mode and fix ts errors --- config/storybook/webpack.config.ts | 42 ++++++++++--------- .../providers/StoreProvider/config/store.ts | 6 +-- src/entities/Profile/model/types/profile.ts | 16 +++---- .../loginByUsername/loginByUsername.test.ts | 16 +++---- .../tests/TestAsyncThunk/TestAsyncThunk.ts | 20 ++++++++- .../tests/componentRender/componentRender.tsx | 9 ++-- 6 files changed, 62 insertions(+), 47 deletions(-) diff --git a/config/storybook/webpack.config.ts b/config/storybook/webpack.config.ts index 7c60227..9614eb3 100644 --- a/config/storybook/webpack.config.ts +++ b/config/storybook/webpack.config.ts @@ -3,35 +3,37 @@ import path from 'path'; import { buildCssLoader } from '../build/loaders/buildCssLoader'; import { BuildPaths } from '../build/types/config'; -export default ({ config }: {config: webpack.Configuration}) => { +export default ({ config }: { config: webpack.Configuration }) => { const paths: BuildPaths = { build: '', html: '', entry: '', src: path.resolve(__dirname, '..', '..', 'src'), }; - config.resolve.modules.push(paths.src); - config.resolve.extensions.push('.ts', '.tsx'); + config!.resolve!.modules!.push(paths.src); + config!.resolve!.extensions!.push('.ts', '.tsx'); - // eslint-disable-next-line no-param-reassign - config.module.rules = config.module.rules.map((rule: RuleSetRule) => { - if (/svg/.test(rule.test as string)) { - return { ...rule, exclude: /\.svg$/i }; - } + // @ts-ignore + config!.module!.rules = config!.module!.rules!.map((rule: RuleSetRule) => { + if (/svg/.test(rule.test as string)) { + return { ...rule, exclude: /\.svg$/i }; + } - return rule; - }); + return rule; + }); - config.module.rules.push({ - test: /\.svg$/, - use: ['@svgr/webpack'], - }); - config.module.rules.push(buildCssLoader(true)); + config!.module!.rules.push({ + test: /\.svg$/, + use: ['@svgr/webpack'], + }); + config!.module!.rules.push(buildCssLoader(true)); - config.plugins.push(new DefinePlugin({ - __IS_DEV__: JSON.stringify(true), - __API__: JSON.stringify(''), - })); + config!.plugins!.push( + new DefinePlugin({ + __IS_DEV__: JSON.stringify(true), + __API__: JSON.stringify(''), + }), + ); - return config; + return config; }; diff --git a/src/app/providers/StoreProvider/config/store.ts b/src/app/providers/StoreProvider/config/store.ts index b95f644..507be00 100644 --- a/src/app/providers/StoreProvider/config/store.ts +++ b/src/app/providers/StoreProvider/config/store.ts @@ -1,7 +1,8 @@ -import { configureStore, ReducersMapObject } from '@reduxjs/toolkit'; +import { configureStore, Reducer, ReducersMapObject } from '@reduxjs/toolkit'; import { $api } from 'shared/api/api'; import { To } from '@remix-run/router'; import { NavigateOptions } from 'react-router/dist/lib/context'; +import { CombinedState } from 'redux'; import { counterReducer } from '../../../../entities/Counter'; import { userReducer } from '../../../../entities/User'; import { StateSchema } from './StateSchema'; @@ -21,8 +22,7 @@ export function createReduxStore( const reducerManager = createReducerManager(rootReducers); const store = configureStore({ - // @ts-ignore - reducer: reducerManager.reduce as ReducersMapObject, + reducer: reducerManager.reduce as Reducer>, devTools: __IS_DEV__, preloadedState: initialState, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ diff --git a/src/entities/Profile/model/types/profile.ts b/src/entities/Profile/model/types/profile.ts index b8d3350..7f7557d 100644 --- a/src/entities/Profile/model/types/profile.ts +++ b/src/entities/Profile/model/types/profile.ts @@ -1,14 +1,14 @@ import { Country, Currency } from 'shared/const/common'; export interface Profile { - 'first': string, - 'lastname': string, - 'age': number, - 'currency': Currency, - 'country': Country, - 'city': string, - 'username': string, - 'avatar': string + first: string, + lastname: string, + age: number, + currency: Currency, + country: Country, + city: string, + username: string, + avatar: string } export interface ProfileSchema { diff --git a/src/features/AuthByUsername/model/services/loginByUsername/loginByUsername.test.ts b/src/features/AuthByUsername/model/services/loginByUsername/loginByUsername.test.ts index 88aebec..f697ae0 100644 --- a/src/features/AuthByUsername/model/services/loginByUsername/loginByUsername.test.ts +++ b/src/features/AuthByUsername/model/services/loginByUsername/loginByUsername.test.ts @@ -1,12 +1,7 @@ -import axios from 'axios'; import { userActions } from 'entities/User'; import { TestAsyncThunk } from 'shared/lib/tests/TestAsyncThunk/TestAsyncThunk'; import { loginByUsername } from './loginByUsername'; -jest.mock('axios'); - -const mockedAxios = jest.mocked(axios, true); - describe('loginByUsername.test', () => { // let dispatch: Dispatch; // let getState: () => StateSchema; @@ -41,26 +36,27 @@ describe('loginByUsername.test', () => { test('loginByUsername async thunk test', async () => { const userValue = { username: '123', id: '1' }; - mockedAxios.post.mockReturnValue(Promise.resolve({ data: userValue })); const thunk = new TestAsyncThunk(loginByUsername); + thunk.api.post.mockReturnValue(Promise.resolve({ data: userValue })); + const result = await thunk.callThunk({ username: '123', password: '123' }); expect(thunk.dispatch).toHaveBeenCalledWith(userActions.setAuthData(userValue)); expect(thunk.dispatch).toHaveBeenCalledTimes(3); - expect(mockedAxios.post).toHaveBeenCalled(); + expect(thunk.api.post).toHaveBeenCalled(); expect(result.meta.requestStatus).toBe('fulfilled'); expect(result.payload).toEqual(userValue); }); test('loginByUsername async error thunk test', async () => { - mockedAxios.post.mockReturnValue(Promise.resolve({ status: 403 })); - const thunk = new TestAsyncThunk(loginByUsername); + thunk.api.post.mockReturnValue(Promise.resolve({ status: 403 })); + const result = await thunk.callThunk({ username: '123', password: '123' }); expect(thunk.dispatch).toHaveBeenCalledTimes(2); - expect(mockedAxios.post).toHaveBeenCalled(); + expect(thunk.api.post).toHaveBeenCalled(); expect(result.meta.requestStatus).toBe('rejected'); expect(result.payload).toBe('error'); }); diff --git a/src/shared/lib/tests/TestAsyncThunk/TestAsyncThunk.ts b/src/shared/lib/tests/TestAsyncThunk/TestAsyncThunk.ts index 14e9c46..db91abe 100644 --- a/src/shared/lib/tests/TestAsyncThunk/TestAsyncThunk.ts +++ b/src/shared/lib/tests/TestAsyncThunk/TestAsyncThunk.ts @@ -1,9 +1,14 @@ import { StateSchema } from 'app/providers/StoreProvider'; import { AsyncThunkAction } from '@reduxjs/toolkit'; +import axios, { AxiosStatic } from 'axios'; type ActionCreatorType = (arg: Arg) => AsyncThunkAction; +jest.mock('axios'); + +const mockedAxios = jest.mocked(axios, true); + export class TestAsyncThunk { dispatch: jest.MockedFn; @@ -11,15 +16,28 @@ export class TestAsyncThunk { actionCreator: ActionCreatorType; + api:jest.MockedFunctionDeep; + + navigate: jest.MockedFn; + constructor(actionCreator: ActionCreatorType) { this.actionCreator = actionCreator; this.dispatch = jest.fn(); this.getState = jest.fn(); + this.api = mockedAxios; + this.navigate = jest.fn(); } async callThunk(arg: Arg) { const action = this.actionCreator(arg); - const result = await action(this.dispatch, this.getState, undefined); + const result = await action( + this.dispatch, + this.getState, + { + api: this.api, + navigate: this.navigate, + }, + ); return result; } diff --git a/src/shared/lib/tests/componentRender/componentRender.tsx b/src/shared/lib/tests/componentRender/componentRender.tsx index 8051698..20d89ea 100644 --- a/src/shared/lib/tests/componentRender/componentRender.tsx +++ b/src/shared/lib/tests/componentRender/componentRender.tsx @@ -16,13 +16,12 @@ export function componentRender(component: ReactNode, options: componentRenderOp initialState, } = options; return render( - - + + {component} - - - , + + , ); }