From 775bf78f54d421fdef3024514ca3a9d61ba6e03e Mon Sep 17 00:00:00 2001 From: Flaminel Date: Thu, 22 Oct 2026 12:59:27 +0300 Subject: [PATCH] changed selection e2e to arr search history --- .../seeker-selection.api.spec.ts | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/e2e/tests/live-arr-fast/seeker-selection.api.spec.ts b/e2e/tests/live-arr-fast/seeker-selection.api.spec.ts index aa42f4f9..9f8b1c30 100644 --- a/e2e/tests/live-arr-fast/seeker-selection.api.spec.ts +++ b/e2e/tests/live-arr-fast/seeker-selection.api.spec.ts @@ -29,6 +29,7 @@ interface Candidate { id: number; title: string; added: string; + lastSearchTime: string | null; } async function monitorEveryMovie(): Promise { @@ -44,9 +45,20 @@ async function monitorEveryMovie(): Promise { id: movie.id as number, title: movie.title as string, added: movie.added as string, + lastSearchTime: (movie.lastSearchTime as string | undefined) ?? null, })); } +function searchedAt(lastSearchTime: string | null | undefined): number { + return lastSearchTime ? Date.parse(lastSearchTime) : 0; +} + +/** Every title tied for the oldest search time. */ +function oldestSearched(candidates: Candidate[]): string[] { + const oldest = Math.min(...candidates.map((c) => searchedAt(c.lastSearchTime))); + return candidates.filter((c) => searchedAt(c.lastSearchTime) === oldest).map((c) => c.title); +} + test.describe('Seeker selection strategies', () => { let library: Array> = []; @@ -79,7 +91,7 @@ test.describe('Seeker selection strategies', () => { expect(event?.itemTitle).toBe(newest.title); }); - test('oldest search first makes the same choice every time', async ({ api }) => { + test("oldest search first follows the arr's last search time", async ({ api }) => { test.setTimeout(180_000); const candidates = await monitorEveryMovie(); @@ -91,15 +103,27 @@ test.describe('Seeker selection strategies', () => { await triggerSeeker(api); await expect.poll(async () => (await listSearchEvents(api, firstRun)).length, { timeout: SETTLE_MS }).toBe(1); const firstChoice = (await firstSearchEvent(api, firstRun))?.itemTitle; + expect(oldestSearched(candidates)).toContain(firstChoice); - // A fresh instance starts with no search history, so the choice is made from scratch. + const picked = candidates.find((c) => c.title === firstChoice)!; + await expect + .poll( + async () => searchedAt((await RADARR.arr.get>(`/api/v3/movie/${picked.id}`)).lastSearchTime as string), + { timeout: SETTLE_MS }, + ) + .toBeGreaterThan(searchedAt(picked.lastSearchTime)); + + // A fresh instance has no Seeker history, so only the arr's search times order the movies. await teardownInstances(api); + const searchedOnce = await monitorEveryMovie(); const secondRun = await arrangeInstance(api, RADARR, strategy); await triggerSeeker(api); await expect.poll(async () => (await listSearchEvents(api, secondRun)).length, { timeout: SETTLE_MS }).toBe(1); + const secondChoice = (await firstSearchEvent(api, secondRun))?.itemTitle; - expect((await firstSearchEvent(api, secondRun))?.itemTitle).toBe(firstChoice); + expect(oldestSearched(searchedOnce)).toContain(secondChoice); + expect(secondChoice).not.toBe(firstChoice); }); test('a cycle covers every candidate before repeating one', async ({ api }) => {