refactor: define typescript types for CheckCash Transaction Model (#1522)

* Define Typescript types for CheckCash Transaction Model
This commit is contained in:
Mukul Jangid
2021-08-16 18:41:07 -04:00
committed by Mayukha Vadari
parent 293f09d409
commit 6d08b9e12c
7 changed files with 142 additions and 16 deletions

View File

@@ -5,9 +5,9 @@ name: Node.js CI
on: on:
push: push:
branches: [ develop, master ] branches: [ develop, master, 2.0 ]
pull_request: pull_request:
branches: [ develop ] branches: [ develop, 2.0 ]
jobs: jobs:
unit: unit:

View File

@@ -0,0 +1,36 @@
import { ValidationError } from "../../common/errors";
import { Amount } from "../common";
import { BaseTransaction, verifyBaseTransaction, isAmount } from "./common";
export interface CheckCash extends BaseTransaction {
TransactionType: "CheckCash";
CheckID: string;
Amount?: Amount;
DeliverMin?: Amount;
}
/**
* Verify the form and type of an CheckCash at runtime.
*
* @param tx - An CheckCash Transaction
* @returns - Void.
* @throws - When the CheckCash is Malformed.
*/
export function verifyCheckCash(tx: CheckCash): void {
verifyBaseTransaction(tx)
if (tx.hasOwnProperty('Amount') && tx.hasOwnProperty('DeliverMin'))
throw new ValidationError("CheckCash: cannot have both Amount and DeliverMin")
if (!tx.hasOwnProperty('Amount') && !tx.hasOwnProperty('DeliverMin'))
throw new ValidationError("CheckCash: must have either Amount or DeliverMin")
if (tx.hasOwnProperty('Amount') && tx.Amount !== undefined && !isAmount(tx.Amount))
throw new ValidationError("CheckCash: invalid Amount")
if (tx.hasOwnProperty('DeliverMin') && tx.DeliverMin !== undefined && !isAmount(tx.DeliverMin))
throw new ValidationError("CheckCash: invalid DeliverMin")
if (tx.CheckID !== undefined && typeof tx.CheckID !== 'string')
throw new ValidationError("CheckCash: invalid CheckID")
}

View File

@@ -1,5 +1,5 @@
import { ValidationError } from "../../common/errors" import { ValidationError } from "../../common/errors"
import { Memo, Signer } from "../common" import { Amount, Memo, Signer, IssuedCurrencyAmount } from "../common"
import { onlyHasFields } from "../utils" import { onlyHasFields } from "../utils"
const transactionTypes = [ const transactionTypes = [
@@ -48,6 +48,17 @@ const isSigner = (signer: Signer): boolean => {
&& typeof signer.SigningPubKey === 'string' && typeof signer.SigningPubKey === 'string'
} }
export function isIssuedCurrency (obj: IssuedCurrencyAmount): boolean {
return Object.keys(obj).length === 3
&& typeof obj.value === 'string'
&& typeof obj.issuer === 'string'
&& typeof obj.currency === 'string'
}
export function isAmount(amount: Amount): boolean {
return typeof amount === 'string' || isIssuedCurrency(amount);
}
export interface GlobalFlags { export interface GlobalFlags {
tfFullyCanonicalSig: boolean, tfFullyCanonicalSig: boolean,
} }

View File

@@ -1,4 +1,5 @@
export * from './transaction' export * from './transaction'
export * from './offerCreate' export * from './offerCreate'
export * from './checkCancel'
export * from './checkCreate' export * from './checkCreate'
export * from './checkCash'
export * from './checkCancel'

View File

@@ -1,6 +1,6 @@
import { ValidationError } from "../../common/errors"; import { ValidationError } from "../../common/errors";
import { Amount, IssuedCurrencyAmount } from "../common"; import { Amount } from "../common";
import { BaseTransaction, GlobalFlags, verifyBaseTransaction } from "./common"; import { BaseTransaction, GlobalFlags, verifyBaseTransaction, isAmount } from "./common";
export interface OfferCreateFlags extends GlobalFlags { export interface OfferCreateFlags extends GlobalFlags {
tfPassive?: boolean; tfPassive?: boolean;
@@ -34,17 +34,10 @@ export interface OfferCreate extends BaseTransaction {
if (tx.TakerPays === undefined) if (tx.TakerPays === undefined)
throw new ValidationError("OfferCreate: missing field TakerPays") throw new ValidationError("OfferCreate: missing field TakerPays")
const isIssuedCurrency = (obj: IssuedCurrencyAmount): boolean => { if (typeof tx.TakerGets !== 'string' && !isAmount(tx.TakerGets))
return Object.keys(obj).length === 3
&& typeof obj.value === 'string'
&& typeof obj.issuer === 'string'
&& typeof obj.currency === 'string'
}
if (typeof tx.TakerGets !== 'string' && !isIssuedCurrency(tx.TakerGets))
throw new ValidationError("OfferCreate: invalid TakerGets") throw new ValidationError("OfferCreate: invalid TakerGets")
if (typeof tx.TakerPays !== 'string' && !isIssuedCurrency(tx.TakerPays)) if (typeof tx.TakerPays !== 'string' && !isAmount(tx.TakerPays))
throw new ValidationError("OfferCreate: invalid TakerPays") throw new ValidationError("OfferCreate: invalid TakerPays")
if (tx.Expiration !== undefined && typeof tx.Expiration !== 'number') if (tx.Expiration !== undefined && typeof tx.Expiration !== 'number')

View File

@@ -1,5 +1,6 @@
import Metadata from "../common/metadata"; import Metadata from "../common/metadata";
import { OfferCreate } from "./offerCreate"; import { OfferCreate } from "./offerCreate";
import { CheckCash } from "./checkCash";
import { CheckCancel } from "./checkCancel"; import { CheckCancel } from "./checkCancel";
import { CheckCreate } from "./checkCreate"; import { CheckCreate } from "./checkCreate";
@@ -7,7 +8,7 @@ export type Transaction =
// AccountSet // AccountSet
// | AccountDelete // | AccountDelete
CheckCancel CheckCancel
// | CheckCash | CheckCash
| CheckCreate | CheckCreate
// | DepositPreauth // | DepositPreauth
// | EscrowCancel // | EscrowCancel

84
test/models/checkCash.ts Normal file
View File

@@ -0,0 +1,84 @@
import { ValidationError } from 'ripple-api/common/errors'
import { verifyCheckCash } from './../../src/models/transactions/checkCash'
import { assert } from 'chai'
/**
* CheckCash Transaction Verification Testing
*
* Providing runtime verification testing for each specific transaction type
*/
describe('CheckCash Transaction Verification', function () {
it (`verifies valid CheckCash`, () => {
const validCheckCash = {
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
TransactionType : "CheckCash",
Amount : "100000000",
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
Fee : "12"
} as any
assert.doesNotThrow(() => verifyCheckCash(validCheckCash))
})
it (`throws w/ invalid CheckID`, () => {
const invalidCheckID = {
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
TransactionType : "CheckCash",
Amount : "100000000",
CheckID : 83876645678909854567890
} as any
assert.throws(
() => verifyCheckCash(invalidCheckID),
ValidationError,
"CheckCash: invalid CheckID"
)
})
it (`throws w/ invalid Amount`, () => {
const invalidAmount = {
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
TransactionType : "CheckCash",
Amount : 100000000,
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334"
} as any
assert.throws(
() => verifyCheckCash(invalidAmount),
ValidationError,
"CheckCash: invalid Amount"
)
})
it (`throws w/ having both Amount and DeliverMin`, () => {
const invalidDeliverMin = {
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
TransactionType : "CheckCash",
Amount : "100000000",
DeliverMin: 852156963,
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334"
} as any
assert.throws(
() => verifyCheckCash(invalidDeliverMin),
ValidationError,
"CheckCash: cannot have both Amount and DeliverMin"
)
})
it (`throws w/ invalid DeliverMin`, () => {
const invalidDeliverMin = {
Account : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
TransactionType : "CheckCash",
DeliverMin: 852156963,
CheckID : "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334"
} as any
assert.throws(
() => verifyCheckCash(invalidDeliverMin),
ValidationError,
"CheckCash: invalid DeliverMin"
)
})
})