feat: 기능 추가 과정중
This commit is contained in:
+32
-1
@@ -4,7 +4,11 @@ import {
|
||||
validateEnvelope,
|
||||
validateOperationPayload,
|
||||
validateOperationRequest,
|
||||
} from "../../src/adapters/http/schema-registry.js";
|
||||
} from "../../src/adapters/http/schema-registry.ts";
|
||||
import {
|
||||
composeRuntimeSchemaCodecs,
|
||||
validateWithRuntimeSchemaRegistry,
|
||||
} from "../../src/contracts/schema-registry.ts";
|
||||
|
||||
describe("HTTP platform schema boundary", () => {
|
||||
it("rejects an invalid top-level envelope", () => {
|
||||
@@ -37,3 +41,30 @@ describe("HTTP platform schema boundary", () => {
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("runtime schema codec contribution", () => {
|
||||
const codec = {
|
||||
schemaId: "Example",
|
||||
parse: (value: unknown) => ({ success: true as const, data: value }),
|
||||
};
|
||||
|
||||
it("resolves installed codecs and fails missing IDs closed", () => {
|
||||
const registry = composeRuntimeSchemaCodecs([{ Example: codec }]);
|
||||
expect(validateWithRuntimeSchemaRegistry("Example", 42, registry)).toEqual({
|
||||
success: true,
|
||||
data: 42,
|
||||
});
|
||||
expect(
|
||||
validateWithRuntimeSchemaRegistry("Missing", 42, registry),
|
||||
).toMatchObject({
|
||||
success: false,
|
||||
issues: [{ code: "SCHEMA_NOT_REGISTERED" }],
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects duplicate codec contributions", () => {
|
||||
expect(() =>
|
||||
composeRuntimeSchemaCodecs([{ Example: codec }, { Example: codec }]),
|
||||
).toThrow("duplicate runtime schema codec");
|
||||
});
|
||||
});
|
||||
+19
-7
@@ -3,17 +3,29 @@ import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
loadReleaseManifest,
|
||||
ReleaseManifestError,
|
||||
} from "../../src/bootstrap/load-release-manifest.js";
|
||||
} from "../../src/bootstrap/load-release-manifest.ts";
|
||||
|
||||
const runtime = {
|
||||
build: { buildId: "build-a" },
|
||||
const runtime: Parameters<typeof loadReleaseManifest>[0] = {
|
||||
build: {
|
||||
buildId: "build-a",
|
||||
commitSha: "abc123",
|
||||
routerBasePath: "/",
|
||||
runtimeConfigUrl: "/config.json",
|
||||
},
|
||||
config: {
|
||||
APP_ENV: "local",
|
||||
API_BASE_URL: "https://api.test",
|
||||
REQUEST_TIMEOUT_MS: 10_000,
|
||||
MAX_RETRY_ATTEMPTS: 2,
|
||||
TELEMETRY_ENABLED: false,
|
||||
AUTH_MODE: "external",
|
||||
RELEASE_MANIFEST_URL: "/release-manifest.json",
|
||||
BUILD_ID: "build-a",
|
||||
RELEASE_ID: "release-a",
|
||||
CONFIG_SCHEMA_VERSION: "1",
|
||||
API_CONTRACT_VERSION: "1",
|
||||
},
|
||||
validationDurationMs: 0,
|
||||
};
|
||||
const manifest = {
|
||||
schemaVersion: 1,
|
||||
@@ -32,7 +44,7 @@ describe("release manifest boot boundary", () => {
|
||||
it("loads a coherent release tuple", async () => {
|
||||
await expect(
|
||||
loadReleaseManifest(
|
||||
/** @type {Parameters<typeof loadReleaseManifest>[0]} */ (runtime),
|
||||
runtime,
|
||||
{ fetcher: async () => new Response(JSON.stringify(manifest)) },
|
||||
),
|
||||
).resolves.toMatchObject({ releaseId: "release-a" });
|
||||
@@ -41,7 +53,7 @@ describe("release manifest boot boundary", () => {
|
||||
it("fails before mount when release and runtime differ", async () => {
|
||||
await expect(
|
||||
loadReleaseManifest(
|
||||
/** @type {Parameters<typeof loadReleaseManifest>[0]} */ (runtime),
|
||||
runtime,
|
||||
{
|
||||
fetcher: async () =>
|
||||
new Response(JSON.stringify({ ...manifest, buildId: "build-b" })),
|
||||
@@ -83,7 +95,7 @@ describe("release manifest boot boundary", () => {
|
||||
async (manifestOverride, options, kind, code) => {
|
||||
await expect(
|
||||
loadReleaseManifest(
|
||||
/** @type {Parameters<typeof loadReleaseManifest>[0]} */ (runtime),
|
||||
runtime,
|
||||
{
|
||||
fetcher: async () =>
|
||||
Response.json({ ...manifest, ...manifestOverride }),
|
||||
@@ -100,7 +112,7 @@ describe("release manifest boot boundary", () => {
|
||||
);
|
||||
await expect(
|
||||
loadReleaseManifest(
|
||||
/** @type {Parameters<typeof loadReleaseManifest>[0]} */ (runtime),
|
||||
runtime,
|
||||
{ fetcher: async () => Response.json(malformed) },
|
||||
),
|
||||
).rejects.toBeInstanceOf(ReleaseManifestError);
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { loadRuntimeConfig } from "../../src/bootstrap/load-runtime-config.js";
|
||||
import { validateRuntimeConfig } from "../../src/bootstrap/runtime-config-schema.js";
|
||||
import { assertSafeConfigNames } from "../../src/contracts/env.js";
|
||||
import { loadRuntimeConfig } from "../../src/bootstrap/load-runtime-config.ts";
|
||||
import { validateRuntimeConfig } from "../../src/bootstrap/runtime-config-schema.ts";
|
||||
import { assertSafeConfigNames } from "../../src/contracts/env.ts";
|
||||
|
||||
const validConfig = {
|
||||
APP_ENV: "local",
|
||||
Reference in New Issue
Block a user