Skip to main content
Glama
resource-cap.test.ts6.25 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import type { Bundle, Patient } from '@medplum/fhirtypes'; import type { Express } from 'express'; import express from 'express'; import request from 'supertest'; import { initApp, shutdownApp } from '../app'; import { loadTestConfig } from '../config/loader'; import type { MedplumServerConfig } from '../config/types'; import { getRedis } from '../redis'; import type { TestRedisConfig } from '../test.setup'; import { createTestProject, deleteRedisKeys } from '../test.setup'; import { getSystemRepo } from './repo'; describe('FHIR Resource Limits', () => { let app: Express; let config: MedplumServerConfig; let redisConfig: TestRedisConfig; beforeAll(async () => { config = await loadTestConfig(); redisConfig = config.redis as TestRedisConfig; }); beforeEach(async () => { app = express(); config.defaultRateLimit = -1; redisConfig.db = 6; // Use different temp Redis instance for these tests redisConfig.keyPrefix = 'resource-cap:'; await initApp(app, config); }); afterEach(async () => { await deleteRedisKeys(getRedis(), redisConfig.keyPrefix); expect(await shutdownApp()).toBeUndefined(); }); test('Blocks request that would exceed limit', async () => { const { accessToken } = await createTestProject({ withAccessToken: true, project: { systemSetting: [ { name: 'enableResourceCap', valueBoolean: true }, { name: 'resourceCap', valueInteger: 3 }, ], }, }); const res = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res.status).toBe(201); const res2 = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res2.status).toBe(201); const res3 = await request(app).get('/fhir/R4/Patient').auth(accessToken, { type: 'bearer' }).send(); expect(res3.status).toBe(200); const res4 = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res4.status).toBe(422); }); test('Loads current count', async () => { const { accessToken, project } = await createTestProject({ withAccessToken: true, project: { systemSetting: [ { name: 'enableResourceCap', valueBoolean: true }, { name: 'resourceCap', valueInteger: 2 }, ], }, }); const systemRepo = getSystemRepo(); await systemRepo.createResource({ resourceType: 'Patient', meta: { project: project.id } }); const res = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res.status).toBe(201); const res2 = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res2.status).toBe(422); const res3 = await request(app).get('/fhir/R4/Patient').auth(accessToken, { type: 'bearer' }).send(); expect(res3.status).toBe(200); }); test('Expunge counteracts create', async () => { const { accessToken } = await createTestProject({ withAccessToken: true, membership: { admin: true }, project: { systemSetting: [ { name: 'enableResourceCap', valueBoolean: true }, { name: 'resourceCap', valueInteger: 2 }, ], }, }); const res = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res.status).toBe(201); const patient = res.body as Patient; const res2 = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res2.status).toBe(422); const res3 = await request(app) .post(`/fhir/R4/Patient/${patient.id}/$expunge`) .auth(accessToken, { type: 'bearer' }) .send(); expect(res3.status).toBe(200); const res4 = await request(app) .post('/fhir/R4/Patient') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Patient' }); expect(res4.status).toBe(201); }); test('Allows transaction under limit', async () => { const { accessToken } = await createTestProject({ withAccessToken: true, project: { features: ['transaction-bundles'], systemSetting: [ { name: 'enableResourceCap', valueBoolean: true }, { name: 'resourceCap', valueInteger: 3 }, ], }, }); const res = await request(app) .post('/fhir/R4/') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Bundle', type: 'transaction', entry: [ { request: { method: 'POST', url: 'Patient' }, resource: { resourceType: 'Patient' } }, { request: { method: 'POST', url: 'Patient' }, resource: { resourceType: 'Patient' } }, ], } as Bundle); expect(res.status).toBe(200); }); test('Blocks oversized transaction bundle', async () => { const { accessToken } = await createTestProject({ withAccessToken: true, project: { features: ['transaction-bundles'], systemSetting: [ { name: 'enableResourceCap', valueBoolean: true }, { name: 'resourceCap', valueInteger: 3 }, ], }, }); const res = await request(app) .post('/fhir/R4/') .auth(accessToken, { type: 'bearer' }) .send({ resourceType: 'Bundle', type: 'transaction', entry: [ { request: { method: 'POST', url: 'Patient' }, resource: { resourceType: 'Patient' } }, { request: { method: 'POST', url: 'Patient' }, resource: { resourceType: 'Patient' } }, { request: { method: 'POST', url: 'Patient' }, resource: { resourceType: 'Patient' } }, ], } satisfies Bundle); expect(res.status).toBe(422); }); });

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