From aa5eaf7df693d418c3cdb800b0e524e2e316ae28 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Tue, 30 May 2023 16:30:41 +0100 Subject: [PATCH] fix: adds test coverage and fixes props --- .../core/src/Provider/HandleProvider/types.ts | 9 ---- .../src/tx-builder/OutputBuilder.ts | 9 ++-- .../src/tx-builder/TxBuilder.ts | 2 +- .../tx-construction/src/tx-builder/types.ts | 11 ++++- .../test/tx-builder/TxBuilder.test.ts | 47 ++++++++++++------- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/packages/core/src/Provider/HandleProvider/types.ts b/packages/core/src/Provider/HandleProvider/types.ts index 5a021937270..c764e6a42f7 100644 --- a/packages/core/src/Provider/HandleProvider/types.ts +++ b/packages/core/src/Provider/HandleProvider/types.ts @@ -2,15 +2,6 @@ import { Cardano, Point, Provider } from '../..'; export type Handle = string; -/** - * Type of addresses that can resolve from a Handle - */ -export type CardanoAddress = - | Cardano.ByronAddress - | Cardano.PaymentAddress - | Cardano.EnterpriseAddress - | Cardano.PointerAddress; - /** * @param policyId a hex encoded policyID * @param handle a personalized string to identify a user diff --git a/packages/tx-construction/src/tx-builder/OutputBuilder.ts b/packages/tx-construction/src/tx-builder/OutputBuilder.ts index 273e79dda4e..73a9955ec1f 100644 --- a/packages/tx-construction/src/tx-builder/OutputBuilder.ts +++ b/packages/tx-construction/src/tx-builder/OutputBuilder.ts @@ -3,14 +3,15 @@ import { Hash32ByteBase16 } from '@cardano-sdk/crypto'; import { Logger } from 'ts-log'; import { + HandleNotFoundError, InvalidConfigurationError, OutputBuilder, OutputBuilderTxOut, OutputValidationMinimumCoinError, OutputValidationMissingRequiredError, OutputValidationTokenBundleSizeError, - TxOutputFailure, - PartialTxOut + PartialTxOut, + TxOutputFailure } from './types'; import { OutputValidation, OutputValidator } from '../output-validation'; @@ -151,9 +152,9 @@ export class TxOutputBuilder implements OutputBuilder { txOut.handle = resolution[0]; txOut.address = resolution[0].resolvedAddresses.cardano; } else { - // The an error because the handle resolved to null so we don't have + // Throw an error because the handle resolved to null so we don't have // an address for the transaction. - throw new OutputValidationMissingRequiredError(this.#partialOutput); + throw new HandleNotFoundError(this.#partialOutput); } } diff --git a/packages/tx-construction/src/tx-builder/TxBuilder.ts b/packages/tx-construction/src/tx-builder/TxBuilder.ts index ed6b19c075e..75d1d0225f1 100644 --- a/packages/tx-construction/src/tx-builder/TxBuilder.ts +++ b/packages/tx-construction/src/tx-builder/TxBuilder.ts @@ -91,7 +91,7 @@ export class GenericTxBuilder implements TxBuilder { #outputValidator: OutputBuilderValidator; #delegateConfig: DelegateConfig; #logger: Logger; - #handleProvider: HandleProvider; + #handleProvider: HandleProvider | undefined; #handles: HandleResolution[]; constructor(dependencies: TxBuilderDependencies) { diff --git a/packages/tx-construction/src/tx-builder/types.ts b/packages/tx-construction/src/tx-builder/types.ts index 0b72dc68ea2..aa217999a74 100644 --- a/packages/tx-construction/src/tx-builder/types.ts +++ b/packages/tx-construction/src/tx-builder/types.ts @@ -21,7 +21,8 @@ export enum TxOutputFailure { MinimumCoin = 'Minimum coin not met', TokenBundleSizeExceedsLimit = 'Token Bundle Exceeds Limit', MissingRequiredFields = 'Mandatory fields address or coin are missing', - MissingHandleProviderError = "Missing 'HandleProvider'" + MissingHandleProviderError = "Missing 'HandleProvider'", + HandleNotFound = 'Handle not found' } export class InvalidConfigurationError extends CustomError { @@ -30,6 +31,12 @@ export class InvalidConfigurationError extends CustomError { } } +export class HandleNotFoundError extends CustomError { + public constructor(public txOut: PartialTxOut) { + super(TxOutputFailure.HandleNotFound); + } +} + export class OutputValidationMissingRequiredError extends CustomError { public constructor(public txOut: PartialTxOut) { super(TxOutputFailure.MissingRequiredFields); @@ -224,7 +231,7 @@ export interface TxBuilderDependencies { txBuilderProviders: TxBuilderProviders; logger: Logger; outputValidator?: OutputBuilderValidator; - handleProvider: HandleProvider; + handleProvider?: HandleProvider; } export type FinalizeTxDependencies = Pick; diff --git a/packages/tx-construction/test/tx-builder/TxBuilder.test.ts b/packages/tx-construction/test/tx-builder/TxBuilder.test.ts index 5dfe4444ca5..e7b6561fad3 100644 --- a/packages/tx-construction/test/tx-builder/TxBuilder.test.ts +++ b/packages/tx-construction/test/tx-builder/TxBuilder.test.ts @@ -13,6 +13,8 @@ import { AssetId, mockProviders as mocks, somePartialStakePools } from '@cardano import { CML, Cardano, Handle, ProviderError, ProviderFailure } from '@cardano-sdk/core'; import { GenericTxBuilder, + HandleNotFoundError, + InvalidConfigurationError, OutputBuilderValidator, OutputValidation, OutputValidationMinimumCoinError, @@ -45,6 +47,7 @@ const resolvedHandle = { describe('GenericTxBuilder', () => { let outputValidator: jest.Mocked; let txBuilder: GenericTxBuilder; + let txBuilderWithoutHandleProvider: GenericTxBuilder; let txBuilderWithHandleErrors: GenericTxBuilder; let txBuilderWithNullHandles: GenericTxBuilder; let txBuilderProviders: jest.Mocked; @@ -91,27 +94,29 @@ describe('GenericTxBuilder', () => { outputValidator = { validateOutput: jest.fn().mockResolvedValue({ coinMissing: 0n } as OutputValidation) }; - txBuilder = new GenericTxBuilder({ - handleProvider: { - healthCheck: jest.fn(), - resolveHandles: async () => [resolvedHandle] - }, + + const builderParams = { inputResolver, keyAgent: util.createAsyncKeyAgent(keyAgent), logger: dummyLogger, outputValidator, txBuilderProviders + }; + + txBuilder = new GenericTxBuilder({ + handleProvider: { + healthCheck: jest.fn(), + resolveHandles: async () => [resolvedHandle] + }, + ...builderParams }); + txBuilderWithoutHandleProvider = new GenericTxBuilder(builderParams); txBuilderWithNullHandles = new GenericTxBuilder({ handleProvider: { healthCheck: jest.fn(), resolveHandles: async () => [null] }, - inputResolver, - keyAgent: util.createAsyncKeyAgent(keyAgent), - logger: dummyLogger, - outputValidator, - txBuilderProviders + ...builderParams }); txBuilderWithHandleErrors = new GenericTxBuilder({ handleProvider: { @@ -126,11 +131,7 @@ describe('GenericTxBuilder', () => { ); } }, - inputResolver, - keyAgent: util.createAsyncKeyAgent(keyAgent), - logger: dummyLogger, - outputValidator, - txBuilderProviders + ...builderParams }); }); @@ -358,6 +359,16 @@ describe('GenericTxBuilder', () => { expect(outputBuilder.toTxOut().handle).toEqual(handle); }); + it('throws an error if attempting to set handle without a handleProvider', async () => { + try { + await txBuilderWithoutHandleProvider.buildOutput().handle(address).build(); + } catch (error) { + expect(error instanceof InvalidConfigurationError).toBeTruthy(); + } + + expect.assertions(1); + }); + it('can build a valid output', async () => { const builtOutput = await txBuilder .buildOutput() @@ -413,13 +424,13 @@ describe('GenericTxBuilder', () => { expect(txOut.address).toBe(resolvedHandle.resolvedAddresses.cardano); }); - it('rejects with an error when a handle is not found', async () => { + it('rejects with an error when a handle provider fails to resolve', async () => { await expect( txBuilderWithNullHandles.buildOutput().handle('alice').coin(output1Coin).build() - ).rejects.toThrowError(OutputValidationMissingRequiredError); + ).rejects.toThrowError(HandleNotFoundError); }); - it('rejects with an error when handle is not found', async () => { + it('rejects with an error when handle provider throws an error', async () => { await expect( txBuilderWithHandleErrors.buildOutput().handle('alice').coin(output1Coin).build() ).rejects.toThrowError(ProviderError);