feat(ai-character): 관리자 웹 기반 구성

This commit is contained in:
Yu Sung
2026-07-26 03:28:09 +09:00
parent 1dcbf43320
commit 42027b9f0d
26 changed files with 4368 additions and 36 deletions

View File

@@ -0,0 +1,27 @@
import { afterEach, describe, expect, test, vi } from "vitest";
import { getRuntimeEnv } from "./env";
describe("getRuntimeEnv", () => {
afterEach(() => {
vi.unstubAllEnvs();
});
test("returns the configured API base URL", () => {
vi.stubEnv("VITE_API_BASE_URL", "https://api.example.com");
expect(getRuntimeEnv()).toEqual({ apiBaseUrl: "https://api.example.com" });
});
test("blocks startup when VITE_API_BASE_URL is missing", () => {
vi.stubEnv("VITE_API_BASE_URL", "");
expect(() => getRuntimeEnv()).toThrow("VITE_API_BASE_URL is required");
});
test("blocks startup when VITE_API_BASE_URL is not an http URL", () => {
vi.stubEnv("VITE_API_BASE_URL", "not-a-url");
expect(() => getRuntimeEnv()).toThrow("VITE_API_BASE_URL must be a valid http(s) URL");
});
});

23
src/shared/config/env.ts Normal file
View File

@@ -0,0 +1,23 @@
export type RuntimeEnv = {
apiBaseUrl: string;
};
export function getRuntimeEnv(): RuntimeEnv {
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;
if (!apiBaseUrl) {
throw new Error("VITE_API_BASE_URL is required");
}
let url: URL;
try {
url = new URL(apiBaseUrl);
} catch {
throw new Error("VITE_API_BASE_URL must be a valid http(s) URL");
}
if (url.protocol !== "http:" && url.protocol !== "https:") {
throw new Error("VITE_API_BASE_URL must be a valid http(s) URL");
}
return { apiBaseUrl };
}

10
src/shared/test/setup.ts Normal file
View File

@@ -0,0 +1,10 @@
import "@testing-library/jest-dom/vitest";
import { cleanup } from "@testing-library/react";
import { afterEach, vi } from "vitest";
afterEach(() => {
cleanup();
vi.clearAllMocks();
sessionStorage.clear();
localStorage.clear();
});