317 lines
20 KiB
JavaScript
317 lines
20 KiB
JavaScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import { parsePoolArguments, poolPlan, runPoolAcceptance, assertPoolRemaining, assertSingleCommercial,
|
|
shrinkingVehicleRequest, expiryWaitMs, poolLocalDateTime, poolPickScope, pickPoolDispatch, POOL_COVERAGE, POOL_REMAINING,
|
|
poolInquiryWrite, poolReadIsDenied, assertPoolBoundCapacity, verifyPoolConfirmedCancellation, verifyPoolBindingRevalidation,
|
|
assertPoolUnknownCommercialFacts } 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
|
|
globalThis.fetch = async () => { throw Error('unexpected network') }
|
|
try {
|
|
for (const args of [[], ['--plan']]) {
|
|
const config = parsePoolArguments(args)
|
|
const plan = await runPoolAcceptance(config, { runner: async () => { throw Error('unexpected runner') } })
|
|
assert.equal(plan.execute, false)
|
|
assert.equal(plan.environment, 'TEST')
|
|
assert.equal(plan.runId, 'plan')
|
|
assert.match(plan.boundary, /no network or filesystem writes/)
|
|
}
|
|
} finally { globalThis.fetch = original }
|
|
})
|
|
|
|
test('execution needs explicit TEST, fresh run ID and current warehouse identifiers', () => {
|
|
for (const args of [
|
|
['--execute'], ['--execute', '--run-id', 'fresh', '--warehouse-id', '10', '--destination-warehouse-id', '11'],
|
|
['--execute', '--environment', 'gray', '--run-id', 'fresh', '--warehouse-id', '10', '--destination-warehouse-id', '11'],
|
|
['--execute', '--environment', 'TEST', '--run-id', '../reuse', '--warehouse-id', '10', '--destination-warehouse-id', '11'],
|
|
['--execute', '--plan'], ['--resume', 'old-report'],
|
|
]) assert.throws(() => parsePoolArguments(args))
|
|
const parsed = parsePoolArguments(['--execute', '--environment', 'TEST', '--run-id', 'pool-r1', '--warehouse-id', '10', '--destination-warehouse-id', '11'])
|
|
assert.equal(parsed.execute, true)
|
|
assert.equal(parsed.runId, 'pool-r1')
|
|
})
|
|
|
|
test('plan distinguishes implemented HTTP scope from remaining whole-feature acceptance', () => {
|
|
const plan = poolPlan(parsePoolArguments([]))
|
|
assert.deepEqual(plan.coveredByThisEntry, POOL_COVERAGE)
|
|
assert.deepEqual(plan.remainingSeparateAcceptance, POOL_REMAINING)
|
|
assert.ok(plan.coveredByThisEntry.includes('both-business-types-real-pda-receipt'))
|
|
assert.ok(plan.remainingSeparateAcceptance.includes('full-UI-1920x1080-and-network-request-budget'))
|
|
assert.ok(plan.coveredByThisEntry.includes('weight-and-volume-independent-capacity-rejections'))
|
|
assert.ok(plan.coveredByThisEntry.includes('paused-create-edit-confirm-rejected'))
|
|
assert.ok(plan.coveredByThisEntry.includes('expired-cutoff-create-edit-confirm-rejected'))
|
|
assert.ok(plan.coveredByThisEntry.includes('assigned-vehicle-disable-and-shrink-rejected'))
|
|
assert.ok(plan.remainingSeparateAcceptance.includes('out-of-band-assigned-vehicle-drift-not-constructible-through-supported-api'))
|
|
assert.match(plan.boundary, /unknown outcome/)
|
|
assert.match(plan.boundary, /No automatic rerun or resume/)
|
|
})
|
|
|
|
test('remaining capacity uses unique current destination and rejects unknown, other-stop or duplicate rows', () => {
|
|
const offer = { capacityKnown: true, destinations: [{ destinationKey: 'FBA:A', remaining: { palletSpaces: 4 } },
|
|
{ destinationKey: 'FBA:B', remaining: { palletSpaces: 30 } }] }
|
|
assert.doesNotThrow(() => assertPoolRemaining(offer, 'FBA:A', 4))
|
|
for (const change of [o => { o.capacityKnown = false }, o => { o.destinations[0].remaining = null },
|
|
o => { o.destinations[0].destinationKey = 'FBA:C' }, o => { o.destinations.push(structuredClone(o.destinations[0])) },
|
|
o => { o.destinations[0].remaining.palletSpaces = 5 }]) {
|
|
const altered = structuredClone(offer); change(altered)
|
|
assert.throws(() => assertPoolRemaining(altered, 'FBA:A', 4), /EXACT_SEGMENT/)
|
|
}
|
|
})
|
|
|
|
test('successful confirmation replay must preserve commercial, booking, business type and customer identity', () => {
|
|
const before = { bookingNo: 'FB-1', businessOrderNo: 'LB-1', businessType: 'LOCAL_LOOSEBOARD', customerId: '9' }
|
|
assert.doesNotThrow(() => assertSingleCommercial(before, { ...before }))
|
|
for (const field of Object.keys(before)) assert.throws(() => assertSingleCommercial(before, { ...before, [field]: 'OTHER' }), /IDENTITY_CHANGED/)
|
|
assert.throws(() => assertSingleCommercial({ ...before, businessOrderNo: null }, { ...before }), /IDENTITY_CHANGED/)
|
|
})
|
|
|
|
test('default executor rejects non-TEST process configuration before any fixture writes', async () => {
|
|
const config = parsePoolArguments(['--execute', '--environment', 'TEST', '--run-id', 'pool-r1', '--warehouse-id', '10', '--destination-warehouse-id', '11'])
|
|
await assert.rejects(runPoolAcceptance(config, { env: { CHONGCHONG_ENV: 'prod' } }), /Explicit TEST configuration/)
|
|
})
|
|
|
|
test('vehicle shrink command preserves the authoritative full request and only changes capacity by one', () => {
|
|
const vehicle = { id: '7', recordVersion: 11, plateNumber: 'TEST-7', model: 'Box Truck', fuelConsumptionPer100Km: 12.5,
|
|
mileageKm: 100, driverOrDispatchCompany: 'TEST', phone: null, region: 'OVERSEAS', ownership: 'OWNED', remark: 'own fixture',
|
|
maxPalletSpaces: 30, maxLoadKg: 18000, maxVolumeCbm: 90, status: 'IN_SERVICE' }
|
|
const request = shrinkingVehicleRequest(vehicle)
|
|
assert.equal(request.maxPalletSpaces, 29)
|
|
for (const field of Object.keys(request).filter(name => name !== 'maxPalletSpaces')) assert.equal(request[field], vehicle[field])
|
|
assert.equal('status' in request, false)
|
|
assert.equal('id' in request, false)
|
|
assert.equal(vehicle.maxPalletSpaces, 30)
|
|
})
|
|
|
|
test('vehicle matrix refuses incomplete snapshots instead of inventing capacity for a write', () => {
|
|
for (const input of [null, {}, { id: '7', recordVersion: 1, maxPalletSpaces: 30 },
|
|
{ id: '7', recordVersion: 1, maxPalletSpaces: 1, maxLoadKg: 18000, maxVolumeCbm: 90 }]) {
|
|
assert.throws(() => shrinkingVehicleRequest(input), /SNAPSHOT_REQUIRED/)
|
|
}
|
|
})
|
|
|
|
test('cutoff wait is bounded and follows the returned instant without negative or unbounded sleeps', () => {
|
|
const now = Date.parse('2030-01-01T08:00:00Z')
|
|
assert.equal(expiryWaitMs('2030-01-01T08:00:08Z', now), 8300)
|
|
assert.equal(expiryWaitMs('2030-01-01T07:59:00Z', now), 0)
|
|
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/)
|
|
})
|
|
|
|
test('PDA namespace belongs to the exact run, customer and dispatch while parent evidence stays shared', () => {
|
|
const context = { marker: 'ORIGINAL-RUN', steps: [], createdResources: {} }, first = { customerId: '9', dispatchNo: 'DS-A' }
|
|
const a = poolPickScope(context, first), replay = poolPickScope(context, first)
|
|
assert.equal(a.marker, replay.marker)
|
|
assert.notEqual(a.marker, poolPickScope(context, { ...first, dispatchNo: 'DS-B' }).marker)
|
|
assert.notEqual(a.marker, poolPickScope(context, { ...first, customerId: '10' }).marker)
|
|
assert.notEqual(a.marker, poolPickScope({ ...context, marker: 'OTHER-RUN' }, first).marker)
|
|
assert.equal(a.steps, context.steps)
|
|
assert.equal(a.createdResources, context.createdResources)
|
|
assert.equal(context.marker, 'ORIGINAL-RUN')
|
|
assert.throws(() => poolPickScope(context, { dispatchNo: 'DS-A' }), /PICK_SCOPE_REQUIRED/)
|
|
})
|
|
|
|
test('real native pickAll preserves separate command namespaces, version zero, exact replays and stale rejection', async () => {
|
|
const operations = new Map(), requests = [], steps = [], picked = new Map()
|
|
const dispatches = ['DS-A', 'DS-B']
|
|
const context = {
|
|
marker: 'SAME-CUSTOMER-RUN', steps, createdResources: {},
|
|
addStep(_module, _name, _response, passed) { steps.push(passed) },
|
|
assert(_module, _name, _response, passed) { assert.equal(Boolean(passed), true) },
|
|
addCoverageGap() { assert.fail('unexpected coverage gap') },
|
|
async request(method, path, body) {
|
|
const dispatchNo = path.split('/dispatches/')[1].split('/')[0], index = dispatches.indexOf(dispatchNo)
|
|
assert.ok(index >= 0)
|
|
const response = data => ({ http: 200, body: { code: '200', data }, requestId: 'test', traceId: 'test' })
|
|
const version = picked.get(dispatchNo) || 0
|
|
if (method === 'GET') return response({ dispatchNo, status: 'ACTIVE', stage: 'LOADING', recordVersion: index === 0 ? version : String(version),
|
|
pickingReconciled: version === 1, counts: { packageCount: 1, pickedPackageCount: version },
|
|
items: [{ dispatchItemId: `${index + 1}`, scheduledPackages: 1, pickedPackages: version,
|
|
positions: [{ positionId: `${index + 100}`, availablePackages: 1 }] }] })
|
|
requests.push({ method, path, body: structuredClone(body) })
|
|
assert.ok(path.endsWith('/pick'))
|
|
assert.equal(body.recordVersion, index === 0 ? 0 : '0')
|
|
const prior = operations.get(body.idempotencyKey), payload = JSON.stringify([path, body])
|
|
if (prior) {
|
|
assert.equal(prior.payload, payload)
|
|
return response({ ...prior.result, replayed: true })
|
|
}
|
|
if (version !== Number(body.recordVersion)) return { http: 409, body: { code: 'A0409' } }
|
|
picked.set(dispatchNo, 1)
|
|
const result = { recordVersion: '1', result: { pickedPackages: 1 }, counts: { packageCount: 1, pickedPackageCount: 1 }, replayed: false }
|
|
operations.set(body.idempotencyKey, { payload, result })
|
|
return response(result)
|
|
},
|
|
}
|
|
for (const dispatchNo of dispatches) await pickPoolDispatch(context, 'test-pda', { customerId: '9', dispatchNo })
|
|
assert.equal(operations.size, 2)
|
|
assert.equal(requests.length, 6)
|
|
assert.ok(steps.every(Boolean))
|
|
for (let index = 0; index < requests.length; index += 3) {
|
|
assert.deepEqual(requests[index], requests[index + 1])
|
|
assert.notEqual(requests[index].body.idempotencyKey, requests[index + 2].body.idempotencyKey)
|
|
}
|
|
})
|
|
|
|
test('failed helper result stops the pool stage immediately instead of appending a misleading generic failure', async () => {
|
|
const context = { marker: 'R', steps: [] }
|
|
await assert.rejects(pickPoolDispatch(context, 'test', { customerId: '9', dispatchNo: 'DS-A' }, async () => false), /PDA_PICK_FAILED:DS-A/)
|
|
})
|
|
|
|
test('foreign read rejection requires actual access/not-found code and no leaked business payload', () => {
|
|
for (const response of [{ http: 403, body: { code: 'A0403' } }, { http: 404, body: { code: 'A0404', data: null } },
|
|
{ http: 200, body: { code: 'A0403' } }, { http: 200, body: { code: 'A0404' } }]) assert.equal(poolReadIsDenied(response), true)
|
|
for (const response of [{ http: 200, body: { code: '200' } }, { http: 401 }, { http: 409 }, { http: 500 },
|
|
{ http: 200, body: { code: 'A0409' } }, { http: 403, body: { data: { orderNo: 'PRIVATE' } } }]) assert.equal(poolReadIsDenied(response), false)
|
|
})
|
|
|
|
test('pool commercial facts accept nullish Jackson fields but reject invented container or palletizing answers', () => {
|
|
for (const type of ['LOCAL_LOOSEBOARD', 'US_TRUCK']) {
|
|
for (const summary of [{}, { containerType: null, palletRequired: null }, { containerType: undefined, palletRequired: undefined }]) {
|
|
assert.doesNotThrow(() => assertPoolUnknownCommercialFacts(type, summary))
|
|
}
|
|
for (const containerType of ['40HQ', '40GP', '45HQ', '', 'UNKNOWN', false, 0]) {
|
|
assert.throws(() => assertPoolUnknownCommercialFacts(type, { containerType }), /CONTAINER_TYPE_MUST_REMAIN_UNKNOWN/)
|
|
}
|
|
assert.throws(() => assertPoolUnknownCommercialFacts(type, null), /SUMMARY_REQUIRED/)
|
|
}
|
|
for (const palletRequired of ['YES', 'NO', '', 'UNKNOWN', false, 0]) {
|
|
assert.throws(() => assertPoolUnknownCommercialFacts('LOCAL_LOOSEBOARD', { palletRequired }), /PALLETIZING_SERVICE_MUST_REMAIN_UNKNOWN/)
|
|
}
|
|
assert.throws(() => assertPoolUnknownCommercialFacts('OTHER', {}), /SUMMARY_REQUIRED/)
|
|
})
|
|
|
|
test('owner rejection sends a valid current edit rather than malformed input', () => {
|
|
const source = { tripRecordVersion: 5, offerRecordVersion: 7, recordVersion: 9, customerId: '42', businessType: 'US_TRUCK',
|
|
deliveryMode: 'SELF_DELIVERY', estimatedArrivalAt: '2030-01-01T00:00:00Z', expectedPalletCount: 1,
|
|
cargo: { destinationKey: 'FBA:1', packageCount: 1, palletSpaces: 4 }, bookingNo: 'FB-1', actions: { canEdit: false } }
|
|
const body = poolInquiryWrite(source, 'CURRENT-KEY')
|
|
assert.equal(body.idempotencyKey, 'CURRENT-KEY')
|
|
assert.equal(body.tripRecordVersion, 5)
|
|
assert.equal(body.offerRecordVersion, 7)
|
|
assert.equal(body.recordVersion, 9)
|
|
assert.deepEqual(body.cargo, source.cargo)
|
|
assert.equal(body.customerId, '42')
|
|
assert.equal(body.estimatedArrivalAt, source.estimatedArrivalAt)
|
|
assert.equal('actions' in body, false)
|
|
assert.equal('bookingNo' in body, false)
|
|
})
|
|
|
|
test('BOUND accounting detects stale reservation, omitted actual pallet and wrong destination in every dimension', () => {
|
|
const planned = { palletSpaces: 3, weightKg: 300, volumeCbm: 3 }, reserved = { palletSpaces: 4, weightKg: 100, volumeCbm: 1 }
|
|
const capacity = { palletSpaces: 30, weightKg: 18000, volumeCbm: 90 }
|
|
const remaining = { palletSpaces: 23, weightKg: 17600, volumeCbm: 86 }
|
|
const offer = { status: 'OPEN', capacityKnown: true, canConfirm: true,
|
|
segments: [{ fromIndex: 0, toIndex: 1, planned, reserved, remaining }], destinations: [{ destinationKey: 'FBA:1', remaining }] }
|
|
assert.doesNotThrow(() => assertPoolBoundCapacity(offer, 'FBA:1', planned, reserved, capacity))
|
|
for (const dimension of ['palletSpaces', 'weightKg', 'volumeCbm']) {
|
|
for (const section of ['planned', 'reserved', 'remaining']) {
|
|
const altered = structuredClone(offer); altered.segments[0][section][dimension]++
|
|
assert.throws(() => assertPoolBoundCapacity(altered, 'FBA:1', planned, reserved, capacity), /DOUBLE_COUNT_OR_MISSING/)
|
|
}
|
|
}
|
|
assert.throws(() => assertPoolBoundCapacity({ ...offer, canConfirm: false }, 'FBA:1', planned, reserved, capacity), /OPEN_KNOWN/)
|
|
assert.throws(() => assertPoolBoundCapacity(offer, 'FBA:OTHER', planned, reserved, capacity), /DESTINATION/)
|
|
})
|
|
|
|
test('binding check requires OPEN invalidation, replan still blocked, then explicit resume in that order', async () => {
|
|
const events = [], check = (label, condition) => assert.ok(condition, label)
|
|
let stage = 'INVALID'
|
|
const snapshots = {
|
|
INVALID: { status: 'OPEN', capacityKnown: false, canConfirm: false, blockReason: '计划容量待调度核对' },
|
|
REPLANNED: { status: 'OPEN', capacityKnown: false, canConfirm: false, blockReason: '发布承诺已变化,请调度重新核对并恢复接单' },
|
|
RESUMED: { status: 'OPEN', capacityKnown: true, canConfirm: true },
|
|
}
|
|
const result = await verifyPoolBindingRevalidation({ check,
|
|
offerDetail: async () => { events.push(`GET-${stage}`); return { offer: snapshots[stage] } },
|
|
blockedConfirm: async reason => { events.push(reason) },
|
|
replan: async () => { events.push('REPLAN'); stage = 'REPLANNED' },
|
|
resume: async current => { assert.equal(current, snapshots.REPLANNED); events.push('RESUME'); stage = 'RESUMED'; return snapshots.RESUMED },
|
|
})
|
|
assert.equal(result.canConfirm, true)
|
|
assert.deepEqual(events, ['GET-INVALID', 'BIND-INVALIDATED', 'REPLAN', 'GET-REPLANNED', 'REPLANNED-NOT-RESUMED', 'RESUME'])
|
|
})
|
|
|
|
test('closed publication or automatic resumption cannot masquerade as OPEN binding revalidation', async () => {
|
|
const check = (label, condition) => assert.ok(condition, label)
|
|
await assert.rejects(verifyPoolBindingRevalidation({ check, offerDetail: async () => ({ offer: { status: 'CLOSED', canConfirm: false } }),
|
|
replan: () => assert.fail('must stop before replan') }), /remains OPEN/)
|
|
let reads = 0
|
|
await assert.rejects(verifyPoolBindingRevalidation({ check,
|
|
offerDetail: async () => ({ offer: ++reads === 1 ? { status: 'OPEN', capacityKnown: false, canConfirm: false, blockReason: '计划容量待调度核对' }
|
|
: { status: 'OPEN', capacityKnown: true, canConfirm: true } }), replan: async () => {}, blockedConfirm: async () => {},
|
|
resume: () => assert.fail('must stop before resume') }), /cannot silently resume/)
|
|
})
|
|
|
|
test('confirmed cancellation verifies both commercial types and reuses exact successful cancellation request', async () => {
|
|
for (const businessType of ['LOCAL_LOOSEBOARD', 'US_TRUCK']) {
|
|
let current = { bookingNo: 'FB-1', offerNo: 'FO-1', customerId: '9', businessType, recordVersion: 1, status: 'DRAFT' }
|
|
let cancellationBody, cancellationCount = 0, commercialStatus = 'WAITING_INBOUND'
|
|
const offer = count => ({ capacityKnown: true, destinations: [{ destinationKey: 'FBA:1', remaining: { palletSpaces: count } }] })
|
|
const request = async (method, path, body) => {
|
|
if (method === 'POST' && path.endsWith('/confirm')) {
|
|
current = { ...current, status: 'CONFIRMED', businessOrderNo: 'BUSINESS-1', recordVersion: 2 }
|
|
return { inquiry: { ...current }, offer: offer(11) }
|
|
}
|
|
if (method === 'POST' && path.endsWith('/cancel')) {
|
|
cancellationCount++
|
|
if (cancellationBody) assert.equal(body, cancellationBody)
|
|
else cancellationBody = body
|
|
commercialStatus = 'CANCELLED'; current = { ...current, status: 'CANCELLED', recordVersion: 3 }
|
|
return { inquiry: { ...current }, offer: offer(12), replayed: cancellationCount > 1 }
|
|
}
|
|
if (path === '/commercial') return { summary: { status: commercialStatus, fleetArrangement: { bookingNo: 'FB-1' } } }
|
|
if (path.endsWith('/FO-1')) return { offer: offer(12) }
|
|
assert.fail(`unexpected ${method} ${path}`)
|
|
}
|
|
const result = await verifyPoolConfirmedCancellation({ inquiry: { ...current }, destinationKey: 'FBA:1', request,
|
|
check: (label, condition) => assert.ok(condition, label), latest: async () => ({ ...current }),
|
|
command: (row, label) => ({ recordVersion: row.recordVersion, idempotencyKey: label }), businessPath: () => '/commercial',
|
|
dispatcherToken: 'offline', label: businessType })
|
|
assert.equal(result.businessType, businessType)
|
|
assert.equal(result.status, 'CANCELLED')
|
|
assert.equal(cancellationCount, 2)
|
|
assert.equal(result.remainingPalletSpaces, 12)
|
|
}
|
|
})
|
|
|
|
|
|
test('pool orchestration keeps native one-main boundaries, explicit reviews and real loading before whole arrangement', () => {
|
|
const source = readFileSync(new URL('./fleet-capacity-pool-test-env.mjs', import.meta.url), 'utf8')
|
|
for (const old of ['controlledPalletMeasurements(', '/external-freight', '/loading-review`', "departed.status === 'IN_TRANSIT'", 'sourceStage:', "'/dispatches/pre-arrange'"]) assert.equal(source.includes(old), false, old)
|
|
assert.match(source, /testPlannedCapacity\(plan\.cargo, detail\.trip\.stops\)/)
|
|
assert.match(source, /actual: false/)
|
|
assert.match(source, /arranged\.booking\.dispatchNo === fixture\.dispatchNo/)
|
|
assert.match(source, /\['submit-review', 'dispatch-review', 'loading-review'\]/)
|
|
const pick = source.indexOf('const namespace = await pickPoolDispatch('), load = source.indexOf('await confirmFleetLoading('), arrange = source.indexOf('await arrangeDispatchDelivery('), depart = source.indexOf("const departed = await request('POST', departPath")
|
|
assert.ok(pick > 0 && pick < load && load < arrange && arrange < depart)
|
|
assert.match(source, /fixture\.loadingMeasurements/)
|
|
assert.match(source, /recordVersion: current\.recordVersion/)
|
|
assert.match(source, /readyTask\.actions\?\.DEPART\?\.allowed === true/)
|
|
assert.match(source, /JSON\.stringify\(actual\.fees\) === JSON\.stringify\(signed\.fees\)/)
|
|
assert.match(source, /sameCustomerOrders\.every\(source => actual\.operations\.filter/)
|
|
})
|
|
|
|
test('pool execution explicitly selects capacity verification before handing off the shared runner', async () => {
|
|
const config = parsePoolArguments(['--execute', '--environment', 'TEST', '--run-id', 'pool-scope', '--warehouse-id', '10', '--destination-warehouse-id', '11'])
|
|
let selected
|
|
await assert.rejects(runPoolAcceptance(config, { env: {}, runner: async (actual, options) => {
|
|
assert.equal(actual, config)
|
|
selected = options.verificationScope
|
|
throw Error('STOP_BEFORE_ENVIRONMENT_ACCESS')
|
|
} }), /STOP_BEFORE_ENVIRONMENT_ACCESS/)
|
|
assert.equal(selected, 'CAPACITY_POOL')
|
|
})
|