diff --git a/specifyweb/frontend/js_src/lib/components/Interactions/__tests__/LoanReturn.test.tsx b/specifyweb/frontend/js_src/lib/components/Interactions/__tests__/LoanReturn.test.tsx new file mode 100644 index 00000000000..b772e32b8f4 --- /dev/null +++ b/specifyweb/frontend/js_src/lib/components/Interactions/__tests__/LoanReturn.test.tsx @@ -0,0 +1,223 @@ +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; + +import { commonText } from '../../../localization/common'; +import { overrideAjax } from '../../../tests/ajax'; +import { mockTime, requireContext } from '../../../tests/helpers'; +import { overwriteReadOnly } from '../../../utils/types'; +import { Contexts } from '../../Core/Contexts'; +import { getResourceApiUrl } from '../../DataModel/resource'; +import { tables } from '../../DataModel/tables'; +import { ShowLoansCommand } from '../../FormCommands/ShowTransactions'; +import { userInformation } from '../../InitialContext/userInformation'; +import { SubViewContext } from '../../Forms/SubView'; + +mockTime(); +requireContext(); + +const agentUrl = getResourceApiUrl('Agent', 1); +const agentResponse = { + id: 1, + resource_uri: agentUrl, + agenttype: 1, + lastname: 'Current', + firstname: 'Agent', +}; +const onAgentFetch = jest.fn(() => agentResponse); +overrideAjax(agentUrl, onAgentFetch); +const emptyInteractionCollection = { + objects: [], + meta: { limit: 0, offset: 0, total_count: 0 }, +}; +for (const [tableName, relationship] of [ + ['disposal', 'disposalpreparations'], + ['exchangein', 'exchangeinpreps'], + ['exchangeout', 'exchangeoutpreps'], + ['gift', 'giftpreparations'], +]) + overrideAjax( + `/api/specify/${tableName}/?${relationship}__preparation__exact=2&limit=0`, + emptyInteractionCollection + ); +overrideAjax( + '/api/specify/loan/?loanpreparations__preparation__exact=2&limit=0', + { + objects: [{ id: 1, resource_uri: getResourceApiUrl('Loan', 1) }], + meta: { limit: 0, offset: 0, total_count: 1 }, + } +); +const preparationUrl = getResourceApiUrl('Preparation', 2); +const collectionObjectUrl = getResourceApiUrl('CollectionObject', 65); +overrideAjax(preparationUrl, { + id: 2, + resource_uri: preparationUrl, + collectionobject: collectionObjectUrl, + preptype: getResourceApiUrl('PrepType', 1), +}); +overrideAjax(getResourceApiUrl('PrepType', 1), { + id: 1, + resource_uri: getResourceApiUrl('PrepType', 1), + name: 'Specimen', +}); +const loanView = ( + tableName: string, + viewName: string, + viewDefinition: string +) => ({ + name: viewName, + class: `edu.ku.brc.specify.datamodel.${tableName}`, + view: viewName, + resourcelabels: 'false', + altviews: { + [`${viewName} Edit`]: { + name: `${viewName} Edit`, + viewdef: viewName, + mode: 'edit', + }, + }, + viewdefs: { [viewName]: viewDefinition }, + viewsetLevel: '', + viewsetName: '', + viewsetSource: '', + viewsetId: null, + viewsetFile: null, +}); +overrideAjax( + '/context/view.json?name=Loan', + loanView( + 'Loan', + 'Loan', + '' + ) +); +overrideAjax( + '/context/view.json?name=LoanItems', + loanView( + 'LoanPreparation', + 'LoanItems', + '' + ) +); +overrideAjax( + '/context/view.json?name=LoanReturnPreparation', + loanView( + 'LoanReturnPreparation', + 'LoanReturnPreparation', + '' + ) +); +overrideAjax(getResourceApiUrl('Loan', 1), { + id: 1, + resource_uri: getResourceApiUrl('Loan', 1), + loanpreparations: [ + { + id: 2, + resource_uri: getResourceApiUrl('LoanPreparation', 2), + preparation: preparationUrl, + quantity: 5, + quantityresolved: 0, + quantityreturned: 0, + loanreturnpreparations: [], + }, + ], +}); +overrideAjax('/delete_blockers/delete_blockers/loan/1/', []); +const onCollectionObjectFetch = jest.fn(() => ({ + id: 65, + resource_uri: collectionObjectUrl, + catalognumber: '65', + collectionmemberid: 1, + collection: getResourceApiUrl('Collection', 4), + collectionObjectType: getResourceApiUrl('CollectionObjectType', 1), + determinations: [], + preparations: [ + { + id: 2, + resource_uri: preparationUrl, + collectionmemberid: 1, + countamt: 2, + collectionobject: collectionObjectUrl, + preptype: getResourceApiUrl('PrepType', 1), + loanpreparations: '/api/specify/loanpreparation/?preparation=2', + }, + ], +})); +overrideAjax(collectionObjectUrl, onCollectionObjectFetch); + +test('opens Return Loan through the Show Loans command', async () => { + const originalCurrentAgent = userInformation.currentCollectionAgent; + overwriteReadOnly(userInformation, 'currentCollectionAgent', agentResponse); + const collectionObject = new tables.CollectionObject.Resource({ + id: 65, + resource_uri: collectionObjectUrl, + preparations: [ + { + id: 2, + resource_uri: preparationUrl, + collectionObject: collectionObjectUrl, + prepType: getResourceApiUrl('PrepType', 1), + countAmt: 2, + isOnLoan: true, + }, + ], + }); + const preparation = new tables.Preparation.Resource({ + id: 2, + resource_uri: preparationUrl, + collectionObject: collectionObjectUrl, + prepType: getResourceApiUrl('PrepType', 1), + countAmt: 2, + isOnLoan: true, + }); + const preparationsRelationship = + tables.CollectionObject.strictGetRelationship('preparations'); + try { + render( + + + + + + + + ); + + fireEvent.click( + await screen.findByRole('button', { + name: /Loan records \(1\)/, + }) + ); + fireEvent.click(await screen.findByRole('button', { name: 'Return Loan' })); + + expect( + await screen.findByRole('button', { name: commonText.apply() }) + ).toBeInTheDocument(); + expect(screen.getAllByRole('dialog')).toHaveLength(3); + expect( + await screen.findByRole('cell', { name: 'Specimen' }) + ).toBeInTheDocument(); + expect(onCollectionObjectFetch).toHaveBeenCalled(); + expect(onAgentFetch).toHaveBeenCalled(); + } finally { + overwriteReadOnly( + userInformation, + 'currentCollectionAgent', + originalCurrentAgent + ); + } +});