-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
662/mk/use open payments types #1024
Changes from 30 commits
c3ccd88
3415f5f
4693a79
c633b30
909462a
8feaacb
5300073
01a0ba0
36d8b8e
d04f994
379aee8
11fa542
27cfdde
4efddb3
dc051ec
0fddf9e
ad57048
d48dc0a
9302bad
5e5d4e8
25972d3
4800c80
cf95410
9a967f1
e5f3c03
5733224
28a34df
5e95486
b6d25c6
09a0c10
c079942
c55e586
fc311e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { IocContract } from '@adonisjs/fold' | ||
import { createTestApp, TestContainer } from '../../../tests/app' | ||
import { Config, IAppConfig } from '../../../config/app' | ||
import { initIocContainer } from '../../..' | ||
import { AppServices } from '../../../app' | ||
import { createIncomingPayment } from '../../../tests/incomingPayment' | ||
import { createPaymentPointer } from '../../../tests/paymentPointer' | ||
import { truncateTables } from '../../../tests/tableManager' | ||
import { Connection } from '../../connection/model' | ||
import { serializeAmount } from '../../amount' | ||
import { IlpAddress } from 'ilp-packet' | ||
import { IncomingPayment } from './model' | ||
|
||
describe('Incoming Payment Model', (): void => { | ||
let deps: IocContract<AppServices> | ||
let appContainer: TestContainer | ||
let config: IAppConfig | ||
|
||
beforeAll(async (): Promise<void> => { | ||
deps = initIocContainer(Config) | ||
appContainer = await createTestApp(deps) | ||
config = await deps.use('config') | ||
}) | ||
|
||
afterEach(async (): Promise<void> => { | ||
jest.useRealTimers() | ||
await truncateTables(appContainer.knex) | ||
}) | ||
|
||
afterAll(async (): Promise<void> => { | ||
await appContainer.shutdown() | ||
}) | ||
|
||
describe('toOpenPaymentsType', () => { | ||
test('returns incoming payment without connection provided', async () => { | ||
const paymentPointer = await createPaymentPointer(deps) | ||
const incomingPayment = await createIncomingPayment(deps, { | ||
paymentPointerId: paymentPointer.id, | ||
description: 'my payment' | ||
}) | ||
|
||
expect(incomingPayment.toOpenPaymentsType(paymentPointer)).toEqual({ | ||
id: `${paymentPointer.url}${IncomingPayment.urlPath}/${incomingPayment.id}`, | ||
paymentPointer: paymentPointer.url, | ||
completed: incomingPayment.completed, | ||
receivedAmount: serializeAmount(incomingPayment.receivedAmount), | ||
incomingAmount: incomingPayment.incomingAmount | ||
? serializeAmount(incomingPayment.incomingAmount) | ||
: undefined, | ||
expiresAt: incomingPayment.expiresAt, | ||
description: incomingPayment.description ?? undefined, | ||
externalRef: incomingPayment.externalRef ?? undefined, | ||
updatedAt: incomingPayment.updatedAt.toISOString(), | ||
createdAt: incomingPayment.createdAt.toISOString() | ||
}) | ||
}) | ||
|
||
test('returns incoming payment with connection as string', async () => { | ||
const paymentPointer = await createPaymentPointer(deps) | ||
const incomingPayment = await createIncomingPayment(deps, { | ||
paymentPointerId: paymentPointer.id, | ||
description: 'my payment' | ||
}) | ||
|
||
const connection = `${config.openPaymentsUrl}/connections/${incomingPayment.connectionId}` | ||
|
||
expect( | ||
incomingPayment.toOpenPaymentsType(paymentPointer, connection) | ||
).toEqual({ | ||
id: `${paymentPointer.url}${IncomingPayment.urlPath}/${incomingPayment.id}`, | ||
paymentPointer: paymentPointer.url, | ||
completed: incomingPayment.completed, | ||
receivedAmount: serializeAmount(incomingPayment.receivedAmount), | ||
incomingAmount: incomingPayment.incomingAmount | ||
? serializeAmount(incomingPayment.incomingAmount) | ||
: undefined, | ||
expiresAt: incomingPayment.expiresAt, | ||
description: incomingPayment.description ?? undefined, | ||
externalRef: incomingPayment.externalRef ?? undefined, | ||
updatedAt: incomingPayment.updatedAt.toISOString(), | ||
createdAt: incomingPayment.createdAt.toISOString(), | ||
ilpStreamConnection: connection | ||
}) | ||
}) | ||
|
||
test('returns incoming payment with connection as object', async () => { | ||
const paymentPointer = await createPaymentPointer(deps) | ||
const incomingPayment = await createIncomingPayment(deps, { | ||
paymentPointerId: paymentPointer.id, | ||
description: 'my payment' | ||
}) | ||
|
||
const connection = Connection.fromPayment({ | ||
payment: incomingPayment, | ||
openPaymentsUrl: config.openPaymentsUrl, | ||
credentials: { | ||
ilpAddress: 'test.ilp' as IlpAddress, | ||
sharedSecret: Buffer.from('') | ||
} | ||
}) | ||
|
||
expect( | ||
incomingPayment.toOpenPaymentsType(paymentPointer, connection) | ||
).toEqual({ | ||
id: `${paymentPointer.url}${IncomingPayment.urlPath}/${incomingPayment.id}`, | ||
paymentPointer: paymentPointer.url, | ||
completed: incomingPayment.completed, | ||
receivedAmount: serializeAmount(incomingPayment.receivedAmount), | ||
incomingAmount: incomingPayment.incomingAmount | ||
? serializeAmount(incomingPayment.incomingAmount) | ||
: undefined, | ||
expiresAt: incomingPayment.expiresAt.toISOString(), | ||
description: incomingPayment.description ?? undefined, | ||
externalRef: incomingPayment.externalRef ?? undefined, | ||
updatedAt: incomingPayment.updatedAt.toISOString(), | ||
createdAt: incomingPayment.createdAt.toISOString(), | ||
ilpStreamConnection: { | ||
id: `${config.openPaymentsUrl}/connections/${incomingPayment.connectionId}`, | ||
ilpAddress: 'test.ilp', | ||
sharedSecret: expect.any(String), | ||
assetCode: incomingPayment.asset.code, | ||
assetScale: incomingPayment.asset.scale | ||
} | ||
}) | ||
}) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -1,8 +1,8 @@ | ||||
import { Model, ModelOptions, Pojo, QueryContext } from 'objection' | ||||
import { Model, ModelOptions, QueryContext } from 'objection' | ||||
import { v4 as uuid } from 'uuid' | ||||
|
||||
import { Amount, AmountJSON, serializeAmount } from '../../amount' | ||||
import { Connection, ConnectionJSON } from '../../connection/model' | ||||
import { Connection } from '../../connection/model' | ||||
import { | ||||
PaymentPointer, | ||||
PaymentPointerSubresource | ||||
|
@@ -11,7 +11,11 @@ import { Asset } from '../../../asset/model' | |||
import { LiquidityAccount, OnCreditOptions } from '../../../accounting/service' | ||||
import { ConnectorAccount } from '../../../connector/core/rafiki' | ||||
import { WebhookEvent } from '../../../webhook/model' | ||||
import { IncomingPayment as OpenPaymentsIncomingPayment } from 'open-payments' | ||||
import { | ||||
IncomingPayment as OpenPaymentsIncomingPayment, | ||||
IncomingPaymentWithConnection as OpenPaymentsIncomingPaymentWithConnection, | ||||
IncomingPaymentWithConnectionUrl as OpenPaymentsIncomingPaymentWithConnectionUrl | ||||
} from 'open-payments' | ||||
|
||||
export enum IncomingPaymentEventType { | ||||
IncomingPaymentExpired = 'incoming_payment.expired', | ||||
|
@@ -80,7 +84,6 @@ export class IncomingPayment | |||
} | ||||
} | ||||
|
||||
public paymentPointer!: PaymentPointer | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no non-null assertion since we can start removing |
||||
public description?: string | ||||
public expiresAt!: Date | ||||
public state!: IncomingPaymentState | ||||
|
@@ -127,8 +130,8 @@ export class IncomingPayment | |||
this.receivedAmountValue = amount.value | ||||
} | ||||
|
||||
public get url(): string { | ||||
return `${this.paymentPointer.url}${IncomingPayment.urlPath}/${this.id}` | ||||
public getUrl(paymentPointer: PaymentPointer): string { | ||||
return `${paymentPointer.url}${IncomingPayment.urlPath}/${this.id}` | ||||
} | ||||
|
||||
public async onCredit({ | ||||
|
@@ -211,67 +214,60 @@ export class IncomingPayment | |||
} | ||||
} | ||||
|
||||
$formatJson(json: Pojo): Pojo { | ||||
json = super.$formatJson(json) | ||||
const payment: Pojo = { | ||||
id: json.id, | ||||
receivedAmount: { | ||||
...json.receivedAmount, | ||||
value: json.receivedAmount.value.toString() | ||||
}, | ||||
completed: json.completed, | ||||
createdAt: json.createdAt, | ||||
updatedAt: json.updatedAt, | ||||
expiresAt: json.expiresAt.toISOString() | ||||
} | ||||
if (json.incomingAmount) { | ||||
payment.incomingAmount = { | ||||
...json.incomingAmount, | ||||
value: json.incomingAmount.value.toString() | ||||
} | ||||
} | ||||
if (json.description) { | ||||
payment.description = json.description | ||||
} | ||||
if (json.externalRef) { | ||||
payment.externalRef = json.externalRef | ||||
} | ||||
return payment | ||||
} | ||||
|
||||
public toOpenPaymentsType({ | ||||
ilpStreamConnection | ||||
}: { | ||||
public toOpenPaymentsType( | ||||
paymentPointer: PaymentPointer | ||||
): OpenPaymentsIncomingPayment | ||||
public toOpenPaymentsType( | ||||
paymentPointer: PaymentPointer, | ||||
ilpStreamConnection: Connection | ||||
}): OpenPaymentsIncomingPayment { | ||||
return { | ||||
id: this.url, | ||||
paymentPointer: this.paymentPointer.url, | ||||
): OpenPaymentsIncomingPaymentWithConnection | ||||
public toOpenPaymentsType( | ||||
paymentPointer: PaymentPointer, | ||||
ilpStreamConnection: string | ||||
): OpenPaymentsIncomingPaymentWithConnectionUrl | ||||
public toOpenPaymentsType( | ||||
paymentPointer: PaymentPointer, | ||||
ilpStreamConnection?: Connection | string | ||||
): | ||||
| OpenPaymentsIncomingPaymentWithConnection | ||||
| OpenPaymentsIncomingPaymentWithConnectionUrl | ||||
|
||||
public toOpenPaymentsType( | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if we added some |
||||
paymentPointer: PaymentPointer, | ||||
ilpStreamConnection?: Connection | string | ||||
): | ||||
| OpenPaymentsIncomingPayment | ||||
| OpenPaymentsIncomingPaymentWithConnection | ||||
| OpenPaymentsIncomingPaymentWithConnectionUrl { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was going to suggest adding an abstract
|
||||
const baseIncomingPayment: OpenPaymentsIncomingPayment = { | ||||
id: this.getUrl(paymentPointer), | ||||
paymentPointer: paymentPointer.url, | ||||
incomingAmount: this.incomingAmount | ||||
? serializeAmount(this.incomingAmount) | ||||
: undefined, | ||||
receivedAmount: serializeAmount(this.receivedAmount), | ||||
completed: this.completed, | ||||
description: this.description ?? undefined, | ||||
externalRef: this.externalRef ?? undefined, | ||||
createdAt: this.createdAt.toISOString(), | ||||
updatedAt: this.updatedAt.toISOString(), | ||||
expiresAt: this.expiresAt.toISOString(), | ||||
expiresAt: this.expiresAt.toISOString() | ||||
} | ||||
|
||||
if (!ilpStreamConnection) { | ||||
return baseIncomingPayment | ||||
} | ||||
|
||||
if (typeof ilpStreamConnection === 'string') { | ||||
return { | ||||
...baseIncomingPayment, | ||||
ilpStreamConnection | ||||
} | ||||
} | ||||
|
||||
return { | ||||
...baseIncomingPayment, | ||||
ilpStreamConnection: ilpStreamConnection.toOpenPaymentsType() | ||||
} | ||||
} | ||||
} | ||||
|
||||
// TODO: disallow undefined | ||||
// https://github.com/interledger/rafiki/issues/594 | ||||
export type IncomingPaymentJSON = { | ||||
id: string | ||||
paymentPointer: string | ||||
incomingAmount?: AmountJSON | ||||
receivedAmount: AmountJSON | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @wilsonianb Keeping There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 I'm good with keeping amount values as strings in |
||||
completed: boolean | ||||
description?: string | ||||
externalRef?: string | ||||
createdAt: string | ||||
updatedAt: string | ||||
expiresAt?: string | ||||
ilpStreamConnection?: ConnectionJSON | string | ||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if there was a single
test.each
to make clear that output is the same other thanilpStreamConnection
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking this, but having a test case where the
connection
var in thetest.each
case was eitheror
didn't feel nice