Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jest.mock('src/features/language/Lang', () => ({
jest.mock('src/features/applicationMetadata/ApplicationMetadataProvider', () => ({
useApplicationMetadata: jest.fn(() => ({
dataTypes: [],
altinnNugetVersion: '8.9.0.225',
})),
}));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DownloadIcon } from '@navikt/aksel-icons';

import { AppTable } from 'src/app-components/Table/Table';
import { Caption } from 'src/components/form/caption/Caption';
import { useApplicationMetadata } from 'src/features/applicationMetadata/ApplicationMetadataProvider';
import { Lang } from 'src/features/language/Lang';
import { useLanguage } from 'src/features/language/useLanguage';
import classes from 'src/layout/SigneeList/SigneeListComponent.module.css';
Expand All @@ -21,8 +22,9 @@ export function SigningDocumentListComponent({
}) {
const { instanceOwnerPartyId, instanceGuid } = useParams();
const { langAsString } = useLanguage();
const { altinnNugetVersion } = useApplicationMetadata();

const { data, isLoading, error } = useDocumentList(instanceOwnerPartyId, instanceGuid);
const { data, isLoading, error } = useDocumentList(instanceOwnerPartyId, instanceGuid, altinnNugetVersion);

if (error) {
return <SigningDocumentListError error={error} />;
Expand Down
88 changes: 88 additions & 0 deletions src/layout/SigningDocumentList/api.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { jest } from '@jest/globals';
import { useQuery } from '@tanstack/react-query';
import { renderHook } from '@testing-library/react';

import { type SigningDocument, useDocumentList } from 'src/layout/SigningDocumentList/api';
import { httpGet } from 'src/utils/network/sharedNetworking';

jest.mock('@tanstack/react-query', () => ({
useQuery: jest.fn(),
}));

jest.mock('src/utils/network/sharedNetworking', () => ({
httpGet: jest.fn(),
}));

describe('useDocumentList', () => {
const mockedUseQuery = jest.mocked(useQuery);
const mockedHttpGet = jest.mocked(httpGet);

const response = {
dataElements: [
{
id: '1',
dataType: 'attachment',
contentType: 'application/pdf',
filename: 'zeta.pdf',
size: 100,
tags: ['tag-a'],
selfLinks: {
apps: 'https://storage.example.com/zeta.pdf',
},
},
{
id: '2',
dataType: 'attachment',
contentType: 'application/pdf',
filename: 'alpha.pdf',
size: 200,
tags: ['tag-b'],
selfLinks: {
apps: 'https://storage.example.com/alpha.pdf',
},
},
],
};

beforeEach(() => {
jest.clearAllMocks();
mockedHttpGet.mockResolvedValue(response);
});

function hasQueryFn(value: unknown): value is { queryFn: () => Promise<SigningDocument[]> } {
if (typeof value !== 'object' || value === null) {
return false;
}

return 'queryFn' in value && typeof value.queryFn === 'function';
}

const runQueryFn = async (altinnNugetVersion: string | undefined): Promise<SigningDocument[]> => {
mockedUseQuery.mockReturnValue({} as ReturnType<typeof useQuery>);

renderHook(() => useDocumentList('party-id', 'instance-guid', altinnNugetVersion));

const [queryOptions] = mockedUseQuery.mock.calls.at(-1) ?? [];

if (!hasQueryFn(queryOptions)) {
throw new Error('Expected useQuery to receive a queryFn');
}

return queryOptions.queryFn();
};

it('returns backend order when altinnNugetVersion is at least 8.9.0.225', async () => {
const documents = await runQueryFn('8.9.0.225');

expect(documents.map((doc) => doc.filename)).toEqual(['zeta.pdf', 'alpha.pdf']);
});

it.each<[string | undefined]>([['8.9.0.224'], [undefined]])(
'sorts by filename when altinnNugetVersion is %s',
async (altinnNugetVersion) => {
const documents = await runQueryFn(altinnNugetVersion);

expect(documents.map((doc) => doc.filename)).toEqual(['alpha.pdf', 'zeta.pdf']);
},
);
});
16 changes: 11 additions & 5 deletions src/layout/SigningDocumentList/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DataTypeReference } from 'src/utils/attachmentsUtils';
import { httpGet } from 'src/utils/network/sharedNetworking';
import { appPath } from 'src/utils/urls/appUrlHelper';
import { makeUrlRelativeIfSameDomain } from 'src/utils/urls/urlHelper';
import { backendSupportsSigningDocumentOrdering } from 'src/utils/versioning/versions';

const signingDocumentSchema = z
.object({
Expand Down Expand Up @@ -33,18 +34,23 @@ export type SigningDocument = z.infer<typeof signingDocumentSchema>;
export function useDocumentList(
instanceOwnerPartyId: string | undefined,
instanceGuid: string | undefined,
altinnNugetVersion: string | undefined,
): UseQueryResult<SigningDocument[]> {
const backendHandlesOrdering = backendSupportsSigningDocumentOrdering(altinnNugetVersion);

return useQuery({
queryKey: ['signingDocumentList', instanceOwnerPartyId, instanceGuid],
queryKey: ['signingDocumentList', instanceOwnerPartyId, instanceGuid, backendHandlesOrdering],
queryFn: async () => {
const url = `${appPath}/instances/${instanceOwnerPartyId}/${instanceGuid}/signing/data-elements`;

const response = await httpGet(url);

return z
.object({ dataElements: z.array(signingDocumentSchema) })
.parse(response)
.dataElements.toSorted((a, b) => (a.filename ?? '').localeCompare(b.filename ?? ''));
const dataElements = z.object({ dataElements: z.array(signingDocumentSchema) }).parse(response).dataElements;

if (backendHandlesOrdering) {
return dataElements;
}
return dataElements.toSorted((a, b) => (a.filename ?? '').localeCompare(b.filename ?? ''));
},
staleTime: 1000 * 60 * 30, // 30 minutes
refetchOnMount: 'always',
Expand Down
5 changes: 5 additions & 0 deletions src/utils/versioning/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const FEATURE_VERSION_MAP = {
PDF_PREVIEW_BUTTON: '8.5.0.157',
APP_LANGUAGES_IN_ANONYMOUS: '8.5.6.180',
SET_TAGS_ENDPOINT: '8.8.0.215',
BACKEND_ORDERED_SIGNING_DOCUMENTS: '8.9.0.225',
} as const;

type AppFeature = keyof typeof FEATURE_VERSION_MAP;
Expand Down Expand Up @@ -67,3 +68,7 @@ export function appSupportsIncrementalValidationFeatures(currentNugetVersion: st
export function appSupportsSetTagsEndpoint(currentNugetVersion: string | undefined) {
return isFeatureSupported({ feature: 'SET_TAGS_ENDPOINT', currentNugetVersion });
}

export function backendSupportsSigningDocumentOrdering(currentNugetVersion: string | undefined) {
return isFeatureSupported({ feature: 'BACKEND_ORDERED_SIGNING_DOCUMENTS', currentNugetVersion });
}
Loading