Skip to content

Commit

Permalink
#1532 - add unit tests for doi version editing
Browse files Browse the repository at this point in the history
  • Loading branch information
louise-davies committed Apr 10, 2024
1 parent 98eaeb6 commit 45ed831
Show file tree
Hide file tree
Showing 6 changed files with 662 additions and 1 deletion.
99 changes: 98 additions & 1 deletion packages/datagateway-common/src/api/dois.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { renderHook, act } from '@testing-library/react-hooks';
import axios, { AxiosError, AxiosHeaders } from 'axios';
import { handleDOIAPIError, useCheckUser } from '.';
import { handleDOIAPIError, useCheckUser, useUpdateDOI } from '.';
import { createReactQueryWrapper } from '../setupTests';
import { InvalidateTokenType } from '../state/actions/actions.types';
import { setLogger } from 'react-query';
import log from 'loglevel';
import { ContributorType } from '../app.types';

// silence react-query errors
setLogger({
Expand Down Expand Up @@ -239,4 +240,100 @@ describe('doi api functions', () => {
expect(axios.get).toHaveBeenCalledTimes(4);
});
});

describe('useUpdateDOI', () => {
const doiMetadata = {
title: 'Test title',
description: 'Test description',
creators: [{ username: '1', contributor_type: ContributorType.Minter }],
related_items: [],
};
const content = {
datafile_ids: [1],
dataset_ids: [2],
investigation_ids: [3],
};
it('should send a put request with payload indicating the updated data', async () => {
axios.put = jest.fn().mockResolvedValue({
data: {
concept: { data_publication: 'new', doi: 'pid' },
version: {
data_publication: 'new_version',
doi: 'new.version.pid',
},
},
});

const { result } = renderHook(() => useUpdateDOI(), {
wrapper: createReactQueryWrapper(),
});

await act(async () => {
await result.current.mutateAsync({
dataPublicationId: 'pid',
content,
doiMetadata,
});
});

expect(result.current.data).toEqual({
concept: { data_publication: 'new', doi: 'pid' },
version: {
data_publication: 'new_version',
doi: 'new.version.pid',
},
});
expect(axios.put).toHaveBeenCalledWith(
expect.stringContaining('/mint/version/update/pid'),
{
metadata: {
...doiMetadata,
resource_type: 'Collection',
},
investigation_ids: [3],
dataset_ids: [2],
datafile_ids: [1],
},
{ headers: { Authorization: 'Bearer null' } }
);
});

it('handles errors correctly', async () => {
const error = {
message: 'Test error message',
response: {
status: 500,
},
};
axios.put = jest.fn().mockRejectedValue(error);

const { result, waitFor } = renderHook(() => useUpdateDOI(), {
wrapper: createReactQueryWrapper(),
});

act(() => {
result.current.mutate({
dataPublicationId: 'pid',
content: { ...content, investigation_ids: [] },
doiMetadata,
});
});
await waitFor(() => expect(result.current.isError).toBe(true));

expect(log.error).toHaveBeenCalledWith(error);
expect(axios.put).toHaveBeenCalledWith(
expect.stringContaining('/mint/version/update/pid'),
{
metadata: {
...doiMetadata,
resource_type: 'Dataset',
},
investigation_ids: [],
dataset_ids: [2],
datafile_ids: [1],
},
{ headers: { Authorization: 'Bearer null' } }
);
});
});
});
8 changes: 8 additions & 0 deletions packages/datagateway-common/src/app.types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,19 @@ export interface DataCollection {
dataPublications?: DataPublication[];
}

export interface Affiliation {
id: number;
name: string;
user?: DataPublicationUser;
}

export interface DataPublicationUser {
id: number;
contributorType: string;
fullName: string;
user?: User;
email?: string;
affiliations?: Affiliation[];
}

export interface DataPublicationType {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { render, RenderResult, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import * as React from 'react';
import {
ContributorType,
DOIRelationType,
DOIResourceType,
} from '../app.types';
import DOIMetadataForm from './DOIMetadataForm.component';
import { QueryClient, QueryClientProvider } from 'react-query';

describe('DOI generation form component', () => {
let props: React.ComponentProps<typeof DOIMetadataForm>;

const renderComponent = (): RenderResult =>
render(<DOIMetadataForm {...props} />, {
wrapper: ({ children }) => (
<QueryClientProvider client={new QueryClient()}>
{children}
</QueryClientProvider>
),
});

let user: ReturnType<typeof userEvent.setup>;

beforeEach(() => {
user = userEvent.setup();

props = {
title: 'test',
setTitle: jest.fn(),
description: 'description',
setDescription: jest.fn(),
selectedUsers: [
{ id: 1, name: 'test', contributor_type: ContributorType.Minter },
],
setSelectedUsers: jest.fn(),
relatedDOIs: [
{
title: 'DOI Title',
fullReference: '',
identifier: 'doi',
relatedItemType: DOIResourceType.Dataset,
relationType: DOIRelationType.Cites,
},
],
setRelatedDOIs: jest.fn(),
disableMintButton: false,
onMintClick: jest.fn(),
doiMinterUrl: 'https://example.com/doi-minter',
dataCiteUrl: 'https://example.com/datacite',
};
});

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

it('should call onChange handlers when user interacts with fields', async () => {
renderComponent();

expect(
screen.getByRole('textbox', { name: 'DOIGenerationForm.title' })
).toHaveValue('test');
await user.type(
screen.getByRole('textbox', { name: 'DOIGenerationForm.title' }),
'1'
);

expect(props.setTitle).toHaveBeenCalledWith('test1');

expect(
screen.getByRole('textbox', { name: 'DOIGenerationForm.description' })
).toHaveValue('description');
await user.type(
screen.getByRole('textbox', { name: 'DOIGenerationForm.description' }),
'2'
);

expect(props.setDescription).toHaveBeenCalledWith('description2');
});

it('should disable mint button button at correct times', () => {
const { rerender } = renderComponent();

expect(
screen.getByRole('button', { name: 'DOIGenerationForm.generate_DOI' })
).not.toBeDisabled();

// title is empty
props.title = '';
rerender(<DOIMetadataForm {...props} />);

expect(
screen.getByRole('button', { name: 'DOIGenerationForm.generate_DOI' })
).toBeDisabled();

// description is empty
props.title = 'test';
props.description = '';
rerender(<DOIMetadataForm {...props} />);

expect(
screen.getByRole('button', { name: 'DOIGenerationForm.generate_DOI' })
).toBeDisabled();

// selectedUsers is empty
props.description = 'test';
props.selectedUsers = [];
rerender(<DOIMetadataForm {...props} />);

expect(
screen.getByRole('button', { name: 'DOIGenerationForm.generate_DOI' })
).toBeDisabled();

// selectedUsers has empty contributor type
props.selectedUsers = [{ id: 1, name: 'test', contributor_type: '' }];
rerender(<DOIMetadataForm {...props} />);

expect(
screen.getByRole('button', { name: 'DOIGenerationForm.generate_DOI' })
).toBeDisabled();

// relatedDOIs has empty relationtypes or relatedItemtypes
props.selectedUsers = [
{ id: 1, name: 'test', contributor_type: ContributorType.Minter },
];
props.relatedDOIs = [
{
title: 'DOI Title',
fullReference: '',
identifier: 'doi',
relatedItemType: DOIResourceType.Dataset,
relationType: '',
},
{
title: 'DOI Title 2',
fullReference: '',
identifier: 'doi2',
relatedItemType: '',
relationType: DOIRelationType.Cites,
},
];
rerender(<DOIMetadataForm {...props} />);

expect(
screen.getByRole('button', { name: 'DOIGenerationForm.generate_DOI' })
).toBeDisabled();

// disableMintButton is set to true
props.relatedDOIs = [
{
title: 'DOI Title',
fullReference: '',
identifier: 'doi',
relatedItemType: DOIResourceType.Dataset,
relationType: DOIRelationType.Cites,
},
];
props.disableMintButton = true;
rerender(<DOIMetadataForm {...props} />);

expect(
screen.getByRole('button', { name: 'DOIGenerationForm.generate_DOI' })
).toBeDisabled();
});
});
1 change: 1 addition & 0 deletions packages/datagateway-dataview/src/__mocks__/axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const requests = {
}
}),
post: jest.fn(() => Promise.resolve({ data: {} })),
put: jest.fn(() => Promise.resolve({ data: {} })),
delete: jest.fn(() => Promise.resolve({ data: {} })),
CancelToken: axios.CancelToken,
isAxiosError: axios.isAxiosError,
Expand Down
Loading

0 comments on commit 45ed831

Please sign in to comment.