Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
Require paymentDetails be omitted if requiredPaymentDetails omitted
Browse files Browse the repository at this point in the history
  • Loading branch information
Diane Huxley committed Feb 13, 2024
1 parent 5e373c7 commit d253636
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
24 changes: 15 additions & 9 deletions packages/protocol/src/message-kinds/rfq.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,10 @@ export class Rfq extends Message {
*
* @param rfqPaymentMethod - The Rfq's selected payin/payout method being validated
* @param allowedPaymentMethods - The Offering's allowed payin/payout methods
* @param payDirection - Either 'payin' or 'payout', used to provide more detailed error messages.
*
* @throws if payinMethod in {@link Rfq.data} property `kind` cannot be validated against the provided offering's payinMethod kinds
* @throws if payinMethod in {@link Rfq.data} property `paymentDetails` cannot be validated against the provided offering's payinMethod requiredPaymentDetails
* @throws if payoutMethod in {@link Rfq.data} property `kind` cannot be validated against the provided offering's payoutMethod kinds
* @throws if payoutMethod in {@link Rfq.data} property `paymentDetails` cannot be validated against the provided offering's payoutMethod requiredPaymentDetails
* @throws if rfqPaymentMethod property `kind` cannot be validated against the provided offering's paymentMethod's kinds
* @throws if rfqPaymentMethod property `paymentDetails` cannot be validated against the provided offering's paymentMethod's requiredPaymentDetails
*/
private verifyPaymentMethod(
rfqPaymentMethod: SelectedPaymentMethod,
Expand All @@ -157,8 +156,14 @@ export class Rfq extends Message {

for (const paymentMethodMatch of paymentMethodMatches) {
if (!paymentMethodMatch.requiredPaymentDetails) {
// The offering does not required any payment details for this kind of payment method
return
// If requiredPaymentDetails is omitted, and paymentDetails is also omitted, we have a match
if (!rfqPaymentMethod.paymentDetails) {
return
}

// paymentDetails is present even though requiredPaymentDetails is omitted. This is unsatisfactory.
invalidPaymentDetailsErrors.add(new Error('paymentDetails must be omitted when requiredPaymentDetails is omitted'))
continue
}

const validate = ajv.compile(paymentMethodMatch.requiredPaymentDetails)
Expand All @@ -170,9 +175,10 @@ export class Rfq extends Message {
invalidPaymentDetailsErrors.add(validate.errors)
}

if (invalidPaymentDetailsErrors.size > 0) {
throw new Error(`rfq ${payDirection}Method paymentDetails could not be validated against offering requiredPaymentDetails. Schema validation errors: ${Array.from(invalidPaymentDetailsErrors).join()}`)
}
throw new Error(
`rfq ${payDirection}Method paymentDetails could not be validated against offering requiredPaymentDetails. ` +
`Schema validation errors: ${Array.from(invalidPaymentDetailsErrors).join()}`
)
}

/**
Expand Down
47 changes: 41 additions & 6 deletions packages/protocol/tests/rfq.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
<<<<<<< HEAD
import { VerifiableCredential } from '@web5/credentials'
import { CreateRfqOptions, Offering } from '../src/main.js'
||||||| parent of c6aae4c (Handle requiredPaymentDetails undefined for RFQ verification)
import type { CreateRfqOptions, Offering } from '../src/main.js'
=======
import { CreateRfqOptions, Offering } from '../src/main.js'
>>>>>>> c6aae4c (Handle requiredPaymentDetails undefined for RFQ verification)

import { Rfq, DevTools } from '../src/main.js'
import { Convert } from '@web5/common'
Expand Down Expand Up @@ -287,6 +281,47 @@ describe('Rfq', () => {
}
})

it('throws an error if paymentDetails is present but offering\'s requiredPaymentDetails is omitted', async () => {
offering.data.payinMethods = [{
kind: 'CASH',
// requiredPaymentDetails deliberately omitted
}]
const rfq = Rfq.create({
...rfqOptions,
data: {
...rfqOptions.data,
payinMethod: {
...rfqOptions.data.payinMethod, // paymentDetails deliberately present
kind: 'CASH'
}
}
})
try {
await rfq.verifyOfferingRequirements(offering)
expect.fail()
} catch(e) {
expect(e.message).to.include('paymentDetails must be omitted when requiredPaymentDetails is omitted')
}
})

it('succeeds if paymentDetails is omitted and offering\'s requiredPaymentDetails is omitted', async () => {
offering.data.payinMethods = [{
kind: 'CASH',
// requiredPaymentDetails deliberately omitted
}]
const rfq = Rfq.create({
...rfqOptions,
data: {
...rfqOptions.data,
payinMethod: {
// paymentDetails deliberately omitted
kind: 'CASH'
}
}
})
await rfq.verifyOfferingRequirements(offering)
})

it('throws an error if payinMethod paymentDetails cannot be validated against the provided offering\'s payinMethod requiredPaymentDetails', async () => {
const rfq = Rfq.create({
...rfqOptions,
Expand Down
2 changes: 1 addition & 1 deletion tbdex

0 comments on commit d253636

Please sign in to comment.