Skip to main content
Glama
ChargeItemPanel.test.tsx3.96 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { MantineProvider } from '@mantine/core'; import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MedplumProvider } from '@medplum/react'; import type { ChargeItem } from '@medplum/fhirtypes'; import { MockClient } from '@medplum/mock'; import { describe, expect, test, beforeEach, vi } from 'vitest'; import ChargeItemPanel from './ChargeItemPanel'; const mockChargeItem: ChargeItem = { resourceType: 'ChargeItem', id: 'charge-123', status: 'billable', subject: { reference: 'Patient/patient-123' }, code: { coding: [ { system: 'http://www.ama-assn.org/go/cpt', code: '99213', display: 'Office Visit', }, ], }, priceOverride: { value: 100, currency: 'USD', }, }; describe('ChargeItemPanel', () => { let medplum: MockClient; beforeEach(() => { medplum = new MockClient(); vi.clearAllMocks(); }); const setup = (props: Partial<Parameters<typeof ChargeItemPanel>[0]> = {}): ReturnType<typeof render> => { return render( <MedplumProvider medplum={medplum}> <MantineProvider> <ChargeItemPanel chargeItem={mockChargeItem} onChange={vi.fn()} onDelete={vi.fn()} {...props} /> </MantineProvider> </MedplumProvider> ); }; test('renders charge item details', () => { setup(); expect(screen.getByText('CPT Code')).toBeInTheDocument(); expect(screen.getByDisplayValue('$100.00')).toBeInTheDocument(); expect(screen.getByText('Calculated Price')).toBeInTheDocument(); }); test('renders modifiers input', () => { setup(); expect(screen.getByText('Modifiers')).toBeInTheDocument(); }); test('handles delete charge item', async () => { const onDelete = vi.fn(); const user = userEvent.setup(); vi.spyOn(medplum, 'deleteResource').mockResolvedValue({ resourceType: 'ChargeItem' } as ChargeItem); setup({ onDelete }); const buttons = screen.getAllByRole('button', { hidden: true }); const deleteMenuButton = buttons.find((btn) => btn.getAttribute('aria-haspopup') === 'menu'); if (!deleteMenuButton) { throw new Error('Delete menu button not found'); } await user.click(deleteMenuButton); const deleteButton = await screen.findByText('Delete'); await user.click(deleteButton); await waitFor(() => { expect(medplum.deleteResource).toHaveBeenCalledWith('ChargeItem', 'charge-123'); expect(onDelete).toHaveBeenCalledWith(mockChargeItem); }); }); test('displays updated price', () => { const itemWithPrice: ChargeItem = { ...mockChargeItem, priceOverride: { value: 150.5, currency: 'USD' }, }; setup({ chargeItem: itemWithPrice }); expect(screen.getByDisplayValue('$150.50')).toBeInTheDocument(); }); test('displays price as N/A when no price override', () => { const itemWithoutPrice: ChargeItem = { ...mockChargeItem, priceOverride: undefined, }; setup({ chargeItem: itemWithoutPrice }); expect(screen.getByDisplayValue('N/A')).toBeInTheDocument(); }); test('displays modifier when present', () => { const itemWithModifier: ChargeItem = { ...mockChargeItem, extension: [ { url: 'http://hl7.org/fhir/StructureDefinition/chargeitem-modifier', valueCodeableConcept: { coding: [{ code: '26', display: 'Professional Component' }], }, }, ], }; setup({ chargeItem: itemWithModifier }); expect(screen.getByText('Modifiers')).toBeInTheDocument(); }); test('renders price calculation explanation', () => { setup(); expect( screen.getByText(/Price calculated from Price chart, taking into account applied modifiers/) ).toBeInTheDocument(); }); });

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