diff --git a/app/src/features/funding-sources/components/CreateFundingSource.test.tsx b/app/src/features/funding-sources/components/CreateFundingSource.test.tsx new file mode 100644 index 0000000000..412e4fa70d --- /dev/null +++ b/app/src/features/funding-sources/components/CreateFundingSource.test.tsx @@ -0,0 +1,160 @@ +import { AuthStateContext } from 'contexts/authStateContext'; +import { DialogContextProvider } from 'contexts/dialogContext'; +import { createMemoryHistory } from 'history'; +import { useBiohubApi } from 'hooks/useBioHubApi'; +import { IGetFundingSourceResponse, IGetFundingSourcesResponse } from 'interfaces/useFundingSourceApi.interface'; +import { Router } from 'react-router'; +import { getMockAuthState, SystemAdminAuthState } from 'test-helpers/auth-helpers'; +import { act, cleanup, fireEvent, render, waitFor } from 'test-helpers/test-utils'; +import CreateFundingSource from './CreateFundingSource'; + +jest.mock('../../../hooks/useBioHubApi'); +const mockBioHubApi = useBiohubApi as jest.Mock; +const mockUseApi = { + funding: { + getFundingSources: jest.fn, []>(), + postFundingSource: jest.fn, []>() + } +}; +const history = createMemoryHistory(); +describe('CreateFundingSource', () => { + beforeEach(() => { + mockBioHubApi.mockImplementation(() => mockUseApi); + mockUseApi.funding.getFundingSources.mockClear(); + mockUseApi.funding.postFundingSource.mockClear(); + }); + + afterEach(() => { + cleanup(); + }); + + it('renders with empty form fields', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + + mockUseApi.funding.getFundingSources.mockResolvedValue([]); + + const onClose = jest.fn(); + + const { getByTestId } = render( + + + + + + + + ); + + await waitFor(() => { + expect(getByTestId('name')).toBeVisible(); + expect(getByTestId('description')).toBeVisible(); + expect(getByTestId('start_date')).toBeVisible(); + expect(getByTestId('end_date')).toBeVisible(); + }); + }); + + it('renders form errors when submitting with no data', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + mockUseApi.funding.getFundingSources.mockResolvedValue([]); + const onClose = jest.fn(); + + const { findByTestId, getByText } = render( + + + + + + + + ); + + await act(async () => { + // submit empty form + const saveChangesButton = await findByTestId('edit-dialog-save'); + fireEvent.click(saveChangesButton); + }); + + await waitFor(() => { + expect(getByText('Name is Required', { exact: false })).toBeVisible(); + expect(getByText('Description is Required', { exact: false })).toBeVisible(); + }); + }); + + it('renders name used error when submitting with a previously used name', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + mockUseApi.funding.getFundingSources.mockResolvedValue([ + { + funding_source_id: 1, + name: 'Used Name', + description: '', + start_date: '', + end_date: '', + revision_count: 1, + survey_reference_count: 0, + survey_reference_amount_total: 0 + } + ]); + const onClose = jest.fn(); + + const { findByTestId, getByText, getByTestId } = render( + + + + + + + + ); + + await act(async () => { + // Fill form + const nameInput = getByTestId('name'); + fireEvent.change(nameInput, { target: { value: 'Used Name' } }); + + const descriptionInput = getByTestId('description'); + fireEvent.change(descriptionInput, { target: { value: 'description' } }); + + // submit form + const saveChangesButton = await findByTestId('edit-dialog-save'); + fireEvent.click(saveChangesButton); + }); + + await waitFor(() => { + expect(getByText('Name has already been used', { exact: false })).toBeVisible(); + }); + }); + + it('form submits properly', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + mockUseApi.funding.getFundingSources.mockResolvedValue([]); + const onClose = jest.fn(); + + const { findByTestId, getByTestId } = render( + + + + + + + + ); + + await act(async () => { + // Fill form + const nameInput = getByTestId('name'); + fireEvent.change(nameInput, { target: { value: 'Used Name' } }); + + const descriptionInput = getByTestId('description'); + fireEvent.change(descriptionInput, { target: { value: 'description' } }); + + // submit form + const saveChangesButton = await findByTestId('edit-dialog-save'); + fireEvent.click(saveChangesButton); + }); + + await waitFor(() => { + expect(mockUseApi.funding.postFundingSource).toHaveBeenCalledTimes(1); + expect(onClose).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/app/src/features/funding-sources/components/DeleteFundingSource.test.tsx b/app/src/features/funding-sources/components/DeleteFundingSource.test.tsx new file mode 100644 index 0000000000..e9f9f60884 --- /dev/null +++ b/app/src/features/funding-sources/components/DeleteFundingSource.test.tsx @@ -0,0 +1,109 @@ +import { cleanup, waitFor } from '@testing-library/react'; +import { AuthStateContext } from 'contexts/authStateContext'; +import { DialogContextProvider } from 'contexts/dialogContext'; +import { createMemoryHistory } from 'history'; +import { useBiohubApi } from 'hooks/useBioHubApi'; +import { IGetFundingSourceResponse } from 'interfaces/useFundingSourceApi.interface'; +import { Router } from 'react-router'; +import { getMockAuthState, SystemAdminAuthState } from 'test-helpers/auth-helpers'; +import { render } from 'test-helpers/test-utils'; +import DeleteFundingSource from './DeleteFundingSource'; + +jest.mock('../../../hooks/useBioHubApi'); +const mockBioHubApi = useBiohubApi as jest.Mock; +const mockUseApi = { + funding: { + getFundingSource: jest.fn, []>() + } +}; +const history = createMemoryHistory(); + +describe('DeleteFundingSource', () => { + beforeEach(() => { + mockBioHubApi.mockImplementation(() => mockUseApi); + mockUseApi.funding.getFundingSource.mockClear(); + }); + afterEach(() => { + cleanup(); + }); + + it('renders delete option', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + mockUseApi.funding.getFundingSource.mockResolvedValue({ + funding_source: { + funding_source_id: 1, + name: 'Funding Source Name', + description: 'funding source description', + start_date: null, + end_date: null, + revision_count: 1, + survey_reference_count: 0, + survey_reference_amount_total: 0 + }, + funding_source_survey_references: [] + }); + + const onClose = jest.fn(); + const openViewModal = jest.fn(); + + const { findByText } = render( + + + + + + + + ); + + await waitFor(async () => { + expect(mockUseApi.funding.getFundingSource).toBeCalled(); + expect(await findByText('Delete Funding Source?')).toBeVisible(); + }); + }); + + it('renders view more dialog', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + mockUseApi.funding.getFundingSource.mockResolvedValue({ + funding_source: { + funding_source_id: 1, + name: 'Funding Source Name', + description: 'funding source description', + start_date: null, + end_date: null, + revision_count: 1, + survey_reference_count: 0, + survey_reference_amount_total: 0 + }, + funding_source_survey_references: [ + { + survey_funding_source_id: 1, + survey_id: 1, + funding_source_id: 1, + amount: 1, + revision_count: 1, + project_id: 1, + survey_name: 'Survey' + } + ] + }); + + const onClose = jest.fn(); + const openViewModal = jest.fn(); + + const { findByText } = render( + + + + + + + + ); + + await waitFor(async () => { + expect(mockUseApi.funding.getFundingSource).toBeCalled(); + expect(await findByText("You can't delete this funding source")).toBeVisible(); + }); + }); +}); diff --git a/app/src/features/funding-sources/components/EditFundingSource.test.tsx b/app/src/features/funding-sources/components/EditFundingSource.test.tsx new file mode 100644 index 0000000000..2e9d9e6456 --- /dev/null +++ b/app/src/features/funding-sources/components/EditFundingSource.test.tsx @@ -0,0 +1,108 @@ +import { AuthStateContext } from 'contexts/authStateContext'; +import { DialogContextProvider } from 'contexts/dialogContext'; +import { createMemoryHistory } from 'history'; +import { useBiohubApi } from 'hooks/useBioHubApi'; +import { IGetFundingSourceResponse, IGetFundingSourcesResponse } from 'interfaces/useFundingSourceApi.interface'; +import { Router } from 'react-router'; +import { getMockAuthState, SystemAdminAuthState } from 'test-helpers/auth-helpers'; +import { act, cleanup, fireEvent, render, waitFor } from 'test-helpers/test-utils'; +import EditFundingSource from './EditFundingSource'; + +jest.mock('../../../hooks/useBioHubApi'); +const mockBioHubApi = useBiohubApi as jest.Mock; +const mockUseApi = { + funding: { + getFundingSources: jest.fn, []>(), + getFundingSource: jest.fn, []>(), + putFundingSource: jest.fn, []>() + } +}; +const history = createMemoryHistory(); +describe('EditFundingSource', () => { + beforeEach(() => { + mockBioHubApi.mockImplementation(() => mockUseApi); + mockUseApi.funding.getFundingSources.mockClear(); + mockUseApi.funding.getFundingSource.mockClear(); + mockUseApi.funding.putFundingSource.mockClear(); + }); + + afterEach(() => { + cleanup(); + }); + + it('renders with prefilled form fields', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + + mockUseApi.funding.getFundingSources.mockResolvedValue([]); + mockUseApi.funding.getFundingSource.mockResolvedValue({ + funding_source: { + funding_source_id: 1, + name: 'Funding Source Name', + description: 'funding source description', + start_date: null, + end_date: null, + revision_count: 1, + survey_reference_count: 0, + survey_reference_amount_total: 0 + }, + funding_source_survey_references: [] + }); + + const onClose = jest.fn(); + + const { getByDisplayValue } = render( + + + + + + + + ); + await waitFor(() => { + expect(getByDisplayValue('Funding Source Name', { exact: false })).toBeVisible(); + expect(getByDisplayValue('funding source description', { exact: false })).toBeVisible(); + }); + }); + + it('form submits properly', async () => { + const authState = getMockAuthState({ base: SystemAdminAuthState }); + + mockUseApi.funding.getFundingSources.mockResolvedValue([]); + mockUseApi.funding.getFundingSource.mockResolvedValue({ + funding_source: { + funding_source_id: 1, + name: 'Funding Source Name', + description: 'funding source description', + start_date: null, + end_date: null, + revision_count: 1, + survey_reference_count: 0, + survey_reference_amount_total: 0 + }, + funding_source_survey_references: [] + }); + + const onClose = jest.fn(); + + const { findByTestId } = render( + + + + + + + + ); + + await act(async () => { + const button = await findByTestId('edit-dialog-save'); + fireEvent.click(button); + }); + + await waitFor(() => { + expect(mockUseApi.funding.putFundingSource).toHaveBeenCalledTimes(1); + expect(onClose).toHaveBeenCalledTimes(1); + }); + }); +});