test fixes

This commit is contained in:
Ishaan Jaffer 2026-01-27 17:23:07 -08:00
parent 4b4d658e74
commit 3e98b44d39
2 changed files with 230 additions and 8 deletions

View file

@ -6,31 +6,34 @@
// Page descriptions for UI Settings configuration
export const pageDescriptions: Record<string, string> = {
"api-keys": "Manage virtual keys for API access and authentication",
playground: "Interactive playground for testing LLM requests",
"models-and-endpoints": "Configure and manage LLM models and endpoints",
"llm-playground": "Interactive playground for testing LLM requests",
models: "Configure and manage LLM models and endpoints",
agents: "Create and manage AI agents",
"mcp-servers": "Configure Model Context Protocol servers",
guardrails: "Set up content moderation and safety guardrails",
policies: "Define access control and usage policies",
"search-tools": "Configure RAG search and retrieval tools",
"vector-stores": "Manage vector databases for embeddings",
usage: "View usage analytics and metrics",
new_usage: "View usage analytics and metrics",
logs: "Access request and response logs",
"internal-users": "Manage internal user accounts and permissions",
users: "Manage internal user accounts and permissions",
teams: "Create and manage teams for access control",
organizations: "Manage organizations and their members",
budgets: "Set and monitor spending budgets",
"api-reference": "Browse API documentation and endpoints",
"ai-hub": "Explore available AI models and providers",
api_ref: "Browse API documentation and endpoints",
"model-hub-table": "Explore available AI models and providers",
"learning-resources": "Access tutorials and documentation",
caching: "Configure response caching settings",
"transform-request": "Set up request transformation rules",
"pass-through-endpoints": "Configure pass-through API endpoints",
"cost-tracking": "Track and analyze API costs",
"ui-themes": "Customize dashboard appearance",
"ui-theme": "Customize dashboard appearance",
"tag-management": "Organize resources with tags",
prompts: "Manage and version prompt templates",
"claude-code-plugins": "Configure Claude Code plugins",
usage: "View legacy usage dashboard",
"router-settings": "Configure routing and load balancing settings",
"logging-and-alerts": "Set up logging and alert configurations",
"admin-panel": "Access admin panel and settings",
};
export interface PageMetadata {

View file

@ -0,0 +1,219 @@
/**
* Tests to ensure page metadata stays in sync with leftnav configuration
* This catches issues when leftnav structure changes but page_utils/page_metadata aren't updated
*/
import { describe, it, expect } from "vitest";
import { getAvailablePages } from "./page_utils";
import { menuGroups } from "./leftnav";
import { pageDescriptions } from "./page_metadata";
describe("Page Utils - LeftNav Sync", () => {
it("should return all pages from leftnav configuration", () => {
const availablePages = getAvailablePages();
// Should have pages
expect(availablePages.length).toBeGreaterThan(0);
// Each page should have required fields
availablePages.forEach((page) => {
expect(page).toHaveProperty("page");
expect(page).toHaveProperty("label");
expect(page).toHaveProperty("group");
expect(page).toHaveProperty("description");
expect(typeof page.page).toBe("string");
expect(typeof page.label).toBe("string");
expect(typeof page.group).toBe("string");
expect(typeof page.description).toBe("string");
});
});
it("should include all navigable pages from menuGroups", () => {
const availablePages = getAvailablePages();
const availablePageKeys = availablePages.map((p) => p.page);
// Collect all page keys from menuGroups (excluding parent containers)
const menuPageKeys: string[] = [];
const excludedParents = ["tools", "experimental", "settings"];
menuGroups.forEach((group) => {
group.items.forEach((item) => {
if (item.page && !excludedParents.includes(item.page)) {
menuPageKeys.push(item.page);
}
// Add children
if (item.children) {
item.children.forEach((child) => {
menuPageKeys.push(child.page);
});
}
});
});
// Every menu page should be in available pages
menuPageKeys.forEach((pageKey) => {
expect(
availablePageKeys,
`Page "${pageKey}" from menuGroups should be in getAvailablePages() output`
).toContain(pageKey);
});
});
it("should not include parent container pages (tools, experimental, settings)", () => {
const availablePages = getAvailablePages();
const availablePageKeys = availablePages.map((p) => p.page);
const excludedParents = ["tools", "experimental", "settings"];
excludedParents.forEach((parent) => {
expect(
availablePageKeys,
`Parent container "${parent}" should not be in available pages`
).not.toContain(parent);
});
});
it("should have descriptions for all pages", () => {
const availablePages = getAvailablePages();
availablePages.forEach((page) => {
expect(
page.description,
`Page "${page.page}" should have a description`
).toBeTruthy();
expect(
page.description,
`Page "${page.page}" should not have placeholder description`
).not.toBe("No description available");
});
});
it("should have pageDescriptions entry for all navigable pages in menuGroups", () => {
// Collect all page keys from menuGroups
const menuPageKeys: string[] = [];
const excludedParents = ["tools", "experimental", "settings"];
menuGroups.forEach((group) => {
group.items.forEach((item) => {
if (item.page && !excludedParents.includes(item.page)) {
menuPageKeys.push(item.page);
}
if (item.children) {
item.children.forEach((child) => {
menuPageKeys.push(child.page);
});
}
});
});
// Every menu page should have a description
const missingDescriptions: string[] = [];
menuPageKeys.forEach((pageKey) => {
if (!pageDescriptions[pageKey]) {
missingDescriptions.push(pageKey);
}
});
expect(
missingDescriptions,
`These pages are missing descriptions in page_metadata.ts: ${missingDescriptions.join(", ")}`
).toHaveLength(0);
});
it("should not have orphaned descriptions (descriptions for pages not in menuGroups)", () => {
// Collect all page keys from menuGroups
const menuPageKeys: string[] = [];
const excludedParents = ["tools", "experimental", "settings"];
menuGroups.forEach((group) => {
group.items.forEach((item) => {
if (item.page && !excludedParents.includes(item.page)) {
menuPageKeys.push(item.page);
}
if (item.children) {
item.children.forEach((child) => {
menuPageKeys.push(child.page);
});
}
});
});
// Check for descriptions that don't match any menu page
const orphanedDescriptions: string[] = [];
Object.keys(pageDescriptions).forEach((descKey) => {
if (!menuPageKeys.includes(descKey)) {
orphanedDescriptions.push(descKey);
}
});
expect(
orphanedDescriptions,
`These descriptions don't match any page in menuGroups: ${orphanedDescriptions.join(", ")}. Remove them or add the pages to leftnav.`
).toHaveLength(0);
});
it("should have proper group hierarchy for nested pages", () => {
const availablePages = getAvailablePages();
// Find pages that should be nested (children of Tools, Experimental, Settings)
const nestedPages = availablePages.filter((page) =>
page.group.includes(" > ")
);
// Each nested page should have parent > child format
nestedPages.forEach((page) => {
const parts = page.group.split(" > ");
expect(
parts.length,
`Nested page "${page.page}" should have exactly 2 parts in group hierarchy`
).toBe(2);
// Parent should be one of the group labels
const parentGroup = parts[0];
const groupLabels = menuGroups.map((g) => g.groupLabel);
expect(
groupLabels,
`Parent group "${parentGroup}" for page "${page.page}" should be a valid group label`
).toContain(parentGroup);
});
});
it("should have unique page keys", () => {
const availablePages = getAvailablePages();
const pageKeys = availablePages.map((p) => p.page);
const uniquePageKeys = new Set(pageKeys);
expect(
pageKeys.length,
"All page keys should be unique (no duplicates)"
).toBe(uniquePageKeys.size);
});
it("should match the structure expected by PageVisibilitySettings component", () => {
const availablePages = getAvailablePages();
// Group pages by their group (same logic as in PageVisibilitySettings)
const grouped: Record<string, typeof availablePages> = {};
availablePages.forEach((page) => {
if (!grouped[page.group]) {
grouped[page.group] = [];
}
grouped[page.group].push(page);
});
// Should have multiple groups
expect(Object.keys(grouped).length).toBeGreaterThan(1);
// Each group should have at least one page
Object.entries(grouped).forEach(([groupName, pages]) => {
expect(
pages.length,
`Group "${groupName}" should have at least one page`
).toBeGreaterThan(0);
});
});
});