add mobile api unit tests for gyms and recommendations
This commit is contained in:
parent
80110acbf7
commit
aa662a9b74
@ -1,11 +1,19 @@
|
|||||||
import 'react-native-gesture-handler/jestSetup'
|
try {
|
||||||
|
require("react-native-gesture-handler/jestSetup");
|
||||||
|
} catch {
|
||||||
|
// Package may be absent in minimal test environments
|
||||||
|
}
|
||||||
|
|
||||||
jest.mock('react-native-reanimated', () => {
|
jest.mock(
|
||||||
const Reanimated = require('react-native-reanimated/mock')
|
"react-native-reanimated",
|
||||||
Reanimated.default.call = () => {}
|
() => {
|
||||||
return Reanimated
|
const Reanimated = require("react-native-reanimated/mock");
|
||||||
})
|
Reanimated.default.call = () => {};
|
||||||
|
return Reanimated;
|
||||||
|
},
|
||||||
|
{ virtual: true },
|
||||||
|
);
|
||||||
|
|
||||||
jest.mock('@expo/vector-icons', () => ({
|
jest.mock("@expo/vector-icons", () => ({
|
||||||
Ionicons: 'Ionicons',
|
Ionicons: "Ionicons",
|
||||||
}))
|
}));
|
||||||
|
|||||||
55
apps/mobile/src/api/__tests__/gyms.test.ts
Normal file
55
apps/mobile/src/api/__tests__/gyms.test.ts
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
|
||||||
|
import { gymsApi } from "../gyms";
|
||||||
|
import { apiClient, withAuth } from "../client";
|
||||||
|
|
||||||
|
jest.mock("../client", () => ({
|
||||||
|
apiClient: {
|
||||||
|
get: jest.fn(),
|
||||||
|
patch: jest.fn(),
|
||||||
|
},
|
||||||
|
withAuth: jest.fn((token?: string | null) =>
|
||||||
|
token ? { headers: { Authorization: `Bearer ${token}` } } : {},
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("gymsApi", () => {
|
||||||
|
const getMock = apiClient.get as any;
|
||||||
|
const patchMock = apiClient.patch as any;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns array payload from getGyms", async () => {
|
||||||
|
getMock.mockResolvedValue({
|
||||||
|
data: [{ id: "gym_1", name: "Gym One" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await gymsApi.getGyms("token_1");
|
||||||
|
|
||||||
|
expect(result).toEqual([{ id: "gym_1", name: "Gym One" }]);
|
||||||
|
expect(withAuth).toHaveBeenCalledWith("token_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns nested data payload from getGyms", async () => {
|
||||||
|
getMock.mockResolvedValue({
|
||||||
|
data: { data: [{ id: "gym_2", name: "Gym Two" }] },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await gymsApi.getGyms(null);
|
||||||
|
|
||||||
|
expect(result).toEqual([{ id: "gym_2", name: "Gym Two" }]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("patches selected gym for current user", async () => {
|
||||||
|
patchMock.mockResolvedValue({});
|
||||||
|
|
||||||
|
await gymsApi.updateUserGym("gym_2", "token_2");
|
||||||
|
|
||||||
|
expect(apiClient.patch).toHaveBeenCalledWith(
|
||||||
|
"/api/users/gym",
|
||||||
|
{ gymId: "gym_2" },
|
||||||
|
expect.any(Object),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
68
apps/mobile/src/api/__tests__/recommendations.test.ts
Normal file
68
apps/mobile/src/api/__tests__/recommendations.test.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
|
||||||
|
import {
|
||||||
|
approveRecommendation,
|
||||||
|
generateRecommendation,
|
||||||
|
getRecommendations,
|
||||||
|
} from "../recommendations";
|
||||||
|
import { apiClient, withAuth } from "../client";
|
||||||
|
|
||||||
|
jest.mock("../client", () => ({
|
||||||
|
apiClient: {
|
||||||
|
get: jest.fn(),
|
||||||
|
post: jest.fn(),
|
||||||
|
},
|
||||||
|
withAuth: jest.fn((token?: string | null) =>
|
||||||
|
token ? { headers: { Authorization: `Bearer ${token}` } } : {},
|
||||||
|
),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe("recommendations api", () => {
|
||||||
|
const getMock = apiClient.get as any;
|
||||||
|
const postMock = apiClient.post as any;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns normalized list from standardized response", async () => {
|
||||||
|
getMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
data: [{ id: "rec_1", status: "pending" }],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await getRecommendations("user_1", "token_1");
|
||||||
|
|
||||||
|
expect(result).toEqual([{ id: "rec_1", status: "pending" }]);
|
||||||
|
expect(withAuth).toHaveBeenCalledWith("token_1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("falls back to legacy response for generate", async () => {
|
||||||
|
postMock.mockResolvedValue({
|
||||||
|
data: { id: "rec_2", status: "pending" },
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await generateRecommendation({ userId: "user_1" }, null);
|
||||||
|
|
||||||
|
expect(result).toEqual({ id: "rec_2", status: "pending" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sends approval payload without approvedBy", async () => {
|
||||||
|
postMock.mockResolvedValue({
|
||||||
|
data: {
|
||||||
|
success: true,
|
||||||
|
data: { id: "rec_3", status: "approved" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await approveRecommendation("rec_3", "token_3");
|
||||||
|
|
||||||
|
expect(result).toEqual({ id: "rec_3", status: "approved" });
|
||||||
|
expect(apiClient.post).toHaveBeenCalledWith(
|
||||||
|
"/api/recommendations/approve",
|
||||||
|
{ recommendationId: "rec_3", status: "approved" },
|
||||||
|
expect.any(Object),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user