Merge branch 'phase-6-coverage-expansion'
This commit is contained in:
commit
7ad1e5133e
120
apps/mobile/src/api/__tests__/notifications.test.ts
Normal file
120
apps/mobile/src/api/__tests__/notifications.test.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
|
||||||
|
import {
|
||||||
|
deleteNotification,
|
||||||
|
fetchNotifications,
|
||||||
|
fetchUnreadCount,
|
||||||
|
markAllAsRead,
|
||||||
|
markAsRead,
|
||||||
|
savePushToken,
|
||||||
|
} from "../notifications";
|
||||||
|
import { apiClient, withAuth } from "../client";
|
||||||
|
|
||||||
|
jest.mock("../client", () => ({
|
||||||
|
apiClient: {
|
||||||
|
get: jest.fn(),
|
||||||
|
put: jest.fn(),
|
||||||
|
post: jest.fn(),
|
||||||
|
delete: jest.fn(),
|
||||||
|
},
|
||||||
|
withAuth: jest.fn((token?: string | null) =>
|
||||||
|
token ? { headers: { Authorization: `Bearer ${token}` } } : {},
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("notifications api", () => {
|
||||||
|
const getMock = apiClient.get as any;
|
||||||
|
const putMock = apiClient.put as any;
|
||||||
|
const postMock = apiClient.post as any;
|
||||||
|
const deleteMock = apiClient.delete as any;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns notifications and normalizes createdAt", async () => {
|
||||||
|
getMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
id: "n_1",
|
||||||
|
userId: "u_1",
|
||||||
|
title: "Hi",
|
||||||
|
message: "Welcome",
|
||||||
|
type: "system",
|
||||||
|
read: false,
|
||||||
|
createdAt: "2026-03-29T10:00:00.000Z",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await fetchNotifications("token_1");
|
||||||
|
|
||||||
|
expect(result).toHaveLength(1);
|
||||||
|
expect(result[0].createdAt).toBeInstanceOf(Date);
|
||||||
|
expect(withAuth).toHaveBeenCalledWith("token_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns unread count from response wrapper", async () => {
|
||||||
|
getMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
data: { count: 3 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const count = await fetchUnreadCount(null);
|
||||||
|
expect(count).toBe(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("marks notification as read", async () => {
|
||||||
|
putMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
id: "n_1",
|
||||||
|
userId: "u_1",
|
||||||
|
title: "Hi",
|
||||||
|
message: "Welcome",
|
||||||
|
type: "system",
|
||||||
|
read: true,
|
||||||
|
createdAt: "2026-03-29T10:00:00.000Z",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await markAsRead("n_1", "token_1");
|
||||||
|
|
||||||
|
expect(result.read).toBe(true);
|
||||||
|
expect(putMock).toHaveBeenCalledWith(
|
||||||
|
"/api/notifications/n_1",
|
||||||
|
{},
|
||||||
|
expect.any(Object),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls mark-all, delete and save-token endpoints", async () => {
|
||||||
|
postMock.mockResolvedValue({});
|
||||||
|
deleteMock.mockResolvedValue({});
|
||||||
|
|
||||||
|
await markAllAsRead("token_1");
|
||||||
|
await deleteNotification("n_2", "token_1");
|
||||||
|
await savePushToken("expo-token", "android", "token_1");
|
||||||
|
|
||||||
|
expect(postMock).toHaveBeenCalledWith(
|
||||||
|
"/api/notifications/mark-all-read",
|
||||||
|
{},
|
||||||
|
expect.any(Object),
|
||||||
|
);
|
||||||
|
expect(deleteMock).toHaveBeenCalledWith(
|
||||||
|
"/api/notifications/n_2",
|
||||||
|
expect.any(Object),
|
||||||
|
);
|
||||||
|
expect(postMock).toHaveBeenCalledWith(
|
||||||
|
"/api/notifications/save-token",
|
||||||
|
{ expoPushToken: "expo-token", deviceType: "android" },
|
||||||
|
expect.any(Object),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user