import { beforeEach, describe, expect, it, vi } from 'vitest' import { getCurrentGcj02Location, isLocationPermissionDenied } from '../src/services/location' describe('current location adapter', () => { beforeEach(() => { vi.useRealTimers() Object.assign(uni, { canIUse: vi.fn(() => true), getLocation: vi.fn(), }) }) it('requests a new high-accuracy GCJ-02 sample', async () => { vi.mocked(uni.getLocation).mockImplementation((options) => { options.success?.({ longitude: 113.94, latitude: 22.76, accuracy: 18 } as UniNamespace.GetLocationSuccess) return undefined as never }) await expect(getCurrentGcj02Location()).resolves.toMatchObject({ longitude: 113.94, latitude: 22.76, accuracy: 18, receivedAt: expect.any(String), coordinateSystem: 'GCJ02', }) expect(uni.getLocation).toHaveBeenCalledWith(expect.objectContaining({ type: 'gcj02', isHighAccuracy: true, highAccuracyExpireTime: 8000, })) }) it('starts a separate native request for every location lookup', async () => { vi.mocked(uni.getLocation).mockImplementation((options) => { options.success?.({ longitude: 113.94, latitude: 22.76, accuracy: 18 } as UniNamespace.GetLocationSuccess) return undefined as never }) await getCurrentGcj02Location() await getCurrentGcj02Location() expect(uni.getLocation).toHaveBeenCalledTimes(2) }) it('falls back to the basic object shape on older base libraries', async () => { vi.mocked(uni.canIUse).mockReturnValue(false) vi.mocked(uni.getLocation).mockImplementation((options) => { options.success?.({ longitude: 113.94, latitude: 22.76, accuracy: 20 } as UniNamespace.GetLocationSuccess) return undefined as never }) await getCurrentGcj02Location() expect(uni.getLocation).toHaveBeenCalledWith(expect.not.objectContaining({ isHighAccuracy: true })) }) it('times out once and ignores a late callback', async () => { vi.useFakeTimers() let success: ((result: UniNamespace.GetLocationSuccess) => void) | undefined vi.mocked(uni.getLocation).mockImplementation((options) => { success = options.success return undefined as never }) const request = getCurrentGcj02Location({ timeoutMs: 3000 }) const rejection = expect(request).rejects.toThrow('定位超时') await vi.advanceTimersByTimeAsync(3001) await rejection success?.({ longitude: 113.94, latitude: 22.76, accuracy: 20 } as UniNamespace.GetLocationSuccess) await vi.runAllTimersAsync() }) it('identifies WeChat permission denials', () => { expect(isLocationPermissionDenied({ errMsg: 'getLocation:fail auth deny' })).toBe(true) expect(isLocationPermissionDenied({ errMsg: 'getLocation:fail privacy permission is not authorized' })).toBe(false) expect(isLocationPermissionDenied({ errMsg: 'getLocation:fail system error' })).toBe(false) }) })