Files
matrix-backend/tests/rest/restLocation.test.ts
StarAppeal e678bc800b feat: add location search endpoint, update weather polling to use coordinates, and enforce weather rate limiting
- Introduce /api/location/search endpoint for location autocomplete using OpenWeather geocoding
- Refactor weather polling service and user schema to use latitude/longitude instead of location name
- Add weatherLimiter middleware to rate limit location API requests
- Update tests for new location structure and endpoint
2025-12-27 18:31:12 +01:00

90 lines
2.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import request from "supertest";
import { RestLocation } from "../../src/rest/restLocation";
import { setupTestEnvironment, type TestEnvironment } from "../helpers/testSetup";
vi.mock("../../src/services/db/UserService", () => ({
UserService: {
create: vi.fn(),
getUserByUUID: vi.fn()
}
}));
vi.mock("../../src/utils/passwordUtils", () => ({
PasswordUtils: {
validatePassword: vi.fn(),
hashPassword: vi.fn(),
comparePassword: vi.fn()
}
}));
vi.mock("../../src/services/owmApiService", () => ({
validateLocation: vi.fn()
}));
import { validateLocation } from "../../src/services/owmApiService";
describe("RestLocation", () => {
let testEnv: TestEnvironment;
const mockedValidateLocation = vi.mocked(validateLocation);
beforeEach(() => {
vi.clearAllMocks();
const restLocation = new RestLocation();
testEnv = setupTestEnvironment(restLocation.createRouter(), "/location");
});
afterEach(() => {
vi.resetAllMocks();
});
describe("GET /search", () => {
const endpoint = "/location/search";
it("should return list of locations for valid query", async () => {
const query = "Berlin";
const mockResult = [
{ name: "Berlin", country: "DE", lat: 52.5, lon: 13.4 }
];
mockedValidateLocation.mockResolvedValue(mockResult as any);
const response = await request(testEnv.app)
.get(endpoint)
.query({ q: query })
.expect(200);
expect(response.body.data.locations).toEqual(mockResult);
expect(mockedValidateLocation).toHaveBeenCalledWith(query);
});
it("should return 400 if query 'q' is missing", async () => {
const response = await request(testEnv.app)
.get(endpoint)
.expect(400);
expect(response.body.details).toContain("q is required");
});
it("should return 400 if query 'q' is empty", async () => {
const response = await request(testEnv.app)
.get(endpoint)
.query({ q: "" })
.expect(400);
expect(response.body.details).toContain("q must be a non-empty string");
});
it("should return empty list if service returns empty list (e.g. nothing found)", async () => {
mockedValidateLocation.mockResolvedValue([]);
const response = await request(testEnv.app)
.get(endpoint)
.query({ q: "GibtsNichtStadt" })
.expect(200);
expect(response.body.data.locations).toEqual([]);
});
});
});