feat: initialize parent-bff service with full core features
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
This commit is contained in:
110
services/parent-bff/test/unit/parent-inputs.dto.test.ts
Normal file
110
services/parent-bff/test/unit/parent-inputs.dto.test.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import {
|
||||
UpdateNotificationPreferencesSchema,
|
||||
NotificationChannelSchema,
|
||||
NotificationEventTypesInputSchema,
|
||||
} from "../../src/parent/dto/parent-inputs.dto.js";
|
||||
|
||||
describe("NotificationChannelSchema", () => {
|
||||
it("接受有效渠道", () => {
|
||||
expect(NotificationChannelSchema.parse("APP")).toBe("APP");
|
||||
expect(NotificationChannelSchema.parse("SMS")).toBe("SMS");
|
||||
expect(NotificationChannelSchema.parse("EMAIL")).toBe("EMAIL");
|
||||
expect(NotificationChannelSchema.parse("WECHAT")).toBe("WECHAT");
|
||||
});
|
||||
|
||||
it("拒绝无效渠道", () => {
|
||||
expect(() => NotificationChannelSchema.parse("PUSH")).toThrow();
|
||||
expect(() => NotificationChannelSchema.parse("")).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("NotificationEventTypesInputSchema", () => {
|
||||
it("接受所有可选布尔字段", () => {
|
||||
const result = NotificationEventTypesInputSchema.parse({
|
||||
gradeReleased: true,
|
||||
homeworkGraded: false,
|
||||
examPublished: true,
|
||||
attendanceAlert: false,
|
||||
schoolAnnouncement: true,
|
||||
});
|
||||
expect(result.gradeReleased).toBe(true);
|
||||
expect(result.homeworkGraded).toBe(false);
|
||||
});
|
||||
|
||||
it("允许部分字段(未传为 undefined)", () => {
|
||||
const result = NotificationEventTypesInputSchema.parse({
|
||||
gradeReleased: true,
|
||||
});
|
||||
expect(result.gradeReleased).toBe(true);
|
||||
expect(result.homeworkGraded).toBeUndefined();
|
||||
});
|
||||
|
||||
it("接受空对象", () => {
|
||||
const result = NotificationEventTypesInputSchema.parse({});
|
||||
expect(result.gradeReleased).toBeUndefined();
|
||||
});
|
||||
|
||||
it("拒绝非布尔值", () => {
|
||||
expect(() =>
|
||||
NotificationEventTypesInputSchema.parse({ gradeReleased: "yes" }),
|
||||
).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("UpdateNotificationPreferencesSchema", () => {
|
||||
it("接受完整有效输入", () => {
|
||||
const input = {
|
||||
channels: ["APP", "WECHAT"],
|
||||
eventTypes: {
|
||||
gradeReleased: true,
|
||||
homeworkGraded: false,
|
||||
},
|
||||
};
|
||||
const result = UpdateNotificationPreferencesSchema.parse(input);
|
||||
expect(result.channels).toEqual(["APP", "WECHAT"]);
|
||||
expect(result.eventTypes.gradeReleased).toBe(true);
|
||||
});
|
||||
|
||||
it("拒绝空 channels 数组", () => {
|
||||
expect(() =>
|
||||
UpdateNotificationPreferencesSchema.parse({
|
||||
channels: [],
|
||||
eventTypes: {},
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it("拒绝无效 channel 值", () => {
|
||||
expect(() =>
|
||||
UpdateNotificationPreferencesSchema.parse({
|
||||
channels: ["INVALID"],
|
||||
eventTypes: {},
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it("拒绝缺少 channels", () => {
|
||||
expect(() =>
|
||||
UpdateNotificationPreferencesSchema.parse({
|
||||
eventTypes: {},
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it("拒绝缺少 eventTypes", () => {
|
||||
expect(() =>
|
||||
UpdateNotificationPreferencesSchema.parse({
|
||||
channels: ["APP"],
|
||||
}),
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it("接受单个 channel", () => {
|
||||
const result = UpdateNotificationPreferencesSchema.parse({
|
||||
channels: ["APP"],
|
||||
eventTypes: {},
|
||||
});
|
||||
expect(result.channels).toEqual(["APP"]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user