aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Media/Anime/Airing/classify.test.ts
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-03-03 22:54:56 -0800
committerFuwn <[email protected]>2026-03-03 22:54:56 -0800
commit07a00c3ea35b4df7eb23275704dd26f842db76be (patch)
tree097ee52433779830aa4ddd6666e85ed42878cfc9 /src/lib/Media/Anime/Airing/classify.test.ts
parentrefactor(effect): migrate svelte json hotspots to typed decoders (diff)
downloaddue.moe-07a00c3ea35b4df7eb23275704dd26f842db76be.tar.xz
due.moe-07a00c3ea35b4df7eb23275704dd26f842db76be.zip
fix(anime): align due cover rendering with due classification
Diffstat (limited to 'src/lib/Media/Anime/Airing/classify.test.ts')
-rw-r--r--src/lib/Media/Anime/Airing/classify.test.ts94
1 files changed, 93 insertions, 1 deletions
diff --git a/src/lib/Media/Anime/Airing/classify.test.ts b/src/lib/Media/Anime/Airing/classify.test.ts
index fb7f2c8f..b05be83b 100644
--- a/src/lib/Media/Anime/Airing/classify.test.ts
+++ b/src/lib/Media/Anime/Airing/classify.test.ts
@@ -6,7 +6,10 @@ import {
hasDueEpisodes,
getAnimeEpisodeState,
} from "$lib/Media/Anime/Airing/classify";
-import { injectAiringTime } from "$lib/Media/Anime/Airing/Subtitled/match";
+import {
+ clearInjectAiringTimeCache,
+ injectAiringTime,
+} from "$lib/Media/Anime/Airing/Subtitled/match";
import type { SubsPlease } from "$lib/Media/Anime/Airing/Subtitled/subsPlease";
const toScheduleTime = (epochSeconds: number) => {
@@ -196,4 +199,93 @@ describe("injectAiringTime cache safety", () => {
expect(typeof second.nextAiringEpisode?.airingAt).toBe("number");
expect(typeof second.nextAiringEpisode?.nativeAiringAt).toBe("number");
});
+
+ it("does not reuse stale progress across cache hits for media 194028", () => {
+ clearInjectAiringTimeCache();
+
+ const media = baseMedia(194028);
+ const subtitledAiringAt = Math.floor(Date.now() / 1000) + 24 * 60 * 60;
+ const nativeAiringAt = subtitledAiringAt + 12 * 60 * 60;
+ const nativeAiringDate = new Date(nativeAiringAt * 1000);
+ const airingDay = nativeAiringDate.toLocaleString("en-US", {
+ weekday: "long",
+ });
+ const subsPlease = {
+ tz: "America/Los_Angeles",
+ schedule: {
+ [airingDay]: [
+ {
+ title: media.title.romaji,
+ page: "",
+ image_url: "",
+ time: toScheduleTime(subtitledAiringAt),
+ },
+ ],
+ },
+ } as unknown as SubsPlease;
+
+ media.nextAiringEpisode = {
+ episode: 10,
+ airingAt: nativeAiringAt,
+ };
+
+ settings.setKey("displayNativeCountdown", false);
+
+ const caughtUp = {
+ ...media,
+ mediaListEntry: {
+ ...(media.mediaListEntry || {}),
+ progress: 9,
+ },
+ } as Media;
+ const behind = {
+ ...media,
+ mediaListEntry: {
+ ...(media.mediaListEntry || {}),
+ progress: 8,
+ },
+ } as Media;
+ const cachedCaughtUp = injectAiringTime(caughtUp, subsPlease);
+ const updatedBehind = injectAiringTime(behind, subsPlease);
+
+ expect(hasDueEpisodes(cachedCaughtUp)).toBe(false);
+ expect(hasDueEpisodes(updatedBehind)).toBe(true);
+ });
+
+ it("does not let caller mutate cached mediaListEntry progress", () => {
+ clearInjectAiringTimeCache();
+
+ const media = baseMedia(194028);
+ const subtitledAiringAt = Math.floor(Date.now() / 1000) + 24 * 60 * 60;
+ const nativeAiringAt = subtitledAiringAt + 12 * 60 * 60;
+ const nativeAiringDate = new Date(nativeAiringAt * 1000);
+ const airingDay = nativeAiringDate.toLocaleString("en-US", {
+ weekday: "long",
+ });
+ const subsPlease = {
+ tz: "America/Los_Angeles",
+ schedule: {
+ [airingDay]: [
+ {
+ title: media.title.romaji,
+ page: "",
+ image_url: "",
+ time: toScheduleTime(subtitledAiringAt),
+ },
+ ],
+ },
+ } as unknown as SubsPlease;
+
+ settings.setKey("displayNativeCountdown", false);
+
+ const originalProgress = media.mediaListEntry?.progress || 0;
+ const first = injectAiringTime(media, subsPlease);
+
+ if (first.mediaListEntry) first.mediaListEntry.progress = 999;
+
+ const second = injectAiringTime(media, subsPlease);
+
+ expect(media.mediaListEntry?.progress).toBe(originalProgress);
+ expect(second.mediaListEntry?.progress).toBe(originalProgress);
+ });
});