From f9bce29174f2f01fdb94131c32b5a580e64bb8a7 Mon Sep 17 00:00:00 2001 From: Mukul Jangid <49061120+mukulljangid@users.noreply.github.com> Date: Thu, 12 Aug 2021 15:42:32 -0400 Subject: [PATCH] refactor: define typescript types for CheckCreate Transaction Model (#1524) * feat: define checkCreate model * test: add tests --- src/models/transactions/checkCreate.ts | 51 ++++++++++ src/models/transactions/index.ts | 1 + src/models/transactions/transaction.ts | 7 +- test/models/checkCreate.ts | 123 +++++++++++++++++++++++++ 4 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 src/models/transactions/checkCreate.ts create mode 100644 test/models/checkCreate.ts diff --git a/src/models/transactions/checkCreate.ts b/src/models/transactions/checkCreate.ts new file mode 100644 index 00000000..f09756c9 --- /dev/null +++ b/src/models/transactions/checkCreate.ts @@ -0,0 +1,51 @@ +import { ValidationError } from "../../common/errors"; +import { Amount, IssuedCurrencyAmount } from "../common"; +import { BaseTransaction, verifyBaseTransaction } from "./common"; + +export interface CheckCreate extends BaseTransaction { + TransactionType: "CheckCreate"; + Destination: string; + SendMax: Amount; + DestinationTag?: number; + Expiration?: number; + InvoiceID?: string +} + +/** + * Verify the form and type of an CheckCreate at runtime. + * + * @param tx - An CheckCreate Transaction + * @returns - Void. + * @throws - When the CheckCreate is Malformed. + */ + export function verifyCheckCreate(tx: CheckCreate): void { + verifyBaseTransaction(tx) + + if (tx.SendMax === undefined) + throw new ValidationError("CheckCreate: missing field SendMax") + + if (tx.Destination === undefined) + throw new ValidationError("CheckCreate: missing field Destination") + + const isIssuedCurrency = (obj: IssuedCurrencyAmount): boolean => { + return Object.keys(obj).length === 3 + && typeof obj.value === 'string' + && typeof obj.issuer === 'string' + && typeof obj.currency === 'string' + } + + if (typeof tx.SendMax !== 'string' && !isIssuedCurrency(tx.SendMax)) + throw new ValidationError("CheckCreate: invalid SendMax") + + if (typeof tx.Destination !== 'string') + throw new ValidationError("CheckCreate: invalid Destination") + + if (tx.DestinationTag !== undefined && typeof tx.DestinationTag !== 'number') + throw new ValidationError("CheckCreate: invalid DestinationTag") + + if (tx.Expiration !== undefined && typeof tx.Expiration !== 'number') + throw new ValidationError("CheckCreate: invalid Expiration") + + if (tx.InvoiceID !== undefined && typeof tx.InvoiceID !== 'string') + throw new ValidationError("CheckCreate: invalid InvoiceID") +} \ No newline at end of file diff --git a/src/models/transactions/index.ts b/src/models/transactions/index.ts index f1f45ab5..4327de7a 100644 --- a/src/models/transactions/index.ts +++ b/src/models/transactions/index.ts @@ -1,2 +1,3 @@ export * from './transaction' export * from './offerCreate' +export * from './checkCreate' diff --git a/src/models/transactions/transaction.ts b/src/models/transactions/transaction.ts index c0cfc8f0..7f8c8a29 100644 --- a/src/models/transactions/transaction.ts +++ b/src/models/transactions/transaction.ts @@ -1,5 +1,6 @@ import Metadata from "../common/metadata"; import { OfferCreate } from "./offerCreate"; +import { CheckCreate } from "./checkCreate"; export type Transaction = @@ -7,13 +8,13 @@ export type Transaction = // | AccountDelete // | CheckCancel // | CheckCash -// | CheckCreate + CheckCreate // | DepositPreauth // | EscrowCancel // | EscrowCreate // | EscrowFinish // | OfferCancel - OfferCreate + | OfferCreate // | PaymentTransaction // | PaymentChannelClaim // | PaymentChannelCreate @@ -26,4 +27,4 @@ export type Transaction = export interface TransactionAndMetadata { transaction: Transaction; metadata: Metadata -} \ No newline at end of file +} diff --git a/test/models/checkCreate.ts b/test/models/checkCreate.ts new file mode 100644 index 00000000..ee7dbad0 --- /dev/null +++ b/test/models/checkCreate.ts @@ -0,0 +1,123 @@ +import { ValidationError } from 'ripple-api/common/errors' +import { verifyCheckCreate } from './../../src/models/transactions/checkCreate' +import { assert } from 'chai' + +/** + * CheckCreate Transaction Verification Testing + * + * Providing runtime verification testing for each specific transaction type + */ +describe('CheckCreate Transaction Verification', function () { + + it (`verifies valid CheckCreate`, () => { + const validCheck = { + TransactionType : "CheckCreate", + Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo", + Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy", + SendMax : "100000000", + Expiration : 570113521, + InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + DestinationTag : 1, + Fee : "12" + } as any + + assert.doesNotThrow(() => verifyCheckCreate(validCheck)) + }) + + + it (`throws w/ invalid Destination`, () => { + const invalidDestination = { + TransactionType : "CheckCreate", + Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo", + Destination : 7896214563214789632154, + SendMax : "100000000", + Expiration : 570113521, + InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + DestinationTag : 1, + Fee : "12" + } as any + + assert.throws( + () => verifyCheckCreate(invalidDestination), + ValidationError, + "CheckCreate: invalid Destination" + ) + }) + + it (`throws w/ invalid SendMax`, () => { + const invalidSendMax = { + TransactionType : "CheckCreate", + Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo", + Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy", + SendMax : 100000000, + Expiration : 570113521, + InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + DestinationTag : 1, + Fee : "12" + } as any + + assert.throws( + () => verifyCheckCreate(invalidSendMax), + ValidationError, + "CheckCreate: invalid SendMax" + ) + }) + + it (`throws w/ invalid DestinationTag`, () => { + const invalidDestinationTag = { + TransactionType : "CheckCreate", + Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo", + Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy", + SendMax : "100000000", + Expiration : 570113521, + InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + DestinationTag : "1", + Fee : "12" + } as any + + assert.throws( + () => verifyCheckCreate(invalidDestinationTag), + ValidationError, + "CheckCreate: invalid DestinationTag" + ) + }) + + it (`throws w/ invalid Expiration`, () => { + const invalidExpiration = { + TransactionType : "CheckCreate", + Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo", + Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy", + SendMax : "100000000", + Expiration : "570113521", + InvoiceID : "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B", + DestinationTag : 1, + Fee : "12" + } as any + + assert.throws( + () => verifyCheckCreate(invalidExpiration), + ValidationError, + "CheckCreate: invalid Expiration" + ) + }) + + it (`throws w/ invalid InvoiceID`, () => { + const invalidInvoiceID = { + TransactionType : "CheckCreate", + Account : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo", + Destination : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy", + SendMax : "100000000", + Expiration : 570113521, + InvoiceID : 7896545655285446963258531, + DestinationTag : 1, + Fee : "12" + } as any + + assert.throws( + () => verifyCheckCreate(invalidInvoiceID), + ValidationError, + "CheckCreate: invalid InvoiceID" + ) + }) + +}) \ No newline at end of file