g1t/services/projects/src/transfer.test.ts
Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 1 | import { test } from "node:test"; |
| 2 | import assert from "node:assert/strict"; | |
| 3 | ||
| 4 | import { moveStatements, slugOf, strandedQuery } from "./transfer.ts"; | |
| 5 | ||
| 6 | test("each statement is bound with as many values as it asks for", () => { | |
| 7 | for (const [stale, current] of [ | |
| 8 | [["syntaqx/g1t"], "flagon-io/g1t"], | |
| 9 | [["flagon-io/g1t"], "flagon-io/forge"], | |
| 10 | [["syntaqx/g1t", "flagon-io/g1t"], "flagon-io/forge"], | |
| 11 | ] as const) { | |
| 12 | for (const { sql, params } of moveStatements([...stale], current, "rep_1")) { | |
| 13 | assert.equal(sql.split("?").length - 1, params.length, sql); | |
| 14 | } | |
| 15 | } | |
| 16 | const stranded = strandedQuery(["syntaqx/g1t"], "flagon-io/g1t", "rep_1")!; | |
| 17 | assert.equal(stranded.sql.split("?").length - 1, stranded.params.length); | |
| 18 | }); | |
| 19 | ||
| 20 | test("projects move from the workspace the repository left to the one it is in", () => { | |
| 21 | const [move] = moveStatements(["syntaqx/g1t"], "flagon-io/g1t", "rep_1"); | |
| 22 | assert.deepEqual(move!.params, ["flagon-io", "flagon-io", "rep_1", "syntaqx"]); | |
| 23 | }); | |
| 24 | ||
| 25 | test("a delivery after the rows moved moves nothing but the path", () => { | |
| 26 | // Transferred back: only the workspace it is not in now moves. | |
| 27 | const statements = moveStatements(["flagon-io/g1t"], "syntaqx/g1t", "rep_1"); | |
| 28 | assert.equal(statements.filter((s) => s.sql.startsWith("UPDATE OR IGNORE")).length, 1); | |
| 29 | assert.equal(strandedQuery([], "syntaqx/g1t", "rep_1"), null); | |
| 30 | }); | |
| 31 | ||
| 32 | test("a transfer keeps every slug", () => { | |
| 33 | const statements = moveStatements(["syntaqx/g1t"], "flagon-io/g1t", "rep_1"); | |
| 34 | assert.ok(!statements.some((s) => s.sql.includes("SET slug"))); | |
| 35 | assert.ok(!statements.some((s) => s.sql.includes("SET name"))); | |
| 36 | }); | |
| 37 | ||
| 38 | test("renamed, the repository's own project takes the new name as its slug if it is free", () => { | |
| 39 | const statements = moveStatements(["flagon-io/g1t"], "flagon-io/Forge", "rep_1"); | |
| 40 | const slug = statements.find((s) => s.sql.includes("SET slug"))!; | |
| 41 | assert.match(slug.sql, /^UPDATE OR IGNORE/); | |
| 42 | assert.match(slug.sql, /is_primary = 1/); | |
| 43 | assert.deepEqual(slug.params, ["forge", "rep_1", "flagon-io", "g1t"]); | |
| 44 | const name = statements.find((s) => s.sql.includes("SET name"))!; | |
| 45 | assert.deepEqual(name.params, ["Forge", "rep_1", "g1t"]); | |
| 46 | const path = statements.find((s) => s.sql.includes("repo_name"))!; | |
| 47 | assert.deepEqual(path.params, ["flagon-io", "Forge", "rep_1"]); | |
| 48 | // Nothing moves between workspaces. | |
| 49 | assert.equal(statements.filter((s) => s.sql.includes("SET workspace")).length, 0); | |
| 50 | assert.equal(strandedQuery(["flagon-io/g1t"], "flagon-io/Forge", "rep_1"), null); | |
| 51 | }); | |
| 52 | ||
| 53 | test("a rename of letter case alone keeps the slug", () => { | |
| 54 | const statements = moveStatements(["flagon-io/forge"], "flagon-io/Forge", "rep_1"); | |
| 55 | assert.ok(!statements.some((s) => s.sql.includes("SET slug"))); | |
| 56 | assert.ok(statements.some((s) => s.sql.includes("SET name"))); | |
| 57 | }); | |
| 58 | ||
| 59 | test("names become slugs as projects spell them", () => { | |
| 60 | assert.equal(slugOf(" My App! "), "my-app"); | |
| 61 | assert.equal(slugOf("g1t.sh"), "g1t.sh"); | |
| 62 | }); |