Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 184 additions & 10 deletions src/__tests__/components/RouteSpecificPreferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,179 @@ import {
within,
} from "@testing-library/react-native";

import preferencesApi, {
Route,
RoutePreference,
RouteWithPreferences,
} from "@/lib/api/preferences";

import RouteSpecificPreferences from "@/components/RouteSpecificPreferences";

const getRouteKey = (route: Route) =>
`${route.fromLat},${route.fromLon},${route.toLat},${route.toLon}`;

// Mock data
const MOCK_ROUTES_WITH_PREFERENCES: RouteWithPreferences[] = [
{
route: {
from: "Exactum",
to: "Kamppi",
fromLat: 60.204,
fromLon: 24.962,
toLat: 60.169,
toLon: 24.932,
},
preferences: [
{
id: 1,
prompt: "Prefer bus 506",
created_at: "2023-01-01T12:00:00.000Z",
from_latitude: 60.204,
from_longitude: 24.962,
to_latitude: 60.169,
to_longitude: 24.932,
updated_at: null,
},
{
id: 2,
prompt: "Never use the tram for this route",
created_at: "2023-01-01T12:00:00.000Z",
from_latitude: 60.204,
from_longitude: 24.962,
to_latitude: 60.169,
to_longitude: 24.932,
updated_at: null,
},
{
id: 3,
prompt: "Avoid rush hour metro",
created_at: "2023-01-01T12:00:00.000Z",
from_latitude: 60.204,
from_longitude: 24.962,
to_latitude: 60.169,
to_longitude: 24.932,
updated_at: null,
},
],
},
{
route: {
from: "Kamppi",
to: "Pasila",
fromLat: 60.169,
fromLon: 24.932,
toLat: 60.199,
toLon: 24.934,
},
preferences: [
{
id: 4,
prompt: "Always use metro when available",
created_at: "2023-01-01T12:00:00.000Z",
from_latitude: 60.169,
from_longitude: 24.932,
to_latitude: 60.199,
to_longitude: 24.934,
updated_at: null,
},
{
id: 5,
prompt: "Avoid walking through Töölö",
created_at: "2023-01-01T12:00:00.000Z",
from_latitude: 60.169,
from_longitude: 24.932,
to_latitude: 60.199,
to_longitude: 24.934,
updated_at: null,
},
],
},
];

let mockRoutesWithPreferences: RouteWithPreferences[];
let mockNextPreferenceId: number;

// Mock the API module
jest.mock("@/lib/api/preferences", () => ({
getRoutesWithPreferences: jest.fn(async () => mockRoutesWithPreferences),
addRouteSpecificPreference: jest.fn(
async (route: Route, { prompt }: { prompt: string }) => {
const newPreference: RoutePreference = {
id: mockNextPreferenceId++,
prompt,
created_at: new Date().toISOString(),
from_latitude: route.fromLat,
from_longitude: route.fromLon,
to_latitude: route.toLat,
to_longitude: route.toLon,
updated_at: null,
};
mockRoutesWithPreferences = mockRoutesWithPreferences.map((r) =>
getRouteKey(r.route) === getRouteKey(route)
? { ...r, preferences: [...r.preferences, newPreference] }
: r
);
return newPreference;
}
),
deleteRouteSpecificPreference: jest.fn(
async (route: Route, preferenceId: number) => {
mockRoutesWithPreferences = mockRoutesWithPreferences.map((r) =>
getRouteKey(r.route) === getRouteKey(route)
? {
...r,
preferences: r.preferences.filter(
(p) => p.id !== preferenceId
),
}
: r
);
}
),
addSavedRoute: jest.fn(async (from: string, to: string) => {
const newRoute: RouteWithPreferences = {
route: {
from,
to,
fromLat: 60.224, // Dummy coords
fromLon: 24.952,
toLat: 60.189,
toLon: 25.042,
},
preferences: [],
};
mockRoutesWithPreferences.push(newRoute);
}),
__resetMocks: () => {
mockRoutesWithPreferences = JSON.parse(
JSON.stringify(MOCK_ROUTES_WITH_PREFERENCES)
);
mockNextPreferenceId = 6;
},
}));

// Mock the location service hook
jest.mock("@/lib/location", () => ({
useLocationService: () => ({
getSuggestions: jest.fn().mockResolvedValue([]),
isValidPlace: jest.fn().mockReturnValue(true),
}),
}));

describe("RouteSpecificPreferences component", () => {
// Define route keys based on mock data
const route1Key = getRouteKey(MOCK_ROUTES_WITH_PREFERENCES[0].route);
const route2Key = getRouteKey(MOCK_ROUTES_WITH_PREFERENCES[1].route);

beforeEach(() => {
preferencesApi.__resetMocks();
});

it("should render initial routes and preferences", async () => {
const { findByTestId } = render(<RouteSpecificPreferences />);

// Check for first route
const route1 = await findByTestId("route-preferences-1");
const route1 = await findByTestId(`route-preferences-${route1Key}`);
expect(within(route1).getByText("Exactum")).toBeTruthy();
expect(within(route1).getByText("Kamppi")).toBeTruthy();
expect(
Expand All @@ -24,7 +189,7 @@ describe("RouteSpecificPreferences component", () => {
expect(within(route1).getByText("Avoid rush hour metro")).toBeTruthy();

// Check for second route
const route2 = await findByTestId("route-preferences-2");
const route2 = await findByTestId(`route-preferences-${route2Key}`);
expect(within(route2).getByText("Kamppi")).toBeTruthy();
expect(within(route2).getByText("Pasila")).toBeTruthy();
expect(
Expand All @@ -36,27 +201,32 @@ describe("RouteSpecificPreferences component", () => {
});

it("should add a new preference to a route", async () => {
const { getByTestId, findByText } = render(
const { getByTestId, findByText, findByTestId } = render(
<RouteSpecificPreferences />
);
const newPreference = "Use a city bike";

const input = getByTestId("add-preference-input-1");
const input = await findByTestId(`add-preference-input-${route1Key}`);
fireEvent.changeText(input, newPreference);

const addButton = getByTestId("add-preference-button-1");
const addButton = getByTestId(`add-preference-button-${route1Key}`);
fireEvent.press(addButton);

expect(await findByText(newPreference)).toBeTruthy();
await waitFor(async () => {
expect(await findByText(newPreference)).toBeTruthy();
});
});

it("should delete a preference from a route", async () => {
const { getByTestId, queryByText } = render(
const { queryByText, findByTestId } = render(
<RouteSpecificPreferences />
);
const preferenceToDelete = "Prefer bus 506";
const preferenceId = MOCK_ROUTES_WITH_PREFERENCES[0].preferences[0].id;

const deleteButton = getByTestId("delete-preference-1-1");
const deleteButton = await findByTestId(
`delete-preference-${route1Key}-${preferenceId}`
);
fireEvent.press(deleteButton);

await waitFor(() => {
Expand All @@ -78,10 +248,14 @@ describe("RouteSpecificPreferences component", () => {

fireEvent.changeText(fromInput, "Kumpula");
fireEvent.changeText(toInput, "Herttoniemi");

fireEvent.press(addRouteButton);

expect(await findByText("Kumpula")).toBeTruthy();
expect(await findByText("Herttoniemi")).toBeTruthy();
await waitFor(async () => {
// The component refetches after adding, so we wait for the new content to appear
expect(await findByText("Kumpula")).toBeTruthy();
expect(await findByText("Herttoniemi")).toBeTruthy();
});
});

it("should cancel adding a new route", async () => {
Expand Down
Loading