Skip to content

Commit e3ad94d

Browse files
committed
fix(tests): unbreak npm test on Windows + close 20-day CI gap
Eight tests have been failing on Windows since (a) 2026-03-17 dfedc25 (3 stale fixtures cross-platform) and (b) forever (5 POSIX assumptions). CI never noticed because its bash glob 'src/**/*.test.ts' silently skips top-level src files when globstar is off (the default). Fixes: 1. src/keystore.test.ts: drop 'tier' and 'lease_expires_at' from test fixtures (loadKeyStore strips them since dfedc25). 3 tests fixed cross-platform. 2. src/keystore.test.ts + core/src/keystore.test.ts + core/src/allowance.test.ts: skip 'creates file with 0600 permissions' on Windows with explicit reason. Windows NTFS doesn't enforce POSIX file modes. 3. core/src/config.test.ts: use path.join() in expected values for path-derivation tests so backslash paths on Windows match. 4. .github/workflows/test.yml: enable bash globstar and add core/src/**/*.test.ts to the CI test command. Without this, root-level src test files (keystore, client, errors, paid-fetch) were silently skipped by CI. Result: npm test on Windows is now 262/262 + 56/56 = 318 pass, 3 skip (POSIX file mode), 0 fail. Linux CI will now actually execute the previously-skipped 4 src/*.test.ts files plus all core/src/*.test.ts files.
1 parent f972a80 commit e3ad94d

5 files changed

Lines changed: 15 additions & 20 deletions

File tree

.github/workflows/test.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ jobs:
2020
- run: npm run build
2121
- run: npm run test:skill
2222
- run: npm run test:sync
23-
- run: node --experimental-test-module-mocks --test --import tsx src/**/*.test.ts
23+
# Use bash globstar so `**` recurses into nested dirs AND matches files
24+
# at depth 0. Without this, files like src/keystore.test.ts (at depth 0)
25+
# were silently skipped by CI for 20+ days. Also explicitly run the
26+
# core/src tests, which were never matched by the old glob.
27+
- shell: bash
28+
run: |
29+
shopt -s globstar
30+
node --experimental-test-module-mocks --test --import tsx src/**/*.test.ts core/src/**/*.test.ts
2431
- run: npm run test:e2e
2532
- run: npm run test:integration

core/src/allowance.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe("allowance", () => {
3535
assert.deepEqual(loaded, allowance);
3636
});
3737

38-
it("creates file with 0600 permissions", () => {
38+
it("creates file with 0600 permissions", { skip: process.platform === "win32" ? "POSIX file modes not enforced on Windows NTFS" : false }, () => {
3939
saveAllowance({ address: "0x1", privateKey: "0x2" }, allowancePath);
4040
const stats = statSync(allowancePath);
4141
const mode = stats.mode & 0o777;

core/src/config.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ describe("config", () => {
4242

4343
it("derives keystore path from config dir", () => {
4444
process.env.RUN402_CONFIG_DIR = "/tmp/test-config";
45-
assert.equal(getKeystorePath(), "/tmp/test-config/projects.json");
45+
// Use path.join in the expected value so the test passes on both POSIX
46+
// and Windows (Windows produces backslashes via path.join).
47+
assert.equal(getKeystorePath(), join("/tmp/test-config", "projects.json"));
4648
});
4749

4850
it("derives allowance path from config dir", () => {
4951
process.env.RUN402_CONFIG_DIR = "/tmp/test-config";
5052
delete process.env.RUN402_ALLOWANCE_PATH;
51-
assert.equal(getAllowancePath(), "/tmp/test-config/allowance.json");
53+
assert.equal(getAllowancePath(), join("/tmp/test-config", "allowance.json"));
5254
});
5355

5456
it("returns custom allowance path from RUN402_ALLOWANCE_PATH env", () => {

core/src/keystore.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ describe("core keystore", () => {
3434
assert.deepEqual(loaded, project);
3535
});
3636

37-
it("creates file with 0600 permissions", () => {
37+
it("creates file with 0600 permissions", { skip: process.platform === "win32" ? "POSIX file modes not enforced on Windows NTFS" : false }, () => {
3838
saveProject("proj-002", {
3939
anon_key: "ak", service_key: "sk",
4040
}, storePath);

src/keystore.test.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,17 @@ describe("keystore", () => {
2828
const project: StoredProject = {
2929
anon_key: "anon-key-123",
3030
service_key: "svc-key-456",
31-
tier: "prototype",
32-
lease_expires_at: "2026-03-06T00:00:00Z",
3331
};
3432
saveProject("proj-001", project, storePath);
3533

3634
const loaded = getProject("proj-001", storePath);
3735
assert.deepEqual(loaded, project);
3836
});
3937

40-
it("creates file with 0600 permissions", () => {
38+
it("creates file with 0600 permissions", { skip: process.platform === "win32" ? "POSIX file modes not enforced on Windows NTFS" : false }, () => {
4139
const project: StoredProject = {
4240
anon_key: "ak",
4341
service_key: "sk",
44-
tier: "hobby",
45-
lease_expires_at: "2026-04-01T00:00:00Z",
4642
};
4743
saveProject("proj-002", project, storePath);
4844

@@ -55,14 +51,10 @@ describe("keystore", () => {
5551
const p1: StoredProject = {
5652
anon_key: "ak1",
5753
service_key: "sk1",
58-
tier: "prototype",
59-
lease_expires_at: "2026-03-01T00:00:00Z",
6054
};
6155
const p2: StoredProject = {
6256
anon_key: "ak2",
6357
service_key: "sk2",
64-
tier: "team",
65-
lease_expires_at: "2026-04-01T00:00:00Z",
6658
};
6759

6860
saveProject("proj-a", p1, storePath);
@@ -80,14 +72,10 @@ describe("keystore", () => {
8072
const v1: StoredProject = {
8173
anon_key: "old",
8274
service_key: "old",
83-
tier: "prototype",
84-
lease_expires_at: "2026-03-01T00:00:00Z",
8575
};
8676
const v2: StoredProject = {
8777
anon_key: "new",
8878
service_key: "new",
89-
tier: "hobby",
90-
lease_expires_at: "2026-04-01T00:00:00Z",
9179
};
9280

9381
saveProject("proj-x", v1, storePath);
@@ -112,8 +100,6 @@ describe("keystore", () => {
112100
const project: StoredProject = {
113101
anon_key: "ak",
114102
service_key: "sk",
115-
tier: "prototype",
116-
lease_expires_at: "2026-03-01T00:00:00Z",
117103
};
118104
saveProject("proj-atomic", project, storePath);
119105

0 commit comments

Comments
 (0)