260 lines
8.1 KiB
TypeScript
260 lines
8.1 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
import {
|
|
appBannerSchema,
|
|
appPopupSchema,
|
|
appSplashScreenSchema,
|
|
exploreTabSchema,
|
|
h5LinkUpdateSchema,
|
|
} from "@/features/app-config/schema";
|
|
import { FormValidationError, parseForm } from "@/shared/forms/validation";
|
|
|
|
const validBannerForm = {
|
|
bannerType: "h5",
|
|
countryCode: "",
|
|
coverUrl: "https://media.haiyihy.com/banner/home.png",
|
|
description: "",
|
|
displayScope: "home",
|
|
displayScopes: ["home"],
|
|
endsAtMs: "1800000000000",
|
|
param: "https://h5.example.com/activity",
|
|
platform: "android",
|
|
regionId: "",
|
|
roomSmallImageUrl: "",
|
|
sortOrder: "0",
|
|
startsAtMs: "1700000000000",
|
|
status: "active",
|
|
};
|
|
|
|
const validSplashScreenForm = {
|
|
countryCode: "",
|
|
coverUrl: "https://media.haiyihy.com/splash/launch.png",
|
|
description: "",
|
|
displayDurationMs: "4500",
|
|
endsAtMs: "1800000000000",
|
|
param: "https://h5.example.com/splash",
|
|
platform: "ios",
|
|
regionId: "",
|
|
sortOrder: "0",
|
|
splashType: "h5",
|
|
startsAtMs: "1700000000000",
|
|
status: "active",
|
|
};
|
|
|
|
const validPopupForm = {
|
|
code: "new-user-popup",
|
|
displayPeriodDays: "2",
|
|
endsAtMs: "1800000000000",
|
|
imageUrl: "",
|
|
jumpType: "h5",
|
|
jumpUrl: "https://h5.example.com/popup",
|
|
name: "新人活动",
|
|
sortOrder: "0",
|
|
startsAtMs: "1700000000000",
|
|
status: "active",
|
|
};
|
|
|
|
describe("app config form schema", () => {
|
|
test("validates dynamic h5 config item", () => {
|
|
const payload = parseForm(h5LinkUpdateSchema, {
|
|
key: "host-center.v2",
|
|
label: "Host Center",
|
|
url: "https://h5.example.com/host",
|
|
});
|
|
|
|
expect(payload.key).toBe("host-center.v2");
|
|
expect(payload.label).toBe("Host Center");
|
|
});
|
|
|
|
test("rejects dynamic h5 config key with spaces", () => {
|
|
expect(() =>
|
|
parseForm(h5LinkUpdateSchema, {
|
|
key: "host center",
|
|
label: "Host Center",
|
|
url: "https://h5.example.com/host",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("keeps banner display scope and delivery time fields", () => {
|
|
const payload = parseForm(appBannerSchema, validBannerForm);
|
|
|
|
expect(payload.displayScopes).toEqual(["home"]);
|
|
expect(payload.startsAtMs).toBe(1700000000000);
|
|
expect(payload.endsAtMs).toBe(1800000000000);
|
|
});
|
|
|
|
test("accepts public app jump json for banner", () => {
|
|
const payload = parseForm(appBannerSchema, {
|
|
...validBannerForm,
|
|
bannerType: "app",
|
|
param: '{"type":"room_random_game","game_id":"dice"}',
|
|
});
|
|
|
|
expect(payload.bannerType).toBe("app");
|
|
expect(payload.param).toBe('{"type":"room_random_game","game_id":"dice"}');
|
|
});
|
|
|
|
test("rejects incomplete public app jump json for banner", () => {
|
|
expect(() =>
|
|
parseForm(appBannerSchema, {
|
|
...validBannerForm,
|
|
bannerType: "app",
|
|
param: '{"type":"room_game","room_id":"room_1"}',
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("accepts multiple banner display scopes", () => {
|
|
const payload = parseForm(appBannerSchema, {
|
|
...validBannerForm,
|
|
displayScopes: ["home", "room", "recharge"],
|
|
roomSmallImageUrl: "https://media.haiyihy.com/banner/room-small.png",
|
|
});
|
|
|
|
expect(payload.displayScopes).toEqual(["home", "room", "recharge"]);
|
|
});
|
|
|
|
test("requires room small image for room banner", () => {
|
|
expect(() =>
|
|
parseForm(appBannerSchema, {
|
|
...validBannerForm,
|
|
displayScopes: ["home", "room"],
|
|
roomSmallImageUrl: "",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("rejects inverted banner delivery time range", () => {
|
|
expect(() =>
|
|
parseForm(appBannerSchema, {
|
|
...validBannerForm,
|
|
endsAtMs: "1700000000000",
|
|
startsAtMs: "1800000000000",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("keeps splash screen delivery and placement fields without display scope", () => {
|
|
const payload = parseForm(appSplashScreenSchema, validSplashScreenForm);
|
|
|
|
expect(payload.splashType).toBe("h5");
|
|
expect(payload.displayDurationMs).toBe(4500);
|
|
expect(payload.startsAtMs).toBe(1700000000000);
|
|
expect(payload.endsAtMs).toBe(1800000000000);
|
|
expect("displayScopes" in payload).toBe(false);
|
|
});
|
|
|
|
test("accepts public app jump json for splash screen", () => {
|
|
const payload = parseForm(appSplashScreenSchema, {
|
|
...validSplashScreenForm,
|
|
param: '{"type":"wallet"}',
|
|
splashType: "app",
|
|
});
|
|
|
|
expect(payload.splashType).toBe("app");
|
|
expect(payload.param).toBe('{"type":"wallet"}');
|
|
});
|
|
|
|
test("requires h5 link for splash screen h5 type", () => {
|
|
expect(() =>
|
|
parseForm(appSplashScreenSchema, {
|
|
...validSplashScreenForm,
|
|
param: "",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("rejects negative splash screen display duration", () => {
|
|
expect(() =>
|
|
parseForm(appSplashScreenSchema, {
|
|
...validSplashScreenForm,
|
|
displayDurationMs: "-1",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("rejects inverted splash screen delivery time range", () => {
|
|
expect(() =>
|
|
parseForm(appSplashScreenSchema, {
|
|
...validSplashScreenForm,
|
|
endsAtMs: "1700000000000",
|
|
startsAtMs: "1800000000000",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("keeps popup optional image and display period", () => {
|
|
const payload = parseForm(appPopupSchema, validPopupForm);
|
|
|
|
expect(payload.code).toBe("new-user-popup");
|
|
expect(payload.imageUrl).toBe("");
|
|
expect(payload.displayPeriodDays).toBe(2);
|
|
expect(payload.startsAtMs).toBe(1700000000000);
|
|
expect(payload.endsAtMs).toBe(1800000000000);
|
|
});
|
|
|
|
test("accepts public app jump json for popup", () => {
|
|
const payload = parseForm(appPopupSchema, {
|
|
...validPopupForm,
|
|
jumpType: "app",
|
|
jumpUrl: '{"type":"room_window","room_id":"room_1","window":"gift_panel","gift_id":"gift_1"}',
|
|
});
|
|
|
|
expect(payload.jumpType).toBe("app");
|
|
expect(payload.jumpUrl).toBe(
|
|
'{"type":"room_window","room_id":"room_1","window":"gift_panel","gift_id":"gift_1"}',
|
|
);
|
|
});
|
|
|
|
test("rejects popup code with spaces", () => {
|
|
expect(() =>
|
|
parseForm(appPopupSchema, {
|
|
...validPopupForm,
|
|
code: "new user popup",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("requires popup jump address", () => {
|
|
expect(() =>
|
|
parseForm(appPopupSchema, {
|
|
...validPopupForm,
|
|
jumpUrl: "",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("rejects inverted popup effective time range", () => {
|
|
expect(() =>
|
|
parseForm(appPopupSchema, {
|
|
...validPopupForm,
|
|
endsAtMs: "1700000000000",
|
|
startsAtMs: "1800000000000",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
|
|
test("validates explore tab h5 url and sort order", () => {
|
|
const payload = parseForm(exploreTabSchema, {
|
|
enabled: true,
|
|
h5Url: "https://h5.example.com/explore/live",
|
|
sortOrder: "3",
|
|
tab: "Live",
|
|
});
|
|
|
|
expect(payload.sortOrder).toBe(3);
|
|
expect(payload.h5Url).toBe("https://h5.example.com/explore/live");
|
|
});
|
|
|
|
test("rejects explore tab url with whitespace", () => {
|
|
expect(() =>
|
|
parseForm(exploreTabSchema, {
|
|
enabled: true,
|
|
h5Url: "https://h5.example.com/explore live",
|
|
sortOrder: "0",
|
|
tab: "Live",
|
|
}),
|
|
).toThrow(FormValidationError);
|
|
});
|
|
});
|