Skip to content

Commit 57b820f

Browse files
committed
test: loader/utils 단위 및 통합 스모크 테스트 추가
1 parent cd7fd31 commit 57b820f

4 files changed

Lines changed: 106 additions & 0 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { describe, expect, it } from "vitest";
2+
3+
import { buildBackendRouteRegistrations, type ModuleManifest } from "../loader";
4+
5+
describe("api integration smoke", () => {
6+
it("creates route registrations from enabled module manifests", () => {
7+
const manifests: ModuleManifest[] = [
8+
{
9+
name: "ledger",
10+
version: "1.0.0",
11+
enabled: true,
12+
dependencies: [],
13+
routes: {
14+
frontend: "/ledger",
15+
api: "/api/ledger",
16+
},
17+
},
18+
];
19+
20+
const routes = buildBackendRouteRegistrations(manifests);
21+
expect(routes).toEqual([{ moduleName: "ledger", apiBasePath: "/api/ledger" }]);
22+
});
23+
});

apps/api/src/loader/index.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { describe, expect, it } from "vitest";
2+
3+
import {
4+
buildBackendRouteRegistrations,
5+
parseModuleJson,
6+
scanBackendModules,
7+
validateModuleDependencies,
8+
} from "./index";
9+
10+
describe("api module loader", () => {
11+
it("parses module json and scans enabled modules", async () => {
12+
const entries = [
13+
{
14+
name: "ledger",
15+
manifestJson: JSON.stringify({
16+
version: "1.0.0",
17+
enabled: true,
18+
dependencies: [],
19+
routes: { frontend: "/ledger", api: "/api/ledger" },
20+
}),
21+
},
22+
{
23+
name: "disabled",
24+
manifestJson: JSON.stringify({
25+
version: "1.0.0",
26+
enabled: false,
27+
dependencies: [],
28+
routes: { frontend: "/disabled", api: "/api/disabled" },
29+
}),
30+
},
31+
];
32+
33+
const manifests = await scanBackendModules(entries);
34+
expect(manifests).toHaveLength(1);
35+
expect(manifests[0]?.name).toBe("ledger");
36+
});
37+
38+
it("builds route registrations and validates dependencies", () => {
39+
const ledger = parseModuleJson(
40+
JSON.stringify({
41+
name: "ledger",
42+
version: "1.0.0",
43+
enabled: true,
44+
dependencies: ["subscription"],
45+
routes: { frontend: "/ledger", api: "/api/ledger" },
46+
}),
47+
);
48+
49+
const routes = buildBackendRouteRegistrations([ledger]);
50+
expect(routes[0]?.apiBasePath).toBe("/api/ledger");
51+
52+
const issues = validateModuleDependencies([ledger]);
53+
expect(issues).toHaveLength(1);
54+
expect(issues[0]?.missingDependencies).toContain("subscription");
55+
});
56+
});

apps/api/src/loader/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,10 @@ export function validateModuleDependencies(manifests: ModuleManifest[]): Depende
8080
})
8181
.filter((issue) => issue.missingDependencies.length > 0);
8282
}
83+
84+
export default {
85+
parseModuleJson,
86+
scanBackendModules,
87+
buildBackendRouteRegistrations,
88+
validateModuleDependencies,
89+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { describe, expect, it } from "vitest";
2+
3+
import { isEmail, isNonEmpty, isStrongPassword } from "./validation";
4+
5+
describe("validation utils", () => {
6+
it("validates non-empty values", () => {
7+
expect(isNonEmpty("fieldstack")).toBe(true);
8+
expect(isNonEmpty(" ")).toBe(false);
9+
});
10+
11+
it("validates email format", () => {
12+
expect(isEmail("user@example.com")).toBe(true);
13+
expect(isEmail("invalid-email")).toBe(false);
14+
});
15+
16+
it("validates strong password rule", () => {
17+
expect(isStrongPassword("Abcd1234")).toBe(true);
18+
expect(isStrongPassword("abcd1234")).toBe(false);
19+
});
20+
});

0 commit comments

Comments
 (0)