From 402829c198ccb7c19ede0379d58fa64d8fa71408 Mon Sep 17 00:00:00 2001 From: sushichan044 Date: Fri, 7 Mar 2025 17:53:27 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20null=20=E3=81=AE=E3=83=8F=E3=83=B3?= =?UTF-8?q?=E3=83=89=E3=83=AA=E3=83=B3=E3=82=B0=E3=81=8C=E7=94=98=E3=81=8B?= =?UTF-8?q?=E3=81=A3=E3=81=9F=E3=81=AE=E3=81=A7=E6=B2=BB=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/feature/search/pagination.test.ts | 19 +++++++++++++++++++ app/feature/search/pagination.ts | 12 ++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/app/feature/search/pagination.test.ts b/app/feature/search/pagination.test.ts index ed71d05..e2939b6 100644 --- a/app/feature/search/pagination.test.ts +++ b/app/feature/search/pagination.test.ts @@ -82,4 +82,23 @@ describe("buildPaginationMeta", () => { expect(prevQuery).toBe(null); }); + + test("API 修正前ロジック: 次のページが存在しない場合に next が null になる", () => { + const currentQuery = { + post_includes_text: "地震", + limit: 10, + offset: 10, + } satisfies z.infer; + + // API が limit, offset 以外のクエリパラメータを削除してしまう挙動を再現 + const currentBrokenMeta = { + next: null, + prev: "https://example.com/api/v1/data/search?offset=0&limit=10", + } satisfies PaginationMeta; + + const fixedMeta = buildPaginationMeta(currentBrokenMeta, currentQuery); + const nextQuery = fixedMeta.next ? getQuery(fixedMeta.next) : null; + + expect(nextQuery).toBe(null); + }); }); diff --git a/app/feature/search/pagination.ts b/app/feature/search/pagination.ts index 2d8ab2c..b9a3bf1 100644 --- a/app/feature/search/pagination.ts +++ b/app/feature/search/pagination.ts @@ -42,9 +42,13 @@ export const buildPaginationMeta = ( const baseUrl = stringifyParsedURL(url); return { - next: withQuery(baseUrl, { ...rest, limit, offset: nextOffset }), - prev: isFirstPage - ? null - : withQuery(baseUrl, { ...rest, limit, offset: prevOffset }), + next: + meta.next != null + ? withQuery(baseUrl, { ...rest, limit, offset: nextOffset }) + : null, + prev: + isFirstPage || meta.prev == null + ? null + : withQuery(baseUrl, { ...rest, limit, offset: prevOffset }), }; }; From 94652d8a5aaf3d5302b27a10a3c3e4cd61cdd52c Mon Sep 17 00:00:00 2001 From: sushichan044 Date: Fri, 7 Mar 2025 17:53:42 +0900 Subject: [PATCH 2/2] =?UTF-8?q?test:=20=E5=90=8C=E3=81=98=E3=82=AF?= =?UTF-8?q?=E3=82=A8=E3=83=AA=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=82=92=202=20=E5=9B=9E=E4=BB=A5=E4=B8=8A=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AE=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/feature/search/pagination.test.ts | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/app/feature/search/pagination.test.ts b/app/feature/search/pagination.test.ts index e2939b6..dbb1dc7 100644 --- a/app/feature/search/pagination.test.ts +++ b/app/feature/search/pagination.test.ts @@ -101,4 +101,33 @@ describe("buildPaginationMeta", () => { expect(nextQuery).toBe(null); }); + + test("API修正前ロジック: 同じクエリパラメータが 2 回以上指定されていてもそのまま処理できる", () => { + const currentQuery = { + note_status: ["CURRENTLY_RATED_HELPFUL", "NEEDS_MORE_RATINGS"], + limit: 10, + offset: 10, + } satisfies z.infer; + + const currentBrokenMeta = { + // API が note_status を複数回指定した際、最後のもの以外を削除してしまう挙動を再現 + next: "https://example.com/api/v1/data/search?note_status=NEEDS_MORE_RATINGS&limit=10&offset=20", + prev: "https://example.com/api/v1/data/search?note_status=NEEDS_MORE_RATINGS&limit=10&offset=0", + } satisfies PaginationMeta; + + const fixedMeta = buildPaginationMeta(currentBrokenMeta, currentQuery); + const prevQuery = fixedMeta.prev ? getQuery(fixedMeta.prev) : null; + const nextQuery = fixedMeta.next ? getQuery(fixedMeta.next) : null; + + expect(prevQuery).toStrictEqual({ + note_status: ["CURRENTLY_RATED_HELPFUL", "NEEDS_MORE_RATINGS"], + limit: "10", + offset: "0", + }); + expect(nextQuery).toStrictEqual({ + note_status: ["CURRENTLY_RATED_HELPFUL", "NEEDS_MORE_RATINGS"], + limit: "10", + offset: "20", + }); + }); });