import assert from 'node:assert/strict'; import {mkdtemp, rm} from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import test from 'node:test'; import {IndexStore, startServer} from '../src/server.js'; async function fetchJson(url, options = {}) { const response = await fetch(url, options); const text = await response.text(); const body = text ? JSON.parse(text) : null; return {response, body, text}; } function ownerHeaders(extra = {}) { return { 'content-type': 'application/json', 'x-jmpkit-identity-id': 'id_owner', 'x-jmpkit-billing-ref': 'free_id_owner', 'x-jmpkit-billing-path': '/identities/id_owner', 'x-jmpkit-app-id': 'appdemo123', 'x-jmpkit-app-host': 'appdemo123.jmpkit.app', ...extra }; } test('index10 stores public entity profiles and searchable items', async () => { const rootDir = await mkdtemp(path.join(os.tmpdir(), 'jmpkit-index-test-')); const service = await startServer({ host: '127.0.0.1', port: 0, store: new IndexStore({dataDir: rootDir}) }); try { const health = await fetchJson(`${service.baseUrl}/healthz`); assert.equal(health.response.status, 200); assert.deepEqual(health.body, {ok: true, resourceVersion: 'index10'}); const denied = await fetchJson(`${service.baseUrl}/items`, { method: 'POST', headers: {'content-type': 'application/json'}, body: JSON.stringify({ kind: 'ziphost10', url: 'https://example.jmpkit.app/' }) }); assert.equal(denied.response.status, 401); const profile = await fetchJson(`${service.baseUrl}/entities/me`, { method: 'PUT', headers: ownerHeaders(), body: JSON.stringify({ indexed: true, followable: true, displayName: 'Example Maker', nickname: 'example', description: 'Small tools and demos.', links: ['https://example.com'] }) }); assert.equal(profile.response.status, 200); assert.equal(profile.body.entity.displayName, 'Example Maker'); const created = await fetchJson(`${service.baseUrl}/items`, { method: 'POST', headers: ownerHeaders(), body: JSON.stringify({ kind: 'ziphost10', resourceId: 'readtest1', url: 'https://appdemo123.jmpkit.app/ziphost10/p/readtest1/', title: 'Todo tracker demo', description: 'A small browser todo app using Q.', tags: ['todo', 'demo', 'q10'] }) }); assert.equal(created.response.status, 201); assert.equal(created.body.item.ownerEntityId, 'id_owner'); assert.equal(created.body.item.entity.displayName, 'Example Maker'); assert.equal(created.body.item.appId, 'appdemo123'); const search = await fetchJson(`${service.baseUrl}/search?q=todo`); assert.equal(search.response.status, 200); assert.equal(search.body.items.length, 1); assert.equal(search.body.items[0].title, 'Todo tracker demo'); assert.equal(search.body.items[0].entity.nickname, 'example'); const byEntity = await fetchJson(`${service.baseUrl}/entities/id_owner/items`); assert.equal(byEntity.response.status, 200); assert.equal(byEntity.body.items.length, 1); const hidden = await fetchJson(`${service.baseUrl}/items/${created.body.item.itemId}`, { method: 'PATCH', headers: ownerHeaders(), body: JSON.stringify({indexed: false}) }); assert.equal(hidden.response.status, 200); assert.equal(hidden.body.item.indexed, false); const publicSearch = await fetchJson(`${service.baseUrl}/search?q=todo`); assert.equal(publicSearch.response.status, 200); assert.equal(publicSearch.body.items.length, 0); const ownerSearch = await fetchJson(`${service.baseUrl}/search?q=todo`, { headers: ownerHeaders() }); assert.equal(ownerSearch.response.status, 200); assert.equal(ownerSearch.body.items.length, 1); } finally { await service.close(); await rm(rootDir, {recursive: true, force: true}); } });