121 lines
2.9 KiB
TypeScript
121 lines
2.9 KiB
TypeScript
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),
|
|
);
|
|
});
|
|
});
|