Skip to content

Commit

Permalink
test: move decline-expired-usd test to new integration format
Browse files Browse the repository at this point in the history
  • Loading branch information
vindard committed Sep 26, 2023
1 parent adadcef commit a9236f7
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 60 deletions.
62 changes: 62 additions & 0 deletions test/integration/app/wallets/update-pending-invoices.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { randomUUID } from "crypto"

import { handleHeldInvoices } from "@app/wallets"
import * as UpdatePendingInvoicesImpl from "@app/wallets/update-pending-invoices"

import { DEFAULT_EXPIRATIONS } from "@domain/bitcoin/lightning/invoice-expiration"
import { WalletCurrency } from "@domain/shared"
import { baseLogger } from "@services/logger"
import { WalletInvoicesRepository } from "@services/mongoose"
import { WalletInvoice } from "@services/mongoose/schema"
import { getSecretAndPaymentHash } from "@domain/bitcoin/lightning"

afterEach(async () => {
await WalletInvoice.deleteMany({})
})

describe("update pending invoices", () => {
describe("handleHeldInvoices", () => {
it("declines USD invoice with expired 'createdAt'", async () => {
// Setup mocks
const declineHeldInvoiceMock = jest.fn()
const declineHeldInvoiceSpy = jest
.spyOn(UpdatePendingInvoicesImpl, "declineHeldInvoice")
.mockImplementation(declineHeldInvoiceMock)

// Setup expired USD wallet invoice
const { paymentHash } = getSecretAndPaymentHash()
const expiredUsdWalletInvoice = {
paymentHash,
secret: "secretPreImage" as SecretPreImage,
selfGenerated: true,
pubkey: "pubkey" as Pubkey,
recipientWalletDescriptor: {
id: randomUUID() as WalletId,
currency: WalletCurrency.Usd,
},
paid: false,
}
const persisted = await WalletInvoicesRepository().persistNew(
expiredUsdWalletInvoice,
)
if (persisted instanceof Error) throw persisted

const usdDelayMs = DEFAULT_EXPIRATIONS.USD.delay * 1000
const pastCreatedAt = new Date(Date.now() - usdDelayMs)
await WalletInvoice.findOneAndUpdate(
{ _id: paymentHash },
{ timestamp: pastCreatedAt },
)

// Handle invoices
await handleHeldInvoices(baseLogger)

// Expect declined invoice
expect(declineHeldInvoiceMock.mock.calls.length).toBe(1)
expect(declineHeldInvoiceMock.mock.calls[0][0].paymentHash).toBe(paymentHash)

// Restore system state
declineHeldInvoiceSpy.mockRestore()
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,10 @@ import { CouldNotFindWalletInvoiceError } from "@domain/errors"
import { WalletInvoicesRepository } from "@services/mongoose"
import { LedgerService } from "@services/ledger"
import { LndService } from "@services/lnd"
import { KnownLndErrorDetails } from "@services/lnd/errors"
import { baseLogger } from "@services/logger"
import { setupInvoiceSubscribe } from "@servers/trigger"

import { sleep } from "@utils"

import { parseLndErrorDetails } from "@services/lnd/config"

import { WalletInvoice } from "@services/mongoose/schema"

import {
Expand All @@ -33,17 +29,14 @@ import {
getHash,
getPubKey,
getUsdWalletIdByPhone,
lnd1,
lndOutside1,
pay,
randomPhone,
safePay,
subscribeToInvoices,
} from "test/helpers"

let walletIdB: WalletId
let walletIdUsdB: WalletId
let walletIdUsdF: WalletId
let initBalanceB: Satoshis
let initBalanceUsdB: UsdCents

Expand All @@ -55,7 +48,6 @@ beforeAll(async () => {
await createUserAndWalletFromPhone(phoneF)
walletIdB = await getDefaultWalletIdByPhone(phoneB)
walletIdUsdB = await getUsdWalletIdByPhone(phoneB)
walletIdUsdF = await getUsdWalletIdByPhone(phoneF)
})

beforeEach(async () => {
Expand Down Expand Up @@ -275,55 +267,3 @@ describe("UserWallet - Lightning", () => {
])
})
})

describe("Invoice handling from trigger", () => {
describe("usd recipient invoice", () => {
const cents = toCents(100)

it("should decline held invoice when trigger comes back up", async () => {
// Create invoice for self
const lnInvoice = await Wallets.addInvoiceForSelfForUsdWallet({
walletId: walletIdUsdF,
amount: cents,
})
expect(lnInvoice).not.toBeInstanceOf(Error)
if (lnInvoice instanceof Error) throw lnInvoice

// fake timestamp in wallet invoice to avoid the use of fake timers
await WalletInvoice.findOneAndUpdate(
{ _id: lnInvoice.paymentHash },
{ timestamp: new Date(Date.now() - SECS_PER_10_MINS * 1000) },
)

// Pay invoice promise
const startPay = async () => {
try {
return await pay({
lnd: lndOutside1,
request: lnInvoice.paymentRequest,
})
} catch (err) {
return parseLndErrorDetails(err)
}
}

// Listener promise
const delayedListener = async (subInvoices) => {
await sleep(500)
setupInvoiceSubscribe({
lnd: lnd1,
pubkey: process.env.LND1_PUBKEY as Pubkey,
subInvoices,
})
}

// Pay and then listen
const subInvoices = subscribeToInvoices({ lnd: lnd1 })
const [result] = await Promise.all([startPay(), delayedListener(subInvoices)])

// See successful payment
expect(result).toMatch(KnownLndErrorDetails.PaymentRejectedByDestination)
subInvoices.removeAllListeners()
})
})
})

0 comments on commit a9236f7

Please sign in to comment.