feat(web): simplify subscription and manual download flows and sync UHD styles
This commit is contained in:
1 parent
27c0f27434
commit
c3c4456913
33 files changed
+1083
-633
No files matched your search
@@ -15,7 +15,6 @@ import {
|
||||
seasonLabel,
|
||||
shiftMonth,
|
||||
slotBadge,
|
||||
upgradeOf,
|
||||
} from "./model.ts";
|
||||
|
||||
const slot = (x: Partial<SubscriptionSlotSummary>): SubscriptionSlotSummary => ({
|
||||
@@ -86,15 +85,44 @@ describe("覆盖矩阵格", () => {
|
||||
expect(moveItem(["a", "b", "c"], 2, 0)).toEqual(["c", "a", "b"]);
|
||||
expect(moveItem(["a", "b"], 0, 5)).toEqual(["a", "b"]);
|
||||
});
|
||||
it("升级策略取自收录版本", () => {
|
||||
expect(upgradeOf([{ upgradeThreshold: {} }], "series")).toBe("off");
|
||||
expect(upgradeOf([{ upgradeThreshold: { enabled: true, mode: "full_pack" } }], "series")).toBe("full_pack");
|
||||
expect(upgradeOf([{ upgradeThreshold: { enabled: true } }], "movie")).toBe("movie");
|
||||
});
|
||||
});
|
||||
|
||||
describe("表单 ↔ params", () => {
|
||||
it("保留未知键,空值不写,只在改动时带 best_version / total_episode", () => {
|
||||
it("普通编辑不重建补全配置;只改补全开关也保留预算精度,明确修改才更新", () => {
|
||||
const params = {
|
||||
autoFill: "on",
|
||||
fillBudget: { unitsPerDay: 2, bytesPerDay: Math.round(1.25 * 1024 ** 3), future: true },
|
||||
};
|
||||
const sub = {
|
||||
mediaKind: "movie",
|
||||
seasonScope: "current_season",
|
||||
mode: "once",
|
||||
priority: "tracking",
|
||||
seasonUnitId: null,
|
||||
policyRevisionId: null,
|
||||
params,
|
||||
} as unknown as Subscription;
|
||||
const d = draftFromSubscription(sub);
|
||||
const ordinary = draftToParams({ ...d, searchIntervalHours: "6" }, params, {
|
||||
totalChanged: false,
|
||||
autoFillChanged: false,
|
||||
});
|
||||
expect(ordinary.params).toEqual({ ...params, searchIntervalHours: 6 });
|
||||
const modeOnly = draftToParams({ ...d, autoFill: "off" }, params, { totalChanged: false, autoFillChanged: true });
|
||||
expect(modeOnly.params).toEqual({ ...params, autoFill: "off" });
|
||||
const changed = draftToParams({ ...d, gbPerDay: "2", unitsPerDay: "" }, params, {
|
||||
totalChanged: false,
|
||||
autoFillChanged: true,
|
||||
});
|
||||
expect(changed.params.fillBudget).toEqual({ bytesPerDay: 2 * 1024 ** 3, future: true });
|
||||
const cleared = draftToParams(
|
||||
{ ...d, gbPerDay: "", unitsPerDay: "" },
|
||||
{ ...params, fillBudget: { unitsPerDay: 2, bytesPerDay: params.fillBudget.bytesPerDay } },
|
||||
{ totalChanged: false, autoFillChanged: true },
|
||||
);
|
||||
expect(cleared.params.fillBudget).toBeUndefined();
|
||||
});
|
||||
it("保留未知键,空值不写,只在改动时带 total_episode", () => {
|
||||
const d = {
|
||||
...emptyDraft("series"),
|
||||
siteIds: ["x"],
|
||||
@@ -104,12 +132,11 @@ describe("表单 ↔ params", () => {
|
||||
unitsPerDay: "2",
|
||||
gbPerDay: "1.5",
|
||||
total: "12",
|
||||
upgrade: "full_pack" as const,
|
||||
};
|
||||
const { params, errors } = draftToParams(
|
||||
d,
|
||||
{ custom: 1, keywords: ["旧"] },
|
||||
{ upgradeChanged: true, totalChanged: true },
|
||||
{ totalChanged: true, autoFillChanged: true },
|
||||
);
|
||||
expect(errors).toEqual({});
|
||||
expect(params).toEqual({
|
||||
@@ -121,10 +148,8 @@ describe("表单 ↔ params", () => {
|
||||
manual_total_episode: false,
|
||||
autoFill: "off",
|
||||
fillBudget: { unitsPerDay: 2, bytesPerDay: Math.round(1.5 * 1024 ** 3) },
|
||||
best_version: true,
|
||||
best_version_full: true,
|
||||
});
|
||||
const same = draftToParams(d, {}, { upgradeChanged: false, totalChanged: false }).params;
|
||||
const same = draftToParams(d, {}, { totalChanged: false, autoFillChanged: true }).params;
|
||||
expect(same.best_version).toBeUndefined();
|
||||
expect(same.total_episode).toBeUndefined();
|
||||
});
|
||||
@@ -132,7 +157,7 @@ describe("表单 ↔ params", () => {
|
||||
const { errors } = draftToParams(
|
||||
{ ...emptyDraft("series"), episodeStart: "5", episodeEnd: "2" },
|
||||
{},
|
||||
{ upgradeChanged: false, totalChanged: false },
|
||||
{ totalChanged: false, autoFillChanged: true },
|
||||
);
|
||||
expect(errors.episodeEnd).toBeTruthy();
|
||||
});
|
||||
@@ -151,40 +176,45 @@ describe("表单 ↔ params", () => {
|
||||
keywords: ["a", "b"],
|
||||
},
|
||||
} as unknown as Subscription;
|
||||
const d = draftFromSubscription(sub, "per_unit");
|
||||
const d = draftFromSubscription(sub);
|
||||
expect(d.episodeStart).toBe("2");
|
||||
expect(d.autoFill).toBe("on");
|
||||
expect(d.gbPerDay).toBe("2");
|
||||
expect(d.keywords).toBe("a\nb");
|
||||
expect(d.upgrade).toBe("per_unit");
|
||||
});
|
||||
it("质量预设:草稿 ↔ params;未知值回填为空", () => {
|
||||
const d = { ...emptyDraft("movie"), resolution: "4k" as const, source: "remux" as const, effect: "dv" as const };
|
||||
const { params } = draftToParams(
|
||||
d,
|
||||
{ resolution: "720p", effect: "sdr" },
|
||||
{ upgradeChanged: false, totalChanged: false },
|
||||
);
|
||||
expect(params).toEqual({ resolution: "4k", source: "remux", effect: "dv" });
|
||||
const cleared = draftToParams(
|
||||
emptyDraft("movie"),
|
||||
{ resolution: "720p" },
|
||||
{ upgradeChanged: false, totalChanged: false },
|
||||
);
|
||||
expect(cleared.params.resolution).toBeUndefined();
|
||||
const back = draftFromSubscription(
|
||||
{
|
||||
mediaKind: "movie",
|
||||
seasonScope: "current_season",
|
||||
mode: "once",
|
||||
priority: "tracking",
|
||||
seasonUnitId: null,
|
||||
policyRevisionId: null,
|
||||
params: { resolution: "1080p", source: "bogus", effect: "hdr" },
|
||||
} as unknown as Subscription,
|
||||
"off",
|
||||
);
|
||||
expect([back.resolution, back.source, back.effect]).toEqual(["1080p", "", "hdr"]);
|
||||
it("编辑跟踪与下载信息保留旧收录规则,不再生成统一洗版指令", () => {
|
||||
const legacy = {
|
||||
resolution: "4k",
|
||||
source: "uhd",
|
||||
effect: "atmos",
|
||||
ruleGroupIds: ["quality"],
|
||||
future: { keep: true },
|
||||
};
|
||||
const sub = {
|
||||
mediaKind: "movie",
|
||||
seasonScope: "current_season",
|
||||
mode: "once",
|
||||
priority: "tracking",
|
||||
seasonUnitId: null,
|
||||
policyRevisionId: null,
|
||||
params: legacy,
|
||||
} as unknown as Subscription;
|
||||
const draft = draftFromSubscription(sub);
|
||||
const { params, errors } = draftToParams({ ...draft, siteIds: ["site"], searchIntervalHours: "6" }, legacy, {
|
||||
totalChanged: false,
|
||||
autoFillChanged: true,
|
||||
});
|
||||
expect(errors).toEqual({});
|
||||
expect(params).toEqual({ ...legacy, siteIds: ["site"], searchIntervalHours: 6 });
|
||||
expect(params.best_version).toBeUndefined();
|
||||
expect(params.best_version_full).toBeUndefined();
|
||||
const cleared = draftToParams(draft, legacy, {
|
||||
totalChanged: false,
|
||||
autoFillChanged: false,
|
||||
clearQualityPreset: true,
|
||||
});
|
||||
expect(cleared.params).toEqual({ ruleGroupIds: ["quality"], future: { keep: true } });
|
||||
expect(draftToParams(emptyDraft("movie"), {}, { totalChanged: false, autoFillChanged: true }).params).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user