Files
frontend-miniapp/tests/unit/SdkGuideRouteRepository.spec.ts
lyf 9ea1bfab71
Some checks failed
CI / verify (push) Has been cancelled
同步 sgs-frontend-mobile 源码
2026-07-27 11:26:01 +08:00

197 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it, vi } from 'vitest'
import type { SgsSdkApiProvider } from '@/data/providers/sgsSdkApiProvider'
import { SdkGuideRouteRepository } from '@/repositories/SdkGuideRouteRepository'
const floorId = '2065808921272119298'
const createProvider = () => {
const planRoute = vi.fn().mockResolvedValue({
distance: 24,
segments: [{
floorId,
floorName: '1.0层',
transferType: 'WALK',
pathPoints: [
{ x: 2, y: 0, z: 3 },
{ x: 8, y: 0, z: 9 }
]
}]
})
return {
getManifest: vi.fn().mockResolvedValue({
mapId: '1',
capabilities: { routePlanning: true },
floors: [{
floorId,
floorCode: 'L1',
floorName: '1.0层'
}]
}),
getMapDiagnostics: vi.fn().mockResolvedValue({
floors: [{
floorId,
floorCode: 'L1',
floorName: '1.0层',
status: 'OK',
routePlanningReady: true,
navigablePlaceCount: 1
}]
}),
getNavigablePlaces: vi.fn().mockResolvedValue([{
id: 'route-node-service-desk',
sourceId: 'poi-service-desk',
anchorId: 'anchor-service-desk',
name: '服务台 出入口',
floorId,
floorCode: 'L1',
floorName: '1.0层',
x: 2,
y: 0,
z: 3,
nodeId: 'start-node'
}]),
planRoute
} as unknown as SgsSdkApiProvider
}
describe('SdkGuideRouteRepository', () => {
it('使用 manifest 路线能力判断就绪,不调用全图 diagnostics 慢接口', async () => {
const provider = createProvider()
const repository = new SdkGuideRouteRepository(provider)
const readiness = await repository.getRouteReadiness()
expect(readiness.ready).toBe(true)
expect(provider.getManifest).toHaveBeenCalledTimes(1)
expect(provider.getMapDiagnostics).not.toHaveBeenCalled()
})
it('允许未预绑定路网的地图对象作为终点,并向后端提交其定位坐标', async () => {
const provider = createProvider()
const repository = new SdkGuideRouteRepository(provider)
const route = await repository.findRoute('anchor-service-desk', {
poiId: 'space-stamp',
name: '文创盖章打卡',
floorId,
floorLabel: '1F',
categoryLabel: '购物空间',
positionGltf: [61.8, 1.2, 45.3]
})
expect(provider.planRoute).toHaveBeenCalledWith(expect.objectContaining({
startNodeId: 'start-node',
endFloorId: floorId,
endX: 61.8,
endY: 45.3,
endNodeId: null,
verticalTransferPolicy: 'PREFER_ELEVATOR_ESCALATOR'
}))
expect(route.end.name).toBe('文创盖章打卡')
expect(route.distanceMeters).toBe(24)
})
it('保留业务对象 ID使地图标签可精确回连到对应接入点', async () => {
const repository = new SdkGuideRouteRepository(createProvider())
const targets = await repository.listRouteTargets()
expect(targets).toEqual([expect.objectContaining({
routeTargetId: 'anchor-service-desk',
poiId: 'route-node-service-desk',
sourceId: 'poi-service-desk',
routeNodeId: 'start-node'
})])
})
it('路线起点选择只读取当前楼层目标,不扫描全馆楼层', async () => {
const provider = createProvider()
const repository = new SdkGuideRouteRepository(provider)
const targets = await repository.listRouteTargetsForFloor(floorId)
expect(targets).toHaveLength(1)
expect(provider.getNavigablePlaces).toHaveBeenCalledTimes(1)
expect(provider.getNavigablePlaces).toHaveBeenCalledWith(floorId)
expect(provider.getMapDiagnostics).not.toHaveBeenCalled()
})
it('为只有 nodeId 的路网节点生成稳定兜底身份', async () => {
const provider = createProvider()
provider.getNavigablePlaces = vi.fn().mockResolvedValue([{
id: null,
sourceId: 'space-42',
name: '球幕影院节点',
floorId,
floorCode: 'L1',
floorName: '1.0层',
x: 1,
y: 0,
z: 2,
nodeId: 'node-only'
}])
const repository = new SdkGuideRouteRepository(provider)
const targets = await repository.listRouteTargets()
expect(targets).toEqual([expect.objectContaining({
routeTargetId: 'node-node-only:node-only',
poiId: 'node-node-only',
sourceId: 'space-42',
routeNodeId: 'node-only'
})])
})
it('允许地图对象坐标作为起点,由路线服务负责吸附到正式路网', async () => {
const provider = createProvider()
const repository = new SdkGuideRouteRepository(provider)
await repository.findRoute({
poiId: 'hall-unanchored',
name: '球幕影院',
floorId,
floorLabel: '1F',
positionGltf: [1.7, 3.3, -5.6]
}, {
poiId: 'space-stamp',
name: '文创盖章打卡',
floorId,
floorLabel: '1F',
positionGltf: [61.8, 1.2, 45.3]
})
expect(provider.planRoute).toHaveBeenCalledWith(expect.objectContaining({
startX: 1.7,
startY: -5.6,
startNodeId: null,
endNodeId: null
}))
})
it('将路线接口异常转换为不暴露内部请求细节的用户错误', async () => {
const provider = createProvider()
provider.planRoute = vi.fn().mockRejectedValue(new Error(
'SGS 数据接口请求失败: 500 /app-api/gis/sdk/routes/plan body="internal response"'
))
const repository = new SdkGuideRouteRepository(provider)
await expect(repository.findRoute({
poiId: 'start-poi',
name: '起点',
floorId,
floorLabel: '1F',
positionGltf: [1, 0, 2]
}, {
poiId: 'end-poi',
name: '终点',
floorId,
floorLabel: '1F',
positionGltf: [3, 0, 4]
})).rejects.toMatchObject({
code: 'ROUTE_SERVICE_UNAVAILABLE',
message: '路线服务暂时不可用,请稍后重试'
})
})
})