From 5c6cd6af44b84d4f4b9e84e762c9b3a2da65f68c Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 7 Oct 2026 16:54:05 +0800 Subject: [PATCH] test(fleet): use local wall time for planned delivery fixture --- scripts/fleet-capacity-pool-test-env.mjs | 7 ++++++- scripts/fleet-capacity-pool-test-env.test.mjs | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/scripts/fleet-capacity-pool-test-env.mjs b/scripts/fleet-capacity-pool-test-env.mjs index ca7478c0b..a0a3f130f 100644 --- a/scripts/fleet-capacity-pool-test-env.mjs +++ b/scripts/fleet-capacity-pool-test-env.mjs @@ -15,7 +15,12 @@ const id = value => String(value ?? ''), requireThat = (ok, reason) => { if (!ok const success = response => response?.http === 200 && id(response.body?.code) === '200' const denied = response => [403, 409].includes(response?.http) || response?.http === 200 && ['A0403', 'A0409'].includes(id(response.body?.code)) const encode = encodeURIComponent -const localTime = ms => new Date(Date.now() + ms).toISOString().slice(0, 19) +// DeliveryRequests.Transfer uses LocalDateTime. Fleet offer/booking Instant fields below retain Z. +export function poolLocalDateTime(date) { + requireThat(date instanceof Date && Number.isFinite(date.getTime()), 'VALID_LOCAL_DATE_REQUIRED') + return new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 19) +} +const localTime = ms => poolLocalDateTime(new Date(Date.now() + ms)) const PNG = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aH1kAAAAASUVORK5CYII=', 'base64') export const POOL_COVERAGE = Object.freeze([ diff --git a/scripts/fleet-capacity-pool-test-env.test.mjs b/scripts/fleet-capacity-pool-test-env.test.mjs index 89d189547..5832fefd1 100644 --- a/scripts/fleet-capacity-pool-test-env.test.mjs +++ b/scripts/fleet-capacity-pool-test-env.test.mjs @@ -1,7 +1,7 @@ import test from 'node:test' import assert from 'node:assert/strict' import { parsePoolArguments, poolPlan, runPoolAcceptance, assertPoolRemaining, assertSingleCommercial, - shrinkingVehicleRequest, expiryWaitMs, POOL_COVERAGE, POOL_REMAINING } from './fleet-capacity-pool-test-env.mjs' + shrinkingVehicleRequest, expiryWaitMs, poolLocalDateTime, POOL_COVERAGE, POOL_REMAINING } from './fleet-capacity-pool-test-env.mjs' test('default and explicit plans make no network requests or invoke the mutating runner', async () => { const original = globalThis.fetch @@ -95,3 +95,14 @@ test('cutoff wait is bounded and follows the returned instant without negative o assert.throws(() => expiryWaitMs('invalid', now), /INVALID_SERVER_CUTOFF/) assert.throws(() => expiryWaitMs('2030-01-01T08:10:00Z', now), /BOUNDED_WINDOW/) }) + +test('LocalDateTime transport time keeps actual local wall clock while Instant dates remain zoned', () => { + class ShanghaiDate extends Date { getTimezoneOffset() { return -480 } } + class LosAngelesDate extends Date { getTimezoneOffset() { return 420 } } + const instant = '2030-01-01T20:30:45.123Z' + assert.equal(poolLocalDateTime(new ShanghaiDate(instant)), '2030-01-02T04:30:45') + assert.equal(poolLocalDateTime(new LosAngelesDate(instant)), '2030-01-01T13:30:45') + assert.equal(new ShanghaiDate(instant).toISOString(), instant) + assert.equal(new LosAngelesDate(instant).toISOString(), instant) + assert.throws(() => poolLocalDateTime(new Date('invalid')), /VALID_LOCAL_DATE_REQUIRED/) +})