Skip to main content
Glama
PatientPage.utils.test.ts7.87 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import type { Patient } from '@medplum/fhirtypes'; import { describe, expect, test } from 'vitest'; import { formatPatientPageTabUrl, getPatientPageTabOrThrow, patientPathPrefix, PatientPageTabs, prependPatientPath, } from './PatientPage.utils'; describe('PatientPage.utils', () => { describe('patientPathPrefix', () => { test('returns correct path prefix for patient ID', () => { expect(patientPathPrefix('123')).toBe('/Patient/123'); expect(patientPathPrefix('patient-456')).toBe('/Patient/patient-456'); expect(patientPathPrefix('abc-def-ghi')).toBe('/Patient/abc-def-ghi'); }); test('handles empty string patient ID', () => { expect(patientPathPrefix('')).toBe('/Patient/'); }); }); describe('prependPatientPath', () => { const mockPatient: Patient = { resourceType: 'Patient', id: 'patient-123', }; test('prepends patient path when patient has ID', () => { expect(prependPatientPath(mockPatient, 'edit')).toBe('/Patient/patient-123/edit'); expect(prependPatientPath(mockPatient, '/edit')).toBe('/Patient/patient-123/edit'); expect(prependPatientPath(mockPatient, 'Encounter')).toBe('/Patient/patient-123/Encounter'); }); test('handles path without leading slash', () => { expect(prependPatientPath(mockPatient, 'edit')).toBe('/Patient/patient-123/edit'); expect(prependPatientPath(mockPatient, 'Task')).toBe('/Patient/patient-123/Task'); }); test('handles path with leading slash', () => { expect(prependPatientPath(mockPatient, '/edit')).toBe('/Patient/patient-123/edit'); expect(prependPatientPath(mockPatient, '/Encounter')).toBe('/Patient/patient-123/Encounter'); }); test('returns original path when patient is undefined', () => { expect(prependPatientPath(undefined, 'edit')).toBe('edit'); expect(prependPatientPath(undefined, '/edit')).toBe('/edit'); expect(prependPatientPath(undefined, 'Encounter')).toBe('Encounter'); }); test('returns original path when patient has no ID', () => { const patientWithoutId: Patient = { resourceType: 'Patient', }; expect(prependPatientPath(patientWithoutId, 'edit')).toBe('edit'); expect(prependPatientPath(patientWithoutId, '/edit')).toBe('/edit'); }); test('handles empty path string', () => { expect(prependPatientPath(mockPatient, '')).toBe('/Patient/patient-123/'); expect(prependPatientPath(undefined, '')).toBe(''); }); }); describe('formatPatientPageTabUrl', () => { test('formats URL with patient ID replacement', () => { const tab = { id: 'encounter', url: 'Encounter?patient=%patient.id', label: 'Visits', }; expect(formatPatientPageTabUrl('patient-123', tab)).toBe('/Patient/patient-123/Encounter?patient=patient-123'); }); test('handles tab with empty URL', () => { const tab = { id: 'timeline', url: '', label: 'Timeline', }; expect(formatPatientPageTabUrl('patient-456', tab)).toBe('/Patient/patient-456/'); }); test('handles tab URL without patient.id placeholder', () => { const tab = { id: 'labs', url: 'labs', label: 'Labs', }; expect(formatPatientPageTabUrl('patient-789', tab)).toBe('/Patient/patient-789/labs'); }); test('handles multiple patient.id placeholders (replaces only first)', () => { const tab = { id: 'test', url: 'Resource?patient=%patient.id&other=%patient.id', label: 'Test', }; // replace() only replaces the first occurrence expect(formatPatientPageTabUrl('patient-123', tab)).toBe( '/Patient/patient-123/Resource?patient=patient-123&other=%patient.id' ); }); test('handles complex query string with patient.id placeholder', () => { const tab = PatientPageTabs.find((t) => t.id === 'encounter'); if (tab) { const result = formatPatientPageTabUrl('patient-123', tab); expect(result).toContain('/Patient/patient-123/Encounter'); expect(result).toContain('patient=patient-123'); expect(result).not.toContain('%patient.id'); } }); }); describe('getPatientPageTabOrThrow', () => { test('returns tab when found', () => { const timelineTab = getPatientPageTabOrThrow('timeline'); expect(timelineTab.id).toBe('timeline'); expect(timelineTab.url).toBe(''); expect(timelineTab.label).toBe('Timeline'); const editTab = getPatientPageTabOrThrow('edit'); expect(editTab.id).toBe('edit'); expect(editTab.url).toBe('edit'); expect(editTab.label).toBe('Edit'); const medsTab = getPatientPageTabOrThrow('meds'); expect(medsTab.id).toBe('meds'); expect(medsTab.label).toBe('Meds'); }); test('throws error when tab not found', () => { expect(() => getPatientPageTabOrThrow('nonexistent')).toThrow( 'Could not find patient page tab with id nonexistent' ); expect(() => getPatientPageTabOrThrow('invalid-tab')).toThrow( 'Could not find patient page tab with id invalid-tab' ); }); test('finds all defined tabs', () => { const tabIds = [ 'timeline', 'edit', 'encounter', 'tasks', 'meds', 'labs', 'devices', 'documentreference', 'careplan', 'message', 'dosespot', 'export', ]; for (const tabId of tabIds) { const tab = getPatientPageTabOrThrow(tabId); expect(tab).toBeDefined(); expect(tab.id).toBe(tabId); expect(tab.url).toBeDefined(); expect(tab.label).toBeDefined(); } }); }); describe('PatientPageTabs', () => { test('is an array', () => { expect(Array.isArray(PatientPageTabs)).toBe(true); }); test('contains expected tabs', () => { const tabIds = PatientPageTabs.map((tab) => tab.id); expect(tabIds).toContain('timeline'); expect(tabIds).toContain('edit'); expect(tabIds).toContain('encounter'); expect(tabIds).toContain('tasks'); expect(tabIds).toContain('meds'); expect(tabIds).toContain('labs'); expect(tabIds).toContain('devices'); expect(tabIds).toContain('documentreference'); expect(tabIds).toContain('careplan'); expect(tabIds).toContain('message'); expect(tabIds).toContain('dosespot'); expect(tabIds).toContain('export'); }); test('all tabs have required properties', () => { for (const tab of PatientPageTabs) { expect(tab).toHaveProperty('id'); expect(tab).toHaveProperty('url'); expect(tab).toHaveProperty('label'); expect(typeof tab.id).toBe('string'); expect(typeof tab.url).toBe('string'); expect(typeof tab.label).toBe('string'); } }); test('timeline tab has empty URL', () => { const timelineTab = PatientPageTabs.find((tab) => tab.id === 'timeline'); expect(timelineTab).toBeDefined(); expect(timelineTab?.url).toBe(''); }); test('tabs with patient.id placeholder contain the placeholder', () => { const tabsWithPlaceholder = PatientPageTabs.filter((tab) => tab.url.includes('%patient.id')); expect(tabsWithPlaceholder.length).toBeGreaterThan(0); for (const tab of tabsWithPlaceholder) { expect(tab.url).toContain('%patient.id'); } }); test('tasks tab has correct URL', () => { const tasksTab = PatientPageTabs.find((tab) => tab.id === 'tasks'); expect(tasksTab).toBeDefined(); expect(tasksTab?.url).toBe('Task'); expect(tasksTab?.label).toBe('Tasks'); }); }); });

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