add complete parent-bff implementation including: - GraphQL endpoint with depth/cost validation - ChildGuard越权校验 with redis cache and singleflight - parallel orchestration with partial failure fallback - three-level cache fallback strategy (Redis + LRU + downstream) - Kafka consumer for cache invalidation and notification push - opossum circuit breaker for downstream services - Prometheus metrics and SLO alerts - Helm chart for k8s deployment with multi-environment configs - Grafana dashboard for observability - complete unit and integration tests
86 lines
2.4 KiB
TypeScript
86 lines
2.4 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { CacheKeys } from "../../src/shared/cache/cache-key.builder.js";
|
|
|
|
describe("CacheKeys", () => {
|
|
describe("dashboard", () => {
|
|
it("应该为 dashboard 构建正确的 key", () => {
|
|
expect(CacheKeys.dashboard("parent-001")).toBe("dashboard:parent-001");
|
|
});
|
|
});
|
|
|
|
describe("children", () => {
|
|
it("应该为 children 构建正确的 key", () => {
|
|
expect(CacheKeys.children("parent-001")).toBe("children:parent-001");
|
|
});
|
|
});
|
|
|
|
describe("grades", () => {
|
|
it("应该为 grades 构建带分页的 key", () => {
|
|
expect(CacheKeys.grades("student-001", 1)).toBe("grades:student-001:1");
|
|
expect(CacheKeys.grades("student-002", 3)).toBe("grades:student-002:3");
|
|
});
|
|
});
|
|
|
|
describe("homework", () => {
|
|
it("应该为 homework 构建带 classId 的 key", () => {
|
|
expect(CacheKeys.homework("student-001", "class-001")).toBe(
|
|
"homework:student-001:class-001",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("exams", () => {
|
|
it("应该为 exams 构建带 classId 的 key", () => {
|
|
expect(CacheKeys.exams("student-001", "class-001")).toBe(
|
|
"exams:student-001:class-001",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("weakness", () => {
|
|
it("应该为 weakness 构建正确的 key", () => {
|
|
expect(CacheKeys.weakness("student-001")).toBe(
|
|
"analytics:weakness:student-001",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("trend", () => {
|
|
it("应该为 trend 构建带 range 的 key", () => {
|
|
expect(CacheKeys.trend("student-001", "7d")).toBe(
|
|
"analytics:trend:student-001:7d",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("notifications", () => {
|
|
it("应该为 notifications 构建带分页的 key", () => {
|
|
expect(CacheKeys.notifications("parent-001", 1)).toBe(
|
|
"notifications:parent-001:1",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("notificationPrefs", () => {
|
|
it("应该为 notificationPrefs 构建正确的 key", () => {
|
|
expect(CacheKeys.notificationPrefs("parent-001")).toBe(
|
|
"notification-prefs:parent-001",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("childBindings", () => {
|
|
it("应该为 childBindings 构建正确的 key", () => {
|
|
expect(CacheKeys.childBindings("parent-001")).toBe(
|
|
"child-bindings:parent-001",
|
|
);
|
|
});
|
|
});
|
|
|
|
it("不同 parentId 应该产生不同 key", () => {
|
|
expect(CacheKeys.dashboard("parent-001")).not.toBe(
|
|
CacheKeys.dashboard("parent-002"),
|
|
);
|
|
});
|
|
});
|