fix(#338): Standardize API base URL and auth mechanism across components
- Create centralized config module (apps/web/src/lib/config.ts) exporting: - API_BASE_URL: Main API server URL from NEXT_PUBLIC_API_URL - ORCHESTRATOR_URL: Orchestrator service URL from NEXT_PUBLIC_ORCHESTRATOR_URL - Helper functions for building full URLs - Update client.ts to import from central config - Update LoginButton.tsx to use API_BASE_URL from config - Update useWebSocket.ts to use API_BASE_URL from config - Update AgentStatusWidget.tsx to use ORCHESTRATOR_URL from config - Update TaskProgressWidget.tsx to use ORCHESTRATOR_URL from config - Update useGraphData.ts to use API_BASE_URL from config - Fixed wrong default port (was 8000, now uses correct 3001) - Add comprehensive tests for config module - Update useWebSocket tests to properly mock config module Refs #338 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
91
apps/web/src/lib/config.test.ts
Normal file
91
apps/web/src/lib/config.test.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Tests for centralized API configuration
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
|
||||
// Store original env
|
||||
const originalEnv = { ...process.env };
|
||||
|
||||
describe("API Configuration", () => {
|
||||
beforeEach(() => {
|
||||
// Reset modules to pick up new env values
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Restore original env
|
||||
process.env = originalEnv;
|
||||
});
|
||||
|
||||
describe("default values", () => {
|
||||
it("should use default API URL when NEXT_PUBLIC_API_URL is not set", async () => {
|
||||
delete process.env.NEXT_PUBLIC_API_URL;
|
||||
delete process.env.NEXT_PUBLIC_ORCHESTRATOR_URL;
|
||||
|
||||
const { API_BASE_URL, ORCHESTRATOR_URL } = await import("./config");
|
||||
|
||||
expect(API_BASE_URL).toBe("http://localhost:3001");
|
||||
expect(ORCHESTRATOR_URL).toBe("http://localhost:3001");
|
||||
});
|
||||
});
|
||||
|
||||
describe("custom values", () => {
|
||||
it("should use NEXT_PUBLIC_API_URL when set", async () => {
|
||||
process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
|
||||
delete process.env.NEXT_PUBLIC_ORCHESTRATOR_URL;
|
||||
|
||||
const { API_BASE_URL, ORCHESTRATOR_URL } = await import("./config");
|
||||
|
||||
expect(API_BASE_URL).toBe("https://api.example.com");
|
||||
// ORCHESTRATOR_URL should fall back to API_BASE_URL
|
||||
expect(ORCHESTRATOR_URL).toBe("https://api.example.com");
|
||||
});
|
||||
|
||||
it("should use separate NEXT_PUBLIC_ORCHESTRATOR_URL when set", async () => {
|
||||
process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
|
||||
process.env.NEXT_PUBLIC_ORCHESTRATOR_URL = "https://orchestrator.example.com";
|
||||
|
||||
const { API_BASE_URL, ORCHESTRATOR_URL } = await import("./config");
|
||||
|
||||
expect(API_BASE_URL).toBe("https://api.example.com");
|
||||
expect(ORCHESTRATOR_URL).toBe("https://orchestrator.example.com");
|
||||
});
|
||||
});
|
||||
|
||||
describe("helper functions", () => {
|
||||
it("should build API URLs correctly", async () => {
|
||||
process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
|
||||
delete process.env.NEXT_PUBLIC_ORCHESTRATOR_URL;
|
||||
|
||||
const { buildApiUrl } = await import("./config");
|
||||
|
||||
expect(buildApiUrl("/api/v1/tasks")).toBe("https://api.example.com/api/v1/tasks");
|
||||
expect(buildApiUrl("/auth/signin")).toBe("https://api.example.com/auth/signin");
|
||||
});
|
||||
|
||||
it("should build orchestrator URLs correctly", async () => {
|
||||
process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
|
||||
process.env.NEXT_PUBLIC_ORCHESTRATOR_URL = "https://orch.example.com";
|
||||
|
||||
const { buildOrchestratorUrl } = await import("./config");
|
||||
|
||||
expect(buildOrchestratorUrl("/agents")).toBe("https://orch.example.com/agents");
|
||||
expect(buildOrchestratorUrl("/tasks/status")).toBe("https://orch.example.com/tasks/status");
|
||||
});
|
||||
});
|
||||
|
||||
describe("apiConfig object", () => {
|
||||
it("should expose all configuration through apiConfig", async () => {
|
||||
process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
|
||||
process.env.NEXT_PUBLIC_ORCHESTRATOR_URL = "https://orch.example.com";
|
||||
|
||||
const { apiConfig } = await import("./config");
|
||||
|
||||
expect(apiConfig.baseUrl).toBe("https://api.example.com");
|
||||
expect(apiConfig.orchestratorUrl).toBe("https://orch.example.com");
|
||||
expect(apiConfig.buildUrl("/test")).toBe("https://api.example.com/test");
|
||||
expect(apiConfig.buildOrchestratorUrl("/test")).toBe("https://orch.example.com/test");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user