Skip to content

Commit

Permalink
(tests) O3-4098 Add tests for downloading a schema
Browse files Browse the repository at this point in the history
  • Loading branch information
CynthiaKamau committed Nov 6, 2024
1 parent fa2b1c8 commit f261976
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 16 deletions.
98 changes: 96 additions & 2 deletions src/components/dashboard/dashboard.component.test.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,74 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom';
import { ContentPackagesList } from './dashboard.component';
import { getAllPackagesFromLocalStorage } from '../../utils';
import { ActionButtons, ContentPackagesList } from './dashboard.component';
import { deletePackageFromLocalStorage, getAllPackagesFromLocalStorage } from '../../utils';
import { mockContentPackages } from '../../../__mocks__/content-packages.mock';
import userEvent from '@testing-library/user-event';

jest.mock('../../utils', () => ({
getAllPackagesFromLocalStorage: jest.fn(),
deletePackageFromLocalStorage: jest.fn(),
}));

const mockSetClinicalViews = jest.fn();

describe('DashboardComponent', () => {
// Mock setup
const setupMocks = () => {
const mocks = {
setClinicalViews: jest.fn(),
consoleSpy: jest.spyOn(console, 'error').mockImplementation(() => {}),
localStorageGetItem: jest.fn(),
mockUrl: 'blob:mock-url',
mockAnchor: document.createElement('a'),
mockClick: jest.fn(),
originalCreateObjectURL: URL.createObjectURL,
originalRevokeObjectURL: URL.revokeObjectURL,
originalCreateElement: document.createElement.bind(document),
};

// Setup localStorage mock
Object.defineProperty(window, 'localStorage', {
value: {
getItem: mocks.localStorageGetItem,
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
},
writable: true,
});

// Setup URL mocks
URL.createObjectURL = jest.fn(() => mocks.mockUrl);
URL.revokeObjectURL = jest.fn();

// Setup anchor element mock
Object.defineProperties(mocks.mockAnchor, {
click: { value: mocks.mockClick, writable: true },
href: { value: '', writable: true },
download: { value: '', writable: true },
});

// Setup document.createElement mock
document.createElement = jest.fn((tag) => {
if (tag === 'a') {
return mocks.mockAnchor;
}
return mocks.originalCreateElement(tag);
});

return mocks;
};

// Cleanup function
const cleanupMocks = (mocks: ReturnType<typeof setupMocks>) => {
URL.createObjectURL = mocks.originalCreateObjectURL;
URL.revokeObjectURL = mocks.originalRevokeObjectURL;
document.createElement = mocks.originalCreateElement;
mocks.consoleSpy.mockRestore();
};

beforeEach(() => {
(getAllPackagesFromLocalStorage as jest.Mock).mockReturnValue(mockContentPackages);
});
Expand Down Expand Up @@ -73,4 +129,42 @@ describe('DashboardComponent', () => {
await userEvent.type(searchInput, 'Clinical View 1');
expect(searchInput).toHaveValue('Clinical View 1');
});

it('handles downloading the schema', async () => {
const mocks = setupMocks();

mocks.localStorageGetItem.mockImplementation(() => mockContentPackages[0]);

render(
<ContentPackagesList
t={(key) => key}
clinicalViews={mockContentPackages}
setClinicalViews={mocks.setClinicalViews}
/>,
);

const downloadButton = await screen.findByRole('button', {
name: /downloadSchema/i,
});

await userEvent.click(downloadButton);

expect(mocks.localStorageGetItem).toHaveBeenCalled();
expect(URL.createObjectURL).toHaveBeenCalledWith(expect.any(Blob));
expect(mocks.mockClick).toHaveBeenCalled();

mocks.localStorageGetItem.mockReset();
mocks.mockClick.mockReset();
mocks.consoleSpy.mockReset();

mocks.localStorageGetItem.mockReturnValue(null);

await userEvent.click(downloadButton);
const blobCall = (URL.createObjectURL as jest.Mock).mock.calls[0][0];
expect(blobCall).toBeInstanceOf(Blob);
expect(blobCall.type).toBe('application/json;charset=utf-8');

expect(mocks.mockAnchor.href).toBe('blob:mock-url');
cleanupMocks(mocks);
});
});
54 changes: 40 additions & 14 deletions src/components/dashboard/dashboard.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,14 @@ interface ActionButtonsProps {
onDownload: (key: string) => void;
}

function ActionButtons({ responsiveSize, clinicalViewKey, t, onDelete, onDownload, onEdit }: ActionButtonsProps) {
export function ActionButtons({
responsiveSize,
clinicalViewKey,
t,
onDelete,
onDownload,
onEdit,
}: ActionButtonsProps) {
const defaultEnterDelayInMs = 300;

const launchDeleteClinicalViewsPackageModal = () => {
Expand Down Expand Up @@ -145,16 +152,34 @@ export function ContentPackagesList({ t, clinicalViews, setClinicalViews }: Cont
const { paginated, goTo, results, currentPage } = usePagination(filteredViews, pageSize);

const handleDownload = (key) => {
const schema = localStorage.getItem(`packageJSON_${key}`);
if (schema) {
const blob = new Blob([schema], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${key}.json`;
a.click();
} else {
console.error('No schema found to download.');
let url;
let anchor;
try {
const schema = localStorage.getItem(key);
if (!schema) {
console.error('No schema found to download.');
return;
}

const blob = new Blob([schema], {
type: 'application/json;charset=utf-8',
});
url = URL.createObjectURL(blob);

anchor = document.createElement('a');
anchor.href = url;
anchor.download = `${key}.json`;
document.body.appendChild(anchor);
anchor.click();
} catch (error) {
console.error('Error downloading schema:', error);
} finally {
if (url) {
URL.revokeObjectURL(url);
}
if (anchor && anchor.parentNode) {
anchor.parentNode.removeChild(anchor);
}
}
};

Expand Down Expand Up @@ -196,7 +221,8 @@ export function ContentPackagesList({ t, clinicalViews, setClinicalViews }: Cont
const tableRows = results.map((contentPackage) => {
const clinicalViewName = getNavGroupTitle(contentPackage);
const dashboardTitles = getDashboardTitles(contentPackage);
const key = Object.keys(contentPackage)[0];

const key = Object.keys(contentPackage)[1];

return {
id: contentPackage.key,
Expand Down Expand Up @@ -272,8 +298,8 @@ export function ContentPackagesList({ t, clinicalViews, setClinicalViews }: Cont
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key="row.id" {...getRowProps({ row })} data-testid={`content-package-row-${row.id}`}>
{rows.map((row, key) => (
<TableRow key={key} {...getRowProps({ row })} data-testid={`content-package-row-${row.id}`}>
{row.cells.map((cell) => (
<TableCell key={cell.id}>{cell.value}</TableCell>
))}
Expand Down

0 comments on commit f261976

Please sign in to comment.