import assert from 'node:assert/strict'; import test from 'node:test'; import { ParseRestClient, ParseRestError } from '../src/db/parse-rest.client.js'; test('Parse REST client keeps the master key server-side and encodes structured queries', async () => { const calls: Array<{ url: string; init: RequestInit }> = []; const fetchMock: typeof fetch = async (input, init = {}) => { calls.push({ url: String(input), init }); return new Response(JSON.stringify({ results: [] }), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; const client = new ParseRestClient({ serverUrl: 'https://parse.example.test/parse/', appId: 'app-id', masterKey: 'master-secret', }, fetchMock); await client.find('VocProduct', { where: { workspaceId: 'demashi', platform: 'jd' }, order: 'productKey', limit: 25, }); await client.request('/health', { master: false }); const queryUrl = new URL(calls[0]!.url); assert.equal(queryUrl.pathname, '/parse/classes/VocProduct'); assert.deepEqual(JSON.parse(queryUrl.searchParams.get('where')!), { workspaceId: 'demashi', platform: 'jd' }); assert.equal(queryUrl.searchParams.get('order'), 'productKey'); assert.equal(queryUrl.searchParams.get('limit'), '25'); assert.equal((calls[0]!.init.headers as Record)['X-Parse-Master-Key'], 'master-secret'); assert.equal('X-Parse-Master-Key' in (calls[1]!.init.headers as Record), false); }); test('Parse REST batch requests stay under the upstream limit and preserve the mount path', async () => { let requestBody: { requests: Array<{ path: string }> } | null = null; const fetchMock: typeof fetch = async (_input, init = {}) => { requestBody = JSON.parse(String(init.body)) as { requests: Array<{ path: string }> }; return new Response(JSON.stringify([{ success: { objectId: 'one' } }]), { status: 200, headers: { 'Content-Type': 'application/json' }, }); }; const client = new ParseRestClient({ serverUrl: 'https://parse.example.test/custom/parse', appId: 'app-id', masterKey: 'master-secret', }, fetchMock); await client.batch([{ method: 'POST', path: '/classes/VocWorkspace', body: { publicId: 'demashi' } }]); assert.equal(requestBody!.requests[0]!.path, '/custom/parse/classes/VocWorkspace'); await assert.rejects( () => client.batch(Array.from({ length: 51 }, () => ({ method: 'DELETE' as const, path: '/classes/VocProduct/id' }))), /limited to 50/, ); }); test('Parse REST errors expose status and Parse code without returning raw response text', async () => { const client = new ParseRestClient({ serverUrl: 'https://parse.example.test/parse', appId: 'app-id', masterKey: 'master-secret', }, async () => new Response(JSON.stringify({ code: 119, error: 'Permission denied' }), { status: 400, headers: { 'Content-Type': 'application/json' }, })); await assert.rejects( () => client.find('VocWorkspace'), (error: unknown) => error instanceof ParseRestError && error.status === 400 && error.code === 119 && error.message === 'Permission denied', ); });