Skip to content

Commit

Permalink
fix(backend): combined_payment, ilp service tests (#2094)
Browse files Browse the repository at this point in the history
* fix(backend): combined_payment, ilp service tests

* chore(backend): format

* fix(backend): bad test refactor
  • Loading branch information
BlairCurrey authored Oct 23, 2023
1 parent b9ca3e6 commit 8fc554a
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 133 deletions.
259 changes: 129 additions & 130 deletions packages/backend/src/open_payments/payment/outgoing/service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ describe('OutgoingPaymentService', (): void => {
OutgoingPaymentState.Failed,
retryableError.message
)

expect(payment.stateAttempts).toBe(0)
await expectOutcome(payment, {
accountBalance: payment.debitAmount.value - 10n,
Expand All @@ -975,169 +975,168 @@ describe('OutgoingPaymentService', (): void => {
})

test('FAILED (non-retryable error)', async (): Promise<void> => {
const createdPayment = await setup({
receiver,
debitAmount,
method: 'ilp'
})

mockPaymentHandlerPay(
createdPayment,
incomingPayment,
new PaymentMethodHandlerError('Failed payment', {
description: '',
retryable: false
})
)

const payment = await processNext(
createdPayment.id,
OutgoingPaymentState.Failed,
'Failed payment'
)

await expectOutcome(payment, {
accountBalance: payment.debitAmount.value,
amountSent: 0n,
amountDelivered: 0n,
incomingPaymentReceived: incomingPayment.receivedAmount.value,
withdrawAmount: 0n
})
const createdPayment = await setup({
receiver,
debitAmount,
method: 'ilp'
})

test('SENDING→COMPLETED (partial payment, resume, complete)', async (): Promise<void> => {
const createdPayment = await setup({
receiver,
receiveAmount,
method: 'ilp'
})

await makeTransfer({
incomingPayment,
receiveAmount: 5n,
outgoingPayment: createdPayment,
debitAmount: 10n
mockPaymentHandlerPay(
createdPayment,
incomingPayment,
new PaymentMethodHandlerError('Failed payment', {
description: '',
retryable: false
})
)

mockPaymentHandlerPay(createdPayment, incomingPayment)

const payment = await processNext(
createdPayment.id,
OutgoingPaymentState.Completed
)
const payment = await processNext(
createdPayment.id,
OutgoingPaymentState.Failed,
'Failed payment'
)

await expectOutcome(payment, {
accountBalance: 0n,
amountSent: payment.debitAmount.value,
amountDelivered: payment.receiveAmount.value,
incomingPaymentReceived: payment.receiveAmount.value
})
await expectOutcome(payment, {
accountBalance: payment.debitAmount.value,
amountSent: 0n,
amountDelivered: 0n,
incomingPaymentReceived: incomingPayment.receivedAmount.value,
withdrawAmount: 0n
})
})

// Caused by retry after failed SENDING→COMPLETED transition commit.
test('COMPLETED (already fully paid)', async (): Promise<void> => {
const createdPayment = await setup(
{
receiver,
receiveAmount,
method: 'ilp'
},
receiveAmount
)

mockPaymentHandlerPay(createdPayment, incomingPayment)

await processNext(createdPayment.id, OutgoingPaymentState.Completed)
// Pretend that the transaction didn't commit.
await OutgoingPayment.query(knex)
.findById(createdPayment.id)
.patch({ state: OutgoingPaymentState.Sending })
test('SENDING→COMPLETED (partial payment, resume, complete)', async (): Promise<void> => {
const createdPayment = await setup({
receiver,
receiveAmount,
method: 'ilp'
})

mockPaymentHandlerPay(createdPayment, incomingPayment)
const payment = await processNext(
createdPayment.id,
OutgoingPaymentState.Completed
)
await expectOutcome(payment, {
accountBalance: 0n,
amountSent: payment.debitAmount.value,
amountDelivered: payment.receiveAmount.value,
incomingPaymentReceived: payment.receiveAmount.value
})
await makeTransfer({
incomingPayment,
receiveAmount: 5n,
outgoingPayment: createdPayment,
debitAmount: 10n
})

test('COMPLETED (already fully paid)', async (): Promise<void> => {
const { id: paymentId } = await setup(
{
receiver,
receiveAmount,
method: 'ilp'
},
receiveAmount
)
// The quote thinks there's a full amount to pay, but actually sending will find the incoming payment has been paid (e.g. by another payment).
await payIncomingPayment(receiveAmount.value)
mockPaymentHandlerPay(createdPayment, incomingPayment)

const payment = await processNext(
paymentId,
OutgoingPaymentState.Completed
)
await expectOutcome(payment, {
accountBalance: payment.debitAmount.value,
amountSent: BigInt(0),
amountDelivered: BigInt(0),
incomingPaymentReceived: receiveAmount.value,
withdrawAmount: payment.debitAmount.value
})
const payment = await processNext(
createdPayment.id,
OutgoingPaymentState.Completed
)

await expectOutcome(payment, {
accountBalance: 0n,
amountSent: payment.debitAmount.value,
amountDelivered: payment.receiveAmount.value,
incomingPaymentReceived: payment.receiveAmount.value
})
})

test('FAILED (source asset changed)', async (): Promise<void> => {
const { id: paymentId } = await setup({
// Caused by retry after failed SENDING→COMPLETED transition commit.
test('COMPLETED (already fully paid)', async (): Promise<void> => {
const createdPayment = await setup(
{
receiver,
receiveAmount,
method: 'ilp'
},
receiveAmount
)

await processNext(paymentId, OutgoingPaymentState.Completed)
mockPaymentHandlerPay(createdPayment, incomingPayment)

await processNext(createdPayment.id, OutgoingPaymentState.Completed)
// Pretend that the transaction didn't commit.
await OutgoingPayment.query(knex)
.findById(paymentId)
.findById(createdPayment.id)
.patch({ state: OutgoingPaymentState.Sending })

mockPaymentHandlerPay(createdPayment, incomingPayment)
const payment = await processNext(
createdPayment.id,
OutgoingPaymentState.Completed
)
await expectOutcome(payment, {
accountBalance: 0n,
amountSent: payment.debitAmount.value,
amountDelivered: payment.receiveAmount.value,
incomingPaymentReceived: payment.receiveAmount.value
})
})

test('COMPLETED (already fully paid)', async (): Promise<void> => {
const { id: paymentId } = await setup(
{
receiver,
receiveAmount,
method: 'ilp'
},
receiveAmount
)
// The quote thinks there's a full amount to pay, but actually sending will find the incoming payment has been paid (e.g. by another payment).
await payIncomingPayment(receiveAmount.value)

const payment = await processNext(
paymentId,
OutgoingPaymentState.Completed
)
const sentAmount = payment.receiveAmount.value * BigInt(2)
await expectOutcome(payment, {
accountBalance: payment.debitAmount.value - sentAmount,
amountSent: sentAmount,
amountDelivered: payment.receiveAmount.value
accountBalance: payment.debitAmount.value,
amountSent: BigInt(0),
amountDelivered: BigInt(0),
incomingPaymentReceived: receiveAmount.value,
withdrawAmount: payment.debitAmount.value
})
})

test('FAILED (destination asset changed)', async (): Promise<void> => {
const createdPayment = await setup({
test('FAILED (source asset changed)', async (): Promise<void> => {
const { id: paymentId } = await setup(
{
receiver,
debitAmount,
receiveAmount,
method: 'ilp'
})
},
receiveAmount
)

// Pretend that the destination asset was initially different.
await OutgoingPayment.relatedQuery('quote')
.for(createdPayment.id)
.patch({
receiveAmount: {
...receiveAmount,
assetScale: 55
}
})
await processNext(
createdPayment.id,
OutgoingPaymentState.Failed,
LifecycleError.DestinationAssetConflict
)
const { id: assetId } = await createAsset(deps, {
code: asset.code,
scale: asset.scale + 1
})

await OutgoingPayment.relatedQuery('walletAddress').for(paymentId).patch({
assetId
})

await processNext(
paymentId,
OutgoingPaymentState.Failed,
LifecycleError.SourceAssetConflict
)
})
test('FAILED (destination asset changed)', async (): Promise<void> => {
const createdPayment = await setup({
receiver,
debitAmount,
method: 'ilp'
})

// Pretend that the destination asset was initially different.
await OutgoingPayment.relatedQuery('quote')
.for(createdPayment.id)
.patch({
receiveAmount: {
...receiveAmount,
assetScale: 55
}
})
await processNext(
createdPayment.id,
OutgoingPaymentState.Failed,
LifecycleError.DestinationAssetConflict
)
})
})

Expand Down
7 changes: 4 additions & 3 deletions packages/backend/src/tests/outgoingPayment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export async function createOutgoingPayment(
const incomingPayment = await createIncomingPayment(deps, {
walletAddressId: options.walletAddressId
})
await incomingPayment.$query().delete()
const walletAddress = await walletAddressService.get(
options.walletAddressId
)
Expand Down Expand Up @@ -78,7 +79,7 @@ export async function createOutgoingPayment(

interface CreateOutgoingPaymentWithReceiverArgs {
receivingWalletAddress: WalletAddress
method: 'ilp',
method: 'ilp'
incomingPaymentOptions?: Partial<CreateIncomingPaymentOptions>
quoteOptions?: Partial<
Pick<
Expand Down Expand Up @@ -116,8 +117,8 @@ export async function createOutgoingPaymentWithReceiver(
walletAddressId: args.receivingWalletAddress.id
})

const streamServer = await deps.use('streamServer')
const streamCredentials = streamServer.generateCredentials()
const streamCredentialsService = await deps.use('streamCredentialsService')
const streamCredentials = await streamCredentialsService.get(incomingPayment)

const receiver = new Receiver(
incomingPayment.toOpenPaymentsTypeWithMethods(
Expand Down

0 comments on commit 8fc554a

Please sign in to comment.