import { afterEach, describe, expect, it, vi } from 'vitest' import { buildAmapNavigationUrl, buildBaiduNavigationUrl, openExternalNavigation } from '@/services/MapNavigationService' afterEach(() => { vi.unstubAllGlobals() }) describe('H5 原生地图导航 URL', () => { it('百度地图使用 GCJ-02 坐标参数', () => { const url = buildBaiduNavigationUrl({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' }) expect(url).toContain('baidumap://map/direction?') expect(url).toContain('destination=latlng%3A22.692763%2C114.363572') expect(url).toContain('coord_type=gcj02') }) it('iOS 高德地图使用 iosamap Scheme', () => { const url = buildAmapNavigationUrl({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' }, 'ios') expect(url).toMatch(/^iosamap:\/\/path\?/) expect(url).toContain('dlat=22.692763') expect(url).toContain('dlon=114.363572') expect(url).toContain('dev=0') }) it('Android 高德地图使用 androidamap Scheme', () => { const url = buildAmapNavigationUrl({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' }, 'android') expect(url).toMatch(/^androidamap:\/\/route\?/) expect(url).toContain('dlat=22.692763') expect(url).toContain('dlon=114.363572') expect(url).toContain('dev=0') }) it('中文目的地名称会进行 URL 编码', () => { const encodedName = '%E6%B7%B1%E5%9C%B3%E8%87%AA%E7%84%B6%E5%8D%9A%E7%89%A9%E9%A6%86' expect(buildBaiduNavigationUrl({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' })).toContain(`destination=latlng%3A22.692763%2C114.363572%7Cname%3A${encodedName}`) expect(buildAmapNavigationUrl({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' }, 'android')).toContain(`dname=${encodedName}`) }) it('选择百度地图后直接打开原生 Scheme', async () => { const location = { href: 'https://guide.example.com/' } const showActionSheet = vi.fn(({ success }) => success({ tapIndex: 0 })) vi.stubGlobal('window', { location, navigator: { userAgent: 'Mozilla/5.0 (Linux; Android 14)' } }) vi.stubGlobal('uni', { showActionSheet, showToast: vi.fn() }) const result = await openExternalNavigation({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' }) expect(showActionSheet).toHaveBeenCalledWith(expect.objectContaining({ itemList: ['百度地图', '高德地图'] })) expect(location.href).toMatch(/^baidumap:\/\/map\/direction\?/) expect(result).toBe(true) }) it('iPhone 选择高德地图后打开 iosamap Scheme', async () => { const location = { href: 'https://guide.example.com/' } const showActionSheet = vi.fn(({ success }) => success({ tapIndex: 1 })) vi.stubGlobal('window', { location, navigator: { userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)', platform: 'iPhone', maxTouchPoints: 5 } }) vi.stubGlobal('uni', { showActionSheet, showToast: vi.fn() }) const result = await openExternalNavigation({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' }) expect(location.href).toMatch(/^iosamap:\/\/path\?/) expect(result).toBe(true) }) it('取消地图选择时静默返回 false', async () => { const location = { href: 'https://guide.example.com/' } const showToast = vi.fn() const showActionSheet = vi.fn(({ fail }) => fail({ errMsg: 'showActionSheet:fail cancel' })) vi.stubGlobal('window', { location, navigator: { userAgent: 'Mozilla/5.0 (Linux; Android 14)' } }) vi.stubGlobal('uni', { showActionSheet, showToast }) const result = await openExternalNavigation({ latitude: 22.692763, longitude: 114.363572, name: '深圳自然博物馆' }) expect(result).toBe(false) expect(location.href).toBe('https://guide.example.com/') expect(showToast).not.toHaveBeenCalled() }) })