Merge pull request 'Update planner, check-in records, location service and tests' (#10) from zhouruizhe into main

Reviewed-on: #10
This commit was merged in pull request #10.
This commit is contained in:
2026-08-01 22:01:35 +08:00
11 changed files with 174 additions and 53 deletions
+17 -1
View File
@@ -1,5 +1,9 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { getCurrentGcj02Location, isLocationPermissionDenied } from '../src/services/location'
import {
getCurrentGcj02Location,
isLocationPermissionDenied,
isLocationSnapshotFresh,
} from '../src/services/location'
describe('current location adapter', () => {
beforeEach(() => {
@@ -73,4 +77,16 @@ describe('current location adapter', () => {
expect(isLocationPermissionDenied({ errMsg: 'getLocation:fail privacy permission is not authorized' })).toBe(false)
expect(isLocationPermissionDenied({ errMsg: 'getLocation:fail system error' })).toBe(false)
})
it('evaluates location freshness at exact boundaries and rejects invalid clocks', () => {
const capturedAt = '2026-07-31T02:00:00.000Z'
const capturedTimestamp = Date.parse(capturedAt)
const maxAgeMs = 5 * 60 * 1000
expect(isLocationSnapshotFresh(capturedAt, capturedTimestamp, maxAgeMs)).toBe(true)
expect(isLocationSnapshotFresh(capturedAt, capturedTimestamp + maxAgeMs, maxAgeMs)).toBe(true)
expect(isLocationSnapshotFresh(capturedAt, capturedTimestamp + maxAgeMs + 1, maxAgeMs)).toBe(false)
expect(isLocationSnapshotFresh(capturedAt, capturedTimestamp - 1, maxAgeMs)).toBe(false)
expect(isLocationSnapshotFresh('invalid', capturedTimestamp, maxAgeMs)).toBe(false)
})
})
+17 -7
View File
@@ -15,6 +15,7 @@ import {
type PlanResponse,
resolveCanonicalPoiId,
type TravelPreferences,
TravelValidationError,
} from '../src/domain/travel'
import {
createPlan,
@@ -222,13 +223,22 @@ describe('deterministic local POC planner', () => {
})
it('rejects a quick plan when even the first stop cannot fit the budget', () => {
expect(() => createLocalPlan({
mode: 'quick',
preferences: preferences({ pace: 'relaxed', transport: 'walking' }),
durationMinutes: 120,
selectedPoiIds: [],
origin: { longitude: 114.3, latitude: 22.3, coordinateSystem: 'GCJ02' },
}, repository)).toThrow('没有可用于规划的地点')
let thrown: unknown
try {
createLocalPlan({
mode: 'quick',
preferences: preferences({ pace: 'relaxed', transport: 'walking' }),
durationMinutes: 120,
selectedPoiIds: [],
origin: { longitude: 114.3, latitude: 22.3, coordinateSystem: 'GCJ02' },
}, repository)
}
catch (error) {
thrown = error
}
expect(thrown).toBeInstanceOf(TravelValidationError)
expect(thrown).toMatchObject({ code: 'quick_route_unreachable' })
})
it('returns the same route and canonical IDs for equivalent input', () => {