试试
This commit is contained in:
@@ -168,9 +168,6 @@ function createMockContext() {
|
||||
process.env.MOCK_PROMOTION_REDEMPTION_INITIATE_SOURCE || 'PROMOTION_MODULE'
|
||||
const promotionRedemptionSourceBucket =
|
||||
(process.env.MOCK_PROMOTION_REDEMPTION_SOURCE_BUCKET || 'm-comp').trim().toLowerCase()
|
||||
const promotionRedemptionSimulateErrorAfterBridge =
|
||||
(process.env.MOCK_PROMOTION_REDEMPTION_SIMULATE_ERROR_AFTER_BRIDGE || 'false').toLowerCase() ===
|
||||
'true'
|
||||
const defaultPromotionRedemptionIdStart = resolveDefaultPromotionRedemptionIdStart()
|
||||
const promotionRedemptionIdStartRaw =
|
||||
Number(process.env.MOCK_PROMOTION_REDEMPTION_ID_START || defaultPromotionRedemptionIdStart)
|
||||
@@ -209,15 +206,11 @@ function createMockContext() {
|
||||
process.env.MOCK_LDAP_ALLOW_ANY_USER_GROUP_CN || 'SG-APP-EWALLET-SUPER-ADMIN'
|
||||
const ldapAllowAnyUserMailDomain =
|
||||
process.env.MOCK_LDAP_ALLOW_ANY_USER_MAIL_DOMAIN || 'macausjm-glp.com'
|
||||
const ldapForceNoSuchObject =
|
||||
(process.env.MOCK_LDAP_FORCE_NO_SUCH_OBJECT || '').toLowerCase() === 'true'
|
||||
const ldapForceNoSuchObjectMatch =
|
||||
process.env.MOCK_LDAP_FORCE_NO_SUCH_OBJECT_MATCH || 'OU=macauin-glp,DC=com'
|
||||
|
||||
const mockProfile = {
|
||||
firstName: process.env.MOCK_MEMBER_FIRST_NAME || 'Gary',
|
||||
lastName: process.env.MOCK_MEMBER_LAST_NAME || 'Chan',
|
||||
nickName: process.env.MOCK_MEMBER_NICK_NAME || 'xxx',
|
||||
nickName: process.env.MOCK_MEMBER_NICK_NAME || '陳加里',
|
||||
tier: process.env.MOCK_MEMBER_TIER || 'Novel',
|
||||
eBonus: process.env.MOCK_MEMBER_EBONUS || '0',
|
||||
phoneNum: process.env.MOCK_MEMBER_PHONE || '+853-68282140',
|
||||
@@ -309,7 +302,7 @@ function createMockContext() {
|
||||
firstName: 'Gary',
|
||||
lastName: 'Chan',
|
||||
middleName: 'David',
|
||||
nickName: 'xxxx',
|
||||
nickName: '陳加里',
|
||||
image: '',
|
||||
},
|
||||
attribute: {
|
||||
@@ -1138,22 +1131,6 @@ function createMockContext() {
|
||||
return false
|
||||
}
|
||||
|
||||
function findRecordedRedeemedPromotionOutcome(redeemedId) {
|
||||
const numericRedeemedId = Number(redeemedId)
|
||||
if (!Number.isFinite(numericRedeemedId)) {
|
||||
return null
|
||||
}
|
||||
|
||||
for (const outcomeList of recordedRedeemedPromotionsByAccount.values()) {
|
||||
const found = outcomeList.find((item) => item?.redemptionId === numericRedeemedId)
|
||||
if (found) {
|
||||
return found
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// Task 10766: Return a deterministic redeem failure for the dedicated member so error rendering can be checked reliably.
|
||||
function getPlayerPromotionRedeemMock(accountNum) {
|
||||
if (isTask10766Account(accountNum)) {
|
||||
@@ -1245,7 +1222,6 @@ function createMockContext() {
|
||||
promotionRedemptionBridgeTimeoutMs,
|
||||
promotionRedemptionInitiateSource,
|
||||
promotionRedemptionSourceBucket,
|
||||
promotionRedemptionSimulateErrorAfterBridge,
|
||||
redeemedPromotionVoidErrorCode,
|
||||
redeemedPromotionVoidErrorMsg,
|
||||
redeemedPromotionVoidResult,
|
||||
@@ -1263,9 +1239,7 @@ function createMockContext() {
|
||||
ldapAllowAnyUserOu,
|
||||
ldapAllowAnyUserGroupCn,
|
||||
ldapAllowAnyUserMailDomain,
|
||||
ldapForceNoSuchObject,
|
||||
ldapForceNoSuchObjectMatch,
|
||||
},
|
||||
},
|
||||
edipForceErrorCode: process.env.MOCK_EDIP_FORCE_ERROR_CODE || '',
|
||||
edipForceErrorMsg: process.env.MOCK_EDIP_FORCE_ERROR_MSG || 'Mock EDIP token error',
|
||||
edipRefreshTokenMustExist:
|
||||
@@ -1301,7 +1275,6 @@ function createMockContext() {
|
||||
recordRedeemedPromotionOutcome,
|
||||
getRecordedRedeemedPromotionOutcomes,
|
||||
voidRecordedRedeemedPromotionOutcome,
|
||||
findRecordedRedeemedPromotionOutcome,
|
||||
getAccountSpecificRedeemedPromotionsFixture,
|
||||
cloneJsonValue,
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ function createMockLdapService({ ldapConfig }) {
|
||||
ldapAllowAnyUserOu,
|
||||
ldapAllowAnyUserGroupCn,
|
||||
ldapAllowAnyUserMailDomain,
|
||||
ldapForceNoSuchObject,
|
||||
ldapForceNoSuchObjectMatch,
|
||||
} = ldapConfig
|
||||
|
||||
function normalizeDn(value) {
|
||||
@@ -457,15 +455,6 @@ function createMockLdapService({ ldapConfig }) {
|
||||
const searchBase = resolveSearchBase(req.dn?.toString())
|
||||
const scope = req.scope || 'sub'
|
||||
|
||||
if (ldapForceNoSuchObject) {
|
||||
// Reproduce QA's "LDAP error code 32 - NO_OBJECT" from real AD.
|
||||
// The "best match of" suffix mirrors the AD DSID-0310028D / NameErr output seen on QA.
|
||||
const match = ldapForceNoSuchObjectMatch || 'OU=macauin-glp,DC=com'
|
||||
const error = new ldap.NoSuchObjectError()
|
||||
error.message = `NO_OBJECT: best match of: '${match}'\n000001`
|
||||
return next(error)
|
||||
}
|
||||
|
||||
if (ldapAllowAnyUserMode) {
|
||||
let hasAnyModeResult = false
|
||||
const usernames = dedupeStringValues(extractEqFilterValues(req.filter, 'sAMAccountName'))
|
||||
|
||||
@@ -268,10 +268,15 @@ function resolveTargetPrizeValue(prize, sourceBucket, promotion) {
|
||||
return bucketPrice
|
||||
}
|
||||
|
||||
// When the source bucket price is absent, leave the value unspecified (null)
|
||||
// so the redemption payload sends valueUsed: null and eWallet computes it
|
||||
// from its own configuration (instead of falling back to prizeValue).
|
||||
return null
|
||||
if (Number.isFinite(prize?.prizeValue)) {
|
||||
return prize.prizeValue
|
||||
}
|
||||
|
||||
if (Number.isFinite(promotion?.toEarn1Unit)) {
|
||||
return promotion.toEarn1Unit
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function buildPromotionMetadata(requestData, promotion, redemptionId) {
|
||||
@@ -443,11 +448,7 @@ async function bridgePromotionRedeemToEwallet({
|
||||
accountNum,
|
||||
backdate = false,
|
||||
}) {
|
||||
const { log } = require('../../../logger')
|
||||
const requestData = requestBody?.data || {}
|
||||
log(
|
||||
`[BRIDGE] start account=${accountNum} promotionId=${requestData.promotionId} outcomeId=${requestData.outcomeId} backdate=${backdate}`,
|
||||
)
|
||||
const selection = context.resolvePromotionRedeemSelection(
|
||||
accountNum,
|
||||
requestData.promotionId,
|
||||
@@ -501,7 +502,6 @@ async function bridgePromotionRedeemToEwallet({
|
||||
throw new Error('Promotion bridge login did not return an access token')
|
||||
}
|
||||
|
||||
log(`[BRIDGE] calling eWallet POST ${redemptionUrl} (sync)`)
|
||||
const redemptionResponseBody = await requestJson(
|
||||
redemptionUrl,
|
||||
createRequestOptions(
|
||||
@@ -518,12 +518,10 @@ async function bridgePromotionRedeemToEwallet({
|
||||
context.promotionRedemptionBridgeTimeoutMs,
|
||||
),
|
||||
)
|
||||
log(`[BRIDGE][SYNC-RAW] ${JSON.stringify(redemptionResponseBody)}`)
|
||||
const redemptionResponseData = unwrapApiResponseBody(
|
||||
redemptionResponseBody,
|
||||
'Promotion bridge prize redemption',
|
||||
)
|
||||
log(`[BRIDGE][SYNC-DATA] ${JSON.stringify(redemptionResponseData)}`)
|
||||
|
||||
if (!redemptionResponseData?.publicId) {
|
||||
throw new Error('Promotion bridge prize redemption did not return a publicId')
|
||||
@@ -557,10 +555,6 @@ function registerPlayerPromotionRedeemRoute({ app, context }) {
|
||||
]
|
||||
|
||||
routes.forEach((route) => app.post(route, async (req, res) => {
|
||||
const { log } = require('../../../logger')
|
||||
log(
|
||||
`[REDEEM-RECV] ${route} account=${context.resolveAccountNum(req.body)} promotionId=${req.body?.data?.promotionId} outcomeId=${req.body?.data?.outcomeId}`,
|
||||
)
|
||||
const headerMergedRequestBody = mergeIssueTargetToWalletOverrides(req.body, req.headers)
|
||||
const accountNum = context.resolveAccountNum(headerMergedRequestBody)
|
||||
const normalizedRequestBody = mergeRuntimeIssueTargetToWalletOverrides(
|
||||
@@ -574,7 +568,6 @@ function registerPlayerPromotionRedeemRoute({ app, context }) {
|
||||
let errorMsg = redeemMock.errorMsg
|
||||
let result = redeemMock.result
|
||||
|
||||
let simulatePublicId = null
|
||||
if (result && !errorCode) {
|
||||
try {
|
||||
if (context.promotionRedemptionBridgeEnabled) {
|
||||
@@ -584,18 +577,7 @@ function registerPlayerPromotionRedeemRoute({ app, context }) {
|
||||
accountNum,
|
||||
backdate: backdateRedeemRequest,
|
||||
})
|
||||
if (context.promotionRedemptionSimulateErrorAfterBridge) {
|
||||
// Plan C: simulate the promotion error AFTER the bridge created the
|
||||
// eWallet redemption, but do NOT record a redeemed promotion in the
|
||||
// Mock store so the history won't show a non-voided "success".
|
||||
simulatePublicId =
|
||||
bridgeResult.redeemedOutcome?.outcome?.redeemedList?.[0]?.transId || null
|
||||
errorCode = 'SIMULATED_PROMO_REDEEM_ERROR'
|
||||
errorMsg = `Simulated promotion redeem failure after eWallet sync created publicId=${simulatePublicId}`
|
||||
result = false
|
||||
} else {
|
||||
context.recordRedeemedPromotionOutcome(accountNum, bridgeResult.redeemedOutcome)
|
||||
}
|
||||
context.recordRedeemedPromotionOutcome(accountNum, bridgeResult.redeemedOutcome)
|
||||
} else if (backdateRedeemRequest) {
|
||||
const mockResult = createMockPromotionRedeemResult({
|
||||
context,
|
||||
@@ -617,7 +599,6 @@ function registerPlayerPromotionRedeemRoute({ app, context }) {
|
||||
errorMsg,
|
||||
accountNum,
|
||||
result,
|
||||
...(simulatePublicId ? { redemptionPublicId: simulatePublicId } : {}),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1,216 +1,23 @@
|
||||
const { log } = require('../../../logger')
|
||||
|
||||
function joinUrl(baseUrl, pathname) {
|
||||
const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`
|
||||
return new URL(pathname.replace(/^\//, ''), normalizedBaseUrl).toString()
|
||||
}
|
||||
|
||||
function createRequestOptions(method, body, headers, timeoutMs) {
|
||||
return {
|
||||
method,
|
||||
headers,
|
||||
body: body === undefined ? undefined : JSON.stringify(body),
|
||||
signal: AbortSignal.timeout(timeoutMs),
|
||||
timeoutMs,
|
||||
}
|
||||
}
|
||||
|
||||
async function requestJson(url, options) {
|
||||
let response
|
||||
try {
|
||||
response = await fetch(url, options)
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error)
|
||||
if (error?.name === 'TimeoutError' || /aborted due to timeout/i.test(message)) {
|
||||
throw new Error(
|
||||
`Timeout after ${options.timeoutMs}ms on ${options.method || 'GET'} request for "${url}"`,
|
||||
)
|
||||
}
|
||||
throw error
|
||||
}
|
||||
const rawBody = await response.text()
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`HTTP ${response.status} ${response.statusText} on ${options.method || 'GET'} request for "${url}"${
|
||||
rawBody ? `: ${rawBody}` : ''
|
||||
}`,
|
||||
)
|
||||
}
|
||||
if (!rawBody) {
|
||||
return null
|
||||
}
|
||||
try {
|
||||
return JSON.parse(rawBody)
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Invalid JSON response on ${options.method || 'GET'} request for "${url}": "${rawBody}"`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function unwrapApiResponseBody(responseBody, requestLabel) {
|
||||
if (!responseBody || typeof responseBody !== 'object') {
|
||||
throw new Error(`${requestLabel} returned an empty response body`)
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(responseBody, 'success')) {
|
||||
if (responseBody.success === false) {
|
||||
const detail =
|
||||
responseBody.error?.detail || responseBody.message || `${requestLabel} returned an error`
|
||||
throw new Error(detail)
|
||||
}
|
||||
return responseBody.data
|
||||
}
|
||||
return responseBody
|
||||
}
|
||||
|
||||
async function loginToEwallet(context) {
|
||||
const baseUrl = context.promotionRedemptionBridgeBaseUrl
|
||||
if (!baseUrl) {
|
||||
throw new Error('promotionRedemptionBridgeBaseUrl is not configured; cannot bridge void to eWallet')
|
||||
}
|
||||
|
||||
const loginUsername = context.promotionRedemptionBridgeLoginUsername || 'mock.gateway'
|
||||
const authUrl = joinUrl(baseUrl, '/api/v1/auth/login')
|
||||
const authResp = await requestJson(
|
||||
authUrl,
|
||||
createRequestOptions(
|
||||
'POST',
|
||||
{
|
||||
username: loginUsername,
|
||||
password: context.promotionRedemptionBridgeLoginPassword,
|
||||
},
|
||||
{ 'Content-Type': 'application/json' },
|
||||
context.promotionRedemptionBridgeTimeoutMs,
|
||||
),
|
||||
)
|
||||
const authData = unwrapApiResponseBody(authResp, 'Promotion void bridge login')
|
||||
const accessToken = authData?.accessToken
|
||||
if (!accessToken) {
|
||||
throw new Error('Promotion void bridge login did not return an access token')
|
||||
}
|
||||
return accessToken
|
||||
}
|
||||
|
||||
// Mirror playerPromotionRedeem.bridgePromotionRedeemToEwallet: in production the promotion /
|
||||
// Bally void first calls eWallet's own prize-redemption void, and only after that succeeds does
|
||||
// Bally mark its promotion record voided. This Mock simulates that cascade so the eWallet side
|
||||
// (prize_redemption_transactions / prize_redemption_void_transactions) is voided before the
|
||||
// recorded promotion file flips isVoided.
|
||||
//
|
||||
// A promotion outcome may contain multiple redeemed prizes, each with its own eWallet
|
||||
// prize-redemption publicId (transId) nested under outcome.redeemedList. Void every one of them.
|
||||
async function voidPrizeRedemptionInEwallet(context, { accessToken, transId, correlationId, voidReason, initiateType, initiateSource, schema, data }) {
|
||||
const baseUrl = context.promotionRedemptionBridgeBaseUrl
|
||||
const voidUrl = joinUrl(baseUrl, `/api/v1/prize-redemptions/${transId}/sync`)
|
||||
log(`[BRIDGE][VOID] calling eWallet DELETE ${voidUrl} (correlationId=${correlationId}, transId=${transId})`)
|
||||
const voidResp = await requestJson(
|
||||
voidUrl,
|
||||
createRequestOptions(
|
||||
'DELETE',
|
||||
{
|
||||
correlationId,
|
||||
voidReason,
|
||||
initiateType,
|
||||
initiateSource,
|
||||
},
|
||||
{
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
'Client-Machine-Id': schema?.computerName || 'mock-gateway',
|
||||
'Content-Type': 'application/json',
|
||||
'Location-Code': data?.locationCode || 'MOCK',
|
||||
'Property-Code': data?.casinoCode || 'GLP',
|
||||
'X-Real-IP': schema?.ipAddress || '',
|
||||
},
|
||||
context.promotionRedemptionBridgeTimeoutMs,
|
||||
),
|
||||
)
|
||||
const voidData = unwrapApiResponseBody(voidResp, 'Promotion void bridge prize redemption void')
|
||||
log(`[BRIDGE][VOID] eWallet void result overallStatus=${voidData?.overallStatus} (transId=${transId})`)
|
||||
// eWallet treats FAILED / COMPENSATED / PENDING / PROCESSING as errors; a successful void
|
||||
// comes back as VOIDED (or COMPLETED). Anything else is treated as success here.
|
||||
const failedStatuses = ['FAILED', 'COMPENSATED', 'PENDING', 'PROCESSING']
|
||||
if (voidData?.overallStatus && failedStatuses.includes(voidData.overallStatus)) {
|
||||
throw new Error(`eWallet prize redemption void finished with status ${voidData.overallStatus} (transId=${transId})`)
|
||||
}
|
||||
return voidData
|
||||
}
|
||||
|
||||
function registerRedeemedPromotionVoidRoute({ app, context }) {
|
||||
const routes = [
|
||||
'/ewl/promotion/v1/redeemedpromotion/void',
|
||||
'/ewl/bal/v1/redeemedpromotion/void',
|
||||
]
|
||||
|
||||
routes.forEach((route) =>
|
||||
app.post(
|
||||
route,
|
||||
async (req, res) => {
|
||||
const schema = req.body?.schema || {}
|
||||
const data = req.body?.data || {}
|
||||
const redeemedId = data.redeemedId
|
||||
const loginId = data.loginId || ''
|
||||
routes.forEach((route) => app.post(route, (req, res) => {
|
||||
if (context.redeemedPromotionVoidResult) {
|
||||
context.voidRecordedRedeemedPromotionOutcome(
|
||||
req.body?.data?.redeemedId,
|
||||
req.body?.data?.loginId || '',
|
||||
)
|
||||
}
|
||||
|
||||
// eWallet void payload. The Bally promotion void request does not carry these, so derive them.
|
||||
const correlationId = `VOID_PROMO_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`
|
||||
const voidReason = data?.remark || 'PROMOTION_VOID'
|
||||
const initiateType = data?.initiateType || 'SYSTEM'
|
||||
const initiateSource = data?.initiateSource || 'WEB_APP'
|
||||
|
||||
try {
|
||||
// Resolve the eWallet prize-redemption publicId(s) (transId) tied to this promotion
|
||||
// redemption. They are nested under outcome.redeemedList[].transId in the recorded
|
||||
// promotion (NOT at the top level of the recorded outcome entry). A promotion outcome
|
||||
// may contain multiple redeemed prizes, each with its own transId.
|
||||
const recordedOutcome = context.findRecordedRedeemedPromotionOutcome
|
||||
? context.findRecordedRedeemedPromotionOutcome(redeemedId)
|
||||
: null
|
||||
|
||||
const transIds = recordedOutcome?.outcome?.redeemedList
|
||||
? recordedOutcome.outcome.redeemedList.map((r) => r.transId).filter(Boolean)
|
||||
: []
|
||||
|
||||
if (transIds.length > 0 && context.promotionRedemptionBridgeBaseUrl) {
|
||||
const accessToken = await loginToEwallet(context)
|
||||
for (const transId of transIds) {
|
||||
await voidPrizeRedemptionInEwallet(context, {
|
||||
accessToken,
|
||||
transId,
|
||||
correlationId,
|
||||
voidReason,
|
||||
initiateType,
|
||||
initiateSource,
|
||||
schema,
|
||||
data,
|
||||
})
|
||||
}
|
||||
log(`[BRIDGE][VOID] eWallet prize redemption void succeeded for transIds=${transIds.join(',')}`)
|
||||
} else {
|
||||
log(
|
||||
`[BRIDGE][VOID] skipped eWallet void bridge (transIds=${JSON.stringify(transIds)}, baseUrl=${context.promotionRedemptionBridgeBaseUrl})`,
|
||||
)
|
||||
}
|
||||
|
||||
// Only mark the recorded promotion as voided after the eWallet void succeeded.
|
||||
if (context.redeemedPromotionVoidResult) {
|
||||
context.voidRecordedRedeemedPromotionOutcome(redeemedId, loginId)
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
errorCode: context.redeemedPromotionVoidErrorCode,
|
||||
errorMsg: context.redeemedPromotionVoidErrorMsg,
|
||||
result: context.redeemedPromotionVoidResult,
|
||||
})
|
||||
} catch (error) {
|
||||
log(`[BRIDGE][VOID] eWallet void bridge failed: ${error.message}`)
|
||||
return res.status(200).json({
|
||||
errorCode: context.redeemedPromotionVoidErrorCode || 'EWALLET_VOID_FAILED',
|
||||
errorMsg: context.redeemedPromotionVoidErrorMsg || error.message,
|
||||
result: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
return res.status(200).json({
|
||||
errorCode: context.redeemedPromotionVoidErrorCode,
|
||||
errorMsg: context.redeemedPromotionVoidErrorMsg,
|
||||
result: context.redeemedPromotionVoidResult,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
module.exports = registerRedeemedPromotionVoidRoute
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Message Gateway 内容发送接口 Mock:POST /ewl/msgw/v1/messages/content/send
|
||||
// 后端短信已从旧 SMS Hub(/SMSToken + /SMSRequest/Post)切换到该接口,认证复用 EDIP Token。
|
||||
// 响应严格按真实网关信封:HTTP 200 + status/errorCode,成功时 smsid 为全小写字段、errorCode 为空字符串。
|
||||
function registerMessageGatewayContentSendRoute({ app }) {
|
||||
app.post('/ewl/msgw/v1/messages/content/send', (req, res) => {
|
||||
const data = req.body?.data || {}
|
||||
const recipients = Array.isArray(data.recipients) ? data.recipients : []
|
||||
|
||||
// 错误注入:MOCK_SMS_FORCE_ERROR_CODE=8923 模拟供应商暂不可用(后端应重试),
|
||||
// MOCK_SMS_FORCE_ERROR_CODE=8907 模拟号码非法(后端不应重试)
|
||||
const forcedErrorCode = process.env.MOCK_SMS_FORCE_ERROR_CODE || ''
|
||||
if (forcedErrorCode) {
|
||||
return res.status(200).json({
|
||||
status: false,
|
||||
errorCode: forcedErrorCode,
|
||||
message: process.env.MOCK_SMS_FORCE_ERROR_MSG || 'Mock message gateway error',
|
||||
data: null,
|
||||
})
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
status: true,
|
||||
errorCode: '',
|
||||
message: '',
|
||||
data: {
|
||||
smsid: `mock-sms-${Date.now()}`,
|
||||
smsStatus: recipients.map((r) => ({
|
||||
recipient: r?.phone || '',
|
||||
status: 'QUEUED',
|
||||
})),
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = registerMessageGatewayContentSendRoute
|
||||
@@ -21,6 +21,7 @@ const registerPlayerPromotionFulfillmentJourneyDetailRoute = require('./ewl/bal/
|
||||
const registerPrizeRedemptionsSyncRoute = require('./api/v1/prizeRedemptionsSync')
|
||||
const registerPromotionRedeemFulfillmentOverridesRoute = require('./mockApi/promotionRedeemFulfillmentOverrides')
|
||||
const registerSmsPortalRoutes = require('./sms/smsPortal')
|
||||
const registerMessageGatewayContentSendRoute = require('./ewl/msgw/contentSend')
|
||||
|
||||
function registerRoutes({ app, context, ldapService }) {
|
||||
registerHealthzRoute({ app, ldapService })
|
||||
@@ -46,6 +47,7 @@ function registerRoutes({ app, context, ldapService }) {
|
||||
registerPrizeRedemptionsSyncRoute({ app, context })
|
||||
registerPromotionRedeemFulfillmentOverridesRoute({ app, context })
|
||||
registerSmsPortalRoutes({ app })
|
||||
registerMessageGatewayContentSendRoute({ app })
|
||||
}
|
||||
|
||||
module.exports = { registerRoutes }
|
||||
|
||||
@@ -9,9 +9,6 @@ const { registerRoutes } = require('./routes/registerRoutes')
|
||||
const app = express()
|
||||
app.use(express.json({ limit: '2mb' }))
|
||||
|
||||
const { requestLogger, log } = require('./logger')
|
||||
app.use(requestLogger)
|
||||
|
||||
const context = createMockContext()
|
||||
const ldapService = createMockLdapService({ ldapConfig: context.ldap })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user