Skip to main content
Glama
EncounterChart.test.tsx6.84 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { MantineProvider } from '@mantine/core'; import { act, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MedplumProvider } from '@medplum/react'; import type { ClinicalImpression, Encounter, Practitioner, Task } from '@medplum/fhirtypes'; import { HomerSimpson, DrAliceSmith, MockClient } from '@medplum/mock'; import { MemoryRouter } from 'react-router'; import { describe, expect, test, beforeEach, vi } from 'vitest'; import { EncounterChart } from './EncounterChart'; import { createReference } from '@medplum/core'; const mockPractitioner: Practitioner = { resourceType: 'Practitioner', id: 'practitioner-123', name: [{ given: ['Dr.'], family: 'Test' }], }; const mockEncounter: Encounter = { resourceType: 'Encounter', id: 'encounter-123', status: 'in-progress', class: { system: 'http://terminology.hl7.org/CodeSystem/v3-ActCode', code: 'AMB', }, subject: { reference: `Patient/${HomerSimpson.id}` }, participant: [ { individual: createReference(mockPractitioner), }, ], }; const mockClinicalImpression: ClinicalImpression = { resourceType: 'ClinicalImpression', id: 'clinical-123', status: 'in-progress', subject: createReference(HomerSimpson), encounter: createReference(mockEncounter), note: [{ text: 'Test clinical note' }], }; const mockTask: Task = { resourceType: 'Task', id: 'task-123', status: 'in-progress', intent: 'order', encounter: createReference(mockEncounter), authoredOn: '2024-01-01T10:00:00Z', }; describe('EncounterChart', () => { let medplum: MockClient; beforeEach(async () => { medplum = new MockClient(); await medplum.createResource(HomerSimpson); await medplum.createResource(DrAliceSmith); await medplum.createResource(mockPractitioner); await medplum.createResource(mockEncounter); await medplum.createResource(mockClinicalImpression); vi.clearAllMocks(); }); const setup = (props: Partial<Parameters<typeof EncounterChart>[0]> = {}): ReturnType<typeof render> => { return render( <MemoryRouter> <MedplumProvider medplum={medplum}> <MantineProvider> <EncounterChart encounter={mockEncounter} {...props} /> </MantineProvider> </MedplumProvider> </MemoryRouter> ); }; test('renders loading spinner initially', () => { setup(); // The Loading component renders a spinner, not text const loader = document.querySelector('.mantine-Loader-root'); expect(loader).toBeInTheDocument(); }); test('renders encounter header after loading', async () => { setup(); await waitFor(() => { expect(screen.getByText('Visit')).toBeInTheDocument(); }); }); test('renders chart note textarea', async () => { setup(); await waitFor(() => { expect(screen.getByText('Fill chart note')).toBeInTheDocument(); }); const textarea = screen.getByRole('textbox'); expect(textarea).toBeInTheDocument(); expect(textarea).toHaveValue('Test clinical note'); }); test('updates chart note on change', async () => { const user = userEvent.setup(); vi.spyOn(medplum, 'updateResource').mockResolvedValue(mockClinicalImpression as any); setup(); await waitFor(() => { expect(screen.getByText('Fill chart note')).toBeInTheDocument(); }); const textarea = screen.getByRole('textbox'); await user.clear(textarea); await user.type(textarea, 'Updated note'); await waitFor( () => { expect(medplum.updateResource).toHaveBeenCalled(); }, { timeout: 3000 } ); }); test('displays tasks when available', async () => { await medplum.createResource(mockTask); setup(); await waitFor(() => { expect(screen.getByText('Visit')).toBeInTheDocument(); }); }); test('renders notes tab by default', async () => { setup(); await waitFor(() => { expect(screen.getByText('Visit')).toBeInTheDocument(); }); // The notes tab should be active by default await waitFor(() => { expect(screen.getByText('Fill chart note')).toBeInTheDocument(); }); }); test('fetches provenances on mount', async () => { vi.spyOn(medplum, 'searchResources').mockResolvedValue([] as any); setup(); await waitFor(() => { expect(medplum.searchResources).toHaveBeenCalledWith( 'Provenance', expect.stringContaining('target=Encounter/encounter-123') ); }); }); test('chart note is enabled when not signed', async () => { vi.spyOn(medplum, 'searchResources').mockImplementation((resourceType: string) => { if (resourceType === 'Provenance') { return [] as any; } if (resourceType === 'ClinicalImpression') { return [mockClinicalImpression]; } if (resourceType === 'Task') { return []; } return []; }); setup(); await waitFor(() => { expect(screen.getByText('Fill chart note')).toBeInTheDocument(); }); const textarea = screen.getByRole('textbox'); expect(textarea).not.toBeDisabled(); }); test('handles encounter status change', async () => { const user = userEvent.setup(); vi.spyOn(medplum, 'updateResource').mockResolvedValue({ ...mockEncounter, status: 'finished' } as any); setup(); await waitFor(() => { expect(screen.getByText('In Progress')).toBeInTheDocument(); }); const statusButton = screen.getByText('In Progress'); await user.click(statusButton); await waitFor(() => { expect(screen.getByText('Finished')).toBeInTheDocument(); }); }); test('renders with encounter reference', async () => { const encounterRef = { reference: 'Encounter/encounter-123' }; await act(async () => { setup({ encounter: encounterRef }); }); await waitFor(() => { expect(screen.getByText('Visit')).toBeInTheDocument(); }); }); test('fetches tasks for encounter', async () => { await medplum.createResource(mockTask); vi.spyOn(medplum, 'searchResources'); setup(); await waitFor(() => { expect(medplum.searchResources).toHaveBeenCalledWith( 'Task', expect.stringContaining('encounter=Encounter/encounter-123'), expect.any(Object) ); }); }); test('fetches clinical impressions for encounter', async () => { vi.spyOn(medplum, 'searchResources'); setup(); await waitFor(() => { expect(medplum.searchResources).toHaveBeenCalledWith( 'ClinicalImpression', expect.stringContaining('encounter=Encounter/encounter-123') ); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server