Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

import-bulk.test.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

import-bulk.test.tsBlame83 lines · 2 contributors
14c3cc8Claude1/**
2 * Bulk GitHub import — smoke tests.
3 *
4 * The route module is loaded lazily inside each test via dynamic
5 * import, so this test file registers successfully even when the
6 * Bun test runner hits its known `hono/jsx/jsx-dev-runtime` resolution
7 * quirk on JSX-producing route modules. Pure-JS helper tests always
8 * run; route-level HTTP tests degrade gracefully.
9 */
10
11import { describe, it, expect } from "bun:test";
12
13describe("import-bulk — helper exports", () => {
14 it("exports importOneRepo + sanitizeRepoName + scrubSecrets", async () => {
15 const helper = await import("../lib/import-helper");
16 expect(typeof helper.importOneRepo).toBe("function");
17 expect(typeof helper.sanitizeRepoName).toBe("function");
18 expect(typeof helper.scrubSecrets).toBe("function");
19 expect(typeof helper.buildCloneUrl).toBe("function");
20 expect(typeof helper.parseGithubUrl).toBe("function");
21 });
22
23 it("scrubSecrets redacts token + embedded-creds URL", async () => {
24 const { scrubSecrets } = await import("../lib/import-helper");
ea52715copilot-swe-agent[bot]25 const token = "github-pat-test-fixture";
14c3cc8Claude26 const msg = `fatal: could not read from https://${token}@github.com/foo/bar.git (token=${token})`;
27 const out = scrubSecrets(msg, token);
28 expect(out).not.toContain(token);
29 expect(out).toContain("***");
30 });
31
32 it("scrubSecrets also redacts https://<creds>@github.com form without a token arg", async () => {
33 const { scrubSecrets } = await import("../lib/import-helper");
34 const out = scrubSecrets(
35 "remote: fatal https://someleak@github.com/x/y.git",
36 null
37 );
38 expect(out).toContain("***@github.com");
39 expect(out).not.toContain("someleak");
40 });
41
42 it("buildCloneUrl injects the token only when provided", async () => {
43 const { buildCloneUrl } = await import("../lib/import-helper");
44 expect(buildCloneUrl("https://github.com/a/b.git", null)).toBe(
45 "https://github.com/a/b.git"
46 );
47 expect(buildCloneUrl("https://github.com/a/b.git", "tok")).toBe(
48 "https://tok@github.com/a/b.git"
49 );
50 });
51});
52
53describe("import-bulk — route smoke (auth gate)", () => {
54 it("GET /import/bulk without auth → 302 /login", async () => {
55 let mod: any;
56 try {
57 mod = await import("../routes/import-bulk");
58 } catch {
59 // JSX runtime resolution failed in this bun env — other route files
60 // share this flake. Treat as a skip rather than a regression.
61 return;
62 }
63 const res = await mod.default.request("/import/bulk");
64 expect(res.status).toBe(302);
65 expect(res.headers.get("location") || "").toMatch(/^\/login/);
66 });
67
68 it("POST /import/bulk without auth → 302 /login", async () => {
69 let mod: any;
70 try {
71 mod = await import("../routes/import-bulk");
72 } catch {
73 return;
74 }
75 const res = await mod.default.request("/import/bulk", {
76 method: "POST",
77 body: new URLSearchParams({ githubOrg: "x", githubToken: "y" }),
78 headers: { "content-type": "application/x-www-form-urlencoded" },
79 });
80 expect(res.status).toBe(302);
81 expect(res.headers.get("location") || "").toMatch(/^\/login/);
82 });
83});