42 lines
2.0 KiB
JavaScript
42 lines
2.0 KiB
JavaScript
import test from 'node:test'
|
|||
|
|
import assert from 'node:assert/strict'
|
||
|
|
import { approveReturnFixture } from './phase4-overseas-return-receipt.mjs'
|
||
|
|
|
||
|
|
function fixture({ failedReview = false, wrongOwner = false, stale = false } = {}) {
|
||
|
|
let status = 'PENDING_REVIEW'
|
||
|
|
const calls = []
|
||
|
|
const context = { marker: 'FIXTURE', context: { merchantQualificationFixture: { tenantId: '123' } },
|
||
|
|
addStep() {}, assert() {},
|
||
|
|
async requestOverseas(method, path, body, headers, token) {
|
||
|
|
calls.push({ method, path, body, headers, token })
|
||
|
|
if (method === 'POST') {
|
||
|
|
assert.equal(headers['X-Customer-Id'], '123')
|
||
|
|
assert.equal(body.decision, 'APPROVE')
|
||
|
|
if (!stale) status = 'PENDING_RECEIPT'
|
||
|
|
} else assert.equal(token, 'merchant-session')
|
||
|
|
return { http: 200, requestId: 'request', traceId: 'trace', body: {
|
||
|
|
code: wrongOwner ? 'A0404' : failedReview && method === 'POST' ? 'A0403' : '200',
|
||
|
|
data: { order: { returnNo: 'RT-FIXTURE', status, receivedQuantity: '0' } },
|
||
|
|
} }
|
||
|
|
} }
|
||
|
|
return { context, calls, created: { order: { returnNo: 'RT-FIXTURE', status } } }
|
||
|
|
}
|
||
|
|
test('review requires merchant ownership then explicit platform customer then merchant readback', async () => {
|
||
|
|
const f = fixture()
|
||
|
|
const result = await approveReturnFixture(f.context, 'merchant-session', f.created)
|
||
|
|
assert.equal(result.order.status, 'PENDING_RECEIPT')
|
||
|
|
assert.deepEqual(f.calls.map(c => c.method), ['GET', 'POST', 'GET'])
|
||
|
|
})
|
||
|
|
test('cannot approve inaccessible customer order', async () => {
|
||
|
|
const f = fixture({ wrongOwner: true })
|
||
|
|
await assert.rejects(approveReturnFixture(f.context, 'merchant-session', f.created))
|
||
|
|
assert.equal(f.calls.some(c => c.method === 'POST'), false)
|
||
|
|
})
|
||
|
|
test('permission failure and stale review readback stop the receipt chain', async () => {
|
||
|
|
for (const config of [{ failedReview: true }, { stale: true }]) {
|
||
|
|
const f = fixture(config)
|
||
|
|
await assert.rejects(approveReturnFixture(f.context, 'merchant-session', f.created))
|
||
|
|
assert.equal(f.calls.filter(c => c.method === 'POST').length, 1)
|
||
|
|
}
|
||
|
|
})
|