| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- 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<string, string>)['X-Parse-Master-Key'], 'master-secret');
- assert.equal('X-Parse-Master-Key' in (calls[1]!.init.headers as Record<string, string>), 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',
- );
- });
|