// The git gate in createServer: the full extension mounts whenever the git // package is installed, `git.external` swaps it for the guard alone, and the // /git/ smart HTTP prefix follows the http option. import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, describe, expect, it } from 'vitest'; import { createServer } from '../src/index.js'; /** @type {Array<{close: () => Promise}>} */ const servers = []; /** @type {string[]} */ const dirs = []; /** * @param {{experimental?: {git?: {http?: boolean, external?: boolean, guardOnly?: boolean}}}} [opts] */ async function makeServer(opts = {}) { const dir = mkdtempSync(join(tmpdir(), 'pdsjs-git-wiring-')); dirs.push(dir); const server = await createServer({ dbPath: join(dir, 'pds.db'), blobsDir: join(dir, 'blobs'), jwtSecret: 'wiring-test-secret', hostname: 'pds.example.com', ...opts, }); servers.push(server); return server; } afterEach(async () => { for (const server of servers.splice(0)) { // close() rejects when listen() was never called; these tests only // construct the server. await server.close().catch(() => {}); } for (const dir of dirs.splice(0)) rmSync(dir, { recursive: true, force: true }); }); describe('node git wiring', () => { it('mounts the full extension by default', async () => { const { pds } = await makeServer(); expect(pds.extensionFeatures.git).toBe(true); expect(pds.extensionFeatures.gitBrowse).toBe(true); // The XRPC methods are served; listRepos answers an empty listing. const response = await pds.fetch( new Request('https://pds.example.com/xrpc/dev.pdsjs.git.listRepos'), ); expect(response.status).toBe(200); }); it('serves smart HTTP only with the http option', async () => { const { pds } = await makeServer({ experimental: { git: { http: true } }, }); // Without the option the /git path is nobody's route; the PDS answers // its generic bad request, not a git advertisement. const response = await pds.fetch( new Request('https://pds.example.com/git/x/y/info/refs'), ); expect(response.status).toBe(400); expect(response.headers.get('content-type')).not.toContain( 'git-upload-pack-advertisement', ); const on = await makeServer({ experimental: { git: { http: true } }, }); const advertisement = await on.pds.fetch( new Request( 'https://pds.example.com/git/did:plc:unknown/repo/info/refs?service=git-upload-pack', ), ); expect(advertisement.status).toBe(404); }); it('drops the routes and keeps the guard in external mode', async () => { const { pds } = await makeServer({ experimental: { git: { external: true } }, }); expect(pds.extensionFeatures.git).toBe(true); expect(pds.extensionFeatures.gitBrowse).toBe(false); // An unknown XRPC method is a 501, the unimplemented answer. const response = await pds.fetch( new Request('https://pds.example.com/xrpc/dev.pdsjs.git.listRepos'), ); expect(response.status).toBe(501); }); });