diff --git a/tests/sdk.test.ts b/tests/sdk.test.ts index 96c40b3..45a65bf 100644 --- a/tests/sdk.test.ts +++ b/tests/sdk.test.ts @@ -1,5 +1,6 @@ import { NotificationAPIClientSDK } from '../lib/client'; import { api } from '../lib/api'; +import { PostUserRequest } from '../lib/interfaces'; // Mock the fetch function global.fetch = jest.fn(); @@ -42,7 +43,146 @@ describe('NotificationAPIClientSDK', () => { expect.any(Object) ); }); + test('getInAppNotifications should correctly reduce oldestReceived', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({ + notifications: [ + { id: '1', date: '2023-01-02T00:00:00Z' }, + { id: '2', date: '2023-01-01T00:00:00Z' }, + { id: '3', date: '2023-01-03T00:00:00Z' } + ] + }) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + + const result = await sdk.getInAppNotifications({ + before: '2023-01-04T00:00:00Z' + }); + + expect(result.oldestReceived).toBe('2023-01-01T00:00:00Z'); + }); + test('updateInAppNotifications should set archived to null when archived is false', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({}) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + + await sdk.updateInAppNotifications({ + ids: ['notification1', 'notification2'], + archived: false + }); + + expect(global.fetch).toHaveBeenCalledWith( + 'https://api.notificationapi.com/testClient/users/testUser/notifications/INAPP_WEB', + expect.objectContaining({ + method: 'PATCH', + body: JSON.stringify({ + trackingIds: ['notification1', 'notification2'], + archived: null + }), + headers: { + Authorization: expect.any(String) + } + }) + ); + }); + test('updateInAppNotifications should set clicked to null when clicked is false', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({}) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + + await sdk.updateInAppNotifications({ + ids: ['notification1', 'notification2'], + clicked: false + }); + expect(global.fetch).toHaveBeenCalledWith( + 'https://api.notificationapi.com/testClient/users/testUser/notifications/INAPP_WEB', + expect.objectContaining({ + method: 'PATCH', + body: JSON.stringify({ + trackingIds: ['notification1', 'notification2'], + clicked: null + }), + headers: { + Authorization: expect.any(String) + } + }) + ); + }); + test('updateInAppNotifications should set opened to current date when opened is true', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({}) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + + await sdk.updateInAppNotifications({ + ids: ['notification1', 'notification2'], + opened: true + }); + + expect(global.fetch).toHaveBeenCalledWith( + 'https://api.notificationapi.com/testClient/users/testUser/notifications/INAPP_WEB', + expect.objectContaining({ + method: 'PATCH', + body: expect.stringContaining('"opened":"'), + headers: { + Authorization: expect.any(String) + } + }) + ); + }); + test('updateInAppNotifications should set opened to null when opened is false', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({}) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + + await sdk.updateInAppNotifications({ + ids: ['notification1', 'notification2'], + opened: false + }); + + expect(global.fetch).toHaveBeenCalledWith( + 'https://api.notificationapi.com/testClient/users/testUser/notifications/INAPP_WEB', + expect.objectContaining({ + method: 'PATCH', + body: JSON.stringify({ + trackingIds: ['notification1', 'notification2'], + opened: null + }), + headers: { + Authorization: expect.any(String) + } + }) + ); + }); test('updateInAppNotifications should call api with correct parameters', async () => { const mockResponse = { json: jest.fn().mockResolvedValue({}) @@ -132,6 +272,72 @@ describe('NotificationAPIClientSDK', () => { }) ); }); + + test('identify should call api with correct parameters', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({ preferences: [] }) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + const params: PostUserRequest = { + id: 'testUser', + email: 'userTestEmail@notificationapi.com' + }; + await sdk.identify(params); + + expect(global.fetch).toHaveBeenCalledWith( + expect.stringContaining( + 'https://api.notificationapi.com/testClient/users/testUser/' + ), + expect.objectContaining({ + method: 'POST', + body: JSON.stringify(params) + }) + ); + }); + test('identify should not call api with wrong parameters', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({ preferences: [] }) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + const params: PostUserRequest = { + id: 'testUser2', + email: 'userTestEmail@notificationapi.com' + }; + await expect(sdk.identify(params)).rejects.toThrow( + 'The id in the parameters does not match the initialized userId.' + ); + }); + test('getUserAccountMetadata should call api with correct parameters', async () => { + const mockResponse = { + json: jest.fn().mockResolvedValue({ preferences: [] }) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const sdk = NotificationAPIClientSDK.init({ + userId: 'testUser', + clientId: 'testClient' + }); + await sdk.getUserAccountMetadata(); + + expect(global.fetch).toHaveBeenCalledWith( + expect.stringContaining( + 'https://api.notificationapi.com/testClient/users/testUser/account_metadata' + ), + expect.objectContaining({ + method: 'GET' + }) + ); + }); }); describe('api function', () => { @@ -180,4 +386,20 @@ describe('api function', () => { expect(result).toEqual('error'); }); + test('should return undefined if response is not JSON', async () => { + const mockResponse = { + json: jest.fn().mockRejectedValue(new Error('Invalid JSON')) + }; + (global.fetch as jest.Mock).mockResolvedValue(mockResponse); + + const result = await api( + 'GET', + 'api.notificationapi.com', + 'testResource', + 'testClient', + 'testUser' + ); + + expect(result).toBeUndefined(); + }); });