Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backmerge test to dev #4489

Merged
merged 8 commits into from
Nov 19, 2024
3 changes: 1 addition & 2 deletions source/backend/api/Pims.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<PropertyGroup>
<UserSecretsId>0ef6255f-9ea0-49ec-8c65-c172304b4926</UserSecretsId>
<Version>5.7.0-93.16</Version>
<Version>5.7.0-93.16</Version>
<AssemblyVersion>5.7.0.93</AssemblyVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ProjectGuid>{16BC0468-78F6-4C91-87DA-7403C919E646}</ProjectGuid>
Expand Down Expand Up @@ -86,4 +85,4 @@
<Folder Include="Areas\Keycloak\Mapping\User\" />
<Folder Include="Helpers\Swagger\" />
</ItemGroup>
</Project>
</Project>
9 changes: 4 additions & 5 deletions source/backend/dal/Repositories/PropertyRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -532,11 +532,10 @@ public HashSet<long> GetMatchingIds(PropertyFilterCriteria filter)
}
if (filter.IsOtherInterest)
{
var today = DateOnly.FromDateTime(DateTime.Now);
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsNewLandAct && authorizationTypes.Contains(t.LandActTypeCode) && t.LandActEndDt >= today)));
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsNewInterestInSrw && t.SrwEndDt >= today)));
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsNewLicenseToConstruct && t.LtcEndDt >= today)));
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsActiveLease && t.ActiveLeaseEndDt >= today)));
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsNewLandAct && authorizationTypes.Contains(t.LandActTypeCode))));
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsNewInterestInSrw)));
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsNewLicenseToConstruct)));
ownershipBuilder.Or(p => p.PimsPropertyAcquisitionFiles.Any(x => x.PimsTakes.Any(t => t.TakeStatusTypeCode == "COMPLETE" && t.IsActiveLease)));
}
if (filter.IsDisposed)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -397,10 +397,9 @@ const advancedFilterSideBarStates = {
actions: [
send({ type: 'REFRESH_PROPERTIES' }),
assign({
isFiltering: () => false,
showDisposed: () => false,
showRetired: () => false,
activePimsPropertyIds: () => [],
advancedSearchCriteria: () => new PropertyFilterFormModel(),
}),
],
},
Expand Down
9 changes: 9 additions & 0 deletions source/frontend/src/components/maps/MapLeafletView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import axios from 'axios';
import { dequal } from 'dequal';
import { Feature, GeoJsonProperties, Geometry } from 'geojson';
import {
geoJSON,
Expand Down Expand Up @@ -87,6 +88,14 @@ const MapLeafletView: React.FC<React.PropsWithChildren<MapLeafletViewProps>> = (
const requestedFlyTo = mapMachine.requestedFlyTo;
const mapMachineProcessFlyTo = mapMachine.processFlyTo;

// Set the bounds when the map is ready. Not called from existing handleMapCreated as that function is called every time a state change occurs.
useEffect(() => {
const bounds = mapRef?.current?.getBounds();
if (exists(bounds) && isMapReady && !dequal(bounds.getNorthEast(), bounds.getSouthWest())) {
setBounds(bounds);
}
}, [isMapReady, setBounds]);

useEffect(() => {
if (isMapReady && mapMachinePendingRefresh && mapRef.current !== null) {
// PSP-9347 it is possible that a fit bounds request will be made with an empty array of selected properties. In that case, we do not want to change the screen bounds, so cancel the request with no changes to the map.
Expand Down
16 changes: 9 additions & 7 deletions source/frontend/src/features/documents/ComposedDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,13 @@ export class DocumentUpdateFormData {
return model;
}

public toRequestApi(): ApiGen_Requests_DocumentUpdateRequest {
public static toRequestApi(
formData: DocumentUpdateFormData,
): ApiGen_Requests_DocumentUpdateRequest {
const metadata: ApiGen_Concepts_DocumentMetadataUpdate[] = [];

for (const key in this.documentMetadata) {
const value = this.documentMetadata[key];
for (const key in formData.documentMetadata) {
const value = formData.documentMetadata[key];
const metadataTypeId = Number(key);
metadata.push({
value: value,
Expand All @@ -235,10 +237,10 @@ export class DocumentUpdateFormData {
}

return {
documentId: this.documentId,
mayanDocumentId: this.mayanDocumentId,
documentTypeId: stringToNumber(this.documentTypeId),
documentStatusCode: this.documentStatusCode,
documentId: formData.documentId,
mayanDocumentId: formData.mayanDocumentId,
documentTypeId: stringToNumber(formData.documentTypeId),
documentStatusCode: formData.documentStatusCode,
documentMetadata: metadata,
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import { createMemoryHistory } from 'history';

import { Claims } from '@/constants';
import { useDocumentProvider } from '@/features/documents/hooks/useDocumentProvider';
import {
mockDocumentResponse,
mockDocumentTypeMetadataBcAssessment,
mockDocumentTypesAcquisition,
mockDocumentTypesAll,
} from '@/mocks/documents.mock';
import { mockLookups } from '@/mocks/lookups.mock';
import { ApiGen_CodeTypes_DocumentRelationType } from '@/models/api/generated/ApiGen_CodeTypes_DocumentRelationType';
import { ApiGen_CodeTypes_ExternalResponseStatus } from '@/models/api/generated/ApiGen_CodeTypes_ExternalResponseStatus';
import { ApiGen_System_HttpStatusCode } from '@/models/api/generated/ApiGen_System_HttpStatusCode';
import { lookupCodesSlice } from '@/store/slices/lookupCodes';
import { act, getByName, render, RenderOptions, screen, userEvent } from '@/utils/test-utils';

import { DocumentRow } from '../ComposedDocument';
import { DocumentDetailContainer, IDocumentDetailContainerProps } from './DocumentDetailContainer';

const history = createMemoryHistory();
const storeState = {
[lookupCodesSlice.name]: { lookupCodes: mockLookups },
};

const onUpdateSuccess = vi.fn();

const mockDocumentApi = {
retrieveDocumentMetadata: vi.fn(),
retrieveDocumentMetadataLoading: false,
downloadWrappedDocumentFile: vi.fn(),
downloadWrappedDocumentFileLoading: false,
downloadWrappedDocumentFileLatest: vi.fn(),
downloadWrappedDocumentFileLatestLoading: false,
downloadWrappedDocumentFileLatestResponse: null,
streamDocumentFile: vi.fn(),
streamDocumentFileLoading: false,
streamDocumentFileLatest: vi.fn(),
streamDocumentFileLatestLoading: false,
streamDocumentFileLatestResponse: null,
retrieveDocumentTypeMetadata: vi.fn(),
retrieveDocumentTypeMetadataLoading: false,
getDocumentTypes: vi.fn(),
getDocumentTypesLoading: false,
getDocumentRelationshipTypes: vi.fn(),
getDocumentRelationshipTypesLoading: false,
retrieveDocumentDetail: vi.fn(),
retrieveDocumentDetailLoading: false,
updateDocument: vi.fn(),
updateDocumentLoading: false,
downloadDocumentFilePageImage: vi.fn(),
downloadDocumentFilePageImageLoading: false,
getDocumentFilePageList: vi.fn(),
getDocumentFilePageListLoading: false,
};

vi.mock('@/features/documents/hooks/useDocumentProvider');
vi.mocked(useDocumentProvider).mockReturnValue(mockDocumentApi);

describe('DocumentDetailContainer component', () => {
// render component under test
const setup = (
renderOptions: RenderOptions & { props?: Partial<IDocumentDetailContainerProps> } = {},
) => {
const utils = render(
<DocumentDetailContainer
pimsDocument={
renderOptions?.props?.pimsDocument ?? DocumentRow.fromApi(mockDocumentResponse())
}
relationshipType={
renderOptions?.props?.relationshipType ??
ApiGen_CodeTypes_DocumentRelationType.AcquisitionFiles
}
onUpdateSuccess={renderOptions?.props?.onUpdateSuccess ?? onUpdateSuccess}
/>,
{
...renderOptions,
store: storeState,
history,
claims: renderOptions.claims ?? [Claims.DOCUMENT_VIEW, Claims.DOCUMENT_EDIT],
},
);

return {
...utils,
getDocumentTypeDropdown: () => getByName('documentTypeId') as HTMLSelectElement,
};
};

beforeEach(() => {
mockDocumentApi.getDocumentRelationshipTypes.mockResolvedValue(mockDocumentTypesAcquisition());
mockDocumentApi.getDocumentTypes.mockResolvedValue(mockDocumentTypesAll());
});

afterEach(() => {
vi.clearAllMocks();
});

it('renders the underlying form', async () => {
const { asFragment } = setup();

await act(async () => {});
expect(screen.getByText(/Document Information/i)).toBeVisible();
expect(asFragment()).toMatchSnapshot();
});

it('should call the api to fetch document types when in Edit mode', async () => {
setup();

await act(async () => {});
await act(async () => {
userEvent.click(screen.getByTitle(/Edit document information/i));
});
expect(mockDocumentApi.getDocumentRelationshipTypes).toHaveBeenCalled();
});

it('should call the api to fetch document types for CDOGS templates', async () => {
setup({ props: { relationshipType: ApiGen_CodeTypes_DocumentRelationType.Templates } });

await act(async () => {});
await act(async () => {
userEvent.click(screen.getByTitle(/Edit document information/i));
});
expect(mockDocumentApi.getDocumentTypes).toHaveBeenCalled();
});

it('should call the api to fetch mayan document type metadata', async () => {
mockDocumentApi.retrieveDocumentTypeMetadata.mockResolvedValue({
status: ApiGen_CodeTypes_ExternalResponseStatus.Success,
message: null,
payload: {
results: mockDocumentTypeMetadataBcAssessment(),
},
httpStatusCode: ApiGen_System_HttpStatusCode.OK,
});

setup();

await act(async () => {});
expect(mockDocumentApi.retrieveDocumentTypeMetadata).toHaveBeenCalled();
});

it('should fetch additional document child entities upon rendering this component', async () => {
mockDocumentApi.retrieveDocumentMetadata.mockResolvedValue({
status: ApiGen_CodeTypes_ExternalResponseStatus.Success,
message: null,
payload: {
results: [],
},
httpStatusCode: ApiGen_System_HttpStatusCode.OK,
});
mockDocumentApi.retrieveDocumentDetail.mockResolvedValue({
status: ApiGen_CodeTypes_ExternalResponseStatus.Success,
message: null,
payload: {
id: 1,
label: null,
datetime_created: new Date().toISOString(),
description: null,
uuid: null,
file_latest: { id: 1 },
document_type: null,
},
httpStatusCode: ApiGen_System_HttpStatusCode.OK,
});

setup();

await act(async () => {});
expect(mockDocumentApi.retrieveDocumentMetadata).toHaveBeenCalled();
expect(mockDocumentApi.retrieveDocumentDetail).toHaveBeenCalled();
});

it('should refresh the document type metadata when document type is changed', async () => {
mockDocumentApi.retrieveDocumentTypeMetadata.mockResolvedValue({
status: ApiGen_CodeTypes_ExternalResponseStatus.Success,
message: null,
payload: {
results: mockDocumentTypeMetadataBcAssessment(),
},
httpStatusCode: ApiGen_System_HttpStatusCode.OK,
});
vi.spyOn(console, 'error').mockImplementationOnce(() => {});

const { getDocumentTypeDropdown } = setup();

await act(async () => {});
expect(mockDocumentApi.retrieveDocumentTypeMetadata).toHaveBeenCalled();
await act(async () => {
userEvent.click(screen.getByTitle(/Edit document information/i));
});

const documentType = getDocumentTypeDropdown();
expect(documentType).toBeVisible();
await act(async () => {
userEvent.selectOptions(documentType, '17');
});

// document type metadata should be refreshed
expect(mockDocumentApi.retrieveDocumentTypeMetadata).toHaveBeenCalled();
});

it('should submit the form as expected', async () => {
mockDocumentApi.retrieveDocumentTypeMetadata.mockResolvedValue({
status: ApiGen_CodeTypes_ExternalResponseStatus.Success,
message: null,
payload: {
results: mockDocumentTypeMetadataBcAssessment(),
},
httpStatusCode: ApiGen_System_HttpStatusCode.OK,
});
mockDocumentApi.updateDocument.mockResolvedValue({
metadataExternalResponse: [],
});

setup();

await act(async () => {});
expect(mockDocumentApi.retrieveDocumentTypeMetadata).toHaveBeenCalled();
await act(async () => {
userEvent.click(screen.getByTitle(/Edit document information/i));
});

const yesButton = screen.getByText('Yes');
expect(yesButton).toBeVisible();
await act(async () => {
userEvent.click(yesButton);
});

// document update was called
expect(onUpdateSuccess).toHaveBeenCalled();
});
});
Loading
Loading