This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / api / knotmirror.test.ts
4.6 kB 150 lines
1import { describe, expect, it, vi } from "vitest"; 2import * as knotmirror from "./knotmirror"; 3 4const jsonResponse = (body: unknown): Response => 5 new Response(JSON.stringify(body), { 6 status: 200, 7 headers: { "content-type": "application/json" } 8 }); 9 10describe("knotmirror.tree", () => { 11 it("fetches the readme blob", async () => { 12 const fetchMock = vi.fn<typeof globalThis.fetch>().mockImplementation(async (input) => { 13 const url = new URL(String(input)); 14 if (url.pathname.endsWith("getTree")) { 15 return jsonResponse({ 16 ref: "main", 17 files: [ 18 { 19 name: "README.md", 20 mode: "100644", 21 size: 12, 22 last_commit: { 23 hash: "abc", 24 message: "docs", 25 when: "2026-07-01T00:00:00Z" 26 } 27 } 28 ] 29 }); 30 } 31 return new Response("# hello", { 32 status: 200, 33 headers: { "content-type": "text/plain" } 34 }); 35 }); 36 37 const ctx = knotmirror.createKnotMirrorClient("https://mirror.test", fetchMock); 38 const tree = await knotmirror.tree(ctx, { 39 repo: "did:plc:repo", 40 ref: "main", 41 path: "docs" 42 }); 43 44 expect(tree.readme).toEqual({ filename: "README.md", contents: "# hello" }); 45 expect(tree.files[0]).toMatchObject({ name: "README.md", mode: "100644" }); 46 expect(fetchMock).toHaveBeenCalledTimes(2); 47 const blobUrl = new URL(String(fetchMock.mock.calls[1][0])); 48 expect(blobUrl.pathname).toBe("/xrpc/sh.tangled.git.temp.getBlob"); 49 expect(blobUrl.searchParams.get("path")).toBe("docs/README.md"); 50 }); 51}); 52 53describe("knotmirror.languages", () => { 54 it("uses the languages endpoint", async () => { 55 const fetchMock = vi 56 .fn<typeof globalThis.fetch>() 57 .mockResolvedValue( 58 jsonResponse({ ref: "main", languages: [{ name: "TypeScript", size: 10 }] }) 59 ); 60 const ctx = knotmirror.createKnotMirrorClient("https://mirror.test", fetchMock); 61 62 await knotmirror.languages(ctx, { repo: "did:plc:repo", ref: "main" }); 63 64 const url = new URL(String(fetchMock.mock.calls[0][0])); 65 expect(url.pathname).toBe("/xrpc/sh.tangled.git.temp.listLanguages"); 66 }); 67}); 68 69describe("knotmirror.blob", () => { 70 const entryBody = { 71 name: "hello.txt", 72 mode: "0100644", 73 size: 5, 74 lastCommit: { 75 hash: "abc", 76 message: "hi", 77 author: { name: "dawn", email: "dawn@tangled.org", when: "2026-07-01T00:00:00Z" } 78 } 79 }; 80 81 const blobFetch = (content: Uint8Array, entry: unknown = entryBody) => 82 vi.fn<typeof globalThis.fetch>().mockImplementation(async (input) => { 83 const url = new URL(String(input)); 84 return url.pathname.endsWith("getEntry") 85 ? jsonResponse(entry) 86 : new Response(content.slice().buffer, { status: 200 }); 87 }); 88 89 it("creates the repo blob shape from getEntry plus raw content", async () => { 90 const fetchMock = blobFetch(new TextEncoder().encode("hello")); 91 const ctx = knotmirror.createKnotMirrorClient("https://mirror.test", fetchMock); 92 93 const output = await knotmirror.blob( 94 ctx, 95 { repo: "did:plc:repo", ref: "main", path: "hello.txt" }, 96 1024 97 ); 98 99 expect(output).toMatchObject({ 100 path: "hello.txt", 101 size: 5, 102 isBinary: false, 103 encoding: "utf-8", 104 content: "hello", 105 lastCommit: { hash: "abc", when: "2026-07-01T00:00:00Z" } 106 }); 107 }); 108 109 it("skips the content fetch when the entry is over the inline cap", async () => { 110 const fetchMock = blobFetch(new TextEncoder().encode("hello"), { ...entryBody, size: 2048 }); 111 const ctx = knotmirror.createKnotMirrorClient("https://mirror.test", fetchMock); 112 113 const output = await knotmirror.blob( 114 ctx, 115 { repo: "did:plc:repo", ref: "main", path: "hello.txt" }, 116 1024 117 ); 118 119 expect(output.fileTooLarge).toBe(true); 120 expect(output.content).toBeUndefined(); 121 expect(fetchMock).toHaveBeenCalledTimes(1); 122 }); 123 124 it("marks content with null bytes as binary", async () => { 125 const fetchMock = blobFetch(new Uint8Array([0x50, 0x4b, 0x00, 0x00])); 126 const ctx = knotmirror.createKnotMirrorClient("https://mirror.test", fetchMock); 127 128 const output = await knotmirror.blob( 129 ctx, 130 { repo: "did:plc:repo", ref: "main", path: "hello.txt" }, 131 1024 132 ); 133 134 expect(output.isBinary).toBe(true); 135 expect(output.content).toBeUndefined(); 136 }); 137 138 it("treats a gitlink mode as a submodule", async () => { 139 const fetchMock = blobFetch(new Uint8Array(), { ...entryBody, mode: "0160000" }); 140 const ctx = knotmirror.createKnotMirrorClient("https://mirror.test", fetchMock); 141 142 const output = await knotmirror.blob( 143 ctx, 144 { repo: "did:plc:repo", ref: "main", path: "hello.txt" }, 145 1024 146 ); 147 148 expect(output.submodule).toEqual({ name: "hello.txt", url: "" }); 149 }); 150});