import * as React from 'react'; import { Store } from '@reduxjs/toolkit'; import { render, fireEvent, waitFor } from '@testing-library/react'; import { Provider } from 'react-redux'; import { ThemeProvider } from 'styles/theme/ThemeProvider'; import { HelmetProvider } from 'react-helmet-async'; import { GithubRepoForm, repoErrorText } from '..'; import { configureAppStore } from 'store/configureStore'; import { githubRepoFormActions as actions, initialState } from '../slice'; import { RepoErrorType } from '../slice/types'; function* mockGithubRepoFormSaga() {} jest.mock('../slice/saga', () => ({ githubRepoFormSaga: mockGithubRepoFormSaga, })); const renderGithubRepoForm = (store: Store) => render( , ); describe('', () => { let store: ReturnType; let component: ReturnType; beforeEach(() => { store = configureAppStore(); component = renderGithubRepoForm(store); store.dispatch(actions.reposLoaded([])); expect(store.getState().githubRepoForm).toEqual(initialState); }); afterEach(() => { component.unmount(); }); it("should fetch repos on mount if username isn't empty", () => { component.unmount(); component = renderGithubRepoForm(store); expect(initialState.username.length).toBeGreaterThan(0); expect(store.getState().githubRepoForm.loading).toBe(true); }); it("shouldn't fetch repos on mount if username is empty", () => { store.dispatch(actions.changeUsername('')); store.dispatch(actions.reposLoaded([])); component.unmount(); component = renderGithubRepoForm(store); expect(store.getState().githubRepoForm.loading).toBe(false); }); it('should dispatch action on username change', () => { const input = component.container.querySelector('input'); fireEvent.change(input!, { target: { value: 'test' } }); expect(store.getState().githubRepoForm.loading).toBe(true); }); it('should change username field value on action', () => { const value = 'test'; const form = renderGithubRepoForm(store); const input = form.container.querySelector('input'); fireEvent.change(input!, { target: { value: value } }); expect(form.container.querySelector('input')?.value).toBe(value); }); it('should display loading indicator when state is loading', () => { store.dispatch(actions.loadRepos()); expect(component.container.querySelector('circle')).toBeInTheDocument(); }); it('should display list when repos not empty', async () => { const repoName = 'testRepo'; store.dispatch( actions.reposLoaded([{ id: 'test', name: repoName } as any]), ); await waitFor(() => expect(component.queryByText(repoName)).toBeInTheDocument(), ); }); it('should display error when repoError fired', async () => { let error = RepoErrorType.USER_NOT_FOUND; store.dispatch(actions.repoError(error)); await waitFor(() => expect(component.queryByText(repoErrorText(error))).toBeInTheDocument(), ); error = RepoErrorType.USER_HAS_NO_REPO; store.dispatch(actions.repoError(error)); await waitFor(() => expect(component.queryByText(repoErrorText(error))).toBeInTheDocument(), ); error = RepoErrorType.USERNAME_EMPTY; store.dispatch(actions.repoError(error)); await waitFor(() => expect(component.queryByText(repoErrorText(error))).toBeInTheDocument(), ); error = RepoErrorType.RESPONSE_ERROR; store.dispatch(actions.repoError(error)); await waitFor(() => expect(component.queryByText(repoErrorText(error))).toBeInTheDocument(), ); error = RepoErrorType.GITHUB_RATE_LIMIT; store.dispatch(actions.repoError(error)); await waitFor(() => expect(component.queryByText(repoErrorText(error))).toBeInTheDocument(), ); }); });