From ea038c39e64ff1cc053c22bdaf8802e53de927e0 Mon Sep 17 00:00:00 2001 From: abhinavgautam01 Date: Sun, 6 Sep 2026 12:23:41 +0530 Subject: [PATCH] Fix notification history item validation --- models/NotificationHistoryResponse.ts | 4 +-- tests/unit-tests/api_client.test.ts | 41 ++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/models/NotificationHistoryResponse.ts b/models/NotificationHistoryResponse.ts index 61599f4..2eac080 100644 --- a/models/NotificationHistoryResponse.ts +++ b/models/NotificationHistoryResponse.ts @@ -1,6 +1,6 @@ // Copyright (c) 2023 Apple Inc. Licensed under MIT License. -import { NotificationHistoryResponseItem } from "./NotificationHistoryResponseItem"; +import { NotificationHistoryResponseItem, NotificationHistoryResponseItemValidator } from "./NotificationHistoryResponseItem"; import { Validator } from "./Validator"; /** @@ -34,7 +34,7 @@ export interface NotificationHistoryResponse { export class NotificationHistoryResponseValidator implements Validator { - static readonly notificationHistoryResponseItemValidator = new NotificationHistoryResponseValidator() + static readonly notificationHistoryResponseItemValidator = new NotificationHistoryResponseItemValidator() validate(obj: any): obj is NotificationHistoryResponse { if ((typeof obj['paginationToken'] !== 'undefined') && !(typeof obj['paginationToken'] === "string" || obj['paginationToken'] instanceof String)) { return false diff --git a/tests/unit-tests/api_client.test.ts b/tests/unit-tests/api_client.test.ts index d575ffd..6710a5f 100644 --- a/tests/unit-tests/api_client.test.ts +++ b/tests/unit-tests/api_client.test.ts @@ -307,6 +307,45 @@ describe('The api client ', () => { expect(expectedNotificationHistory).toStrictEqual(notificationHistoryResponse.notificationHistory) }) + it.each([ + { field: 'signedPayload', item: { signedPayload: 123 } }, + { field: 'sendAttempts', item: { sendAttempts: 'not-an-array' } }, + { field: 'attemptDate', item: { sendAttempts: [{ attemptDate: 'not-a-number' }] } }, + { field: 'sendAttemptResult', item: { sendAttempts: [{ sendAttemptResult: 123 }] } }, + { + field: 'later send attempt', + item: { sendAttempts: [{ sendAttemptResult: 'SUCCESS' }, { attemptDate: 'not-a-number' }] } + } + ])('rejects notification history with invalid $field', async ({ item }) => { + const body = { notificationHistory: [{ signedPayload: 'valid_payload' }, item] } + const client = getAppStoreServerAPIClient(JSON.stringify(body), 200, () => {}) + + await expect(client.getNotificationHistory(null, {})).rejects.toThrow('Unexpected response body format') + }) + + it.each([ + { description: 'omitted history', body: {} }, + { description: 'empty history', body: { notificationHistory: [] } }, + { description: 'omitted item fields', body: { notificationHistory: [{}] } }, + { + description: 'omitted send attempts', + body: { notificationHistory: [{ signedPayload: 'signed_payload' }] } + }, + { description: 'empty send attempts', body: { notificationHistory: [{ sendAttempts: [] }] } }, + { + description: 'omitted send attempt fields', + body: { notificationHistory: [{ sendAttempts: [{}] }] } + }, + { + description: 'an unknown send attempt result', + body: { notificationHistory: [{ sendAttempts: [{ sendAttemptResult: 'FUTURE_RESULT' }] }] } + } + ])('accepts notification history with $description', async ({ body }) => { + const client = getAppStoreServerAPIClient(JSON.stringify(body), 200, () => {}) + + await expect(client.getNotificationHistory(null, {})).resolves.toStrictEqual(body) + }) + it('calls getTransactionHistory V1', async () => { const client = getClientWithBody("tests/resources/models/transactionHistoryResponse.json", (path: string, parsedQueryParameters: URLSearchParams, method: string, requestBody: string | Buffer | undefined, headers: { [key: string]: string; }) => { expect("GET").toBe(method) @@ -1144,4 +1183,4 @@ describe('The api client ', () => { await client.finishTransaction("1234"); }) -}) \ No newline at end of file +})