/** * What a settings form offers to link: every package this account publishes, * read from the two registry collections. The write itself goes through OAuth * and a live PDS, which the browser exercises. */ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { account } from '../src/lib/git.js'; import { packageKey, publishedPackages } from '../src/lib/settings.js'; const original = globalThis.fetch; beforeEach(() => { account.did = 'did:plc:owner'; account.pds = 'https://pds.example.com'; account.handle = 'owner.example.com'; }); afterEach(() => { globalThis.fetch = original; }); /** @param {string} name */ const record = (name) => ({ value: { name } }); /** * Answer each collection with the pages it holds, and a cursor while pages * remain. * @param {Record>>} pages */ function serve(pages) { /** @type {string[]} */ const asked = []; globalThis.fetch = async (/** @type {string|URL|Request} */ input) => { const url = new URL(String(input)); asked.push(url.searchParams.get('cursor') ?? ''); const collection = url.searchParams.get('collection') ?? ''; const held = pages[collection] ?? [[]]; const page = Number(url.searchParams.get('cursor') ?? '0'); return Response.json({ records: held[page] ?? [], ...(page + 1 < held.length ? { cursor: String(page + 1) } : {}), }); }; return asked; } describe('packageKey', () => { it('names a package by the pair, since a name repeats across registries', () => { expect(packageKey({ registry: 'npm', name: 'app' })).not.toBe( packageKey({ registry: 'oci', name: 'app' }), ); }); }); describe('publishedPackages', () => { it('reads both registries and says which one holds each name', async () => { serve({ 'dev.pdsjs.npm.package': [[record('@scope/lib')]], 'dev.pdsjs.oci.repo': [[record('app/server')]], }); expect(await publishedPackages()).toEqual([ { registry: 'npm', name: '@scope/lib' }, { registry: 'oci', name: 'app/server' }, ]); }); it('follows the cursor to the end of a collection', async () => { const asked = serve({ 'dev.pdsjs.npm.package': [[record('one')], [record('two')]], }); const packages = await publishedPackages(); expect(packages.map((entry) => entry.name)).toEqual(['one', 'two']); expect(asked).toContain('1'); }); it('leaves out a record naming nothing', async () => { serve({ 'dev.pdsjs.npm.package': [[{ value: {} }, record('lib')]] }); expect(await publishedPackages()).toEqual([ { registry: 'npm', name: 'lib' }, ]); }); it('reads a registry the server does not serve as nothing published', async () => { globalThis.fetch = async () => new Response('no', { status: 404 }); expect(await publishedPackages()).toEqual([]); }); it('reads an unreachable PDS as nothing published', async () => { globalThis.fetch = async () => { throw new Error('offline'); }; expect(await publishedPackages()).toEqual([]); }); });