su2a / frontend /src /api /__tests__ /settings.authSourceDefaults.spec.ts
cjovs's picture
PG local + bucket backup/restore, DB: su2adb
126ef31 verified
Raw
History Blame Contribute Delete
11.4 kB
import { describe, expect, it } from "vitest";
import {
appendAuthSourceDefaultsToUpdateRequest,
buildAuthSourceDefaultsState,
normalizePlatformQuotasMap,
sanitizePlatformQuotasMap,
type UpdateSettingsRequest,
type DefaultPlatformQuotasMap,
} from "@/api/admin/settings";
/** 全 null 的 4 平台 map,用于断言归一化默认值 */
const allNullQuotas: DefaultPlatformQuotasMap = {
anthropic: { daily: null, weekly: null, monthly: null },
openai: { daily: null, weekly: null, monthly: null },
gemini: { daily: null, weekly: null, monthly: null },
antigravity: { daily: null, weekly: null, monthly: null },
}
describe("admin settings auth source defaults helpers", () => {
it("builds auth source defaults state from flat settings fields", () => {
const state = buildAuthSourceDefaultsState({
auth_source_default_email_balance: 9.5,
auth_source_default_email_concurrency: 3,
auth_source_default_email_subscriptions: [
{ group_id: 1, validity_days: 30 },
],
auth_source_default_email_grant_on_signup: false,
auth_source_default_email_grant_on_first_bind: true,
auth_source_default_linuxdo_balance: 6,
auth_source_default_linuxdo_concurrency: 8,
auth_source_default_linuxdo_subscriptions: [
{ group_id: 2, validity_days: 60 },
],
auth_source_default_linuxdo_grant_on_signup: true,
auth_source_default_linuxdo_grant_on_first_bind: false,
});
expect(state.email).toEqual({
balance: 9.5,
concurrency: 3,
subscriptions: [{ group_id: 1, validity_days: 30 }],
grant_on_signup: false,
grant_on_first_bind: true,
platform_quotas: allNullQuotas,
});
expect(state.linuxdo).toEqual({
balance: 6,
concurrency: 8,
subscriptions: [{ group_id: 2, validity_days: 60 }],
grant_on_signup: true,
grant_on_first_bind: false,
platform_quotas: allNullQuotas,
});
expect(state.oidc).toEqual({
balance: 0,
concurrency: 5,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: false,
platform_quotas: allNullQuotas,
});
expect(state.wechat).toEqual({
balance: 0,
concurrency: 5,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: false,
platform_quotas: allNullQuotas,
});
});
it("defaults grant-on-signup to disabled when settings are missing", () => {
const state = buildAuthSourceDefaultsState({});
expect(state.email.grant_on_signup).toBe(false);
expect(state.linuxdo.grant_on_signup).toBe(false);
expect(state.oidc.grant_on_signup).toBe(false);
expect(state.wechat.grant_on_signup).toBe(false);
});
it("reads nested platform_quotas from settings into auth source state", () => {
const state = buildAuthSourceDefaultsState({
auth_source_default_email_platform_quotas: {
anthropic: { daily: 10, weekly: 50, monthly: 200 },
openai: { daily: null, weekly: null, monthly: null },
} as DefaultPlatformQuotasMap,
});
// anthropic 填写的值应被保留
expect(state.email.platform_quotas.anthropic).toEqual({ daily: 10, weekly: 50, monthly: 200 });
// openai 全 null 应被保留
expect(state.email.platform_quotas.openai).toEqual({ daily: null, weekly: null, monthly: null });
// 未出现的平台(gemini/antigravity)归一化为 null
expect(state.email.platform_quotas.gemini).toEqual({ daily: null, weekly: null, monthly: null });
expect(state.email.platform_quotas.antigravity).toEqual({ daily: null, weekly: null, monthly: null });
});
it("appends auth source defaults back onto update payload", () => {
const payload: UpdateSettingsRequest = {
site_name: "Sub2API",
};
appendAuthSourceDefaultsToUpdateRequest(payload, {
email: {
balance: 1.25,
concurrency: 2,
subscriptions: [{ group_id: 3, validity_days: 7 }],
grant_on_signup: true,
grant_on_first_bind: false,
platform_quotas: {},
},
linuxdo: {
balance: 0,
concurrency: 6,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: true,
platform_quotas: {},
},
oidc: {
balance: 4,
concurrency: 9,
subscriptions: [{ group_id: 9, validity_days: 90 }],
grant_on_signup: true,
grant_on_first_bind: true,
platform_quotas: {},
},
wechat: {
balance: 2,
concurrency: 5,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: false,
platform_quotas: {},
},
github: {
balance: 0,
concurrency: 5,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: false,
platform_quotas: {},
},
google: {
balance: 0,
concurrency: 5,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: false,
platform_quotas: {},
},
dingtalk: {
balance: 0,
concurrency: 5,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: false,
platform_quotas: {},
},
});
expect(payload).toMatchObject({
site_name: "Sub2API",
auth_source_default_email_balance: 1.25,
auth_source_default_email_concurrency: 2,
auth_source_default_email_subscriptions: [
{ group_id: 3, validity_days: 7 },
],
auth_source_default_email_grant_on_signup: true,
auth_source_default_email_grant_on_first_bind: false,
auth_source_default_linuxdo_balance: 0,
auth_source_default_linuxdo_concurrency: 6,
auth_source_default_linuxdo_subscriptions: [],
auth_source_default_linuxdo_grant_on_signup: false,
auth_source_default_linuxdo_grant_on_first_bind: true,
auth_source_default_oidc_balance: 4,
auth_source_default_oidc_concurrency: 9,
auth_source_default_oidc_subscriptions: [
{ group_id: 9, validity_days: 90 },
],
auth_source_default_oidc_grant_on_signup: true,
auth_source_default_oidc_grant_on_first_bind: true,
auth_source_default_wechat_balance: 2,
auth_source_default_wechat_concurrency: 5,
auth_source_default_wechat_subscriptions: [],
auth_source_default_wechat_grant_on_signup: false,
auth_source_default_wechat_grant_on_first_bind: false,
// 嵌套 platform_quotas 字段
auth_source_default_email_platform_quotas: allNullQuotas,
auth_source_default_linuxdo_platform_quotas: allNullQuotas,
auth_source_default_oidc_platform_quotas: allNullQuotas,
auth_source_default_wechat_platform_quotas: allNullQuotas,
auth_source_default_github_platform_quotas: allNullQuotas,
auth_source_default_google_platform_quotas: allNullQuotas,
auth_source_default_dingtalk_platform_quotas: allNullQuotas,
});
});
it("appends sanitized nested platform_quotas with non-null values in update payload", () => {
const payload: UpdateSettingsRequest = {};
appendAuthSourceDefaultsToUpdateRequest(payload, {
email: {
balance: 0,
concurrency: 5,
subscriptions: [],
grant_on_signup: false,
grant_on_first_bind: false,
platform_quotas: {
anthropic: { daily: 10, weekly: 50, monthly: 200 },
openai: { daily: 0, weekly: null, monthly: null },
},
},
linuxdo: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} },
oidc: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} },
wechat: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} },
github: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} },
google: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} },
dingtalk: { balance: 0, concurrency: 5, subscriptions: [], grant_on_signup: false, grant_on_first_bind: false, platform_quotas: {} },
});
const emailQuotas = (payload as Record<string, unknown>)["auth_source_default_email_platform_quotas"] as DefaultPlatformQuotasMap;
expect(emailQuotas.anthropic).toEqual({ daily: 10, weekly: 50, monthly: 200 });
// 0 是合法值(不限额=0 与"不设"不同,保留)
expect(emailQuotas.openai?.daily).toBe(0);
// 缺失平台归一化为全 null
expect(emailQuotas.gemini).toEqual({ daily: null, weekly: null, monthly: null });
expect(emailQuotas.antigravity).toEqual({ daily: null, weekly: null, monthly: null });
});
});
describe("normalizePlatformQuotasMap", () => {
it("填充缺失的平台为全 null 三档", () => {
const result = normalizePlatformQuotasMap({ anthropic: { daily: 5, weekly: null, monthly: null } });
expect(result.anthropic).toEqual({ daily: 5, weekly: null, monthly: null });
expect(result.openai).toEqual({ daily: null, weekly: null, monthly: null });
expect(result.gemini).toEqual({ daily: null, weekly: null, monthly: null });
expect(result.antigravity).toEqual({ daily: null, weekly: null, monthly: null });
});
it("无参数时返回全 4 平台全 null", () => {
const result = normalizePlatformQuotasMap();
expect(Object.keys(result)).toHaveLength(4);
for (const v of Object.values(result)) {
expect(v).toEqual({ daily: null, weekly: null, monthly: null });
}
});
it("非 number 类型的值归一化为 null", () => {
const result = normalizePlatformQuotasMap({
anthropic: { daily: "50" as unknown as number, weekly: undefined as unknown as number, monthly: null },
});
expect(result.anthropic).toEqual({ daily: null, weekly: null, monthly: null });
});
});
describe("sanitizePlatformQuotasMap", () => {
it("保留合法的正数和零值", () => {
const result = sanitizePlatformQuotasMap({
anthropic: { daily: 10.5, weekly: 0, monthly: null },
});
expect(result.anthropic?.daily).toBe(10.5);
expect(result.anthropic?.weekly).toBe(0);
expect(result.anthropic?.monthly).toBe(null);
});
it("空字符串(v-model.number 空输入)清洗为 null", () => {
const result = sanitizePlatformQuotasMap({
anthropic: { daily: "" as unknown as number, weekly: null, monthly: null },
});
expect(result.anthropic?.daily).toBe(null);
});
it("负数清洗为 null", () => {
const result = sanitizePlatformQuotasMap({
openai: { daily: -1, weekly: null, monthly: null },
});
expect(result.openai?.daily).toBe(null);
});
it("NaN/Infinity 清洗为 null", () => {
const result = sanitizePlatformQuotasMap({
gemini: { daily: NaN, weekly: Infinity, monthly: null },
});
expect(result.gemini?.daily).toBe(null);
expect(result.gemini?.weekly).toBe(null);
});
it("缺失平台填充为全 null", () => {
const result = sanitizePlatformQuotasMap({});
expect(Object.keys(result)).toHaveLength(4);
for (const v of Object.values(result)) {
expect(v).toEqual({ daily: null, weekly: null, monthly: null });
}
});
});