Skip to content

Commit 0ae8b05

Browse files
committed
Extend unit tests to cover all token types
1 parent 49cdf74 commit 0ae8b05

File tree

1 file changed

+79
-25
lines changed

1 file changed

+79
-25
lines changed

src/artifact-scanner.test.ts

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,90 @@ import * as path from "path";
44

55
import test from "ava";
66

7-
import { scanArtifactsForTokens } from "./artifact-scanner";
7+
import { scanArtifactsForTokens, TokenType } from "./artifact-scanner";
88
import { getRunnerLogger } from "./logging";
9-
import { getRecordingLogger, LoggedMessage } from "./testing-utils";
9+
import {
10+
checkExpectedLogMessages,
11+
getRecordingLogger,
12+
LoggedMessage,
13+
} from "./testing-utils";
1014

11-
test("scanArtifactsForTokens detects GitHub tokens in files", async (t) => {
12-
const logger = getRunnerLogger(true);
13-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "scanner-test-"));
15+
function makeTestToken(length: number = 36) {
16+
const chars =
17+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
18+
return chars.repeat(Math.ceil(length / chars.length)).slice(0, length);
19+
}
1420

15-
try {
16-
// Create a test file with a fake GitHub token
17-
const testFile = path.join(tempDir, "test.txt");
18-
fs.writeFileSync(
19-
testFile,
20-
"This is a test file with token ghp_1234567890123456789012345678901234AB",
21-
);
21+
test("makeTestToken", (t) => {
22+
t.is(makeTestToken().length, 36);
23+
t.is(makeTestToken(255).length, 255);
24+
});
2225

23-
const error = await t.throwsAsync(
24-
async () => await scanArtifactsForTokens([testFile], logger),
25-
);
26+
const testTokens = [
27+
{
28+
type: TokenType.PersonalAccessClassic,
29+
value: `ghp_${makeTestToken()}`,
30+
checkPattern: "Personal Access Token",
31+
},
32+
{
33+
type: TokenType.PersonalAccessFineGrained,
34+
value:
35+
"github_pat_1234567890ABCDEFGHIJKL_MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHI",
36+
checkPattern: "Personal Access Token",
37+
},
38+
{
39+
type: TokenType.OAuth,
40+
value: `gho_${makeTestToken()}`,
41+
},
42+
{
43+
type: TokenType.UserToServer,
44+
value: `ghu_${makeTestToken()}`,
45+
},
46+
{
47+
type: TokenType.ServerToServer,
48+
value: `ghs_${makeTestToken()}`,
49+
},
50+
{
51+
type: TokenType.Refresh,
52+
value: `ghr_${makeTestToken()}`,
53+
},
54+
{
55+
type: TokenType.AppInstallationAccess,
56+
value: `ghs_${makeTestToken(255)}`,
57+
},
58+
];
2659

27-
t.regex(
28-
error?.message || "",
29-
/Found 1 potential GitHub token.*Personal Access Token/,
30-
);
31-
t.regex(error?.message || "", /test\.txt/);
32-
} finally {
33-
// Clean up
34-
fs.rmSync(tempDir, { recursive: true, force: true });
35-
}
36-
});
60+
for (const { type, value, checkPattern } of testTokens) {
61+
test(`scanArtifactsForTokens detects GitHub ${type} tokens in files`, async (t) => {
62+
const logMessages = [];
63+
const logger = getRecordingLogger(logMessages, { logToConsole: false });
64+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "scanner-test-"));
65+
66+
try {
67+
// Create a test file with a fake GitHub token
68+
const testFile = path.join(tempDir, "test.txt");
69+
fs.writeFileSync(testFile, `This is a test file with token ${value}`);
70+
71+
const error = await t.throwsAsync(
72+
async () => await scanArtifactsForTokens([testFile], logger),
73+
);
74+
75+
t.regex(
76+
error?.message || "",
77+
new RegExp(`Found 1 potential GitHub token.*${checkPattern || type}`),
78+
);
79+
t.regex(error?.message || "", /test\.txt/);
80+
81+
checkExpectedLogMessages(t, logMessages, [
82+
"Starting best-effort check",
83+
`Found 1 ${type}`,
84+
]);
85+
} finally {
86+
// Clean up
87+
fs.rmSync(tempDir, { recursive: true, force: true });
88+
}
89+
});
90+
}
3791

3892
test("scanArtifactsForTokens handles files without tokens", async (t) => {
3993
const logger = getRunnerLogger(true);

0 commit comments

Comments
 (0)