初始化

This commit is contained in:
DESKTOP-U5J7A7B\Willtech007
2026-10-12 17:55:59 +08:00
parent 54b4d8f8c5
commit 633690b0c4
52 changed files with 15478 additions and 0 deletions
+199
View File
@@ -0,0 +1,199 @@
const test = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const os = require('node:os')
const path = require('node:path')
const { createMockContext } = require('../src/context/createMockContext')
function withEnv(overrides, fn) {
const previousValues = new Map()
for (const [key, value] of Object.entries(overrides)) {
previousValues.set(key, process.env[key])
if (value === undefined) {
delete process.env[key]
} else {
process.env[key] = value
}
}
try {
return fn()
} finally {
for (const [key, value] of previousValues.entries()) {
if (value === undefined) {
delete process.env[key]
} else {
process.env[key] = value
}
}
}
}
test('uses a timestamp seed when MOCK_PROMOTION_REDEMPTION_ID_START is unset', () =>
withEnv(
{
MOCK_PROMOTION_REDEMPTION_ID_START: undefined,
MOCK_REDEEMED_PROMOTION_RECORDING_ENABLED: 'false',
},
() => {
const originalDateNow = Date.now
Date.now = () => 1760000000123
try {
const context = createMockContext()
assert.equal(context.nextMockPromotionRedemptionId(), 1760000000)
assert.equal(context.nextMockPromotionRedemptionId(), 1760000001)
} finally {
Date.now = originalDateNow
}
},
))
test('falls back to an int-safe timestamp seed when configured redemption id start is out of range', () =>
withEnv(
{
MOCK_PROMOTION_REDEMPTION_ID_START: '1774243846923',
MOCK_REDEEMED_PROMOTION_RECORDING_ENABLED: 'false',
},
() => {
const originalDateNow = Date.now
Date.now = () => 1760000000123
try {
const context = createMockContext()
assert.equal(context.nextMockPromotionRedemptionId(), 1760000000)
} finally {
Date.now = originalDateNow
}
},
))
test('fallback redeemed promotion detail consumes the same incrementing redemption id sequence', () =>
withEnv(
{
MOCK_PROMOTION_REDEMPTION_ID_START: '910000',
MOCK_REDEEMED_PROMOTION_RECORDING_ENABLED: 'false',
},
() => {
const context = createMockContext()
const firstOutcome = context.buildMockRedeemedPromotionOutcome({
data: { loginId: 'tester' },
schema: {},
})
const secondOutcome = context.buildMockRedeemedPromotionOutcome({
data: { loginId: 'tester' },
schema: {},
})
assert.equal(firstOutcome.redemptionId, 910000)
assert.equal(secondOutcome.redemptionId, 910001)
},
))
test('uses the birthday promotion fixture as the default promotion source when no override is configured', () =>
withEnv(
{
MOCK_PROMOTION_CAPTURE_FILE: undefined,
MOCK_REDEEMED_PROMOTION_RECORDING_ENABLED: 'false',
},
() => {
const context = createMockContext()
const promotions = context.getPromotionLists('910700001')
assert.equal(promotions.eligiblePromotionList.length, 1)
assert.equal(promotions.eligiblePromotionList[0].code, 'PROMO-BIRTHDAY-2026')
assert.equal(promotions.eligiblePromotionList[0].ruleId, 3800801)
assert.equal(promotions.eligiblePromotionList[0].outcomeList.length, 3)
assert.equal(promotions.eligiblePromotionList[0].isEntitled, true)
},
))
test('backdate promotions returned by the fixed fixture satisfy the frontend redeemable contract', () =>
withEnv(
{
MOCK_REDEEMED_PROMOTION_RECORDING_ENABLED: 'false',
},
() => {
const context = createMockContext()
const promotions = context.getBackdatePromotionLists('800038008')
assert.ok(promotions.entitledPromotionList.length > 0)
promotions.entitledPromotionList.forEach((item) => {
assert.equal(item.isEntitled, true)
assert.equal(item.isRedeemCompleted, false)
assert.ok(Number(item.awardsEntitled) > Number(item.awardsCount))
})
},
))
test('backdate promotions can be resolved through the default 80038008 member alias', () =>
withEnv(
{
MOCK_REDEEMED_PROMOTION_RECORDING_ENABLED: 'false',
},
() => {
const context = createMockContext()
const promotions = context.getBackdatePromotionLists('80038008')
assert.ok(promotions.entitledPromotionList.length > 0)
assert.equal(promotions.entitledPromotionList[0].ruleId, 3800801)
assert.equal(promotions.entitledPromotionList[0].isEntitled, true)
},
))
test('persists runtime recorded redeemed promotions and resumes redemption id sequence', () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mock-gateway-recording-'))
const recordingFile = path.join(tempDir, 'redeemed-promotions.recorded.json')
try {
withEnv(
{
MOCK_PROMOTION_REDEMPTION_ID_START: '910000',
MOCK_REDEEMED_PROMOTION_RECORDING_ENABLED: 'true',
MOCK_REDEEMED_PROMOTION_RECORDING_FILE: recordingFile,
},
() => {
const firstContext = createMockContext()
firstContext.recordRedeemedPromotionOutcome('80010991', {
redemptionId: 910005,
promotionId: 11225,
outcome: {
redeemedList: [
{
outcomeRemark: 'qa-ebonus-auto',
transId: 'tx-910005',
},
],
},
})
const persisted = JSON.parse(fs.readFileSync(recordingFile, 'utf8'))
assert.equal(persisted.accounts['80010991'][0].redemptionId, 910005)
const secondContext = createMockContext()
assert.equal(secondContext.getRecordedRedeemedPromotionOutcomes('80010991')[0].redemptionId, 910005)
assert.equal(secondContext.nextMockPromotionRedemptionId(), 910006)
},
)
} finally {
fs.rmSync(tempDir, { recursive: true, force: true })
}
})
test('account-specific redeemed promotions fixture preserves voidedByEmployeeId for the 2026-04-06 voided record', () => {
const context = createMockContext()
const fixture = context.getAccountSpecificRedeemedPromotionsFixture('100000059')
const targetOutcome = fixture.data.outcomeList.find(
(item) =>
item.voidedDtm === '2026-04-06T16:11:05.584548' &&
item.outcome?.redeemedList?.[0]?.transId === '43a9ab81-bbff-4812-bd64-bfd4eaa50d72',
)
assert.ok(targetOutcome)
assert.equal(targetOutcome.voidedBy, 'qa-randyng')
assert.equal(targetOutcome.voidedByEmployeeId, '171853')
})