Skip to main content
Glama
launch.test.ts4.2 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { createReference } from '@medplum/core'; import type { ClientApplication, Encounter, Patient, SmartAppLaunch } from '@medplum/fhirtypes'; import express from 'express'; import request from 'supertest'; import { initApp, shutdownApp } from '../../app'; import { loadTestConfig } from '../../config/loader'; import { createTestProject, withTestContext } from '../../test.setup'; import { Repository } from '../repo'; const app = express(); describe('ClientApplication/:id/$smart-launch', () => { let accessToken: string; let client: ClientApplication; let repo: Repository; beforeAll(async () => { const config = await loadTestConfig(); await withTestContext(() => initApp(app, config)); ({ client, accessToken, repo } = await createTestProject({ withClient: true, withAccessToken: true, withRepo: true, })); }); beforeEach(async () => { expect(accessToken).toBeDefined(); expect(client.id).toBeDefined(); expect(repo).toBeInstanceOf(Repository); }); afterAll(async () => { await shutdownApp(); }); test('Requires ID', async () => { const res = await request(app) .get('/fhir/R4/ClientApplication/$smart-launch') .set('Authorization', 'Bearer ' + accessToken) .send(); expect(res.status).toBe(404); }); test('Requires launchUri to be configured', async () => { const res = await request(app) .get(`/fhir/R4/ClientApplication/${client.id}/$smart-launch`) .set('Authorization', 'Bearer ' + accessToken) .send(); expect(res.status).toBe(400); }); test('Redirects to launchUri', async () => { // Update ClientApplication with launchUri const launchUri = 'https://example.com/smart-launch'; client = await repo.updateResource({ ...client, launchUri }); const res = await request(app) .get(`/fhir/R4/ClientApplication/${client.id}/$smart-launch`) .set('Authorization', 'Bearer ' + accessToken) .send(); expect(res.status).toBe(302); expect(res.headers['location'].startsWith(launchUri + '?')).toBe(true); const uri = new URL(res.headers['location']); const launchId = uri.searchParams.get('launch'); // Ensure resource exists const launch = await repo.readResource<SmartAppLaunch>('SmartAppLaunch', launchId as string); expect(launch.id).toEqual(launchId); }); test('Preserves launch parameter', async () => { // Update ClientApplication with launchUri const launchUri = 'https://example.com/smart-launch'; client = await repo.updateResource({ ...client, launchUri }); const patient = await repo.createResource<Patient>({ resourceType: 'Patient' }); const res = await request(app) .get(`/fhir/R4/ClientApplication/${client.id}/$smart-launch`) .set('Authorization', 'Bearer ' + accessToken) .query({ patient: patient.id }) .send(); expect(res.status).toBe(302); expect(res.headers['location'].startsWith(launchUri + '?')).toBe(true); const uri = new URL(res.headers['location']); const launchId = uri.searchParams.get('launch'); // Ensure resource contains launch context const launch = await repo.readResource<SmartAppLaunch>('SmartAppLaunch', launchId as string); expect(launch.patient).toStrictEqual(createReference(patient)); }); test('Requires single launch parameter', async () => { // Update ClientApplication with launchUri const launchUri = 'https://example.com/smart-launch'; client = await repo.updateResource({ ...client, launchUri }); const patient = await repo.createResource<Patient>({ resourceType: 'Patient' }); const encounter = await repo.createResource<Encounter>({ resourceType: 'Encounter', status: 'unknown', class: { display: 'Appointment' }, }); const res = await request(app) .get(`/fhir/R4/ClientApplication/${client.id}/$smart-launch`) .set('Authorization', 'Bearer ' + accessToken) .query({ patient: patient.id, encounter: encounter.id }) .send(); expect(res.status).toBe(400); }); });

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