Spaces:
Sleeping
Sleeping
| import { describe, it, expect, vi, beforeEach } from 'vitest'; | |
| const { maps } = vi.hoisted(() => ({ | |
| maps: { | |
| searchPlaces: vi.fn(), | |
| autocompletePlaces: vi.fn(), | |
| getPlaceDetails: vi.fn(), | |
| getPlaceDetailsExpanded: vi.fn(), | |
| getPlacePhoto: vi.fn(), | |
| reverseGeocode: vi.fn(), | |
| resolveGoogleMapsUrl: vi.fn(), | |
| searchOverpassPois: vi.fn(), | |
| }, | |
| })); | |
| vi.mock('../../../src/services/mapsService', () => maps); | |
| const { serveFilePath } = vi.hoisted(() => ({ serveFilePath: vi.fn() })); | |
| vi.mock('../../../src/services/placePhotoCache', () => ({ serveFilePath })); | |
| import { MapsService } from '../../../src/nest/maps/maps.service'; | |
| import type { DatabaseService } from '../../../src/nest/database/database.service'; | |
| /** A DatabaseService stub whose get() returns the row the test wants. */ | |
| function makeDb(row?: { value: string }) { | |
| const get = vi.fn(() => row); | |
| const db = { get } as unknown as DatabaseService; | |
| return { db, get }; | |
| } | |
| function svc(row?: { value: string }) { | |
| return new MapsService(makeDb(row).db); | |
| } | |
| beforeEach(() => vi.clearAllMocks()); | |
| describe('MapsService', () => { | |
| describe('kill-switch settings reads', () => { | |
| it('reports a switch disabled when the stored value is exactly "false"', () => { | |
| expect(svc({ value: 'false' }).autocompleteDisabled()).toBe(true); | |
| expect(svc({ value: 'false' }).detailsDisabled()).toBe(true); | |
| expect(svc({ value: 'false' }).photosDisabled()).toBe(true); | |
| }); | |
| it('reports enabled when the value is "true"', () => { | |
| expect(svc({ value: 'true' }).autocompleteDisabled()).toBe(false); | |
| expect(svc({ value: 'true' }).detailsDisabled()).toBe(false); | |
| expect(svc({ value: 'true' }).photosDisabled()).toBe(false); | |
| }); | |
| it('reports enabled when the setting row is absent', () => { | |
| expect(svc(undefined).autocompleteDisabled()).toBe(false); | |
| expect(svc(undefined).detailsDisabled()).toBe(false); | |
| expect(svc(undefined).photosDisabled()).toBe(false); | |
| }); | |
| it('queries the matching app_settings key', () => { | |
| const { db, get } = makeDb({ value: 'true' }); | |
| const s = new MapsService(db); | |
| s.autocompleteDisabled(); | |
| expect(get).toHaveBeenCalledWith(expect.stringContaining('app_settings'), 'places_autocomplete_enabled'); | |
| s.detailsDisabled(); | |
| expect(get).toHaveBeenCalledWith(expect.any(String), 'places_details_enabled'); | |
| s.photosDisabled(); | |
| expect(get).toHaveBeenCalledWith(expect.any(String), 'places_photos_enabled'); | |
| }); | |
| }); | |
| describe('delegation to the legacy maps service', () => { | |
| it('search forwards userId, query, lang and bias', () => { | |
| maps.searchPlaces.mockResolvedValue({ places: [], source: 'osm' }); | |
| const bias = { lat: 1, lng: 2, radius: 5 }; | |
| svc().search(3, 'berlin', 'de', bias); | |
| expect(maps.searchPlaces).toHaveBeenCalledWith(3, 'berlin', 'de', bias); | |
| }); | |
| it('search works without optional args', () => { | |
| svc().search(3, 'berlin'); | |
| expect(maps.searchPlaces).toHaveBeenCalledWith(3, 'berlin', undefined, undefined); | |
| }); | |
| it('autocomplete forwards through', () => { | |
| const bias = { low: { lat: 1, lng: 2 }, high: { lat: 3, lng: 4 } }; | |
| svc().autocomplete(3, 'be', 'en', bias); | |
| expect(maps.autocompletePlaces).toHaveBeenCalledWith(3, 'be', 'en', bias); | |
| }); | |
| it('details forwards through', () => { | |
| svc().details(3, 'p1', 'de'); | |
| expect(maps.getPlaceDetails).toHaveBeenCalledWith(3, 'p1', 'de'); | |
| }); | |
| it('detailsExpanded forwards refresh through', () => { | |
| svc().detailsExpanded(3, 'p1', 'de', true); | |
| expect(maps.getPlaceDetailsExpanded).toHaveBeenCalledWith(3, 'p1', 'de', true); | |
| }); | |
| it('photo forwards coords and name through', () => { | |
| svc().photo(3, 'p1', 1.5, 2.5, 'Spot'); | |
| expect(maps.getPlacePhoto).toHaveBeenCalledWith(3, 'p1', 1.5, 2.5, 'Spot'); | |
| }); | |
| it('reverse forwards through', () => { | |
| svc().reverse('1', '2', 'de'); | |
| expect(maps.reverseGeocode).toHaveBeenCalledWith('1', '2', 'de'); | |
| }); | |
| it('resolveUrl forwards through', () => { | |
| svc().resolveUrl('https://maps.app.goo.gl/x'); | |
| expect(maps.resolveGoogleMapsUrl).toHaveBeenCalledWith('https://maps.app.goo.gl/x'); | |
| }); | |
| it('pois forwards category and bbox through', () => { | |
| const bbox = { south: 1, west: 2, north: 3, east: 4 }; | |
| svc().pois('cafe', bbox); | |
| expect(maps.searchOverpassPois).toHaveBeenCalledWith('cafe', bbox); | |
| }); | |
| }); | |
| describe('photoBytesPath', () => { | |
| it('returns the cached file path from placePhotoCache', () => { | |
| serveFilePath.mockReturnValue('/cache/p1.jpg'); | |
| expect(svc().photoBytesPath('p1')).toBe('/cache/p1.jpg'); | |
| expect(serveFilePath).toHaveBeenCalledWith('p1'); | |
| }); | |
| it('returns null when nothing is cached', () => { | |
| serveFilePath.mockReturnValue(null); | |
| expect(svc().photoBytesPath('p1')).toBeNull(); | |
| }); | |
| }); | |
| }); | |