From f8180b7629efc6ccd3d814120e48df1fac625828 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 09:40:28 +0200 Subject: [PATCH 01/34] feat: add logging plugin --- packages/backend/src/app.ts | 4 ++ packages/backend/src/graphql/plugin/index.ts | 55 ++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 packages/backend/src/graphql/plugin/index.ts diff --git a/packages/backend/src/app.ts b/packages/backend/src/app.ts index a6a2c642c3..34473b2230 100644 --- a/packages/backend/src/app.ts +++ b/packages/backend/src/app.ts @@ -97,6 +97,7 @@ import { getWalletAddressUrlFromPath } from './open_payments/wallet_address/middleware' +import { LoggingPlugin } from './graphql/plugin' export interface AppContextData { logger: Logger container: AppContainer @@ -341,12 +342,15 @@ export class App { }) const protection = armor.protect() + const loggingPlugin = new LoggingPlugin(this.logger) + // Setup Apollo this.apolloServer = new ApolloServer({ schema: schemaWithMiddleware, ...protection, plugins: [ ...protection.plugins, + loggingPlugin, ApolloServerPluginDrainHttpServer({ httpServer }) ], introspection: this.config.env !== 'production' diff --git a/packages/backend/src/graphql/plugin/index.ts b/packages/backend/src/graphql/plugin/index.ts new file mode 100644 index 0000000000..10e4a2ce94 --- /dev/null +++ b/packages/backend/src/graphql/plugin/index.ts @@ -0,0 +1,55 @@ +import { + ApolloServerPlugin, + GraphQLRequestContextDidEncounterErrors, + GraphQLRequestContextDidResolveOperation, + GraphQLRequestListener +} from '@apollo/server' +import { Logger } from 'pino' +import { v4 as uuid } from 'uuid' + +export class LoggingPlugin implements ApolloServerPlugin { + private logger + + constructor(logger: Logger) { + this.logger = logger + } + + async requestDidStart(): Promise> { + const requestId = uuid() + const logger = this.logger + let operation: string | null + + return { + async didResolveOperation( + context: GraphQLRequestContextDidResolveOperation + ) { + operation = context.operationName + logger.info({ + requestId, + operation + }) + }, + async didEncounterErrors( + context: GraphQLRequestContextDidEncounterErrors + ): Promise { + if (context.errors) { + context.errors.forEach((error) => { + if (error.extensions.code === 'INTERNAL_SERVER_ERROR') { + logger.error({ + requestId, + variables: context.request.variables, + error + }) + } else { + logger.info({ + requestId, + variables: context.request.variables, + error + }) + } + }) + } + } + } + } +} From 646d7a1e33207926960d0a6958a766274a05497f Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 09:41:00 +0200 Subject: [PATCH 02/34] wip: update graphql schema --- packages/backend/src/graphql/schema.graphql | 86 ++++----------------- 1 file changed, 17 insertions(+), 69 deletions(-) diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index def3b5cc2a..d194a2461c 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -1206,116 +1206,64 @@ interface Model { createdAt: String! } -type CreateWalletAddressMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type CreateWalletAddressMutationResponse { walletAddress: WalletAddress } -type UpdateWalletAddressMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type UpdateWalletAddressMutationResponse { walletAddress: WalletAddress } -type TriggerWalletAddressEventsMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type TriggerWalletAddressEventsMutationResponse { "Number of events triggered" count: Int } -type AssetMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type AssetMutationResponse { asset: Asset } -type DeleteAssetMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type DeleteAssetMutationResponse { + asset: Asset } -type CreatePeerMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type CreatePeerMutationResponse { peer: Peer } -type CreateOrUpdatePeerByUrlMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type CreateOrUpdatePeerByUrlMutationResponse { peer: Peer } -type UpdatePeerMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type UpdatePeerMutationResponse { peer: Peer } -type DeletePeerMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! -} - -type TransferMutationResponse implements MutationResponse { - code: String! +type DeletePeerMutationResponse { success: Boolean! - message: String! } -type LiquidityMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! - error: LiquidityError +type LiquidityMutationResponse { + id: ID! + liquidity: UInt64 } -type WalletAddressWithdrawalMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! - error: LiquidityError +type WalletAddressWithdrawalMutationResponse { withdrawal: WalletAddressWithdrawal } -type CreateWalletAddressKeyMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type CreateWalletAddressKeyMutationResponse { walletAddressKey: WalletAddressKey } -type RevokeWalletAddressKeyMutationResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type RevokeWalletAddressKeyMutationResponse { walletAddressKey: WalletAddressKey } -type SetFeeResponse implements MutationResponse { - code: String! - success: Boolean! - message: String! +type SetFeeResponse { fee: Fee } -interface MutationResponse { - code: String! - success: Boolean! - message: String! -} - scalar UInt8 scalar UInt64 scalar JSONObject From ca151acffb7efcf7f6f3613add0451e7f2db00b9 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 09:41:19 +0200 Subject: [PATCH 03/34] chore: update asset resolvers --- packages/backend/src/graphql/errors/index.ts | 6 + .../src/graphql/resolvers/asset.test.ts | 39 ++---- .../backend/src/graphql/resolvers/asset.ts | 118 ++++++++---------- 3 files changed, 63 insertions(+), 100 deletions(-) create mode 100644 packages/backend/src/graphql/errors/index.ts diff --git a/packages/backend/src/graphql/errors/index.ts b/packages/backend/src/graphql/errors/index.ts new file mode 100644 index 0000000000..9d74c2514d --- /dev/null +++ b/packages/backend/src/graphql/errors/index.ts @@ -0,0 +1,6 @@ +export enum GraphQLErrorCode { + BadUserInput = 'BAD_USER_INPUT', + Duplicate = 'DUPLICATE', + InternalServerError = 'INTERNAL_SERVER_ERROR', + NotFound = 'NOT_FOUND' +} diff --git a/packages/backend/src/graphql/resolvers/asset.test.ts b/packages/backend/src/graphql/resolvers/asset.test.ts index d31f8e9708..adc77e7629 100644 --- a/packages/backend/src/graphql/resolvers/asset.test.ts +++ b/packages/backend/src/graphql/resolvers/asset.test.ts @@ -86,9 +86,6 @@ describe('Asset Resolvers', (): void => { mutation: gql` mutation CreateAsset($input: CreateAssetInput!) { createAsset(input: $input) { - code - success - message asset { id code @@ -112,8 +109,6 @@ describe('Asset Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') assert.ok(response.asset) expect(response.asset).toEqual({ __typename: 'Asset', @@ -137,14 +132,11 @@ describe('Asset Resolvers', (): void => { test('Returns error for duplicate asset', async (): Promise => { const input = randomAsset() await expect(assetService.create(input)).resolves.toMatchObject(input) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateAsset($input: CreateAssetInput!) { createAsset(input: $input) { - code - success - message asset { id } @@ -163,9 +155,8 @@ describe('Asset Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Asset already exists') + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('Asset already exists') }) test('500', async (): Promise => { @@ -173,14 +164,11 @@ describe('Asset Resolvers', (): void => { .spyOn(assetService, 'create') .mockRejectedValueOnce(new Error('unexpected')) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateAsset($input: CreateAssetInput!) { createAsset(input: $input) { - code - success - message asset { id } @@ -198,9 +186,7 @@ describe('Asset Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.code).toBe('500') - expect(response.success).toBe(false) - expect(response.message).toBe('Error trying to create asset') + await expect(gqlQuery).rejects.toThrow(ApolloError) }) }) @@ -558,9 +544,6 @@ describe('Asset Resolvers', (): void => { mutation: gql` mutation updateAsset($input: UpdateAssetInput!) { updateAsset(input: $input) { - code - success - message asset { id code @@ -587,8 +570,6 @@ describe('Asset Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') expect(response.asset).toEqual({ __typename: 'Asset', id: asset.id, @@ -613,14 +594,11 @@ describe('Asset Resolvers', (): void => { ) test('Returns error for unknown asset', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation updateAsset($input: UpdateAssetInput!) { updateAsset(input: $input) { - code - success - message asset { id } @@ -643,9 +621,8 @@ describe('Asset Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown asset') + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('Asset not found') }) }) diff --git a/packages/backend/src/graphql/resolvers/asset.ts b/packages/backend/src/graphql/resolvers/asset.ts index 24075614a0..88ed2d49f6 100644 --- a/packages/backend/src/graphql/resolvers/asset.ts +++ b/packages/backend/src/graphql/resolvers/asset.ts @@ -17,6 +17,8 @@ import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' import { feeToGraphql } from './fee' import { Fee, FeeType } from '../../fee/model' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' export const getAssets: QueryResolvers['assets'] = async ( parent, @@ -50,7 +52,11 @@ export const getAsset: QueryResolvers['asset'] = async ( const assetService = await ctx.container.use('assetService') const asset = await assetService.get(args.id) if (!asset) { - throw new Error('No asset') + throw new GraphQLError('Asset not found', { + extensions: { + code: 'NOT_FOUND' + } + }) } return assetToGraphql(asset) } @@ -61,41 +67,28 @@ export const createAsset: MutationResolvers['createAsset'] = args, ctx ): Promise => { - try { - const assetService = await ctx.container.use('assetService') - const assetOrError = await assetService.create(args.input) - if (isAssetError(assetOrError)) { - switch (assetOrError) { - case AssetError.DuplicateAsset: - return { - code: '409', - message: 'Asset already exists', - success: false + const assetService = await ctx.container.use('assetService') + const assetOrError = await assetService.create(args.input) + if (isAssetError(assetOrError)) { + switch (assetOrError) { + case AssetError.DuplicateAsset: + throw new GraphQLError('Asset already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate } - default: - throw new Error(`AssetError: ${assetOrError}`) - } - } - return { - code: '200', - success: true, - message: 'Created Asset', - asset: assetToGraphql(assetOrError) - } - } catch (err) { - ctx.logger.error( - { - options: args.input, - err - }, - 'error creating asset' - ) - return { - code: '500', - message: 'Error trying to create asset', - success: false + }) + default: + throw new GraphQLError('Internal Server Error', { + extensions: { + code: GraphQLErrorCode.InternalServerError, + error: assetOrError + } + }) } } + return { + asset: assetToGraphql(assetOrError) + } } export const updateAsset: MutationResolvers['updateAsset'] = @@ -104,45 +97,32 @@ export const updateAsset: MutationResolvers['updateAsset'] = args, ctx ): Promise => { - try { - const assetService = await ctx.container.use('assetService') - const assetOrError = await assetService.update({ - id: args.input.id, - withdrawalThreshold: args.input.withdrawalThreshold ?? null, - liquidityThreshold: args.input.liquidityThreshold ?? null - }) - if (isAssetError(assetOrError)) { - switch (assetOrError) { - case AssetError.UnknownAsset: - return { - code: '404', - message: 'Unknown asset', - success: false + const assetService = await ctx.container.use('assetService') + const assetOrError = await assetService.update({ + id: args.input.id, + withdrawalThreshold: args.input.withdrawalThreshold ?? null, + liquidityThreshold: args.input.liquidityThreshold ?? null + }) + if (isAssetError(assetOrError)) { + switch (assetOrError) { + case AssetError.UnknownAsset: + throw new GraphQLError('Asset not found', { + extensions: { + code: GraphQLErrorCode.NotFound } - default: - throw new Error(`AssetError: ${assetOrError}`) - } - } - return { - code: '200', - success: true, - message: 'Updated Asset', - asset: assetToGraphql(assetOrError) - } - } catch (err) { - ctx.logger.error( - { - options: args.input, - err - }, - 'error updating asset' - ) - return { - code: '400', - message: 'Error trying to update asset', - success: false + }) + default: + throw new GraphQLError('Internal Server Error', { + extensions: { + code: GraphQLErrorCode.InternalServerError, + error: assetOrError + } + }) } } + return { + asset: assetToGraphql(assetOrError) + } } export const getAssetSendingFee: AssetResolvers['sendingFee'] = From 509d48d3c0a2d1081c98df754f797cd47d517fa6 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 09:41:35 +0200 Subject: [PATCH 04/34] wip: update autopeering resolvers --- .../graphql/resolvers/auto-peering.test.ts | 31 +++++--------- .../src/graphql/resolvers/auto-peering.ts | 40 ++++++------------- .../payment-method/ilp/auto-peering/errors.ts | 19 +++++---- 3 files changed, 33 insertions(+), 57 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/auto-peering.test.ts b/packages/backend/src/graphql/resolvers/auto-peering.test.ts index 86f0f0a0ad..5927efe935 100644 --- a/packages/backend/src/graphql/resolvers/auto-peering.test.ts +++ b/packages/backend/src/graphql/resolvers/auto-peering.test.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import assert from 'assert' import { createTestApp, TestContainer } from '../../tests/app' @@ -10,7 +10,6 @@ import { initIocContainer } from '../..' import { Config } from '../../config/app' import { truncateTables } from '../../tests/tableManager' import { - errorToCode, errorToMessage, AutoPeeringError } from '../../payment-method/ilp/auto-peering/errors' @@ -18,8 +17,7 @@ import { createAsset } from '../../tests/asset' import { CreateOrUpdatePeerByUrlInput } from '../generated/graphql' import { AutoPeeringService } from '../../payment-method/ilp/auto-peering/service' import { v4 as uuid } from 'uuid' - -const nock = (global as unknown as { nock: typeof import('nock') }).nock +import nock from 'nock' describe('Auto Peering Resolvers', (): void => { let deps: IocContract @@ -121,8 +119,6 @@ describe('Auto Peering Resolvers', (): void => { const response = await callCreateOrUpdatePeerByUrl(input) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') assert.ok(response.peer) expect(response.peer).toEqual({ __typename: 'Peer', @@ -244,12 +240,12 @@ describe('Auto Peering Resolvers', (): void => { ${AutoPeeringError.InvalidPeerUrl} ${AutoPeeringError.InvalidPeeringRequest} ${AutoPeeringError.LiquidityError} - `('4XX - $error', async ({ error }): Promise => { + `('Errors with $error', async ({ error }): Promise => { jest .spyOn(autoPeeringService, 'initiatePeeringRequest') .mockResolvedValueOnce(error) const input = createOrUpdatePeerByUrlInput() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateOrUpdatePeerByUrl( @@ -277,23 +273,18 @@ describe('Auto Peering Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual( - errorToCode[error as AutoPeeringError].toString() - ) - expect(response.message).toEqual( + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( errorToMessage[error as AutoPeeringError] ) }) - test('500', async (): Promise => { + test('Internal server error', async (): Promise => { jest .spyOn(autoPeeringService, 'initiatePeeringRequest') - .mockImplementationOnce(async (_args) => { - throw new Error('unexpected') - }) + .mockRejectedValueOnce(new Error('unexpected')) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateOrUpdatePeerByUrl( @@ -320,9 +311,7 @@ describe('Auto Peering Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.code).toBe('500') - expect(response.success).toBe(false) - expect(response.message).toBe('Error trying to create peer') + await expect(gqlQuery).rejects.toThrow(ApolloError) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/auto-peering.ts b/packages/backend/src/graphql/resolvers/auto-peering.ts index 004436be40..ebf6386aa9 100644 --- a/packages/backend/src/graphql/resolvers/auto-peering.ts +++ b/packages/backend/src/graphql/resolvers/auto-peering.ts @@ -8,6 +8,7 @@ import { isAutoPeeringError } from '../../payment-method/ilp/auto-peering/errors' import { peerToGraphql } from './peer' +import { GraphQLError } from 'graphql' export const createOrUpdatePeerByUrl: MutationResolvers['createOrUpdatePeerByUrl'] = async ( @@ -16,34 +17,17 @@ export const createOrUpdatePeerByUrl: MutationResolvers['createOr ctx ): Promise => { const autoPeeringService = await ctx.container.use('autoPeeringService') - return autoPeeringService - .initiatePeeringRequest(args.input) - .then((peerOrError: Peer | AutoPeeringError) => - isAutoPeeringError(peerOrError) - ? { - code: errorToCode[peerOrError].toString(), - success: false, - message: errorToMessage[peerOrError] - } - : { - code: '200', - success: true, - message: 'ILP peer created or updated', - peer: peerToGraphql(peerOrError) - } - ) - .catch((err) => { - ctx.logger.error( - { - options: args.input, - err - }, - 'error creating peer' - ) - return { - code: '500', - success: false, - message: 'Error trying to create peer' + const peerOrError: Peer | AutoPeeringError = + await autoPeeringService.initiatePeeringRequest(args.input) + if (isAutoPeeringError(peerOrError)) { + throw new GraphQLError(errorToMessage[peerOrError], { + extensions: { + code: errorToCode[peerOrError] } }) + } else { + return { + peer: peerToGraphql(peerOrError) + } + } } diff --git a/packages/backend/src/payment-method/ilp/auto-peering/errors.ts b/packages/backend/src/payment-method/ilp/auto-peering/errors.ts index ddc5252b08..ce841365fc 100644 --- a/packages/backend/src/payment-method/ilp/auto-peering/errors.ts +++ b/packages/backend/src/payment-method/ilp/auto-peering/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../../../graphql/errors' + export enum AutoPeeringError { InvalidIlpConfiguration = 'InvalidIlpConfiguration', InvalidPeerIlpConfiguration = 'InvalidPeerIlpConfiguration', @@ -13,15 +15,16 @@ export const isAutoPeeringError = (o: any): o is AutoPeeringError => Object.values(AutoPeeringError).includes(o) export const errorToCode: { - [key in AutoPeeringError]: number + [key in AutoPeeringError]: string } = { - [AutoPeeringError.InvalidIlpConfiguration]: 400, - [AutoPeeringError.InvalidPeerIlpConfiguration]: 400, - [AutoPeeringError.UnknownAsset]: 404, - [AutoPeeringError.PeerUnsupportedAsset]: 400, - [AutoPeeringError.InvalidPeerUrl]: 400, - [AutoPeeringError.InvalidPeeringRequest]: 400, - [AutoPeeringError.LiquidityError]: 400 + [AutoPeeringError.InvalidIlpConfiguration]: GraphQLErrorCode.BadUserInput, + [AutoPeeringError.InvalidPeerIlpConfiguration]: + GraphQLErrorCode.InternalServerError, + [AutoPeeringError.UnknownAsset]: GraphQLErrorCode.NotFound, + [AutoPeeringError.PeerUnsupportedAsset]: GraphQLErrorCode.BadUserInput, + [AutoPeeringError.InvalidPeerUrl]: GraphQLErrorCode.NotFound, + [AutoPeeringError.InvalidPeeringRequest]: GraphQLErrorCode.BadUserInput, + [AutoPeeringError.LiquidityError]: GraphQLErrorCode.InternalServerError } export const errorToMessage: { From e2555bf91dfe79a6cb8d3e2cd74de6c10119ad11 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 10:59:50 +0200 Subject: [PATCH 05/34] feat: further simplify asset resolver --- packages/backend/src/asset/errors.ts | 10 ++-- .../backend/src/graphql/resolvers/asset.ts | 49 +++++-------------- 2 files changed, 18 insertions(+), 41 deletions(-) diff --git a/packages/backend/src/asset/errors.ts b/packages/backend/src/asset/errors.ts index 100ccb141d..5841e94129 100644 --- a/packages/backend/src/asset/errors.ts +++ b/packages/backend/src/asset/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../graphql/errors' + export enum AssetError { DuplicateAsset = 'DuplicateAsset', UnknownAsset = 'UnknownAsset', @@ -9,11 +11,11 @@ export const isAssetError = (o: any): o is AssetError => Object.values(AssetError).includes(o) export const errorToCode: { - [key in AssetError]: number + [key in AssetError]: string } = { - [AssetError.UnknownAsset]: 404, - [AssetError.DuplicateAsset]: 400, - [AssetError.CannotDeleteInUseAsset]: 400 + [AssetError.UnknownAsset]: GraphQLErrorCode.NotFound, + [AssetError.DuplicateAsset]: GraphQLErrorCode.Duplicate, + [AssetError.CannotDeleteInUseAsset]: GraphQLErrorCode.Forbidden } export const errorToMessage: { diff --git a/packages/backend/src/graphql/resolvers/asset.ts b/packages/backend/src/graphql/resolvers/asset.ts index 88ed2d49f6..9ee0972149 100644 --- a/packages/backend/src/graphql/resolvers/asset.ts +++ b/packages/backend/src/graphql/resolvers/asset.ts @@ -6,12 +6,7 @@ import { AssetResolvers } from '../generated/graphql' import { Asset } from '../../asset/model' -import { - AssetError, - isAssetError, - errorToCode, - errorToMessage -} from '../../asset/errors' +import { errorToCode, errorToMessage, isAssetError } from '../../asset/errors' import { ApolloContext } from '../../app' import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' @@ -54,7 +49,7 @@ export const getAsset: QueryResolvers['asset'] = async ( if (!asset) { throw new GraphQLError('Asset not found', { extensions: { - code: 'NOT_FOUND' + code: GraphQLErrorCode.NotFound } }) } @@ -70,21 +65,11 @@ export const createAsset: MutationResolvers['createAsset'] = const assetService = await ctx.container.use('assetService') const assetOrError = await assetService.create(args.input) if (isAssetError(assetOrError)) { - switch (assetOrError) { - case AssetError.DuplicateAsset: - throw new GraphQLError('Asset already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - default: - throw new GraphQLError('Internal Server Error', { - extensions: { - code: GraphQLErrorCode.InternalServerError, - error: assetOrError - } - }) - } + throw new GraphQLError(errorToMessage[assetOrError], { + extensions: { + code: errorToCode[assetOrError] + } + }) } return { asset: assetToGraphql(assetOrError) @@ -104,21 +89,11 @@ export const updateAsset: MutationResolvers['updateAsset'] = liquidityThreshold: args.input.liquidityThreshold ?? null }) if (isAssetError(assetOrError)) { - switch (assetOrError) { - case AssetError.UnknownAsset: - throw new GraphQLError('Asset not found', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - default: - throw new GraphQLError('Internal Server Error', { - extensions: { - code: GraphQLErrorCode.InternalServerError, - error: assetOrError - } - }) - } + throw new GraphQLError(errorToMessage[assetOrError], { + extensions: { + code: errorToCode[assetOrError] + } + }) } return { asset: assetToGraphql(assetOrError) From 4004989d67f38ec5384811f9d1eab299091823d9 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 11:34:54 +0200 Subject: [PATCH 06/34] feat: update fee resolvers --- packages/backend/src/fee/errors.ts | 12 +++--- .../backend/src/graphql/resolvers/fee.test.ts | 40 +++++-------------- packages/backend/src/graphql/resolvers/fee.ts | 37 +++++------------ 3 files changed, 26 insertions(+), 63 deletions(-) diff --git a/packages/backend/src/fee/errors.ts b/packages/backend/src/fee/errors.ts index 86dd75c726..a6895bfda4 100644 --- a/packages/backend/src/fee/errors.ts +++ b/packages/backend/src/fee/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../graphql/errors' + export enum FeeError { UnknownAsset = 'UnknownAsset', InvalidBasisPointFee = 'InvalidBasisPointFee', @@ -9,17 +11,17 @@ export const isFeeError = (o: any): o is FeeError => Object.values(FeeError).includes(o) export const errorToCode: { - [key in FeeError]: number + [key in FeeError]: string } = { - [FeeError.UnknownAsset]: 404, - [FeeError.InvalidBasisPointFee]: 400, - [FeeError.InvalidFixedFee]: 400 + [FeeError.UnknownAsset]: GraphQLErrorCode.NotFound, + [FeeError.InvalidBasisPointFee]: GraphQLErrorCode.BadUserInput, + [FeeError.InvalidFixedFee]: GraphQLErrorCode.BadUserInput } export const errorToMessage: { [key in FeeError]: string } = { - [FeeError.UnknownAsset]: 'unknown asset', + [FeeError.UnknownAsset]: 'Unknown asset', [FeeError.InvalidBasisPointFee]: 'Basis point fee must be between 0 and 10000', [FeeError.InvalidFixedFee]: 'Fixed fee must be greater than or equal to 0' diff --git a/packages/backend/src/graphql/resolvers/fee.test.ts b/packages/backend/src/graphql/resolvers/fee.test.ts index 99954a97ef..e617b00e8a 100644 --- a/packages/backend/src/graphql/resolvers/fee.test.ts +++ b/packages/backend/src/graphql/resolvers/fee.test.ts @@ -4,7 +4,7 @@ import { initIocContainer } from '../..' import { Config } from '../../config/app' import { createTestApp, TestContainer } from '../../tests/app' import { truncateTables } from '../../tests/tableManager' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { SetFeeResponse } from '../generated/graphql' import { Asset } from '../../asset/model' import { createAsset } from '../../tests/asset' @@ -52,9 +52,6 @@ describe('Fee Resolvers', () => { mutation: gql` mutation SetFee($input: SetFeeInput!) { setFee(input: $input) { - code - success - message fee { id assetId @@ -76,9 +73,6 @@ describe('Fee Resolvers', () => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.message).toEqual('Fee set') expect(response.fee).toMatchObject({ __typename: 'Fee', assetId: input.assetId, @@ -97,14 +91,11 @@ describe('Fee Resolvers', () => { basisPoints: 100 } } - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation SetFee($input: SetFeeInput!) { setFee(input: $input) { - code - success - message fee { id assetId @@ -126,10 +117,8 @@ describe('Fee Resolvers', () => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('unknown asset') - expect(response.fee).toBeNull() + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('Unknown asset') }) test('Returns error for invalid percent fee', async (): Promise => { @@ -141,14 +130,11 @@ describe('Fee Resolvers', () => { basisPoints: -10_000 } } - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation SetFee($input: SetFeeInput!) { setFee(input: $input) { - code - success - message fee { id assetId @@ -170,12 +156,10 @@ describe('Fee Resolvers', () => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual( + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( 'Basis point fee must be between 0 and 10000' ) - expect(response.fee).toBeNull() }) test('Returns 500 error for unhandled errors', async (): Promise => { @@ -190,14 +174,11 @@ describe('Fee Resolvers', () => { basisPoints: -10_000 } } - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation setFee($input: SetFeeInput!) { setFee(input: $input) { - code - success - message fee { id assetId @@ -219,10 +200,7 @@ describe('Fee Resolvers', () => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('500') - expect(response.message).toEqual('Error trying to update fee') - expect(response.fee).toBeNull() + await expect(gqlQuery).rejects.toThrow(ApolloError) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/fee.ts b/packages/backend/src/graphql/resolvers/fee.ts index 32d5afad19..71f8fffe93 100644 --- a/packages/backend/src/graphql/resolvers/fee.ts +++ b/packages/backend/src/graphql/resolvers/fee.ts @@ -6,6 +6,7 @@ import { import { ApolloContext } from '../../app' import { isFeeError, errorToCode, errorToMessage } from '../../fee/errors' import { Fee } from '../../fee/model' +import { GraphQLError } from 'graphql' export const setFee: MutationResolvers['setFee'] = async ( parent, @@ -13,35 +14,17 @@ export const setFee: MutationResolvers['setFee'] = async ( ctx ): Promise => { const feeService = await ctx.container.use('feeService') - try { - const feeOrError = await feeService.create(args.input) + const feeOrError = await feeService.create(args.input) - if (isFeeError(feeOrError)) { - return { - code: errorToCode[feeOrError].toString(), - success: false, - message: errorToMessage[feeOrError] + if (isFeeError(feeOrError)) { + throw new GraphQLError(errorToMessage[feeOrError], { + extensions: { + code: errorToCode[feeOrError] } - } - return { - code: '200', - success: true, - message: 'Fee set', - fee: feeToGraphql(feeOrError) - } - } catch (err) { - ctx.logger.error( - { - options: args.input, - err - }, - 'error updating fee' - ) - return { - code: '500', - success: false, - message: 'Error trying to update fee' - } + }) + } + return { + fee: feeToGraphql(feeOrError) } } From aebe65e8769a3c2236feed14767c5a83a2e62001 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 12:09:07 +0200 Subject: [PATCH 07/34] fix: autopeering tests --- .../src/graphql/resolvers/auto-peering.test.ts | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/auto-peering.test.ts b/packages/backend/src/graphql/resolvers/auto-peering.test.ts index 5927efe935..a594ddb60f 100644 --- a/packages/backend/src/graphql/resolvers/auto-peering.test.ts +++ b/packages/backend/src/graphql/resolvers/auto-peering.test.ts @@ -45,9 +45,6 @@ describe('Auto Peering Resolvers', (): void => { $input: CreateOrUpdatePeerByUrlInput! ) { createOrUpdatePeerByUrl(input: $input) { - code - success - message peer { id asset { @@ -167,8 +164,6 @@ describe('Auto Peering Resolvers', (): void => { const response = await callCreateOrUpdatePeerByUrl(input) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') assert.ok(response.peer) expect(response.peer).toEqual({ __typename: 'Peer', @@ -201,8 +196,6 @@ describe('Auto Peering Resolvers', (): void => { const secondResponse = await callCreateOrUpdatePeerByUrl(secondInput) - expect(secondResponse.success).toBe(true) - expect(secondResponse.code).toEqual('200') assert.ok(secondResponse.peer) expect(secondResponse.peer).toEqual({ __typename: 'Peer', @@ -252,9 +245,6 @@ describe('Auto Peering Resolvers', (): void => { $input: CreateOrUpdatePeerByUrlInput! ) { createOrUpdatePeerByUrl(input: $input) { - code - success - message peer { id } @@ -291,9 +281,6 @@ describe('Auto Peering Resolvers', (): void => { $input: CreateOrUpdatePeerByUrlInput! ) { createOrUpdatePeerByUrl(input: $input) { - code - success - message peer { id } From ae5ada70ff40691c45757d4504dbd9e70332ddff Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 12:44:37 +0200 Subject: [PATCH 08/34] feat: update incoming payments --- packages/backend/src/graphql/errors/index.ts | 1 + .../resolvers/incoming_payment.test.ts | 42 +++++------------ .../src/graphql/resolvers/incoming_payment.ts | 45 ++++++++----------- .../open_payments/payment/incoming/errors.ts | 16 ++++++- .../payment/incoming/routes.test.ts | 4 +- .../open_payments/payment/incoming/routes.ts | 10 +++-- .../src/open_payments/receiver/errors.ts | 2 +- 7 files changed, 54 insertions(+), 66 deletions(-) diff --git a/packages/backend/src/graphql/errors/index.ts b/packages/backend/src/graphql/errors/index.ts index 9d74c2514d..b054bf9ef9 100644 --- a/packages/backend/src/graphql/errors/index.ts +++ b/packages/backend/src/graphql/errors/index.ts @@ -1,6 +1,7 @@ export enum GraphQLErrorCode { BadUserInput = 'BAD_USER_INPUT', Duplicate = 'DUPLICATE', + Inactive = 'INACTIVE', InternalServerError = 'INTERNAL_SERVER_ERROR', NotFound = 'NOT_FOUND' } diff --git a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts index 5f005a1f8d..9b18a1f81b 100644 --- a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -22,10 +22,7 @@ import { IncomingPaymentResponse, IncomingPaymentState as SchemaPaymentState } from '../generated/graphql' -import { - IncomingPaymentError, - errorToMessage -} from '../../open_payments/payment/incoming/errors' +import { IncomingPaymentError } from '../../open_payments/payment/incoming/errors' import { Amount, serializeAmount } from '../../open_payments/amount' describe('Incoming Payment Resolver', (): void => { @@ -100,7 +97,7 @@ describe('Incoming Payment Resolver', (): void => { ${undefined} | ${new Date(Date.now() + 30_000)} | ${false} | ${'expiresAt'} ${undefined} | ${undefined} | ${true} | ${'incomingAmount'} `( - '200 ($desc)', + 'Successfully creates an incoming payment with $desc', async ({ metadata, expiresAt, withAmount }): Promise => { const incomingAmount = withAmount ? amount : undefined const { id: walletAddressId } = await createWalletAddress(deps, { @@ -132,9 +129,6 @@ describe('Incoming Payment Resolver', (): void => { $input: CreateIncomingPaymentInput! ) { createIncomingPayment(input: $input) { - code - success - message payment { id walletAddressId @@ -166,9 +160,6 @@ describe('Incoming Payment Resolver', (): void => { expect(createSpy).toHaveBeenCalledWith(input) expect(query).toEqual({ __typename: 'IncomingPaymentResponse', - code: '200', - success: true, - message: null, payment: { __typename: 'IncomingPayment', id: payment.id, @@ -203,16 +194,13 @@ describe('Incoming Payment Resolver', (): void => { walletAddressId: uuid() } - const query = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .query({ query: gql` mutation CreateIncomingPayment( $input: CreateIncomingPaymentInput! ) { createIncomingPayment(input: $input) { - code - success - message payment { id state @@ -225,13 +213,9 @@ describe('Incoming Payment Resolver', (): void => { .then( (query): IncomingPaymentResponse => query.data?.createIncomingPayment ) - expect(query.code).toBe('404') - expect(query.success).toBe(false) - expect(query.message).toBe( - errorToMessage[IncomingPaymentError.UnknownWalletAddress] - ) - expect(query.payment).toBeNull() - expect(createSpy).toHaveBeenCalledWith(input) + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('unknown wallet address') + await expect(createSpy).toHaveBeenCalledWith(input) }) test('500', async (): Promise => { @@ -243,16 +227,13 @@ describe('Incoming Payment Resolver', (): void => { walletAddressId: uuid() } - const query = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .query({ query: gql` mutation CreateIncomingPayment( $input: CreateIncomingPaymentInput! ) { createIncomingPayment(input: $input) { - code - success - message payment { id state @@ -265,11 +246,8 @@ describe('Incoming Payment Resolver', (): void => { .then( (query): IncomingPaymentResponse => query.data?.createIncomingPayment ) - expect(createSpy).toHaveBeenCalledWith(input) - expect(query.code).toBe('500') - expect(query.success).toBe(false) - expect(query.message).toBe('Error trying to create incoming payment') - expect(query.payment).toBeNull() + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(createSpy).toHaveBeenCalledWith(input) }) }) diff --git a/packages/backend/src/graphql/resolvers/incoming_payment.ts b/packages/backend/src/graphql/resolvers/incoming_payment.ts index 213f6ac375..ed031a0cd6 100644 --- a/packages/backend/src/graphql/resolvers/incoming_payment.ts +++ b/packages/backend/src/graphql/resolvers/incoming_payment.ts @@ -7,7 +7,6 @@ import { } from '../generated/graphql' import { IncomingPayment } from '../../open_payments/payment/incoming/model' import { - IncomingPaymentError, isIncomingPaymentError, errorToCode, errorToMessage @@ -15,6 +14,7 @@ import { import { ApolloContext } from '../../app' import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' +import { GraphQLError } from 'graphql' export const getIncomingPayment: QueryResolvers['incomingPayment'] = async (parent, args, ctx): Promise => { @@ -75,33 +75,24 @@ export const createIncomingPayment: MutationResolvers['createInco const incomingPaymentService = await ctx.container.use( 'incomingPaymentService' ) - return incomingPaymentService - .create({ - walletAddressId: args.input.walletAddressId, - expiresAt: !args.input.expiresAt - ? undefined - : new Date(args.input.expiresAt), - incomingAmount: args.input.incomingAmount, - metadata: args.input.metadata + const incomingPaymentOrError = await incomingPaymentService.create({ + walletAddressId: args.input.walletAddressId, + expiresAt: !args.input.expiresAt + ? undefined + : new Date(args.input.expiresAt), + incomingAmount: args.input.incomingAmount, + metadata: args.input.metadata + }) + if (isIncomingPaymentError(incomingPaymentOrError)) { + throw new GraphQLError(errorToMessage[incomingPaymentOrError], { + extensions: { + code: errorToCode[incomingPaymentOrError] + } }) - .then((paymentOrErr: IncomingPayment | IncomingPaymentError) => - isIncomingPaymentError(paymentOrErr) - ? { - code: errorToCode[paymentOrErr].toString(), - success: false, - message: errorToMessage[paymentOrErr] - } - : { - code: '200', - success: true, - payment: paymentToGraphql(paymentOrErr) - } - ) - .catch(() => ({ - code: '500', - success: false, - message: 'Error trying to create incoming payment' - })) + } else + return { + payment: paymentToGraphql(incomingPaymentOrError) + } } export function paymentToGraphql( diff --git a/packages/backend/src/open_payments/payment/incoming/errors.ts b/packages/backend/src/open_payments/payment/incoming/errors.ts index 3ad27737a5..af3362ca70 100644 --- a/packages/backend/src/open_payments/payment/incoming/errors.ts +++ b/packages/backend/src/open_payments/payment/incoming/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../../../graphql/errors' + export enum IncomingPaymentError { UnknownWalletAddress = 'UnknownWalletAddress', InvalidAmount = 'InvalidAmount', @@ -12,7 +14,7 @@ export enum IncomingPaymentError { export const isIncomingPaymentError = (o: any): o is IncomingPaymentError => Object.values(IncomingPaymentError).includes(o) -export const errorToCode: { +export const errorToHTTPCode: { [key in IncomingPaymentError]: number } = { [IncomingPaymentError.UnknownWalletAddress]: 404, @@ -24,6 +26,18 @@ export const errorToCode: { [IncomingPaymentError.InactiveWalletAddress]: 400 } +export const errorToCode: { + [key in IncomingPaymentError]: string +} = { + [IncomingPaymentError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, + [IncomingPaymentError.InvalidAmount]: GraphQLErrorCode.BadUserInput, + [IncomingPaymentError.UnknownPayment]: GraphQLErrorCode.NotFound, + [IncomingPaymentError.InvalidState]: GraphQLErrorCode.BadUserInput, + [IncomingPaymentError.InvalidExpiry]: GraphQLErrorCode.BadUserInput, + [IncomingPaymentError.WrongState]: GraphQLErrorCode.BadUserInput, + [IncomingPaymentError.InactiveWalletAddress]: GraphQLErrorCode.Inactive +} + export const errorToMessage: { [key in IncomingPaymentError]: string } = { diff --git a/packages/backend/src/open_payments/payment/incoming/routes.test.ts b/packages/backend/src/open_payments/payment/incoming/routes.test.ts index d6357e0b62..72835eae3b 100644 --- a/packages/backend/src/open_payments/payment/incoming/routes.test.ts +++ b/packages/backend/src/open_payments/payment/incoming/routes.test.ts @@ -20,7 +20,7 @@ import { createAsset } from '../../../tests/asset' import { createIncomingPayment } from '../../../tests/incomingPayment' import { createWalletAddress } from '../../../tests/walletAddress' import { Asset } from '../../../asset/model' -import { IncomingPaymentError, errorToCode, errorToMessage } from './errors' +import { IncomingPaymentError, errorToHTTPCode, errorToMessage } from './errors' import { IncomingPaymentService } from './service' import { IncomingPaymentWithPaymentMethods as OpenPaymentsIncomingPaymentWithPaymentMethods } from '@interledger/open-payments' @@ -176,7 +176,7 @@ describe('Incoming Payment Routes', (): void => { .mockResolvedValueOnce(error) await expect(incomingPaymentRoutes.create(ctx)).rejects.toMatchObject({ message: errorToMessage[error], - status: errorToCode[error] + status: errorToHTTPCode[error] }) expect(createSpy).toHaveBeenCalledWith({ walletAddressId: walletAddress.id diff --git a/packages/backend/src/open_payments/payment/incoming/routes.ts b/packages/backend/src/open_payments/payment/incoming/routes.ts index c348184f06..eecbc1db5a 100644 --- a/packages/backend/src/open_payments/payment/incoming/routes.ts +++ b/packages/backend/src/open_payments/payment/incoming/routes.ts @@ -8,7 +8,11 @@ import { } from '../../../app' import { IAppConfig } from '../../../config/app' import { IncomingPaymentService } from './service' -import { errorToCode, errorToMessage, isIncomingPaymentError } from './errors' +import { + errorToHTTPCode, + errorToMessage, + isIncomingPaymentError +} from './errors' import { AmountJSON, parseAmount } from '../../amount' import { listSubresource } from '../../wallet_address/routes' import { StreamCredentialsService } from '../../../payment-method/ilp/stream-credentials/service' @@ -139,7 +143,7 @@ async function createIncomingPayment( if (isIncomingPaymentError(incomingPaymentOrError)) { throw new OpenPaymentsServerRouteError( - errorToCode[incomingPaymentOrError], + errorToHTTPCode[incomingPaymentOrError], errorToMessage[incomingPaymentOrError] ) } @@ -164,7 +168,7 @@ async function completeIncomingPayment( if (isIncomingPaymentError(incomingPaymentOrError)) { throw new OpenPaymentsServerRouteError( - errorToCode[incomingPaymentOrError], + errorToHTTPCode[incomingPaymentOrError], errorToMessage[incomingPaymentOrError] ) } diff --git a/packages/backend/src/open_payments/receiver/errors.ts b/packages/backend/src/open_payments/receiver/errors.ts index 6f655764d1..9affe717fb 100644 --- a/packages/backend/src/open_payments/receiver/errors.ts +++ b/packages/backend/src/open_payments/receiver/errors.ts @@ -1,6 +1,6 @@ import { errorToMessage as incomingPaymentErrorToMessage, - errorToCode as incomingPaymentErrorToCode, + errorToHTTPCode as incomingPaymentErrorToCode, isIncomingPaymentError, IncomingPaymentError } from '../payment/incoming/errors' From 1d74d9b85a787bd0b98f33645182f28eeeffd126 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 14:39:43 +0200 Subject: [PATCH 09/34] fix: improve error handling on incoming payment resolver --- .../graphql/resolvers/incoming_payment.test.ts | 4 ++-- .../src/graphql/resolvers/incoming_payment.ts | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts index 9b18a1f81b..360865d152 100644 --- a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts @@ -185,7 +185,7 @@ describe('Incoming Payment Resolver', (): void => { } ) - test('400', async (): Promise => { + test('Errors when unknown wallet address', async (): Promise => { const createSpy = jest .spyOn(incomingPaymentService, 'create') .mockResolvedValueOnce(IncomingPaymentError.UnknownWalletAddress) @@ -218,7 +218,7 @@ describe('Incoming Payment Resolver', (): void => { await expect(createSpy).toHaveBeenCalledWith(input) }) - test('500', async (): Promise => { + test('Internal server error', async (): Promise => { const createSpy = jest .spyOn(incomingPaymentService, 'create') .mockRejectedValueOnce(new Error('unexpected')) diff --git a/packages/backend/src/graphql/resolvers/incoming_payment.ts b/packages/backend/src/graphql/resolvers/incoming_payment.ts index ed031a0cd6..cde669d166 100644 --- a/packages/backend/src/graphql/resolvers/incoming_payment.ts +++ b/packages/backend/src/graphql/resolvers/incoming_payment.ts @@ -15,6 +15,7 @@ import { ApolloContext } from '../../app' import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' export const getIncomingPayment: QueryResolvers['incomingPayment'] = async (parent, args, ctx): Promise => { @@ -24,7 +25,13 @@ export const getIncomingPayment: QueryResolvers['incomingPayment' const payment = await incomingPaymentService.get({ id: args.id }) - if (!payment) throw new Error('payment does not exist') + if (!payment) { + throw new GraphQLError('payment does not exist', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + } return paymentToGraphql(payment) } @@ -34,7 +41,13 @@ export const getWalletAddressIncomingPayments: WalletAddressResolvers => { - if (!parent.id) throw new Error('missing wallet address id') + if (!parent.id) { + throw new GraphQLError('missing wallet address id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + } const incomingPaymentService = await ctx.container.use( 'incomingPaymentService' ) From f24381e3fd36823f9f3272993aeee7e26af51abd Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 15:44:24 +0200 Subject: [PATCH 10/34] feat: update outgoing payment resolvers --- packages/backend/src/graphql/errors/index.ts | 1 + .../resolvers/outgoing_payment.test.ts | 40 +++++-------- .../src/graphql/resolvers/outgoing_payment.ts | 57 ++++++++++--------- .../open_payments/payment/outgoing/errors.ts | 15 ++++- .../payment/outgoing/routes.test.ts | 4 +- .../open_payments/payment/outgoing/routes.ts | 8 ++- 6 files changed, 67 insertions(+), 58 deletions(-) diff --git a/packages/backend/src/graphql/errors/index.ts b/packages/backend/src/graphql/errors/index.ts index b054bf9ef9..dbd4d60ac2 100644 --- a/packages/backend/src/graphql/errors/index.ts +++ b/packages/backend/src/graphql/errors/index.ts @@ -1,6 +1,7 @@ export enum GraphQLErrorCode { BadUserInput = 'BAD_USER_INPUT', Duplicate = 'DUPLICATE', + Forbidden = 'FORBIDDEN', Inactive = 'INACTIVE', InternalServerError = 'INTERNAL_SERVER_ERROR', NotFound = 'NOT_FOUND' diff --git a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts index 4d41cb3f12..3002c5237b 100644 --- a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { PaymentError } from '@interledger/pay' import { v4 as uuid } from 'uuid' import * as Pay from '@interledger/pay' @@ -13,10 +13,7 @@ import { createAsset } from '../../tests/asset' import { createOutgoingPayment } from '../../tests/outgoingPayment' import { createWalletAddress } from '../../tests/walletAddress' import { truncateTables } from '../../tests/tableManager' -import { - OutgoingPaymentError, - errorToMessage -} from '../../open_payments/payment/outgoing/errors' +import { OutgoingPaymentError } from '../../open_payments/payment/outgoing/errors' import { OutgoingPaymentService } from '../../open_payments/payment/outgoing/service' import { OutgoingPayment as OutgoingPaymentModel, @@ -290,8 +287,6 @@ describe('OutgoingPayment Resolvers', (): void => { $input: CreateOutgoingPaymentInput! ) { createOutgoingPayment(input: $input) { - code - success payment { id state @@ -306,13 +301,16 @@ describe('OutgoingPayment Resolvers', (): void => { ) expect(createSpy).toHaveBeenCalledWith(input) +<<<<<<< HEAD expect(query.code).toBe('201') expect(query.success).toBe(true) +======= +>>>>>>> d55fecd7 (feat: update outgoing payment resolvers) expect(query.payment?.id).toBe(payment.id) expect(query.payment?.state).toBe(SchemaPaymentState.Funding) }) - test('400', async (): Promise => { + test('Fails if walletAddress unknown', async (): Promise => { const createSpy = jest .spyOn(outgoingPaymentService, 'create') .mockResolvedValueOnce(OutgoingPaymentError.UnknownWalletAddress) @@ -322,16 +320,13 @@ describe('OutgoingPayment Resolvers', (): void => { quoteId: uuid() } - const query = await appContainer.apolloClient + const query = appContainer.apolloClient .query({ query: gql` mutation CreateOutgoingPayment( $input: CreateOutgoingPaymentInput! ) { createOutgoingPayment(input: $input) { - code - success - message payment { id state @@ -344,13 +339,9 @@ describe('OutgoingPayment Resolvers', (): void => { .then( (query): OutgoingPaymentResponse => query.data?.createOutgoingPayment ) - expect(query.code).toBe('404') - expect(query.success).toBe(false) - expect(query.message).toBe( - errorToMessage[OutgoingPaymentError.UnknownWalletAddress] - ) - expect(query.payment).toBeNull() - expect(createSpy).toHaveBeenCalledWith(input) + await expect(query).rejects.toThrow(ApolloError) + await expect(query).rejects.toThrow('unknown wallet address') + await expect(createSpy).toHaveBeenCalledWith(input) }) test('500', async (): Promise => { @@ -363,16 +354,13 @@ describe('OutgoingPayment Resolvers', (): void => { quoteId: uuid() } - const query = await appContainer.apolloClient + const query = appContainer.apolloClient .query({ query: gql` mutation CreateOutgoingPayment( $input: CreateOutgoingPaymentInput! ) { createOutgoingPayment(input: $input) { - code - success - message payment { id state @@ -385,11 +373,9 @@ describe('OutgoingPayment Resolvers', (): void => { .then( (query): OutgoingPaymentResponse => query.data?.createOutgoingPayment ) + + await expect(query).rejects.toThrow(ApolloError) expect(createSpy).toHaveBeenCalledWith(input) - expect(query.code).toBe('500') - expect(query.success).toBe(false) - expect(query.message).toBe('Error trying to create outgoing payment') - expect(query.payment).toBeNull() }) }) diff --git a/packages/backend/src/graphql/resolvers/outgoing_payment.ts b/packages/backend/src/graphql/resolvers/outgoing_payment.ts index 20894fdeca..61e0276219 100644 --- a/packages/backend/src/graphql/resolvers/outgoing_payment.ts +++ b/packages/backend/src/graphql/resolvers/outgoing_payment.ts @@ -9,13 +9,15 @@ import { import { OutgoingPaymentError, isOutgoingPaymentError, - errorToCode, - errorToMessage + errorToMessage, + errorToCode } from '../../open_payments/payment/outgoing/errors' import { OutgoingPayment } from '../../open_payments/payment/outgoing/model' import { ApolloContext } from '../../app' import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' export const getOutgoingPayment: QueryResolvers['outgoingPayment'] = async (parent, args, ctx): Promise => { @@ -25,7 +27,13 @@ export const getOutgoingPayment: QueryResolvers['outgoingPayment' const payment = await outgoingPaymentService.get({ id: args.id }) - if (!payment) throw new Error('payment does not exist') + if (!payment) { + throw new GraphQLError('payment does not exist', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + } return paymentToGraphql(payment) } @@ -70,26 +78,19 @@ export const createOutgoingPayment: MutationResolvers['createOutg const outgoingPaymentService = await ctx.container.use( 'outgoingPaymentService' ) - return outgoingPaymentService - .create(args.input) - .then((paymentOrErr: OutgoingPayment | OutgoingPaymentError) => - isOutgoingPaymentError(paymentOrErr) - ? { - code: errorToCode[paymentOrErr].toString(), - success: false, - message: errorToMessage[paymentOrErr] - } - : { - code: '201', - success: true, - payment: paymentToGraphql(paymentOrErr) - } - ) - .catch(() => ({ - code: '500', - success: false, - message: 'Error trying to create outgoing payment' - })) + const outgoingPaymentOrError = await outgoingPaymentService.create( + args.input + ) + if (isOutgoingPaymentError(outgoingPaymentOrError)) { + throw new GraphQLError(errorToMessage[outgoingPaymentOrError], { + extensions: { + code: errorToCode[outgoingPaymentOrError] + } + }) + } else + return { + payment: paymentToGraphql(outgoingPaymentOrError) + } } export const createOutgoingPaymentFromIncomingPayment: MutationResolvers['createOutgoingPaymentFromIncomingPayment'] = @@ -111,8 +112,6 @@ export const createOutgoingPaymentFromIncomingPayment: MutationResolvers => { - if (!parent.id) throw new Error('missing wallet address id') + if (!parent.id) { + throw new GraphQLError('missing wallet address id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + } const outgoingPaymentService = await ctx.container.use( 'outgoingPaymentService' ) diff --git a/packages/backend/src/open_payments/payment/outgoing/errors.ts b/packages/backend/src/open_payments/payment/outgoing/errors.ts index 606906e610..ffbee953c8 100644 --- a/packages/backend/src/open_payments/payment/outgoing/errors.ts +++ b/packages/backend/src/open_payments/payment/outgoing/errors.ts @@ -1,4 +1,5 @@ import { TransferError } from '../../../accounting/errors' +import { GraphQLErrorCode } from '../../../graphql/errors' import { PaymentMethodHandlerError } from '../../../payment-method/handler/errors' import { QuoteError } from '../../quote/errors' @@ -31,7 +32,7 @@ export const quoteErrorToOutgoingPaymentError: Record< export const isOutgoingPaymentError = (o: any): o is OutgoingPaymentError => Object.values(OutgoingPaymentError).includes(o) -export const errorToCode: { +export const errorToHTTPCode: { [key in OutgoingPaymentError]: number } = { [OutgoingPaymentError.UnknownWalletAddress]: 404, @@ -46,6 +47,18 @@ export const errorToCode: { [OutgoingPaymentError.InvalidReceiver]: 400 } +export const errorToCode: { + [key in OutgoingPaymentError]: string +} = { + [OutgoingPaymentError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, + [OutgoingPaymentError.UnknownPayment]: GraphQLErrorCode.NotFound, + [OutgoingPaymentError.UnknownQuote]: GraphQLErrorCode.NotFound, + [OutgoingPaymentError.WrongState]: GraphQLErrorCode.BadUserInput, + [OutgoingPaymentError.InvalidQuote]: GraphQLErrorCode.BadUserInput, + [OutgoingPaymentError.InsufficientGrant]: GraphQLErrorCode.Forbidden, + [OutgoingPaymentError.InactiveWalletAddress]: GraphQLErrorCode.Inactive +} + export const errorToMessage: { [key in OutgoingPaymentError]: string } = { diff --git a/packages/backend/src/open_payments/payment/outgoing/routes.test.ts b/packages/backend/src/open_payments/payment/outgoing/routes.test.ts index 9eb2a2961e..f30dab4641 100644 --- a/packages/backend/src/open_payments/payment/outgoing/routes.test.ts +++ b/packages/backend/src/open_payments/payment/outgoing/routes.test.ts @@ -10,7 +10,6 @@ import { initIocContainer } from '../../..' import { AppServices, CreateContext } from '../../../app' import { truncateTables } from '../../../tests/tableManager' import { createAsset } from '../../../tests/asset' -import { errorToCode, errorToMessage, OutgoingPaymentError } from './errors' import { CreateFromIncomingPayment, CreateFromQuote, @@ -18,6 +17,7 @@ import { OutgoingPaymentService, BaseOptions as CreateOutgoingPaymentBaseOptions } from './service' +import { errorToHTTPCode, errorToMessage, OutgoingPaymentError } from './errors' import { OutgoingPayment, OutgoingPaymentState } from './model' import { OutgoingPaymentRoutes, CreateBody } from './routes' import { serializeAmount } from '../../amount' @@ -295,7 +295,7 @@ describe('Outgoing Payment Routes', (): void => { } catch (err) { assert(err instanceof OpenPaymentsServerRouteError) expect(err.message).toBe(errorToMessage[error]) - expect(err.status).toBe(errorToCode[error]) + expect(err.status).toBe(errorToHTTPCode[error]) } expect(createSpy).toHaveBeenCalledWith({ diff --git a/packages/backend/src/open_payments/payment/outgoing/routes.ts b/packages/backend/src/open_payments/payment/outgoing/routes.ts index 935ab2470b..e39e0c3baf 100644 --- a/packages/backend/src/open_payments/payment/outgoing/routes.ts +++ b/packages/backend/src/open_payments/payment/outgoing/routes.ts @@ -6,7 +6,11 @@ import { OutgoingPaymentService, BaseOptions as OutgoingPaymentCreateBaseOptions } from './service' -import { isOutgoingPaymentError, errorToCode, errorToMessage } from './errors' +import { + isOutgoingPaymentError, + errorToHTTPCode, + errorToMessage +} from './errors' import { OutgoingPayment } from './model' import { listSubresource } from '../../wallet_address/routes' import { @@ -127,7 +131,7 @@ async function createOutgoingPayment( if (isOutgoingPaymentError(outgoingPaymentOrError)) { throw new OpenPaymentsServerRouteError( - errorToCode[outgoingPaymentOrError], + errorToHTTPCode[outgoingPaymentOrError], errorToMessage[outgoingPaymentOrError] ) } From 21cc64f7f0d9f7168381d505742c60c4115047a2 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 16:35:34 +0200 Subject: [PATCH 11/34] feat: update peer resolvers --- .../src/graphql/resolvers/peer.test.ts | 82 +++--------- .../backend/src/graphql/resolvers/peer.ts | 122 ++++++------------ .../src/payment-method/ilp/peer/errors.ts | 18 +-- 3 files changed, 65 insertions(+), 157 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/peer.test.ts b/packages/backend/src/graphql/resolvers/peer.test.ts index a24997566b..f22fdebd40 100644 --- a/packages/backend/src/graphql/resolvers/peer.test.ts +++ b/packages/backend/src/graphql/resolvers/peer.test.ts @@ -12,11 +12,7 @@ import { Asset } from '../../asset/model' import { initIocContainer } from '../..' import { Config } from '../../config/app' import { truncateTables } from '../../tests/tableManager' -import { - errorToCode, - errorToMessage, - PeerError -} from '../../payment-method/ilp/peer/errors' +import { errorToMessage, PeerError } from '../../payment-method/ilp/peer/errors' import { Peer as PeerModel } from '../../payment-method/ilp/peer/model' import { PeerService } from '../../payment-method/ilp/peer/service' import { createAsset } from '../../tests/asset' @@ -83,9 +79,6 @@ describe('Peer Resolvers', (): void => { mutation: gql` mutation CreatePeer($input: CreatePeerInput!) { createPeer(input: $input) { - code - success - message peer { id asset { @@ -119,8 +112,6 @@ describe('Peer Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') assert.ok(response.peer) expect(response.peer).toEqual({ __typename: 'Peer', @@ -161,17 +152,14 @@ describe('Peer Resolvers', (): void => { ${PeerError.UnknownAsset} ${PeerError.DuplicatePeer} ${PeerError.InvalidInitialLiquidity} - `('4XX - $error', async ({ error }): Promise => { + `('Error - $error', async ({ error }): Promise => { jest.spyOn(peerService, 'create').mockResolvedValueOnce(error) const peer = randomPeer() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreatePeer($input: CreatePeerInput!) { createPeer(input: $input) { - code - success - message peer { id } @@ -190,9 +178,8 @@ describe('Peer Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual(errorToCode[error as PeerError].toString()) - expect(response.message).toEqual(errorToMessage[error as PeerError]) + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow(errorToMessage[error as PeerError]) }) test('500', async (): Promise => { @@ -202,14 +189,11 @@ describe('Peer Resolvers', (): void => { throw new Error('unexpected') }) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreatePeer($input: CreatePeerInput!) { createPeer(input: $input) { - code - success - message peer { id } @@ -227,9 +211,7 @@ describe('Peer Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.code).toBe('500') - expect(response.success).toBe(false) - expect(response.message).toBe('Error trying to create peer') + await expect(gqlQuery).rejects.toThrow(ApolloError) }) }) @@ -351,6 +333,7 @@ describe('Peer Resolvers', (): void => { }) await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('Peer not found') }) }) @@ -462,9 +445,6 @@ describe('Peer Resolvers', (): void => { mutation: gql` mutation UpdatePeer($input: UpdatePeerInput!) { updatePeer(input: $input) { - code - success - message peer { id maxPacketAmount @@ -493,8 +473,6 @@ describe('Peer Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') expect(response.peer).toEqual({ __typename: 'Peer', ...updateOptions, @@ -527,16 +505,13 @@ describe('Peer Resolvers', (): void => { ${PeerError.InvalidStaticIlpAddress} ${PeerError.InvalidHTTPEndpoint} ${PeerError.UnknownPeer} - `('4XX - $error', async ({ error }): Promise => { + `('Error - $error', async ({ error }): Promise => { jest.spyOn(peerService, 'update').mockResolvedValueOnce(error) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation UpdatePeer($input: UpdatePeerInput!) { updatePeer(input: $input) { - code - success - message peer { id } @@ -558,9 +533,8 @@ describe('Peer Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual(errorToCode[error as PeerError].toString()) - expect(response.message).toEqual(errorToMessage[error as PeerError]) + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow(errorToMessage[error as PeerError]) }) test('Returns error if unexpected error', async (): Promise => { @@ -568,14 +542,11 @@ describe('Peer Resolvers', (): void => { throw new Error('unexpected') }) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation UpdatePeer($input: UpdatePeerInput!) { updatePeer(input: $input) { - code - success - message peer { id maxPacketAmount @@ -606,9 +577,7 @@ describe('Peer Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('500') - expect(response.message).toEqual('Error trying to update peer') + await expect(gqlQuery).rejects.toThrow(ApolloError) }) }) @@ -625,9 +594,7 @@ describe('Peer Resolvers', (): void => { mutation: gql` mutation DeletePeer($input: DeletePeerInput!) { deletePeer(input: $input) { - code success - message } } `, @@ -646,20 +613,16 @@ describe('Peer Resolvers', (): void => { }) expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.message).toEqual('Deleted ILP Peer') await expect(peerService.get(peer.id)).resolves.toBeUndefined() }) test('Returns error for unknown peer', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DeletePeer($input: DeletePeerInput!) { deletePeer(input: $input) { - code success - message } } `, @@ -677,11 +640,8 @@ describe('Peer Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual( - errorToCode[PeerError.UnknownPeer].toString() - ) - expect(response.message).toEqual(errorToMessage[PeerError.UnknownPeer]) + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('unknown peer') }) test('Returns error if unexpected error', async (): Promise => { @@ -689,14 +649,12 @@ describe('Peer Resolvers', (): void => { throw new Error('unexpected') }) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DeletePeer($input: DeletePeerInput!) { deletePeer(input: $input) { - code success - message } } `, @@ -714,9 +672,7 @@ describe('Peer Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('500') - expect(response.message).toEqual('Error trying to delete peer') + await expect(gqlQuery).rejects.toThrow(ApolloError) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/peer.ts b/packages/backend/src/graphql/resolvers/peer.ts index 2a93c09737..ff18fc9e04 100644 --- a/packages/backend/src/graphql/resolvers/peer.ts +++ b/packages/backend/src/graphql/resolvers/peer.ts @@ -7,14 +7,16 @@ import { } from '../generated/graphql' import { Peer } from '../../payment-method/ilp/peer/model' import { - PeerError, isPeerError, errorToCode, - errorToMessage + errorToMessage, + PeerError } from '../../payment-method/ilp/peer/errors' import { ApolloContext } from '../../app' import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' export const getPeers: QueryResolvers['peers'] = async ( parent, @@ -48,7 +50,11 @@ export const getPeer: QueryResolvers['peer'] = async ( const peerService = await ctx.container.use('peerService') const peer = await peerService.get(args.id) if (!peer) { - throw new Error('No peer') + throw new GraphQLError('Peer not found', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) } return peerToGraphql(peer) } @@ -60,36 +66,17 @@ export const createPeer: MutationResolvers['createPeer'] = ctx ): Promise => { const peerService = await ctx.container.use('peerService') - return peerService - .create(args.input) - .then((peerOrError: Peer | PeerError) => - isPeerError(peerOrError) - ? { - code: errorToCode[peerOrError].toString(), - success: false, - message: errorToMessage[peerOrError] - } - : { - code: '200', - success: true, - message: 'Created ILP Peer', - peer: peerToGraphql(peerOrError) - } - ) - .catch((err) => { - ctx.logger.error( - { - options: args.input, - err - }, - 'error creating peer' - ) - return { - code: '500', - success: false, - message: 'Error trying to create peer' + const peerOrError = await peerService.create(args.input) + if (isPeerError(peerOrError)) { + throw new GraphQLError(errorToMessage[peerOrError], { + extensions: { + code: errorToCode[peerOrError] } }) + } + return { + peer: peerToGraphql(peerOrError) + } } export const updatePeer: MutationResolvers['updatePeer'] = @@ -99,36 +86,17 @@ export const updatePeer: MutationResolvers['updatePeer'] = ctx ): Promise => { const peerService = await ctx.container.use('peerService') - return peerService - .update(args.input) - .then((peerOrError: Peer | PeerError) => - isPeerError(peerOrError) - ? { - code: errorToCode[peerOrError].toString(), - success: false, - message: errorToMessage[peerOrError] - } - : { - code: '200', - success: true, - message: 'Updated ILP Peer', - peer: peerToGraphql(peerOrError) - } - ) - .catch((err) => { - ctx.logger.error( - { - options: args.input, - err - }, - 'error updating peer' - ) - return { - code: '500', - message: 'Error trying to update peer', - success: false + const peerOrError = await peerService.update(args.input) + if (isPeerError(peerOrError)) { + throw new GraphQLError(errorToMessage[peerOrError], { + extensions: { + code: errorToCode[peerOrError] } }) + } + return { + peer: peerToGraphql(peerOrError) + } } export const deletePeer: MutationResolvers['deletePeer'] = @@ -138,35 +106,17 @@ export const deletePeer: MutationResolvers['deletePeer'] = ctx ): Promise => { const peerService = await ctx.container.use('peerService') - return peerService - .delete(args.input.id) - .then((peer: Peer | undefined) => - peer - ? { - code: '200', - success: true, - message: 'Deleted ILP Peer' - } - : { - code: errorToCode[PeerError.UnknownPeer].toString(), - success: false, - message: errorToMessage[PeerError.UnknownPeer] - } - ) - .catch((err) => { - ctx.logger.error( - { - id: args.input.id, - err - }, - 'error deleting peer' - ) - return { - code: '500', - message: 'Error trying to delete peer', - success: false + const peer = await peerService.delete(args.input.id) + if (!peer) { + throw new GraphQLError(errorToMessage[PeerError.UnknownPeer], { + extensions: { + code: errorToCode[PeerError.UnknownPeer] } }) + } + return { + success: true + } } export const peerToGraphql = (peer: Peer): SchemaPeer => ({ diff --git a/packages/backend/src/payment-method/ilp/peer/errors.ts b/packages/backend/src/payment-method/ilp/peer/errors.ts index 634f70b80a..c4b81134dd 100644 --- a/packages/backend/src/payment-method/ilp/peer/errors.ts +++ b/packages/backend/src/payment-method/ilp/peer/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../../../graphql/errors' + export enum PeerError { DuplicateIncomingToken = 'DuplicateIncomingToken', DuplicatePeer = 'DuplicatePeer', @@ -13,15 +15,15 @@ export const isPeerError = (o: any): o is PeerError => Object.values(PeerError).includes(o) export const errorToCode: { - [key in PeerError]: number + [key in PeerError]: string } = { - [PeerError.DuplicateIncomingToken]: 409, - [PeerError.DuplicatePeer]: 409, - [PeerError.InvalidStaticIlpAddress]: 400, - [PeerError.InvalidHTTPEndpoint]: 400, - [PeerError.UnknownAsset]: 400, - [PeerError.UnknownPeer]: 404, - [PeerError.InvalidInitialLiquidity]: 400 + [PeerError.DuplicateIncomingToken]: GraphQLErrorCode.Duplicate, + [PeerError.DuplicatePeer]: GraphQLErrorCode.Duplicate, + [PeerError.InvalidStaticIlpAddress]: GraphQLErrorCode.BadUserInput, + [PeerError.InvalidHTTPEndpoint]: GraphQLErrorCode.BadUserInput, + [PeerError.UnknownAsset]: GraphQLErrorCode.NotFound, + [PeerError.UnknownPeer]: GraphQLErrorCode.NotFound, + [PeerError.InvalidInitialLiquidity]: GraphQLErrorCode.BadUserInput } export const errorToMessage: { From 3fc1188cc4af80b9e5f0b91f00afae902d2eec19 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Wed, 17 Apr 2024 17:35:11 +0200 Subject: [PATCH 12/34] feat: update quote resolvers --- .../src/graphql/resolvers/quote.test.ts | 29 ++++------- .../backend/src/graphql/resolvers/quote.ts | 50 ++++++++++--------- .../backend/src/open_payments/quote/errors.ts | 14 +++++- .../backend/src/open_payments/quote/routes.ts | 4 +- 4 files changed, 51 insertions(+), 46 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/quote.test.ts b/packages/backend/src/graphql/resolvers/quote.test.ts index 1f39f81952..80a59205f2 100644 --- a/packages/backend/src/graphql/resolvers/quote.test.ts +++ b/packages/backend/src/graphql/resolvers/quote.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { v4 as uuid } from 'uuid' import { getPageTests } from './page.test' @@ -129,7 +129,7 @@ describe('Quote Resolvers', (): void => { }) }) - test('404', async (): Promise => { + test('Not found', async (): Promise => { jest.spyOn(quoteService, 'get').mockImplementation(async () => undefined) await expect( @@ -206,8 +206,6 @@ describe('Quote Resolvers', (): void => { query: gql` mutation CreateQuote($input: CreateQuoteInput!) { createQuote(input: $input) { - code - success quote { id } @@ -219,20 +217,15 @@ describe('Quote Resolvers', (): void => { .then((query): QuoteResponse => query.data?.createQuote) expect(createSpy).toHaveBeenCalledWith({ ...input, method: 'ilp' }) - expect(query.code).toBe('200') - expect(query.success).toBe(true) expect(query.quote?.id).toBe(quote?.id) }) - test('400', async (): Promise => { - const query = await appContainer.apolloClient + test('unknown walletAddress', async (): Promise => { + const gqlQuery = appContainer.apolloClient .query({ query: gql` mutation CreateQuote($input: CreateQuoteInput!) { createQuote(input: $input) { - code - success - message quote { id } @@ -242,12 +235,11 @@ describe('Quote Resolvers', (): void => { variables: { input } }) .then((query): QuoteResponse => query.data?.createQuote) - expect(query.code).toBe('404') - expect(query.success).toBe(false) - expect(query.message).toBe( + + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( errorToMessage[QuoteError.UnknownWalletAddress] ) - expect(query.quote).toBeNull() }) test('500', async (): Promise => { @@ -255,7 +247,7 @@ describe('Quote Resolvers', (): void => { .spyOn(quoteService, 'create') .mockRejectedValueOnce(new Error('unexpected')) - const query = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .query({ query: gql` mutation CreateQuote($input: CreateQuoteInput!) { @@ -272,11 +264,8 @@ describe('Quote Resolvers', (): void => { variables: { input } }) .then((query): QuoteResponse => query.data?.createQuote) + await expect(gqlQuery).rejects.toThrow(ApolloError) expect(createSpy).toHaveBeenCalledWith({ ...input, method: 'ilp' }) - expect(query.code).toBe('500') - expect(query.success).toBe(false) - expect(query.message).toBe('Error trying to create quote') - expect(query.quote).toBeNull() }) }) diff --git a/packages/backend/src/graphql/resolvers/quote.ts b/packages/backend/src/graphql/resolvers/quote.ts index 32bd77056a..638c0fecde 100644 --- a/packages/backend/src/graphql/resolvers/quote.ts +++ b/packages/backend/src/graphql/resolvers/quote.ts @@ -6,7 +6,6 @@ import { ResolversTypes } from '../generated/graphql' import { - QuoteError, isQuoteError, errorToCode, errorToMessage @@ -16,6 +15,8 @@ import { ApolloContext } from '../../app' import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' import { CreateQuoteOptions } from '../../open_payments/quote/service' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' export const getQuote: QueryResolvers['quote'] = async ( parent, @@ -26,7 +27,13 @@ export const getQuote: QueryResolvers['quote'] = async ( const quote = await quoteService.get({ id: args.id }) - if (!quote) throw new Error('quote does not exist') + if (!quote) { + throw new GraphQLError('quote does not exist', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + } return quoteToGraphql(quote) } @@ -41,31 +48,28 @@ export const createQuote: MutationResolvers['createQuote'] = if (args.input.debitAmount) options.debitAmount = args.input.debitAmount if (args.input.receiveAmount) options.receiveAmount = args.input.receiveAmount - return quoteService - .create(options) - .then((quoteOrErr: Quote | QuoteError) => - isQuoteError(quoteOrErr) - ? { - code: errorToCode[quoteOrErr].toString(), - success: false, - message: errorToMessage[quoteOrErr] - } - : { - code: '200', - success: true, - quote: quoteToGraphql(quoteOrErr) - } - ) - .catch(() => ({ - code: '500', - success: false, - message: 'Error trying to create quote' - })) + const quoteOrError = await quoteService.create(options) + if (isQuoteError(quoteOrError)) { + throw new GraphQLError(errorToMessage[quoteOrError], { + extensions: { + code: errorToCode[quoteOrError] + } + }) + } else + return { + quote: quoteToGraphql(quoteOrError) + } } export const getWalletAddressQuotes: WalletAddressResolvers['quotes'] = async (parent, args, ctx): Promise => { - if (!parent.id) throw new Error('missing wallet address id') + if (!parent.id) { + throw new GraphQLError('missing wallet address id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + } const quoteService = await ctx.container.use('quoteService') const { sortOrder, ...pagination } = args const order = sortOrder === 'ASC' ? SortOrder.Asc : SortOrder.Desc diff --git a/packages/backend/src/open_payments/quote/errors.ts b/packages/backend/src/open_payments/quote/errors.ts index efb67e14c9..9fff0b0911 100644 --- a/packages/backend/src/open_payments/quote/errors.ts +++ b/packages/backend/src/open_payments/quote/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../../graphql/errors' + export enum QuoteError { UnknownWalletAddress = 'UnknownWalletAddress', InvalidAmount = 'InvalidAmount', @@ -10,7 +12,7 @@ export enum QuoteError { export const isQuoteError = (o: any): o is QuoteError => Object.values(QuoteError).includes(o) -export const errorToCode: { +export const errorToHTTPCode: { [key in QuoteError]: number } = { [QuoteError.UnknownWalletAddress]: 404, @@ -20,6 +22,16 @@ export const errorToCode: { [QuoteError.NegativeReceiveAmount]: 400 } +export const errorToCode: { + [key in QuoteError]: string +} = { + [QuoteError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, + [QuoteError.InvalidAmount]: GraphQLErrorCode.BadUserInput, + [QuoteError.InvalidReceiver]: GraphQLErrorCode.BadUserInput, + [QuoteError.InactiveWalletAddress]: GraphQLErrorCode.Inactive, + [QuoteError.NegativeReceiveAmount]: GraphQLErrorCode.BadUserInput +} + export const errorToMessage: { [key in QuoteError]: string } = { diff --git a/packages/backend/src/open_payments/quote/routes.ts b/packages/backend/src/open_payments/quote/routes.ts index 9f828dc28b..d0069280fc 100644 --- a/packages/backend/src/open_payments/quote/routes.ts +++ b/packages/backend/src/open_payments/quote/routes.ts @@ -3,7 +3,7 @@ import { Logger } from 'pino' import { ReadContext, CreateContext } from '../../app' import { IAppConfig } from '../../config/app' import { CreateQuoteOptions, QuoteService } from './service' -import { isQuoteError, errorToCode, errorToMessage } from './errors' +import { isQuoteError, errorToHTTPCode, errorToMessage } from './errors' import { Quote } from './model' import { AmountJSON, parseAmount } from '../amount' import { Quote as OpenPaymentsQuote } from '@interledger/open-payments' @@ -96,7 +96,7 @@ async function createQuote( if (isQuoteError(quoteOrErr)) { throw new OpenPaymentsServerRouteError( - errorToCode[quoteOrErr], + errorToHTTPCode[quoteOrErr], errorToMessage[quoteOrErr] ) } From 407f1e1057fd1a62a63e82acc999c0cbccc3fbbd Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Mon, 22 Apr 2024 11:56:06 +0200 Subject: [PATCH 13/34] feat: update receiver resolvers --- .../src/graphql/resolvers/receiver.test.ts | 36 +++------------ .../backend/src/graphql/resolvers/receiver.ts | 46 +++++++------------ .../payment/incoming_remote/errors.ts | 11 ++++- .../src/open_payments/receiver/errors.ts | 4 +- 4 files changed, 36 insertions(+), 61 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/receiver.test.ts b/packages/backend/src/graphql/resolvers/receiver.test.ts index 42339016e8..368a2541e5 100644 --- a/packages/backend/src/graphql/resolvers/receiver.test.ts +++ b/packages/backend/src/graphql/resolvers/receiver.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { v4 as uuid } from 'uuid' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -74,9 +74,6 @@ describe('Receiver Resolver', (): void => { query: gql` mutation CreateReceiver($input: CreateReceiverInput!) { createReceiver(input: $input) { - code - success - message receiver { id walletAddressUrl @@ -106,9 +103,6 @@ describe('Receiver Resolver', (): void => { expect(createSpy).toHaveBeenCalledWith(input) expect(query).toEqual({ __typename: 'CreateReceiverResponse', - code: '200', - success: true, - message: null, receiver: { __typename: 'Receiver', id: receiver.incomingPayment?.id, @@ -144,14 +138,11 @@ describe('Receiver Resolver', (): void => { walletAddressUrl: walletAddress.id } - const query = await appContainer.apolloClient + const query = appContainer.apolloClient .query({ query: gql` mutation CreateReceiver($input: CreateReceiverInput!) { createReceiver(input: $input) { - code - success - message receiver { id walletAddressUrl @@ -178,14 +169,9 @@ describe('Receiver Resolver', (): void => { }) .then((query): CreateReceiverResponse => query.data?.createReceiver) + await expect(query).rejects.toThrow(ApolloError) + await expect(query).rejects.toThrow('unknown wallet address') expect(createSpy).toHaveBeenCalledWith(input) - expect(query).toEqual({ - __typename: 'CreateReceiverResponse', - code: '404', - success: false, - message: 'unknown wallet address', - receiver: null - }) }) test('returns error if error thrown when creating receiver', async (): Promise => { @@ -199,14 +185,11 @@ describe('Receiver Resolver', (): void => { walletAddressUrl: walletAddress.id } - const query = await appContainer.apolloClient + const query = appContainer.apolloClient .query({ query: gql` mutation CreateReceiver($input: CreateReceiverInput!) { createReceiver(input: $input) { - code - success - message receiver { id walletAddressUrl @@ -233,14 +216,9 @@ describe('Receiver Resolver', (): void => { }) .then((query): CreateReceiverResponse => query.data?.createReceiver) + await expect(query).rejects.toThrow(ApolloError) + await expect(query).rejects.toThrow('Cannot create receiver') expect(createSpy).toHaveBeenCalledWith(input) - expect(query).toEqual({ - __typename: 'CreateReceiverResponse', - code: '500', - success: false, - message: 'Error trying to create receiver', - receiver: null - }) }) }) diff --git a/packages/backend/src/graphql/resolvers/receiver.ts b/packages/backend/src/graphql/resolvers/receiver.ts index b2e10fc7ce..2a5941e466 100644 --- a/packages/backend/src/graphql/resolvers/receiver.ts +++ b/packages/backend/src/graphql/resolvers/receiver.ts @@ -11,6 +11,7 @@ import { errorToCode as receiverErrorToCode, errorToMessage as receiverErrorToMessage } from '../../open_payments/receiver/errors' +import { GraphQLError } from 'graphql' export const getReceiver: QueryResolvers['receiver'] = async ( _, @@ -30,38 +31,25 @@ export const createReceiver: MutationResolvers['createReceiver'] async (_, args, ctx): Promise => { const receiverService = await ctx.container.use('receiverService') - try { - const receiverOrError = await receiverService.create({ - walletAddressUrl: args.input.walletAddressUrl, - expiresAt: args.input.expiresAt - ? new Date(args.input.expiresAt) - : undefined, - incomingAmount: args.input.incomingAmount, - metadata: args.input.metadata - }) + const receiverOrError = await receiverService.create({ + walletAddressUrl: args.input.walletAddressUrl, + expiresAt: args.input.expiresAt + ? new Date(args.input.expiresAt) + : undefined, + incomingAmount: args.input.incomingAmount, + metadata: args.input.metadata + }) - if (isReceiverError(receiverOrError)) { - return { - code: receiverErrorToCode(receiverOrError).toString(), - success: false, - message: receiverErrorToMessage(receiverOrError) + if (isReceiverError(receiverOrError)) { + throw new GraphQLError(receiverErrorToMessage(receiverOrError), { + extensions: { + code: receiverErrorToCode(receiverOrError) } - } - - return { - code: '200', - success: true, - receiver: receiverToGraphql(receiverOrError) - } - } catch (err) { - const errorMessage = 'Error trying to create receiver' - ctx.logger.error({ err, args }, errorMessage) + }) + } - return { - code: '500', - success: false, - message: errorMessage - } + return { + receiver: receiverToGraphql(receiverOrError) } } diff --git a/packages/backend/src/open_payments/payment/incoming_remote/errors.ts b/packages/backend/src/open_payments/payment/incoming_remote/errors.ts index 81b22a70d1..fde1eea126 100644 --- a/packages/backend/src/open_payments/payment/incoming_remote/errors.ts +++ b/packages/backend/src/open_payments/payment/incoming_remote/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../../../graphql/errors' + export enum RemoteIncomingPaymentError { UnknownWalletAddress = 'UnknownWalletAddress', InvalidRequest = 'InvalidRequest', @@ -10,7 +12,7 @@ export const isRemoteIncomingPaymentError = ( ): o is RemoteIncomingPaymentError => Object.values(RemoteIncomingPaymentError).includes(o) -export const errorToCode: { +export const errorToHTTPCode: { [key in RemoteIncomingPaymentError]: number } = { [RemoteIncomingPaymentError.UnknownWalletAddress]: 404, @@ -18,6 +20,13 @@ export const errorToCode: { [RemoteIncomingPaymentError.InvalidGrant]: 500 } +export const errorToCode: { + [key in RemoteIncomingPaymentError]: string +} = { + [RemoteIncomingPaymentError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, + [RemoteIncomingPaymentError.InvalidRequest]: GraphQLErrorCode.BadUserInput, + [RemoteIncomingPaymentError.InvalidGrant]: GraphQLErrorCode.Forbidden +} export const errorToMessage: { [key in RemoteIncomingPaymentError]: string } = { diff --git a/packages/backend/src/open_payments/receiver/errors.ts b/packages/backend/src/open_payments/receiver/errors.ts index 9affe717fb..c0aa018a91 100644 --- a/packages/backend/src/open_payments/receiver/errors.ts +++ b/packages/backend/src/open_payments/receiver/errors.ts @@ -1,6 +1,6 @@ import { errorToMessage as incomingPaymentErrorToMessage, - errorToHTTPCode as incomingPaymentErrorToCode, + errorToCode as incomingPaymentErrorToCode, isIncomingPaymentError, IncomingPaymentError } from '../payment/incoming/errors' @@ -20,7 +20,7 @@ export const ReceiverError = { export const isReceiverError = (o: any): o is ReceiverError => Object.values(ReceiverError).includes(o) -export const errorToCode = (error: ReceiverError): number => +export const errorToCode = (error: ReceiverError): string => isIncomingPaymentError(error) ? incomingPaymentErrorToCode[error] : remoteIncomingPaymentErrorToCode[error] From 4f368447f8793a2f877a7e5bcd09494b558fcb16 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Mon, 22 Apr 2024 13:41:06 +0200 Subject: [PATCH 14/34] feat: update wallet address resolvers --- .../graphql/resolvers/wallet_address.test.ts | 75 +++---------- .../src/graphql/resolvers/wallet_address.ts | 104 ++++++------------ .../open_payments/wallet_address/errors.ts | 10 +- 3 files changed, 58 insertions(+), 131 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/wallet_address.test.ts b/packages/backend/src/graphql/resolvers/wallet_address.test.ts index da3f318a93..c696a36007 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.test.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.test.ts @@ -13,7 +13,6 @@ import { Config } from '../../config/app' import { truncateTables } from '../../tests/tableManager' import { WalletAddressError, - errorToCode, errorToMessage } from '../../open_payments/wallet_address/errors' import { @@ -83,9 +82,6 @@ describe('Wallet Address Resolvers', (): void => { mutation: gql` mutation CreateWalletAddress($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id asset { @@ -110,8 +106,6 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') assert.ok(response.walletAddress) expect(response.walletAddress).toEqual({ __typename: 'WalletAddress', @@ -220,16 +214,13 @@ describe('Wallet Address Resolvers', (): void => { error ${WalletAddressError.InvalidUrl} ${WalletAddressError.UnknownAsset} - `('4XX - $error', async ({ error }): Promise => { + `('Error - $error', async ({ error }): Promise => { jest.spyOn(walletAddressService, 'create').mockResolvedValueOnce(error) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddress($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id asset { @@ -252,11 +243,8 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual( - errorToCode[error as WalletAddressError].toString() - ) - expect(response.message).toEqual( + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( errorToMessage[error as WalletAddressError] ) }) @@ -267,14 +255,11 @@ describe('Wallet Address Resolvers', (): void => { .mockImplementationOnce(async (_args) => { throw new Error('unexpected') }) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddress($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id asset { @@ -296,9 +281,8 @@ describe('Wallet Address Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.code).toBe('500') - expect(response.success).toBe(false) - expect(response.message).toBe('Error trying to create wallet address') + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('unexpected') }) }) @@ -320,9 +304,6 @@ describe('Wallet Address Resolvers', (): void => { mutation: gql` mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - success - message walletAddress { id status @@ -348,8 +329,6 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') expect(response.walletAddress).toEqual({ __typename: 'WalletAddress', ...updateOptions, @@ -559,14 +538,11 @@ describe('Wallet Address Resolvers', (): void => { ${WalletAddressError.UnknownWalletAddress} `('4XX - $error', async ({ error }): Promise => { jest.spyOn(walletAddressService, 'update').mockResolvedValueOnce(error) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - success - message walletAddress { id } @@ -588,11 +564,8 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual( - errorToCode[error as WalletAddressError].toString() - ) - expect(response.message).toEqual( + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( errorToMessage[error as WalletAddressError] ) }) @@ -603,14 +576,11 @@ describe('Wallet Address Resolvers', (): void => { .mockImplementationOnce(async () => { throw new Error('unexpected') }) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - success - message walletAddress { id } @@ -632,9 +602,8 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('500') - expect(response.message).toEqual('Error trying to update wallet address') + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('unexpected') }) }) @@ -844,9 +813,6 @@ describe('Wallet Address Resolvers', (): void => { $input: TriggerWalletAddressEventsInput! ) { triggerWalletAddressEvents(input: $input) { - code - success - message count } } @@ -866,8 +832,6 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') expect(response.count).toEqual(count) await expect( WalletAddressEvent.query(knex).where({ @@ -889,16 +853,13 @@ describe('Wallet Address Resolvers', (): void => { jest .spyOn(walletAddressService, 'triggerEvents') .mockRejectedValueOnce(new Error('unexpected')) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation TriggerWalletAddressEvents( $input: TriggerWalletAddressEventsInput! ) { triggerWalletAddressEvents(input: $input) { - code - success - message count } } @@ -916,12 +877,8 @@ describe('Wallet Address Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.code).toBe('500') - expect(response.success).toBe(false) - expect(response.message).toBe( - 'Error trying to trigger wallet address events' - ) - expect(response.count).toBeNull() + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('unexpected') }) }) }) diff --git a/packages/backend/src/graphql/resolvers/wallet_address.ts b/packages/backend/src/graphql/resolvers/wallet_address.ts index 965a19af0d..dfff55bd1e 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.ts @@ -1,3 +1,5 @@ +import { GraphQLError } from 'graphql' + import { assetToGraphql } from './asset' import { QueryResolvers, @@ -8,7 +10,6 @@ import { } from '../generated/graphql' import { ApolloContext } from '../../app' import { - WalletAddressError, isWalletAddressError, errorToCode, errorToMessage @@ -21,6 +22,7 @@ import { CreateOptions, UpdateOptions } from '../../open_payments/wallet_address/service' +import { GraphQLErrorCode } from '../errors' export const getWalletAddresses: QueryResolvers['walletAddresses'] = async ( @@ -55,7 +57,11 @@ export const getWalletAddress: QueryResolvers['walletAddress'] = const walletAddressService = await ctx.container.use('walletAddressService') const walletAddress = await walletAddressService.get(args.id) if (!walletAddress) { - throw new Error('No wallet address') + throw new GraphQLError('Wallet address not found', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) } return walletAddressToGraphql(walletAddress) } @@ -83,28 +89,20 @@ export const createWalletAddress: MutationResolvers['createWallet publicName: args.input.publicName, url: args.input.url } - return walletAddressService - .create(options) - .then((walletAddressOrError: WalletAddress | WalletAddressError) => - isWalletAddressError(walletAddressOrError) - ? { - code: errorToCode[walletAddressOrError].toString(), - success: false, - message: errorToMessage[walletAddressOrError] - } - : { - code: '200', - success: true, - message: 'Created wallet address', - walletAddress: walletAddressToGraphql(walletAddressOrError) - } - ) - .catch(() => ({ - code: '500', - success: false, - message: 'Error trying to create wallet address' - })) + + const walletAddressOrError = await walletAddressService.create(options) + if (isWalletAddressError(walletAddressOrError)) { + throw new GraphQLError(errorToMessage[walletAddressOrError], { + extensions: { + code: errorToCode[walletAddressOrError] + } + }) + } + return { + walletAddress: walletAddressToGraphql(walletAddressOrError) + } } + export const updateWalletAddress: MutationResolvers['updateWalletAddress'] = async ( parent, @@ -127,27 +125,17 @@ export const updateWalletAddress: MutationResolvers['updateWallet } ) } - return walletAddressService - .update(updateOptions) - .then((walletAddressOrError: WalletAddress | WalletAddressError) => - isWalletAddressError(walletAddressOrError) - ? { - code: errorToCode[walletAddressOrError].toString(), - success: false, - message: errorToMessage[walletAddressOrError] - } - : { - code: '200', - success: true, - message: 'Updated wallet address', - walletAddress: walletAddressToGraphql(walletAddressOrError) - } - ) - .catch(() => ({ - code: '500', - success: false, - message: 'Error trying to update wallet address' - })) + const walletAddressOrError = await walletAddressService.update(updateOptions) + if (isWalletAddressError(walletAddressOrError)) { + throw new GraphQLError(errorToMessage[walletAddressOrError], { + extensions: { + code: errorToCode[walletAddressOrError] + } + }) + } + return { + walletAddress: walletAddressToGraphql(walletAddressOrError) + } } export const triggerWalletAddressEvents: MutationResolvers['triggerWalletAddressEvents'] = @@ -156,30 +144,10 @@ export const triggerWalletAddressEvents: MutationResolvers['trigg args, ctx ): Promise => { - try { - const walletAddressService = await ctx.container.use( - 'walletAddressService' - ) - const count = await walletAddressService.triggerEvents(args.input.limit) - return { - code: '200', - success: true, - message: 'Triggered Wallet Address Events', - count - } - } catch (err) { - ctx.logger.error( - { - options: args.input.limit, - err - }, - 'error triggering wallet address events' - ) - return { - code: '500', - message: 'Error trying to trigger wallet address events', - success: false - } + const walletAddressService = await ctx.container.use('walletAddressService') + const count = await walletAddressService.triggerEvents(args.input.limit) + return { + count } } diff --git a/packages/backend/src/open_payments/wallet_address/errors.ts b/packages/backend/src/open_payments/wallet_address/errors.ts index 083b7e39dd..3f13126ad9 100644 --- a/packages/backend/src/open_payments/wallet_address/errors.ts +++ b/packages/backend/src/open_payments/wallet_address/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../../graphql/errors' + export enum WalletAddressError { InvalidUrl = 'InvalidUrl', UnknownAsset = 'UnknownAsset', @@ -9,11 +11,11 @@ export const isWalletAddressError = (o: any): o is WalletAddressError => Object.values(WalletAddressError).includes(o) export const errorToCode: { - [key in WalletAddressError]: number + [key in WalletAddressError]: string } = { - [WalletAddressError.InvalidUrl]: 400, - [WalletAddressError.UnknownAsset]: 400, - [WalletAddressError.UnknownWalletAddress]: 404 + [WalletAddressError.InvalidUrl]: GraphQLErrorCode.BadUserInput, + [WalletAddressError.UnknownAsset]: GraphQLErrorCode.BadUserInput, + [WalletAddressError.UnknownWalletAddress]: GraphQLErrorCode.NotFound } export const errorToMessage: { From 7174b7197661365a16b4c21bf238e3615a0633a6 Mon Sep 17 00:00:00 2001 From: Sabine Schaller Date: Mon, 22 Apr 2024 18:51:37 +0200 Subject: [PATCH 15/34] feat: update wallet address key resolvers --- .../resolvers/walletAddressKey.test.ts | 35 ++------- .../src/graphql/resolvers/walletAddressKey.ts | 76 +++++-------------- 2 files changed, 28 insertions(+), 83 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts index c0f0fbf272..a9228842ff 100644 --- a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts +++ b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts @@ -1,5 +1,5 @@ import assert from 'assert' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { generateJwk } from '@interledger/http-signature-utils' import { v4 as uuid } from 'uuid' @@ -58,9 +58,6 @@ describe('Wallet Address Key Resolvers', (): void => { $input: CreateWalletAddressKeyInput! ) { createWalletAddressKey(input: $input) { - code - success - message walletAddressKey { id walletAddressId @@ -89,8 +86,6 @@ describe('Wallet Address Key Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') assert.ok(response.walletAddressKey) expect(response.walletAddressKey).toMatchObject({ __typename: 'WalletAddressKey', @@ -117,16 +112,13 @@ describe('Wallet Address Key Resolvers', (): void => { jwk: TEST_KEY } - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddressKey( $input: CreateWalletAddressKeyInput! ) { createWalletAddressKey(input: $input) { - code - success - message walletAddressKey { id walletAddressId @@ -153,9 +145,8 @@ describe('Wallet Address Key Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.code).toBe('500') - expect(response.success).toBe(false) - expect(response.message).toBe('Error trying to create wallet address key') + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('unexpected') }) }) @@ -175,9 +166,6 @@ describe('Wallet Address Key Resolvers', (): void => { $input: RevokeWalletAddressKeyInput! ) { revokeWalletAddressKey(input: $input) { - code - success - message walletAddressKey { id walletAddressId @@ -207,8 +195,6 @@ describe('Wallet Address Key Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toBe('200') assert.ok(response.walletAddressKey) expect(response.walletAddressKey).toMatchObject({ __typename: 'WalletAddressKey', @@ -222,17 +208,14 @@ describe('Wallet Address Key Resolvers', (): void => { }) }) - test('Returns 404 if key does not exist', async (): Promise => { - const response = await appContainer.apolloClient + test('Returns not found if key does not exist', async (): Promise => { + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation revokeWalletAddressKey( $input: RevokeWalletAddressKeyInput! ) { revokeWalletAddressKey(input: $input) { - code - success - message walletAddressKey { id walletAddressId @@ -254,10 +237,8 @@ describe('Wallet Address Key Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toBe('404') - expect(response.message).toBe('Wallet address key not found') - expect(response.walletAddressKey).toBeNull() + await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow('Wallet address key not found') }) }) diff --git a/packages/backend/src/graphql/resolvers/walletAddressKey.ts b/packages/backend/src/graphql/resolvers/walletAddressKey.ts index d037115f45..7ac40042dc 100644 --- a/packages/backend/src/graphql/resolvers/walletAddressKey.ts +++ b/packages/backend/src/graphql/resolvers/walletAddressKey.ts @@ -10,6 +10,8 @@ import { } from '../generated/graphql' import { ApolloContext } from '../../app' import { WalletAddressKey } from '../../open_payments/wallet_address/key/model' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' import { Pagination } from '../../shared/baseModel' import { getPageInfo } from '../../shared/pagination' @@ -56,39 +58,20 @@ export const revokeWalletAddressKey: MutationResolvers['revokeWal args, ctx ): Promise => { - try { - const walletAddressKeyService = await ctx.container.use( - 'walletAddressKeyService' - ) - const key = await walletAddressKeyService.revoke(args.input.id) - if (!key) { - return { - code: '404', - success: false, - message: 'Wallet address key not found' + const walletAddressKeyService = await ctx.container.use( + 'walletAddressKeyService' + ) + const key = await walletAddressKeyService.revoke(args.input.id) + if (!key) { + throw new GraphQLError('Wallet address key not found', { + extensions: { + code: GraphQLErrorCode.NotFound } - } - - return { - code: '200', - success: true, - message: 'Wallet address key revoked', - walletAddressKey: walletAddressKeyToGraphql(key) - } - } catch (err) { - ctx.logger.error( - { - options: args.input.id, - err - }, - 'error revoking wallet address key' - ) + }) + } - return { - code: '500', - message: 'Error trying to revoke wallet address key', - success: false - } + return { + walletAddressKey: walletAddressKeyToGraphql(key) } } @@ -98,33 +81,14 @@ export const createWalletAddressKey: MutationResolvers['createWal args, ctx ): Promise => { - try { - const walletAddressKeyService = await ctx.container.use( - 'walletAddressKeyService' - ) - - const key = await walletAddressKeyService.create(args.input) + const walletAddressKeyService = await ctx.container.use( + 'walletAddressKeyService' + ) - return { - code: '200', - success: true, - message: 'Added Key To Wallet Address', - walletAddressKey: walletAddressKeyToGraphql(key) - } - } catch (err) { - ctx.logger.error( - { - options: args.input, - err - }, - 'error creating wallet address key' - ) + const key = await walletAddressKeyService.create(args.input) - return { - code: '500', - message: 'Error trying to create wallet address key', - success: false - } + return { + walletAddressKey: walletAddressKeyToGraphql(key) } } From a59451d574f40d29f32047e5995498febce30abf Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Thu, 30 May 2024 15:46:36 -0700 Subject: [PATCH 16/34] feat(wip): backend graphql logs --- .../Deposit Asset Liquidity.bru | 2 - .../app/lib/requesters.ts | 24 +- .../app/lib/webhooks.server.ts | 12 +- .../generated/graphql.ts | 154 +-- packages/backend/src/accounting/errors.ts | 51 + packages/backend/src/graphql/errors/index.ts | 3 +- .../src/graphql/generated/graphql.schema.json | 1134 ++--------------- .../backend/src/graphql/generated/graphql.ts | 154 +-- .../src/graphql/resolvers/liquidity.test.ts | 909 +++++++------ .../src/graphql/resolvers/liquidity.ts | 814 ++++++------ .../open_payments/payment/outgoing/errors.ts | 16 +- .../payment-method/ilp/auto-peering/errors.ts | 12 + .../payment-method/ilp/auto-peering/routes.ts | 4 +- packages/frontend/app/generated/graphql.ts | 188 +-- packages/frontend/app/lib/api/asset.server.ts | 60 +- .../frontend/app/lib/api/payments.server.ts | 12 +- packages/frontend/app/lib/api/peer.server.ts | 23 +- .../app/lib/api/wallet-address.server.ts | 14 +- .../src/generated/graphql.ts | 154 +-- .../src/requesters.ts | 50 +- test/integration/lib/generated/graphql.ts | 154 +-- 21 files changed, 1265 insertions(+), 2679 deletions(-) diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru index 9718c60753..4801ade88b 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru @@ -15,8 +15,6 @@ body:graphql { depositAssetLiquidity(input: $input) { code success - message - error } } } diff --git a/localenv/mock-account-servicing-entity/app/lib/requesters.ts b/localenv/mock-account-servicing-entity/app/lib/requesters.ts index 311d6cc261..5080d392d5 100644 --- a/localenv/mock-account-servicing-entity/app/lib/requesters.ts +++ b/localenv/mock-account-servicing-entity/app/lib/requesters.ts @@ -18,10 +18,8 @@ export async function depositPeerLiquidity( const depositPeerLiquidityMutation = gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } ` @@ -40,7 +38,7 @@ export async function depositPeerLiquidity( }) .then(({ data }): LiquidityMutationResponse => { console.log(data) - if (!data.depositPeerLiquidity.success) { + if (!data.depositPeerLiquidity) { throw new Error('Data was empty') } return data.depositPeerLiquidity @@ -55,10 +53,8 @@ export async function depositAssetLiquidity( const depositAssetLiquidityMutation = gql` mutation DepositAssetLiquidity($input: DepositAssetLiquidityInput!) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } ` @@ -77,7 +73,7 @@ export async function depositAssetLiquidity( }) .then(({ data }): LiquidityMutationResponse => { console.log(data) - if (!data.depositAssetLiquidity.success) { + if (!data.depositAssetLiquidity) { throw new Error('Data was empty') } return data.depositAssetLiquidity @@ -92,9 +88,6 @@ export async function createWalletAddress( const createWalletAddressMutation = gql` mutation CreateWalletAddress($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id url @@ -120,10 +113,7 @@ export async function createWalletAddress( .then(({ data }) => { console.log(data) - if ( - !data.createWalletAddress.success || - !data.createWalletAddress.walletAddress - ) { + if (!data.createWalletAddress.walletAddress) { throw new Error('Data was empty') } diff --git a/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts b/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts index 28f46af534..fee90c8291 100644 --- a/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts +++ b/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts @@ -107,10 +107,8 @@ export async function handleOutgoingPaymentCreated(wh: Webhook) { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -159,10 +157,8 @@ export async function handleIncomingPaymentCompletedExpired(wh: Webhook) { $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, diff --git a/localenv/mock-account-servicing-entity/generated/graphql.ts b/localenv/mock-account-servicing-entity/generated/graphql.ts index af780bc3ad..1ed9179897 100644 --- a/localenv/mock-account-servicing-entity/generated/graphql.ts +++ b/localenv/mock-account-servicing-entity/generated/graphql.ts @@ -92,12 +92,9 @@ export type AssetEdge = { node: Asset; }; -export type AssetMutationResponse = MutationResponse & { +export type AssetMutationResponse = { __typename?: 'AssetMutationResponse'; asset?: Maybe; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type AssetsConnection = { @@ -186,12 +183,9 @@ export type CreateOrUpdatePeerByUrlInput = { peerUrl: Scalars['String']['input']; }; -export type CreateOrUpdatePeerByUrlMutationResponse = MutationResponse & { +export type CreateOrUpdatePeerByUrlMutationResponse = { __typename?: 'CreateOrUpdatePeerByUrlMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateOutgoingPaymentFromIncomingPaymentInput = { @@ -259,12 +253,9 @@ export type CreatePeerLiquidityWithdrawalInput = { timeoutSeconds: Scalars['UInt64']['input']; }; -export type CreatePeerMutationResponse = MutationResponse & { +export type CreatePeerMutationResponse = { __typename?: 'CreatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateQuoteInput = { @@ -322,19 +313,13 @@ export type CreateWalletAddressKeyInput = { walletAddressId: Scalars['String']['input']; }; -export type CreateWalletAddressKeyMutationResponse = MutationResponse & { +export type CreateWalletAddressKeyMutationResponse = { __typename?: 'CreateWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; -export type CreateWalletAddressMutationResponse = MutationResponse & { +export type CreateWalletAddressMutationResponse = { __typename?: 'CreateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -360,11 +345,9 @@ export type DeleteAssetInput = { idempotencyKey?: InputMaybe; }; -export type DeleteAssetMutationResponse = MutationResponse & { +export type DeleteAssetMutationResponse = { __typename?: 'DeleteAssetMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + asset?: Maybe; }; export type DeletePeerInput = { @@ -373,10 +356,8 @@ export type DeletePeerInput = { idempotencyKey?: InputMaybe; }; -export type DeletePeerMutationResponse = MutationResponse & { +export type DeletePeerMutationResponse = { __typename?: 'DeletePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; success: Scalars['Boolean']['output']; }; @@ -596,12 +577,10 @@ export enum LiquidityError { UnknownWalletAddress = 'UnknownWalletAddress' } -export type LiquidityMutationResponse = MutationResponse & { +export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + id: Scalars['ID']['output']; + liquidity?: Maybe; }; export type Model = { @@ -836,12 +815,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; -export type MutationResponse = { - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type OutgoingPayment = BasePayment & Model & { __typename?: 'OutgoingPayment'; /** Information about the wallet address of the Open Payments client that created the outgoing payment. */ @@ -1185,11 +1158,8 @@ export type RevokeWalletAddressKeyInput = { idempotencyKey?: InputMaybe; }; -export type RevokeWalletAddressKeyMutationResponse = MutationResponse & { +export type RevokeWalletAddressKeyMutationResponse = { __typename?: 'RevokeWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; @@ -1204,12 +1174,9 @@ export type SetFeeInput = { type: FeeType; }; -export type SetFeeResponse = MutationResponse & { +export type SetFeeResponse = { __typename?: 'SetFeeResponse'; - code: Scalars['String']['output']; fee?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export enum SortOrder { @@ -1219,13 +1186,6 @@ export enum SortOrder { Desc = 'DESC' } -export type TransferMutationResponse = MutationResponse & { - __typename?: 'TransferMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type TriggerWalletAddressEventsInput = { /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey?: InputMaybe; @@ -1233,13 +1193,10 @@ export type TriggerWalletAddressEventsInput = { limit: Scalars['Int']['input']; }; -export type TriggerWalletAddressEventsMutationResponse = MutationResponse & { +export type TriggerWalletAddressEventsMutationResponse = { __typename?: 'TriggerWalletAddressEventsMutationResponse'; - code: Scalars['String']['output']; /** Number of events triggered */ count?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type UpdateAssetInput = { @@ -1270,12 +1227,9 @@ export type UpdatePeerInput = { staticIlpAddress?: InputMaybe; }; -export type UpdatePeerMutationResponse = MutationResponse & { +export type UpdatePeerMutationResponse = { __typename?: 'UpdatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type UpdateWalletAddressInput = { @@ -1291,11 +1245,8 @@ export type UpdateWalletAddressInput = { status?: InputMaybe; }; -export type UpdateWalletAddressMutationResponse = MutationResponse & { +export type UpdateWalletAddressMutationResponse = { __typename?: 'UpdateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -1419,12 +1370,8 @@ export type WalletAddressWithdrawal = { walletAddress: WalletAddress; }; -export type WalletAddressWithdrawalMutationResponse = MutationResponse & { +export type WalletAddressWithdrawalMutationResponse = { __typename?: 'WalletAddressWithdrawalMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; withdrawal?: Maybe; }; @@ -1541,7 +1488,6 @@ export type DirectiveResolverFn> = { BasePayment: ( Partial ) | ( Partial ) | ( Partial ); Model: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); - MutationResponse: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); }; /** Mapping between all available schema types and the resolvers types */ @@ -1614,7 +1560,6 @@ export type ResolversTypes = { LiquidityMutationResponse: ResolverTypeWrapper>; Model: ResolverTypeWrapper['Model']>; Mutation: ResolverTypeWrapper<{}>; - MutationResponse: ResolverTypeWrapper['MutationResponse']>; OutgoingPayment: ResolverTypeWrapper>; OutgoingPaymentConnection: ResolverTypeWrapper>; OutgoingPaymentEdge: ResolverTypeWrapper>; @@ -1642,7 +1587,6 @@ export type ResolversTypes = { SetFeeResponse: ResolverTypeWrapper>; SortOrder: ResolverTypeWrapper>; String: ResolverTypeWrapper>; - TransferMutationResponse: ResolverTypeWrapper>; TriggerWalletAddressEventsInput: ResolverTypeWrapper>; TriggerWalletAddressEventsMutationResponse: ResolverTypeWrapper>; UInt8: ResolverTypeWrapper>; @@ -1733,7 +1677,6 @@ export type ResolversParentTypes = { LiquidityMutationResponse: Partial; Model: ResolversInterfaceTypes['Model']; Mutation: {}; - MutationResponse: ResolversInterfaceTypes['MutationResponse']; OutgoingPayment: Partial; OutgoingPaymentConnection: Partial; OutgoingPaymentEdge: Partial; @@ -1758,7 +1701,6 @@ export type ResolversParentTypes = { SetFeeInput: Partial; SetFeeResponse: Partial; String: Partial; - TransferMutationResponse: Partial; TriggerWalletAddressEventsInput: Partial; TriggerWalletAddressEventsMutationResponse: Partial; UInt8: Partial; @@ -1820,9 +1762,6 @@ export type AssetEdgeResolvers = { asset?: Resolver, ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1842,18 +1781,12 @@ export type BasePaymentResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1866,31 +1799,21 @@ export type CreateReceiverResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type CreateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeleteAssetMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; + asset?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeletePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1976,10 +1899,8 @@ export type JwkResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; + id?: Resolver; + liquidity?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2023,13 +1944,6 @@ export type MutationResolvers, ParentType, ContextType, RequireFields>; }; -export type MutationResponseResolvers = { - __resolveType: TypeResolveFn<'AssetMutationResponse' | 'CreateOrUpdatePeerByUrlMutationResponse' | 'CreatePeerMutationResponse' | 'CreateWalletAddressKeyMutationResponse' | 'CreateWalletAddressMutationResponse' | 'DeleteAssetMutationResponse' | 'DeletePeerMutationResponse' | 'LiquidityMutationResponse' | 'RevokeWalletAddressKeyMutationResponse' | 'SetFeeResponse' | 'TransferMutationResponse' | 'TriggerWalletAddressEventsMutationResponse' | 'UpdatePeerMutationResponse' | 'UpdateWalletAddressMutationResponse' | 'WalletAddressWithdrawalMutationResponse', ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; -}; - export type OutgoingPaymentResolvers = { client?: Resolver, ParentType, ContextType>; createdAt?: Resolver; @@ -2189,33 +2103,17 @@ export type ReceiverResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type SetFeeResponseResolvers = { - code?: Resolver; fee?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}; - -export type TransferMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type TriggerWalletAddressEventsMutationResponseResolvers = { - code?: Resolver; count?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2228,17 +2126,11 @@ export interface UInt64ScalarConfig extends GraphQLScalarTypeConfig = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type UpdateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2294,10 +2186,6 @@ export type WalletAddressWithdrawalResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; withdrawal?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2357,7 +2245,6 @@ export type Resolvers = { LiquidityMutationResponse?: LiquidityMutationResponseResolvers; Model?: ModelResolvers; Mutation?: MutationResolvers; - MutationResponse?: MutationResponseResolvers; OutgoingPayment?: OutgoingPaymentResolvers; OutgoingPaymentConnection?: OutgoingPaymentConnectionResolvers; OutgoingPaymentEdge?: OutgoingPaymentEdgeResolvers; @@ -2377,7 +2264,6 @@ export type Resolvers = { Receiver?: ReceiverResolvers; RevokeWalletAddressKeyMutationResponse?: RevokeWalletAddressKeyMutationResponseResolvers; SetFeeResponse?: SetFeeResponseResolvers; - TransferMutationResponse?: TransferMutationResponseResolvers; TriggerWalletAddressEventsMutationResponse?: TriggerWalletAddressEventsMutationResponseResolvers; UInt8?: GraphQLScalarType; UInt64?: GraphQLScalarType; diff --git a/packages/backend/src/accounting/errors.ts b/packages/backend/src/accounting/errors.ts index cddf1ca1ba..e54307d8c2 100644 --- a/packages/backend/src/accounting/errors.ts +++ b/packages/backend/src/accounting/errors.ts @@ -1,3 +1,5 @@ +import { GraphQLErrorCode } from '../graphql/errors' + export class CreateAccountError extends Error { constructor(public code: number) { super('CreateAccountError code=' + code) @@ -33,6 +35,55 @@ export enum TransferError { UnknownDestinationAccount = 'UnknownDestinationAccount' } +export const errorToCode: { + [key in TransferError]: string +} = { + [TransferError.AlreadyPosted]: GraphQLErrorCode.Conflict, + [TransferError.AlreadyVoided]: GraphQLErrorCode.Conflict, + [TransferError.DifferentAssets]: GraphQLErrorCode.Forbidden, + [TransferError.InsufficientBalance]: GraphQLErrorCode.Forbidden, + [TransferError.InsufficientDebitBalance]: GraphQLErrorCode.Forbidden, + [TransferError.InsufficientLiquidity]: GraphQLErrorCode.Forbidden, + [TransferError.InvalidAmount]: GraphQLErrorCode.BadUserInput, + [TransferError.InvalidId]: GraphQLErrorCode.BadUserInput, + [TransferError.InvalidSourceAmount]: GraphQLErrorCode.BadUserInput, + [TransferError.InvalidDestinationAmount]: GraphQLErrorCode.BadUserInput, + [TransferError.InvalidTimeout]: GraphQLErrorCode.BadUserInput, + [TransferError.SameAccounts]: GraphQLErrorCode.Forbidden, + [TransferError.TransferExists]: GraphQLErrorCode.Duplicate, + [TransferError.TransferExpired]: GraphQLErrorCode.Forbidden, + [TransferError.UnknownTransfer]: GraphQLErrorCode.NotFound, + [TransferError.UnknownError]: GraphQLErrorCode.InternalServerError, + [TransferError.UnknownSourceAccount]: GraphQLErrorCode.NotFound, + [TransferError.UnknownDestinationAccount]: GraphQLErrorCode.NotFound +} + +export const errorToMessage: { + [key in TransferError]: string +} = { + [TransferError.AlreadyPosted]: 'Transfer already posted', + [TransferError.AlreadyVoided]: 'Transfer already voided', + [TransferError.DifferentAssets]: 'Transfer accounts have different assets', + [TransferError.InsufficientBalance]: 'Insufficient transfer balance', + [TransferError.InsufficientDebitBalance]: + 'Insufficient transfer debit balance', + [TransferError.InsufficientLiquidity]: + 'Insufficient transfer liquidity available', + [TransferError.InvalidAmount]: 'Invalid transfer amount', + [TransferError.InvalidId]: 'Invalid transfer id', + [TransferError.InvalidSourceAmount]: 'Invalid source account amount', + [TransferError.InvalidDestinationAmount]: + 'Invalid destination account amount', + [TransferError.InvalidTimeout]: 'Invalid transfer timeout provided', + [TransferError.SameAccounts]: 'Transfer is between the same accounts', + [TransferError.TransferExists]: 'Transfer already exists', + [TransferError.TransferExpired]: 'Transfer already expired', + [TransferError.UnknownTransfer]: 'Unknown transfer', + [TransferError.UnknownError]: 'Internal server error', + [TransferError.UnknownSourceAccount]: 'Unknown source account', + [TransferError.UnknownDestinationAccount]: 'Unknown destination account' +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types export const isTransferError = (o: any): o is TransferError => Object.values(TransferError).includes(o) diff --git a/packages/backend/src/graphql/errors/index.ts b/packages/backend/src/graphql/errors/index.ts index dbd4d60ac2..e19601440a 100644 --- a/packages/backend/src/graphql/errors/index.ts +++ b/packages/backend/src/graphql/errors/index.ts @@ -4,5 +4,6 @@ export enum GraphQLErrorCode { Forbidden = 'FORBIDDEN', Inactive = 'INACTIVE', InternalServerError = 'INTERNAL_SERVER_ERROR', - NotFound = 'NOT_FOUND' + NotFound = 'NOT_FOUND', + Conflict = 'CONFLICT' } diff --git a/packages/backend/src/graphql/generated/graphql.schema.json b/packages/backend/src/graphql/generated/graphql.schema.json index c1c44db49e..8cf2dfa7df 100644 --- a/packages/backend/src/graphql/generated/graphql.schema.json +++ b/packages/backend/src/graphql/generated/graphql.schema.json @@ -534,64 +534,10 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -1206,38 +1152,6 @@ "name": "CreateOrUpdatePeerByUrlMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "peer", "description": null, @@ -1249,32 +1163,10 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -1702,38 +1594,6 @@ "name": "CreatePeerMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "peer", "description": null, @@ -1745,32 +1605,10 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -2143,9 +1981,55 @@ "description": null, "fields": [ { - "name": "code", + "name": "walletAddressKey", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "WalletAddressKey", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "OBJECT", + "name": "CreateWalletAddressMutationResponse", + "description": null, + "fields": [ + { + "name": "walletAddress", "description": null, "args": [], + "type": { + "kind": "OBJECT", + "name": "WalletAddress", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "CreateWalletAddressWithdrawalInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "id", + "description": "The id of the withdrawal.", "type": { "kind": "NON_NULL", "name": null, @@ -2155,13 +2039,13 @@ "ofType": null } }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "message", - "description": null, - "args": [], + "name": "idempotencyKey", + "description": "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)", "type": { "kind": "NON_NULL", "name": null, @@ -2171,204 +2055,50 @@ "ofType": null } }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "success", - "description": null, - "args": [], + "name": "timeoutSeconds", + "description": "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer.", "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "SCALAR", - "name": "Boolean", + "name": "UInt64", "ofType": null } }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null }, { - "name": "walletAddressKey", - "description": null, - "args": [], + "name": "walletAddressId", + "description": "The id of the Open Payments wallet address to create the withdrawal for.", "type": { - "kind": "OBJECT", - "name": "WalletAddressKey", - "ofType": null + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } }, + "defaultValue": null, "isDeprecated": false, "deprecationReason": null } ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": null, "enumValues": null, "possibleTypes": null }, { - "kind": "OBJECT", - "name": "CreateWalletAddressMutationResponse", - "description": null, - "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "walletAddress", - "description": null, - "args": [], - "type": { - "kind": "OBJECT", - "name": "WalletAddress", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "INPUT_OBJECT", - "name": "CreateWalletAddressWithdrawalInput", - "description": null, - "fields": null, - "inputFields": [ - { - "name": "id", - "description": "The id of the withdrawal.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "idempotencyKey", - "description": "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "timeoutSeconds", - "description": "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "UInt64", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "walletAddressId", - "description": "The id of the Open Payments wallet address to create the withdrawal for.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "ENUM", - "name": "Crv", + "kind": "ENUM", + "name": "Crv", "description": null, "fields": null, "inputFields": null, @@ -2428,62 +2158,20 @@ "description": null, "fields": [ { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", + "name": "asset", "description": null, "args": [], "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } + "kind": "OBJECT", + "name": "Asset", + "ofType": null }, "isDeprecated": false, "deprecationReason": null } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -2531,38 +2219,6 @@ "name": "DeletePeerMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "success", "description": null, @@ -2581,13 +2237,7 @@ } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -4012,7 +3662,7 @@ "description": null, "fields": [ { - "name": "code", + "name": "id", "description": null, "args": [], "type": { @@ -4020,7 +3670,7 @@ "name": null, "ofType": { "kind": "SCALAR", - "name": "String", + "name": "ID", "ofType": null } }, @@ -4028,58 +3678,20 @@ "deprecationReason": null }, { - "name": "error", + "name": "liquidity", "description": null, "args": [], "type": { - "kind": "ENUM", - "name": "LiquidityError", + "kind": "SCALAR", + "name": "UInt64", "ofType": null }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -5150,141 +4762,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "INTERFACE", - "name": "MutationResponse", - "description": null, - "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "AssetMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "CreateOrUpdatePeerByUrlMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "CreatePeerMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "CreateWalletAddressKeyMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "CreateWalletAddressMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "DeleteAssetMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "DeletePeerMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "LiquidityMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "RevokeWalletAddressKeyMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "SetFeeResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "TransferMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "TriggerWalletAddressEventsMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "UpdatePeerMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "UpdateWalletAddressMutationResponse", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "WalletAddressWithdrawalMutationResponse", - "ofType": null - } - ] - }, { "kind": "OBJECT", "name": "OutgoingPayment", @@ -7510,54 +6987,6 @@ "name": "RevokeWalletAddressKeyMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "walletAddressKey", "description": null, @@ -7572,13 +7001,7 @@ } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -7658,22 +7081,6 @@ "name": "SetFeeResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "fee", "description": null, @@ -7685,62 +7092,24 @@ }, "isDeprecated": false, "deprecationReason": null - }, + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "ENUM", + "name": "SortOrder", + "description": null, + "fields": null, + "inputFields": null, + "interfaces": null, + "enumValues": [ { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "ENUM", - "name": "SortOrder", - "description": null, - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": [ - { - "name": "ASC", - "description": "Choose ascending order for results.", + "name": "ASC", + "description": "Choose ascending order for results.", "isDeprecated": false, "deprecationReason": null }, @@ -7763,71 +7132,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "OBJECT", - "name": "TransferMutationResponse", - "description": null, - "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, { "kind": "INPUT_OBJECT", "name": "TriggerWalletAddressEventsInput", @@ -7872,22 +7176,6 @@ "name": "TriggerWalletAddressEventsMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "count", "description": "Number of events triggered", @@ -7899,48 +7187,10 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -8131,38 +7381,6 @@ "name": "UpdatePeerMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "peer", "description": null, @@ -8174,32 +7392,10 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -8291,54 +7487,6 @@ "name": "UpdateWalletAddressMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "walletAddress", "description": null, @@ -8353,13 +7501,7 @@ } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, @@ -9156,66 +8298,6 @@ "name": "WalletAddressWithdrawalMutationResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "error", - "description": null, - "args": [], - "type": { - "kind": "ENUM", - "name": "LiquidityError", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "withdrawal", "description": null, @@ -9230,13 +8312,7 @@ } ], "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "MutationResponse", - "ofType": null - } - ], + "interfaces": [], "enumValues": null, "possibleTypes": null }, diff --git a/packages/backend/src/graphql/generated/graphql.ts b/packages/backend/src/graphql/generated/graphql.ts index af780bc3ad..1ed9179897 100644 --- a/packages/backend/src/graphql/generated/graphql.ts +++ b/packages/backend/src/graphql/generated/graphql.ts @@ -92,12 +92,9 @@ export type AssetEdge = { node: Asset; }; -export type AssetMutationResponse = MutationResponse & { +export type AssetMutationResponse = { __typename?: 'AssetMutationResponse'; asset?: Maybe; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type AssetsConnection = { @@ -186,12 +183,9 @@ export type CreateOrUpdatePeerByUrlInput = { peerUrl: Scalars['String']['input']; }; -export type CreateOrUpdatePeerByUrlMutationResponse = MutationResponse & { +export type CreateOrUpdatePeerByUrlMutationResponse = { __typename?: 'CreateOrUpdatePeerByUrlMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateOutgoingPaymentFromIncomingPaymentInput = { @@ -259,12 +253,9 @@ export type CreatePeerLiquidityWithdrawalInput = { timeoutSeconds: Scalars['UInt64']['input']; }; -export type CreatePeerMutationResponse = MutationResponse & { +export type CreatePeerMutationResponse = { __typename?: 'CreatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateQuoteInput = { @@ -322,19 +313,13 @@ export type CreateWalletAddressKeyInput = { walletAddressId: Scalars['String']['input']; }; -export type CreateWalletAddressKeyMutationResponse = MutationResponse & { +export type CreateWalletAddressKeyMutationResponse = { __typename?: 'CreateWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; -export type CreateWalletAddressMutationResponse = MutationResponse & { +export type CreateWalletAddressMutationResponse = { __typename?: 'CreateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -360,11 +345,9 @@ export type DeleteAssetInput = { idempotencyKey?: InputMaybe; }; -export type DeleteAssetMutationResponse = MutationResponse & { +export type DeleteAssetMutationResponse = { __typename?: 'DeleteAssetMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + asset?: Maybe; }; export type DeletePeerInput = { @@ -373,10 +356,8 @@ export type DeletePeerInput = { idempotencyKey?: InputMaybe; }; -export type DeletePeerMutationResponse = MutationResponse & { +export type DeletePeerMutationResponse = { __typename?: 'DeletePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; success: Scalars['Boolean']['output']; }; @@ -596,12 +577,10 @@ export enum LiquidityError { UnknownWalletAddress = 'UnknownWalletAddress' } -export type LiquidityMutationResponse = MutationResponse & { +export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + id: Scalars['ID']['output']; + liquidity?: Maybe; }; export type Model = { @@ -836,12 +815,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; -export type MutationResponse = { - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type OutgoingPayment = BasePayment & Model & { __typename?: 'OutgoingPayment'; /** Information about the wallet address of the Open Payments client that created the outgoing payment. */ @@ -1185,11 +1158,8 @@ export type RevokeWalletAddressKeyInput = { idempotencyKey?: InputMaybe; }; -export type RevokeWalletAddressKeyMutationResponse = MutationResponse & { +export type RevokeWalletAddressKeyMutationResponse = { __typename?: 'RevokeWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; @@ -1204,12 +1174,9 @@ export type SetFeeInput = { type: FeeType; }; -export type SetFeeResponse = MutationResponse & { +export type SetFeeResponse = { __typename?: 'SetFeeResponse'; - code: Scalars['String']['output']; fee?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export enum SortOrder { @@ -1219,13 +1186,6 @@ export enum SortOrder { Desc = 'DESC' } -export type TransferMutationResponse = MutationResponse & { - __typename?: 'TransferMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type TriggerWalletAddressEventsInput = { /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey?: InputMaybe; @@ -1233,13 +1193,10 @@ export type TriggerWalletAddressEventsInput = { limit: Scalars['Int']['input']; }; -export type TriggerWalletAddressEventsMutationResponse = MutationResponse & { +export type TriggerWalletAddressEventsMutationResponse = { __typename?: 'TriggerWalletAddressEventsMutationResponse'; - code: Scalars['String']['output']; /** Number of events triggered */ count?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type UpdateAssetInput = { @@ -1270,12 +1227,9 @@ export type UpdatePeerInput = { staticIlpAddress?: InputMaybe; }; -export type UpdatePeerMutationResponse = MutationResponse & { +export type UpdatePeerMutationResponse = { __typename?: 'UpdatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type UpdateWalletAddressInput = { @@ -1291,11 +1245,8 @@ export type UpdateWalletAddressInput = { status?: InputMaybe; }; -export type UpdateWalletAddressMutationResponse = MutationResponse & { +export type UpdateWalletAddressMutationResponse = { __typename?: 'UpdateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -1419,12 +1370,8 @@ export type WalletAddressWithdrawal = { walletAddress: WalletAddress; }; -export type WalletAddressWithdrawalMutationResponse = MutationResponse & { +export type WalletAddressWithdrawalMutationResponse = { __typename?: 'WalletAddressWithdrawalMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; withdrawal?: Maybe; }; @@ -1541,7 +1488,6 @@ export type DirectiveResolverFn> = { BasePayment: ( Partial ) | ( Partial ) | ( Partial ); Model: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); - MutationResponse: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); }; /** Mapping between all available schema types and the resolvers types */ @@ -1614,7 +1560,6 @@ export type ResolversTypes = { LiquidityMutationResponse: ResolverTypeWrapper>; Model: ResolverTypeWrapper['Model']>; Mutation: ResolverTypeWrapper<{}>; - MutationResponse: ResolverTypeWrapper['MutationResponse']>; OutgoingPayment: ResolverTypeWrapper>; OutgoingPaymentConnection: ResolverTypeWrapper>; OutgoingPaymentEdge: ResolverTypeWrapper>; @@ -1642,7 +1587,6 @@ export type ResolversTypes = { SetFeeResponse: ResolverTypeWrapper>; SortOrder: ResolverTypeWrapper>; String: ResolverTypeWrapper>; - TransferMutationResponse: ResolverTypeWrapper>; TriggerWalletAddressEventsInput: ResolverTypeWrapper>; TriggerWalletAddressEventsMutationResponse: ResolverTypeWrapper>; UInt8: ResolverTypeWrapper>; @@ -1733,7 +1677,6 @@ export type ResolversParentTypes = { LiquidityMutationResponse: Partial; Model: ResolversInterfaceTypes['Model']; Mutation: {}; - MutationResponse: ResolversInterfaceTypes['MutationResponse']; OutgoingPayment: Partial; OutgoingPaymentConnection: Partial; OutgoingPaymentEdge: Partial; @@ -1758,7 +1701,6 @@ export type ResolversParentTypes = { SetFeeInput: Partial; SetFeeResponse: Partial; String: Partial; - TransferMutationResponse: Partial; TriggerWalletAddressEventsInput: Partial; TriggerWalletAddressEventsMutationResponse: Partial; UInt8: Partial; @@ -1820,9 +1762,6 @@ export type AssetEdgeResolvers = { asset?: Resolver, ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1842,18 +1781,12 @@ export type BasePaymentResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1866,31 +1799,21 @@ export type CreateReceiverResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type CreateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeleteAssetMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; + asset?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeletePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1976,10 +1899,8 @@ export type JwkResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; + id?: Resolver; + liquidity?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2023,13 +1944,6 @@ export type MutationResolvers, ParentType, ContextType, RequireFields>; }; -export type MutationResponseResolvers = { - __resolveType: TypeResolveFn<'AssetMutationResponse' | 'CreateOrUpdatePeerByUrlMutationResponse' | 'CreatePeerMutationResponse' | 'CreateWalletAddressKeyMutationResponse' | 'CreateWalletAddressMutationResponse' | 'DeleteAssetMutationResponse' | 'DeletePeerMutationResponse' | 'LiquidityMutationResponse' | 'RevokeWalletAddressKeyMutationResponse' | 'SetFeeResponse' | 'TransferMutationResponse' | 'TriggerWalletAddressEventsMutationResponse' | 'UpdatePeerMutationResponse' | 'UpdateWalletAddressMutationResponse' | 'WalletAddressWithdrawalMutationResponse', ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; -}; - export type OutgoingPaymentResolvers = { client?: Resolver, ParentType, ContextType>; createdAt?: Resolver; @@ -2189,33 +2103,17 @@ export type ReceiverResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type SetFeeResponseResolvers = { - code?: Resolver; fee?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}; - -export type TransferMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type TriggerWalletAddressEventsMutationResponseResolvers = { - code?: Resolver; count?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2228,17 +2126,11 @@ export interface UInt64ScalarConfig extends GraphQLScalarTypeConfig = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type UpdateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2294,10 +2186,6 @@ export type WalletAddressWithdrawalResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; withdrawal?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2357,7 +2245,6 @@ export type Resolvers = { LiquidityMutationResponse?: LiquidityMutationResponseResolvers; Model?: ModelResolvers; Mutation?: MutationResolvers; - MutationResponse?: MutationResponseResolvers; OutgoingPayment?: OutgoingPaymentResolvers; OutgoingPaymentConnection?: OutgoingPaymentConnectionResolvers; OutgoingPaymentEdge?: OutgoingPaymentEdgeResolvers; @@ -2377,7 +2264,6 @@ export type Resolvers = { Receiver?: ReceiverResolvers; RevokeWalletAddressKeyMutationResponse?: RevokeWalletAddressKeyMutationResponseResolvers; SetFeeResponse?: SetFeeResponseResolvers; - TransferMutationResponse?: TransferMutationResponseResolvers; TriggerWalletAddressEventsMutationResponse?: TriggerWalletAddressEventsMutationResponseResolvers; UInt8?: GraphQLScalarType; UInt64?: GraphQLScalarType; diff --git a/packages/backend/src/graphql/resolvers/liquidity.test.ts b/packages/backend/src/graphql/resolvers/liquidity.test.ts index 48ba6c2fde..06fbaf9a7b 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.test.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.test.ts @@ -40,10 +40,11 @@ import { createPeer } from '../../tests/peer' import { truncateTables } from '../../tests/tableManager' import { WebhookEvent } from '../../webhook/model' import { - LiquidityError, LiquidityMutationResponse, WalletAddressWithdrawalMutationResponse } from '../generated/graphql' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' describe('Liquidity Resolvers', (): void => { let deps: IocContract @@ -73,21 +74,20 @@ describe('Liquidity Resolvers', (): void => { }) test('Can deposit liquidity to peer', async (): Promise => { + const id = uuid() const response = await appContainer.apolloClient .mutate({ mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, variables: { input: { - id: uuid(), + id, peerId: peer.id, amount: '100', idempotencyKey: uuid() @@ -102,21 +102,18 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + expect(response.id).toEqual(id) + expect(response.liquidity).toEqual('100') }) test('Returns an error for invalid id', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -137,22 +134,23 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns an error for unknown peer', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -173,10 +171,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown peer') - expect(response.error).toEqual(LiquidityError.UnknownPeer) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unknown peer', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -188,15 +189,13 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -217,22 +216,23 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) test('Returns an error for zero amount', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -253,10 +253,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Amount is zero') - expect(response.error).toEqual(LiquidityError.AmountZero) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer amount is zero', { + extensions: { + code: GraphQLErrorCode.Forbidden + } + }) + ) }) }) @@ -268,6 +271,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Can deposit liquidity to asset', async (): Promise => { + const id = uuid() const response = await appContainer.apolloClient .mutate({ mutation: gql` @@ -275,16 +279,14 @@ describe('Liquidity Resolvers', (): void => { $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, variables: { input: { - id: uuid(), + id, assetId: asset.id, amount: '100', idempotencyKey: uuid() @@ -299,23 +301,20 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + expect(response.id).toEqual(id) + expect(response.liquidity).toEqual('100') }) test('Returns an error for invalid id', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositAssetLiquidity( $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -336,24 +335,25 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns an error for unknown asset', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositAssetLiquidity( $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -374,10 +374,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown asset') - expect(response.error).toEqual(LiquidityError.UnknownAsset) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Unknown asset', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -389,17 +392,15 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositAssetLiquidity( $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -420,24 +421,25 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) test('Returns an error for zero amount', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositAssetLiquidity( $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -458,10 +460,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Amount is zero') - expect(response.error).toEqual(LiquidityError.AmountZero) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer amount is zero', { + extensions: { + code: GraphQLErrorCode.Forbidden + } + }) + ) }) }) @@ -481,6 +486,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Can create liquidity withdrawal from peer', async (): Promise => { + const id = uuid() const response = await appContainer.apolloClient .mutate({ mutation: gql` @@ -488,16 +494,14 @@ describe('Liquidity Resolvers', (): void => { $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, variables: { input: { - id: uuid(), + id, peerId: peer.id, amount: startingBalance.toString(), idempotencyKey: uuid(), @@ -513,23 +517,20 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + expect(response.id).toEqual(id) + expect(response.liquidity).toEqual(startingBalance.toString()) }) test('Returns an error for unknown peer', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreatePeerLiquidityWithdrawal( $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -551,24 +552,25 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown peer') - expect(response.error).toEqual(LiquidityError.UnknownPeer) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Unknown peer', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) test('Returns an error for invalid id', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreatePeerLiquidityWithdrawal( $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -590,10 +592,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -605,17 +610,15 @@ describe('Liquidity Resolvers', (): void => { amount: 10n }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreatePeerLiquidityWithdrawal( $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -636,30 +639,31 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) test.each` - amount | code | message | error - ${startingBalance + BigInt(1)} | ${'403'} | ${'Insufficient balance'} | ${LiquidityError.InsufficientBalance} - ${BigInt(0)} | ${'400'} | ${'Amount is zero'} | ${LiquidityError.AmountZero} + amount | message | code + ${startingBalance + BigInt(1)} | ${'Insufficient transfer balance'} | ${GraphQLErrorCode.Forbidden} + ${BigInt(0)} | ${'Transfer amount is zero'} | ${GraphQLErrorCode.Forbidden} `( - 'Returns error for $error', - async ({ amount, code, message, error }): Promise => { - const response = await appContainer.apolloClient + 'Returns error for $code', + async ({ amount, message, code }): Promise => { + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreatePeerLiquidityWithdrawal( $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -681,10 +685,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual(code) - expect(response.message).toEqual(message) - expect(response.error).toEqual(error) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(message, { + extensions: { + code + } + }) + ) } ) }) @@ -705,6 +712,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Can create liquidity withdrawal from asset', async (): Promise => { + const id = uuid() const response = await appContainer.apolloClient .mutate({ mutation: gql` @@ -712,16 +720,14 @@ describe('Liquidity Resolvers', (): void => { $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, variables: { input: { - id: uuid(), + id, assetId: asset.id, amount: startingBalance.toString(), idempotencyKey: uuid(), @@ -737,23 +743,20 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + expect(response.id).toEqual(id) + expect(response.liquidity).toEqual(startingBalance.toString()) }) test('Returns an error for unknown asset', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateAssetLiquidityWithdrawal( $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -775,24 +778,25 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown asset') - expect(response.error).toEqual(LiquidityError.UnknownAsset) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Unknown asset', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) test('Returns an error for invalid id', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateAssetLiquidityWithdrawal( $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -814,10 +818,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -829,17 +836,15 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(10) }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateAssetLiquidityWithdrawal( $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -860,30 +865,32 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) test.each` - amount | code | message | error - ${startingBalance + BigInt(1)} | ${'403'} | ${'Insufficient balance'} | ${LiquidityError.InsufficientBalance} - ${BigInt(0)} | ${'400'} | ${'Amount is zero'} | ${LiquidityError.AmountZero} + amount | message | code + ${startingBalance + BigInt(1)} | ${'Insufficient transfer balance'} | ${GraphQLErrorCode.Forbidden} + ${BigInt(0)} | ${'Transfer amount is zero'} | ${GraphQLErrorCode.Forbidden} `( 'Returns error for $error', - async ({ amount, code, message, error }): Promise => { - const response = await appContainer.apolloClient + async ({ amount, code, message }): Promise => { + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateAssetLiquidityWithdrawal( $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -905,10 +912,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual(code) - expect(response.message).toEqual(message) - expect(response.error).toEqual(error) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(message, { + extensions: { + code + } + }) + ) } ) }) @@ -940,10 +950,6 @@ describe('Liquidity Resolvers', (): void => { $input: CreateWalletAddressWithdrawalInput! ) { createWalletAddressWithdrawal(input: $input) { - code - success - message - error withdrawal { id amount @@ -971,9 +977,6 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() expect(response.withdrawal).toMatchObject({ id, amount: amount.toString(), @@ -984,17 +987,13 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for unknown wallet address', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddressWithdrawal( $input: CreateWalletAddressWithdrawalInput! ) { createWalletAddressWithdrawal(input: $input) { - code - success - message - error withdrawal { id } @@ -1018,25 +1017,23 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown wallet address') - expect(response.error).toEqual(LiquidityError.UnknownWalletAddress) - expect(response.withdrawal).toBeNull() + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Unknown wallet address', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) test('Returns an error for invalid id', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddressWithdrawal( $input: CreateWalletAddressWithdrawalInput! ) { createWalletAddressWithdrawal(input: $input) { - code - success - message - error withdrawal { id } @@ -1060,11 +1057,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) - expect(response.withdrawal).toBeNull() + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -1076,17 +1075,13 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(10) }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddressWithdrawal( $input: CreateWalletAddressWithdrawalInput! ) { createWalletAddressWithdrawal(input: $input) { - code - success - message - error withdrawal { id } @@ -1109,11 +1104,14 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) - expect(response.withdrawal).toBeNull() + + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) test('Returns an error for empty balance', async (): Promise => { @@ -1125,17 +1123,13 @@ describe('Liquidity Resolvers', (): void => { timeout: 0 }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddressWithdrawal( $input: CreateWalletAddressWithdrawalInput! ) { createWalletAddressWithdrawal(input: $input) { - code - success - message - error withdrawal { id } @@ -1158,11 +1152,14 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Amount is zero') - expect(response.error).toEqual(LiquidityError.AmountZero) - expect(response.withdrawal).toBeNull() + + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer amount is zero', { + extensions: { + code: GraphQLErrorCode.Forbidden + } + }) + ) }) }) @@ -1200,10 +1197,7 @@ describe('Liquidity Resolvers', (): void => { $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - code - success - message - error + id } } `, @@ -1222,23 +1216,19 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + expect(response.id).toEqual(withdrawalId) }) test("Can't post non-existent withdrawal", async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation PostLiquidityWithdrawal( $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1257,24 +1247,25 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown withdrawal') - expect(response.error).toEqual(LiquidityError.UnknownTransfer) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Unknown transfer', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) test("Can't post invalid withdrawal id", async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation PostLiquidityWithdrawal( $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1293,27 +1284,28 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test("Can't post posted withdrawal", async (): Promise => { await expect( accountingService.postWithdrawal(withdrawalId) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation PostLiquidityWithdrawal( $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1332,27 +1324,28 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Withdrawal already posted') - expect(response.error).toEqual(LiquidityError.AlreadyPosted) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already posted', { + extensions: { + code: GraphQLErrorCode.Conflict + } + }) + ) }) test("Can't post voided withdrawal", async (): Promise => { await expect( accountingService.voidWithdrawal(withdrawalId) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation PostLiquidityWithdrawal( $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1371,10 +1364,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Withdrawal already voided') - expect(response.error).toEqual(LiquidityError.AlreadyVoided) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already voided', { + extensions: { + code: GraphQLErrorCode.Conflict + } + }) + ) }) } ) @@ -1413,10 +1409,7 @@ describe('Liquidity Resolvers', (): void => { $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - code - success - message - error + id } } `, @@ -1435,23 +1428,18 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + expect(response.id).toEqual(withdrawalId) }) test("Can't void non-existent withdrawal", async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation VoidLiquidityWithdrawal( $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - code - success - message - error + id } } `, @@ -1470,24 +1458,24 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('404') - expect(response.message).toEqual('Unknown withdrawal') - expect(response.error).toEqual(LiquidityError.UnknownTransfer) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Unknown transfer', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) test("Can't void invalid withdrawal id", async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation VoidLiquidityWithdrawal( $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - code - success - message - error + id } } `, @@ -1506,27 +1494,27 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test("Can't void posted withdrawal", async (): Promise => { await expect( accountingService.postWithdrawal(withdrawalId) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation VoidLiquidityWithdrawal( $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - code - success - message - error + id } } `, @@ -1545,27 +1533,27 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Withdrawal already posted') - expect(response.error).toEqual(LiquidityError.AlreadyPosted) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already posted', { + extensions: { + code: GraphQLErrorCode.Conflict + } + }) + ) }) test("Can't void voided withdrawal", async (): Promise => { await expect( accountingService.voidWithdrawal(withdrawalId) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation voidLiquidityWithdrawal( $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - code - success - message - error + id } } `, @@ -1584,10 +1572,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Withdrawal already voided') - expect(response.error).toEqual(LiquidityError.AlreadyVoided) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already voided', { + extensions: { + code: GraphQLErrorCode.Conflict + } + }) + ) }) } ) @@ -1653,10 +1644,8 @@ describe('Liquidity Resolvers', (): void => { $input: DepositEventLiquidityInput! ) { depositEventLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1675,9 +1664,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + assert.ok(response.id) assert.ok(payment.debitAmount) await expect(depositSpy).toHaveBeenCalledWith({ id: eventId, @@ -1690,17 +1677,15 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't deposit for non-existent webhook event id", async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositLiquidity( $input: DepositEventLiquidityInput! ) { depositEventLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1719,10 +1704,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -1733,17 +1721,15 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositLiquidity( $input: DepositEventLiquidityInput! ) { depositEventLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1762,10 +1748,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) } ) @@ -1881,10 +1870,8 @@ describe('Liquidity Resolvers', (): void => { $input: WithdrawEventLiquidityInput! ) { withdrawEventLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1903,23 +1890,20 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + expect(response.id).toEqual(eventId) + expect(response.liquidity).toEqual('10') }) test('Returns error for non-existent webhook event id', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation WithdrawLiquidity( $input: WithdrawEventLiquidityInput! ) { withdrawEventLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1938,27 +1922,28 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns error for already completed withdrawal', async (): Promise => { await expect( accountingService.createWithdrawal(withdrawal) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation WithdrawLiquidity( $input: WithdrawEventLiquidityInput! ) { withdrawEventLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -1977,10 +1962,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) } ) @@ -2065,10 +2053,8 @@ describe('Liquidity Resolvers', (): void => { $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2088,9 +2074,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + assert.ok(response.id) expect( accountingService.getBalance(incomingPayment.id) ).resolves.toEqual(balance - amount) @@ -2110,17 +2094,15 @@ describe('Liquidity Resolvers', (): void => { amount } }) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateIncomingPaymentWithdrawal( $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2140,24 +2122,25 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns error when related webhook not found', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateIncomingPaymentWithdrawal( $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2177,10 +2160,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns error for already completed withdrawal', async (): Promise => { @@ -2203,17 +2189,15 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateIncomingPaymentWithdrawal( $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2233,10 +2217,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) }) }) @@ -2284,10 +2271,8 @@ describe('Liquidity Resolvers', (): void => { $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2307,9 +2292,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + assert.ok(response.id) expect( accountingService.getBalance(outgoingPayment.id) ).resolves.toEqual(balance - amount) @@ -2318,17 +2301,15 @@ describe('Liquidity Resolvers', (): void => { describe('Cannot withdraw liquidity', () => { test('Returns error for non-existent outgoing payment id', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateOutgoingPaymentWithdrawal( $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2347,10 +2328,13 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns error when related webhook not found', async (): Promise => { @@ -2361,17 +2345,15 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateIncomingPaymentWithdrawal( $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2390,10 +2372,14 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns error for already completed withdrawal', async (): Promise => { @@ -2415,17 +2401,15 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CreateOutgoingPaymentWithdrawal( $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2444,10 +2428,13 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('403') - expect(response.message).toEqual('Insufficient balance') - expect(response.error).toEqual(LiquidityError.InsufficientBalance) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Insufficient transfer balance', { + extensions: { + code: GraphQLErrorCode.Forbidden + } + }) + ) }) }) }) @@ -2480,10 +2467,8 @@ describe('Liquidity Resolvers', (): void => { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2502,9 +2487,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.error).toBeNull() + assert.ok(response.id) assert.ok(outgoingPayment.debitAmount) await expect(depositSpy).toHaveBeenCalledWith({ id: eventId, @@ -2517,17 +2500,15 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't deposit for non-existent outgoing payment id", async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositLiquidity( $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2546,10 +2527,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('400') - expect(response.message).toEqual('Invalid id') - expect(response.error).toEqual(LiquidityError.InvalidId) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Invalid transfer id', { + extensions: { + code: GraphQLErrorCode.BadUserInput + } + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -2560,17 +2544,15 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DepositLiquidity( $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -2589,10 +2571,13 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('409') - expect(response.message).toEqual('Transfer exists') - expect(response.error).toEqual(LiquidityError.TransferExists) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Transfer already exists', { + extensions: { + code: GraphQLErrorCode.Duplicate + } + }) + ) }) } ) diff --git a/packages/backend/src/graphql/resolvers/liquidity.ts b/packages/backend/src/graphql/resolvers/liquidity.ts index df2e6d59fe..5e32ca9814 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.ts @@ -1,10 +1,10 @@ +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' import { walletAddressToGraphql } from './wallet_address' import { ResolversTypes, MutationResolvers, LiquidityError, - LiquidityMutationResponse, - WalletAddressWithdrawalMutationResponse, AssetResolvers, PeerResolvers, WalletAddressResolvers, @@ -14,15 +14,24 @@ import { } from '../generated/graphql' import { ApolloContext } from '../../app' import { - FundingError, + fundingErrorToMessage, + fundingErrorToCode, isFundingError } from '../../open_payments/payment/outgoing/errors' +import { + errorToCode as transferErrorToCode, + errorToMessage as transferErrorToMessage +} from '../../accounting/errors' import { isOutgoingPaymentEvent, OutgoingPaymentDepositType, OutgoingPaymentEventType } from '../../open_payments/payment/outgoing/model' -import { PeerError } from '../../payment-method/ilp/peer/errors' +import { + PeerError, + errorToMessage as peerErrorToMessage, + errorToCode as peerErrorToCode +} from '../../payment-method/ilp/peer/errors' import { IncomingPaymentEventType } from '../../open_payments/payment/incoming/model' export const getAssetLiquidity: AssetResolvers['liquidity'] = @@ -80,41 +89,37 @@ export const depositPeerLiquidity: MutationResolvers['depositPeer args, ctx ): Promise => { - try { - if (args.input.amount === BigInt(0)) { - return responses[LiquidityError.AmountZero] - } - const peerService = await ctx.container.use('peerService') - const peerOrError = await peerService.depositLiquidity({ - transferId: args.input.id, - peerId: args.input.peerId, - amount: args.input.amount + if (args.input.amount === BigInt(0)) { + throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { + extensions: { + code: errorToCode[LiquidityError.AmountZero] + } }) + } + const peerService = await ctx.container.use('peerService') + const peerOrError = await peerService.depositLiquidity({ + transferId: args.input.id, + peerId: args.input.peerId, + amount: args.input.amount + }) + + if (peerOrError === PeerError.UnknownPeer) { + throw new GraphQLError(peerErrorToMessage[peerOrError], { + extensions: { + code: peerErrorToCode[peerOrError] + } + }) + } else if (isLiquidityError(peerOrError)) { + throw new GraphQLError(errorToMessage[peerOrError], { + extensions: { + code: errorToCode[peerOrError] + } + }) + } - if (peerOrError === PeerError.UnknownPeer) { - return responses[LiquidityError.UnknownPeer] - } else if (isLiquidityError(peerOrError)) { - return errorToResponse(peerOrError) - } - - return { - code: '200', - success: true, - message: 'Added peer liquidity' - } - } catch (err) { - ctx.logger.error( - { - input: args.input, - err - }, - 'error adding peer liquidity' - ) - return { - code: '400', - message: 'Error trying to deposit peer liquidity', - success: false - } + return { + id: args.input.id, + liquidity: args.input.amount } } @@ -124,42 +129,38 @@ export const depositAssetLiquidity: MutationResolvers['depositAss args, ctx ): Promise => { - try { - if (args.input.amount === BigInt(0)) { - return responses[LiquidityError.AmountZero] - } - const assetService = await ctx.container.use('assetService') - const asset = await assetService.get(args.input.assetId) - if (!asset) { - return responses[LiquidityError.UnknownAsset] - } - const accountingService = await ctx.container.use('accountingService') - const error = await accountingService.createDeposit({ - id: args.input.id, - account: asset, - amount: args.input.amount + if (args.input.amount === BigInt(0)) { + throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { + extensions: { + code: errorToCode[LiquidityError.AmountZero] + } + }) + } + const assetService = await ctx.container.use('assetService') + const asset = await assetService.get(args.input.assetId) + if (!asset) { + throw new GraphQLError(errorToMessage[LiquidityError.UnknownAsset], { + extensions: { + code: errorToCode[LiquidityError.UnknownAsset] + } + }) + } + const accountingService = await ctx.container.use('accountingService') + const error = await accountingService.createDeposit({ + id: args.input.id, + account: asset, + amount: args.input.amount + }) + if (error) { + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } }) - if (error) { - return errorToResponse(error) - } - return { - code: '200', - success: true, - message: 'Added asset liquidity' - } - } catch (err) { - ctx.logger.error( - { - input: args.input, - err - }, - 'error adding asset liquidity' - ) - return { - code: '400', - message: 'Error trying to deposit asset liquidity', - success: false - } + } + return { + id: args.input.id, + liquidity: args.input.amount } } @@ -169,6 +170,7 @@ export const createPeerLiquidityWithdrawal: MutationResolvers['cr args, ctx ): Promise => { +<<<<<<< HEAD try { const { amount, id, timeoutSeconds, peerId } = args.input if (amount === BigInt(0)) { @@ -185,28 +187,41 @@ export const createPeerLiquidityWithdrawal: MutationResolvers['cr account: peer, amount, timeout: Number(timeoutSeconds) +======= + if (args.input.amount === BigInt(0)) { + throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { + extensions: { + code: errorToCode[LiquidityError.AmountZero] + } +>>>>>>> c702654c (feat(wip): backend graphql logs) + }) + } + const peerService = await ctx.container.use('peerService') + const peer = await peerService.get(args.input.peerId) + if (!peer) { + throw new GraphQLError(errorToMessage[LiquidityError.UnknownPeer], { + extensions: { + code: errorToCode[LiquidityError.UnknownPeer] + } + }) + } + const accountingService = await ctx.container.use('accountingService') + const error = await accountingService.createWithdrawal({ + id: args.input.id, + account: peer, + amount: args.input.amount, + timeout: 60 + }) + if (error) { + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } }) - if (error) { - return errorToResponse(error) - } - return { - code: '200', - success: true, - message: 'Created peer liquidity withdrawal' - } - } catch (err) { - ctx.logger.error( - { - input: args.input, - err - }, - 'error creating peer liquidity withdrawal' - ) - return { - code: '400', - message: 'Error trying to create peer liquidity withdrawal', - success: false - } + } + return { + id: args.input.id, + liquidity: args.input.amount } } @@ -216,6 +231,7 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c args, ctx ): Promise => { +<<<<<<< HEAD try { const { amount, id, timeoutSeconds, assetId } = args.input if (amount === 0n) { @@ -232,28 +248,41 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c account: asset, amount, timeout: Number(timeoutSeconds) +======= + if (args.input.amount === BigInt(0)) { + throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { + extensions: { + code: errorToCode[LiquidityError.AmountZero] + } +>>>>>>> c702654c (feat(wip): backend graphql logs) }) - if (error) { - return errorToResponse(error) - } - return { - code: '200', - success: true, - message: 'Created asset liquidity withdrawal' - } - } catch (err) { - ctx.logger.error( - { - input: args.input, - err - }, - 'error creating asset liquidity withdrawal' - ) - return { - code: '400', - message: 'Error trying to create asset liquidity withdrawal', - success: false - } + } + const assetService = await ctx.container.use('assetService') + const asset = await assetService.get(args.input.assetId) + if (!asset) { + throw new GraphQLError(errorToMessage[LiquidityError.UnknownAsset], { + extensions: { + code: errorToCode[LiquidityError.UnknownAsset] + } + }) + } + const accountingService = await ctx.container.use('accountingService') + const error = await accountingService.createWithdrawal({ + id: args.input.id, + account: asset, + amount: args.input.amount, + timeout: 60 + }) + if (error) { + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } + }) + } + return { + id: args.input.id, + liquidity: args.input.amount } } @@ -263,6 +292,7 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr args, ctx ): Promise => { +<<<<<<< HEAD try { const { id, walletAddressId, timeoutSeconds } = args.input const walletAddressService = await ctx.container.use( @@ -309,16 +339,53 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr } } catch (err) { ctx.logger.error( +======= + const walletAddressService = await ctx.container.use('walletAddressService') + const walletAddress = await walletAddressService.get( + args.input.walletAddressId + ) + if (!walletAddress) { + throw new GraphQLError( + errorToMessage[LiquidityError.UnknownWalletAddress], +>>>>>>> c702654c (feat(wip): backend graphql logs) { - input: args.input, - err - }, - 'error creating wallet address withdrawal' + extensions: { + code: errorToCode[LiquidityError.UnknownWalletAddress] + } + } ) - return { - code: '500', - message: 'Error trying to create wallet address withdrawal', - success: false + } + const id = args.input.id + const accountingService = await ctx.container.use('accountingService') + const amount = await accountingService.getBalance(walletAddress.id) + if (amount === undefined) + throw new Error('missing incoming payment wallet address') + if (amount === BigInt(0)) { + throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { + extensions: { + code: errorToCode[LiquidityError.AmountZero] + } + }) + } + const error = await accountingService.createWithdrawal({ + id, + account: walletAddress, + amount, + timeout: 60 + }) + + if (error) { + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } + }) + } + return { + withdrawal: { + id, + amount, + walletAddress: walletAddressToGraphql(walletAddress) } } } @@ -334,12 +401,14 @@ export const postLiquidityWithdrawal: MutationResolvers['postLiqu args.input.withdrawalId ) if (error) { - return errorToResponse(error) + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } + }) } return { - code: '200', - success: true, - message: 'Posted Withdrawal' + id: args.input.withdrawalId } } @@ -354,12 +423,14 @@ export const voidLiquidityWithdrawal: MutationResolvers['voidLiqu args.input.withdrawalId ) if (error) { - return errorToResponse(error) + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } + }) } return { - code: '200', - success: true, - message: 'Voided Withdrawal' + id: args.input.withdrawalId } } @@ -376,48 +447,40 @@ export const depositEventLiquidity: MutationResolvers['depositEve args, ctx ): Promise => { - try { - const webhookService = await ctx.container.use('webhookService') - const event = await webhookService.getEvent(args.input.eventId) - if ( - !event || - !isOutgoingPaymentEvent(event) || - !isDepositEventType(event.type) - ) { - return responses[LiquidityError.InvalidId] - } - if (!event.data.debitAmount) { - throw new Error('missing debit amount') - } - const outgoingPaymentService = await ctx.container.use( - 'outgoingPaymentService' - ) - const paymentOrErr = await outgoingPaymentService.fund({ - id: event.data.id, - amount: BigInt(event.data.debitAmount.value), - transferId: event.id + const webhookService = await ctx.container.use('webhookService') + const event = await webhookService.getEvent(args.input.eventId) + if ( + !event || + !isOutgoingPaymentEvent(event) || + !isDepositEventType(event.type) + ) { + throw new GraphQLError(errorToMessage[LiquidityError.InvalidId], { + extensions: { + code: errorToCode[LiquidityError.InvalidId] + } }) - if (isFundingError(paymentOrErr)) { - return errorToResponse(paymentOrErr) - } - return { - code: '200', - success: true, - message: 'Deposited liquidity' - } - } catch (err) { - ctx.logger.error( - { - eventId: args.input.eventId, - err - }, - 'error depositing liquidity' - ) - return { - code: '400', - message: 'Error trying to deposit liquidity', - success: false - } + } + if (!event.data.debitAmount) { + throw new Error('missing debit amount') + } + const outgoingPaymentService = await ctx.container.use( + 'outgoingPaymentService' + ) + const paymentOrErr = await outgoingPaymentService.fund({ + id: event.data.id, + amount: BigInt(event.data.debitAmount.value), + transferId: event.id + }) + if (isFundingError(paymentOrErr)) { + throw new GraphQLError(fundingErrorToMessage[paymentOrErr], { + extensions: { + code: fundingErrorToCode[paymentOrErr] + } + }) + } + return { + id: event.data.id, + liquidity: BigInt(event.data.debitAmount.value) } } @@ -427,48 +490,40 @@ export const withdrawEventLiquidity: MutationResolvers['withdrawE args, ctx ): Promise => { - try { - const webhookService = await ctx.container.use('webhookService') - const event = await webhookService.getEvent(args.input.eventId) - if (!event || !event.withdrawal) { - return responses[LiquidityError.InvalidId] - } - const assetService = await ctx.container.use('assetService') - const asset = await assetService.get(event.withdrawal.assetId) - if (!asset) { - throw new Error('asset id does not map to asset') - } - const accountingService = await ctx.container.use('accountingService') - const error = await accountingService.createWithdrawal({ - id: event.id, - account: { - id: event.withdrawal.accountId, - asset - }, - amount: event.withdrawal.amount + const webhookService = await ctx.container.use('webhookService') + const event = await webhookService.getEvent(args.input.eventId) + if (!event || !event.withdrawal) { + throw new GraphQLError(errorToMessage[LiquidityError.InvalidId], { + extensions: { + code: errorToCode[LiquidityError.InvalidId] + } }) - if (error) { - return errorToResponse(error) - } - // TODO: check for and handle leftover incoming payment or payment balance - return { - code: '200', - success: true, - message: 'Withdrew liquidity' - } - } catch (err) { - ctx.logger.error( - { - eventId: args.input.eventId, - err - }, - 'error withdrawing liquidity' - ) - return { - code: '400', - message: 'Error trying to withdraw liquidity', - success: false - } + } + const assetService = await ctx.container.use('assetService') + const asset = await assetService.get(event.withdrawal.assetId) + if (!asset) { + throw new Error('asset id does not map to asset') + } + const accountingService = await ctx.container.use('accountingService') + const error = await accountingService.createWithdrawal({ + id: event.id, + account: { + id: event.withdrawal.accountId, + asset + }, + amount: event.withdrawal.amount + }) + if (error) { + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } + }) + } + // TODO: check for and handle leftover incoming payment or payment balance + return { + id: event.id, + liquidity: event.withdrawal.amount } } @@ -478,49 +533,41 @@ export const depositOutgoingPaymentLiquidity: MutationResolvers[' args, ctx ): Promise => { - try { - const { outgoingPaymentId } = args.input - const webhookService = await ctx.container.use('webhookService') - const event = await webhookService.getLatestByResourceId({ - outgoingPaymentId, - types: [OutgoingPaymentDepositType.PaymentCreated] + const { outgoingPaymentId } = args.input + const webhookService = await ctx.container.use('webhookService') + const event = await webhookService.getLatestByResourceId({ + outgoingPaymentId, + types: [OutgoingPaymentDepositType.PaymentCreated] + }) + if (!event || !isOutgoingPaymentEvent(event)) { + throw new GraphQLError(errorToMessage[LiquidityError.InvalidId], { + extensions: { + code: errorToCode[LiquidityError.InvalidId] + } }) - if (!event || !isOutgoingPaymentEvent(event)) { - return responses[LiquidityError.InvalidId] - } + } - if (!event.data.debitAmount) { - throw new Error('No debit amount') - } - const outgoingPaymentService = await ctx.container.use( - 'outgoingPaymentService' - ) - const paymentOrErr = await outgoingPaymentService.fund({ - id: outgoingPaymentId, - amount: BigInt(event.data.debitAmount.value), - transferId: event.id + if (!event.data.debitAmount) { + throw new Error('No debit amount') + } + const outgoingPaymentService = await ctx.container.use( + 'outgoingPaymentService' + ) + const paymentOrErr = await outgoingPaymentService.fund({ + id: outgoingPaymentId, + amount: BigInt(event.data.debitAmount.value), + transferId: event.id + }) + if (isFundingError(paymentOrErr)) { + throw new GraphQLError(fundingErrorToMessage[paymentOrErr], { + extensions: { + code: fundingErrorToCode[paymentOrErr] + } }) - if (isFundingError(paymentOrErr)) { - return errorToResponse(paymentOrErr) - } - return { - code: '200', - success: true, - message: 'Deposited liquidity' - } - } catch (err) { - ctx.logger.error( - { - outgoingPaymentId: args.input.outgoingPaymentId, - err - }, - 'error depositing liquidity' - ) - return { - code: '400', - message: 'Error trying to deposit liquidity', - success: false - } + } + return { + id: outgoingPaymentId, + liquidity: BigInt(event.data.debitAmount.value) } } @@ -530,6 +577,7 @@ export const createIncomingPaymentWithdrawal: MutationResolvers[' args, ctx ): Promise => { +<<<<<<< HEAD const { incomingPaymentId, timeoutSeconds } = args.input try { const incomingPaymentService = await ctx.container.use( @@ -537,19 +585,32 @@ export const createIncomingPaymentWithdrawal: MutationResolvers[' ) const incomingPayment = await incomingPaymentService.get({ id: incomingPaymentId +======= + const { incomingPaymentId } = args.input + const incomingPaymentService = await ctx.container.use( + 'incomingPaymentService' + ) + const incomingPayment = await incomingPaymentService.get({ + id: incomingPaymentId + }) + const webhookService = await ctx.container.use('webhookService') + const event = await webhookService.getLatestByResourceId({ + incomingPaymentId, + types: [ + IncomingPaymentEventType.IncomingPaymentCompleted, + IncomingPaymentEventType.IncomingPaymentExpired + ] + }) + if (!incomingPayment || !incomingPayment.receivedAmount || !event?.id) { + throw new GraphQLError(errorToMessage[LiquidityError.InvalidId], { + extensions: { + code: errorToCode[LiquidityError.InvalidId] + } +>>>>>>> c702654c (feat(wip): backend graphql logs) }) - const webhookService = await ctx.container.use('webhookService') - const event = await webhookService.getLatestByResourceId({ - incomingPaymentId, - types: [ - IncomingPaymentEventType.IncomingPaymentCompleted, - IncomingPaymentEventType.IncomingPaymentExpired - ] - }) - if (!incomingPayment || !incomingPayment.receivedAmount || !event?.id) { - return responses[LiquidityError.InvalidId] - } + } +<<<<<<< HEAD const accountingService = await ctx.container.use('accountingService') const error = await accountingService.createWithdrawal({ id: event.id, @@ -560,28 +621,28 @@ export const createIncomingPaymentWithdrawal: MutationResolvers[' amount: incomingPayment.receivedAmount.value, timeout: Number(timeoutSeconds) }) +======= + const accountingService = await ctx.container.use('accountingService') + const error = await accountingService.createWithdrawal({ + id: event.id, + account: { + id: incomingPaymentId, + asset: incomingPayment.asset + }, + amount: incomingPayment.receivedAmount.value + }) +>>>>>>> c702654c (feat(wip): backend graphql logs) - if (error) { - return errorToResponse(error) - } - return { - code: '200', - success: true, - message: 'Withdrew liquidity' - } - } catch (error) { - ctx.logger.error( - { - incomingPaymentId, - error - }, - 'error withdrawing liquidity' - ) - return { - code: '400', - message: 'Error trying to withdraw liquidity', - success: false - } + if (error) { + throw new GraphQLError(fundingErrorToMessage[error], { + extensions: { + code: fundingErrorToCode[error] + } + }) + } + return { + id: event.id, + liquidity: incomingPayment.receivedAmount.value } } @@ -591,6 +652,7 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' args, ctx ): Promise => { +<<<<<<< HEAD const { outgoingPaymentId, timeoutSeconds } = args.input try { const outgoingPaymentService = await ctx.container.use( @@ -598,19 +660,32 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' ) const outgoingPayment = await outgoingPaymentService.get({ id: outgoingPaymentId +======= + const { outgoingPaymentId } = args.input + const outgoingPaymentService = await ctx.container.use( + 'outgoingPaymentService' + ) + const outgoingPayment = await outgoingPaymentService.get({ + id: outgoingPaymentId + }) + const webhookService = await ctx.container.use('webhookService') + const event = await webhookService.getLatestByResourceId({ + outgoingPaymentId, + types: [ + OutgoingPaymentEventType.PaymentCompleted, + OutgoingPaymentEventType.PaymentFailed + ] + }) + if (!outgoingPayment || !event?.id) { + throw new GraphQLError(errorToMessage[LiquidityError.InvalidId], { + extensions: { + code: errorToCode[LiquidityError.InvalidId] + } +>>>>>>> c702654c (feat(wip): backend graphql logs) }) - const webhookService = await ctx.container.use('webhookService') - const event = await webhookService.getLatestByResourceId({ - outgoingPaymentId, - types: [ - OutgoingPaymentEventType.PaymentCompleted, - OutgoingPaymentEventType.PaymentFailed - ] - }) - if (!outgoingPayment || !event?.id) { - return responses[LiquidityError.InvalidId] - } + } +<<<<<<< HEAD const accountingService = await ctx.container.use('accountingService') const balance = await accountingService.getBalance(outgoingPayment.id) if (!balance) { @@ -637,17 +712,40 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' } } catch (error) { ctx.logger.error( +======= + const accountingService = await ctx.container.use('accountingService') + const balance = await accountingService.getBalance(outgoingPayment.id) + if (!balance) { + throw new GraphQLError( + errorToMessage[LiquidityError.InsufficientBalance], +>>>>>>> c702654c (feat(wip): backend graphql logs) { - outgoingPaymentId, - error - }, - 'error withdrawing liquidity' + extensions: { + code: errorToCode[LiquidityError.InsufficientBalance] + } + } ) - return { - code: '400', - message: 'Error trying to withdraw liquidity', - success: false - } + } + + const error = await accountingService.createWithdrawal({ + id: event.id, + account: { + id: outgoingPaymentId, + asset: outgoingPayment.asset + }, + amount: balance + }) + + if (error) { + throw new GraphQLError(transferErrorToMessage[error], { + extensions: { + code: transferErrorToCode[error] + } + }) + } + return { + id: event.id, + liquidity: balance } } @@ -655,86 +753,36 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' const isLiquidityError = (o: any): o is LiquidityError => Object.values(LiquidityError).includes(o) -const errorToResponse = (error: FundingError): LiquidityMutationResponse => { - if (!isLiquidityError(error)) { - throw new Error(error) - } - return responses[error] +const errorToCode: { + [key in LiquidityError]: string +} = { + [LiquidityError.AlreadyPosted]: GraphQLErrorCode.Conflict, + [LiquidityError.AlreadyVoided]: GraphQLErrorCode.Conflict, + [LiquidityError.AmountZero]: GraphQLErrorCode.Forbidden, + [LiquidityError.InsufficientBalance]: GraphQLErrorCode.Forbidden, + [LiquidityError.InvalidId]: GraphQLErrorCode.BadUserInput, + [LiquidityError.TransferExists]: GraphQLErrorCode.Duplicate, + [LiquidityError.UnknownAsset]: GraphQLErrorCode.NotFound, + [LiquidityError.UnknownIncomingPayment]: GraphQLErrorCode.NotFound, + [LiquidityError.UnknownPayment]: GraphQLErrorCode.NotFound, + [LiquidityError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, + [LiquidityError.UnknownPeer]: GraphQLErrorCode.NotFound, + [LiquidityError.UnknownTransfer]: GraphQLErrorCode.NotFound } -const responses: { - [key in LiquidityError]: LiquidityMutationResponse +const errorToMessage: { + [key in LiquidityError]: string } = { - [LiquidityError.AlreadyPosted]: { - code: '409', - message: 'Withdrawal already posted', - success: false, - error: LiquidityError.AlreadyPosted - }, - [LiquidityError.AlreadyVoided]: { - code: '409', - message: 'Withdrawal already voided', - success: false, - error: LiquidityError.AlreadyVoided - }, - [LiquidityError.AmountZero]: { - code: '400', - message: 'Amount is zero', - success: false, - error: LiquidityError.AmountZero - }, - [LiquidityError.InsufficientBalance]: { - code: '403', - message: 'Insufficient balance', - success: false, - error: LiquidityError.InsufficientBalance - }, - [LiquidityError.InvalidId]: { - code: '400', - message: 'Invalid id', - success: false, - error: LiquidityError.InvalidId - }, - [LiquidityError.TransferExists]: { - code: '409', - message: 'Transfer exists', - success: false, - error: LiquidityError.TransferExists - }, - [LiquidityError.UnknownWalletAddress]: { - code: '404', - message: 'Unknown wallet address', - success: false, - error: LiquidityError.UnknownWalletAddress - }, - [LiquidityError.UnknownAsset]: { - code: '404', - message: 'Unknown asset', - success: false, - error: LiquidityError.UnknownAsset - }, - [LiquidityError.UnknownIncomingPayment]: { - code: '404', - message: 'Unknown incoming payment', - success: false, - error: LiquidityError.UnknownIncomingPayment - }, - [LiquidityError.UnknownPayment]: { - code: '404', - message: 'Unknown outgoing payment', - success: false, - error: LiquidityError.UnknownPayment - }, - [LiquidityError.UnknownPeer]: { - code: '404', - message: 'Unknown peer', - success: false, - error: LiquidityError.UnknownPeer - }, - [LiquidityError.UnknownTransfer]: { - code: '404', - message: 'Unknown withdrawal', - success: false, - error: LiquidityError.UnknownTransfer - } + [LiquidityError.AlreadyPosted]: 'Transfer already posted', + [LiquidityError.AlreadyVoided]: 'Transfer already voided', + [LiquidityError.AmountZero]: 'Transfer amount is zero', + [LiquidityError.InsufficientBalance]: 'Insufficient transfer balance', + [LiquidityError.InvalidId]: 'Invalid transfer id', + [LiquidityError.TransferExists]: 'Transfer already exists', + [LiquidityError.UnknownAsset]: 'Unknown asset', + [LiquidityError.UnknownIncomingPayment]: 'Unknown incoming payment', + [LiquidityError.UnknownPayment]: 'Unknown transfer payment', + [LiquidityError.UnknownWalletAddress]: 'Unknown wallet address', + [LiquidityError.UnknownPeer]: 'Unknown peer', + [LiquidityError.UnknownTransfer]: 'Unknown transfer' } diff --git a/packages/backend/src/open_payments/payment/outgoing/errors.ts b/packages/backend/src/open_payments/payment/outgoing/errors.ts index ffbee953c8..53b805ac24 100644 --- a/packages/backend/src/open_payments/payment/outgoing/errors.ts +++ b/packages/backend/src/open_payments/payment/outgoing/errors.ts @@ -1,4 +1,8 @@ -import { TransferError } from '../../../accounting/errors' +import { + TransferError, + errorToMessage as transferErrorToMessage, + errorToCode as transferErrorToCode +} from '../../../accounting/errors' import { GraphQLErrorCode } from '../../../graphql/errors' import { PaymentMethodHandlerError } from '../../../payment-method/handler/errors' import { QuoteError } from '../../quote/errors' @@ -56,7 +60,10 @@ export const errorToCode: { [OutgoingPaymentError.WrongState]: GraphQLErrorCode.BadUserInput, [OutgoingPaymentError.InvalidQuote]: GraphQLErrorCode.BadUserInput, [OutgoingPaymentError.InsufficientGrant]: GraphQLErrorCode.Forbidden, - [OutgoingPaymentError.InactiveWalletAddress]: GraphQLErrorCode.Inactive + [OutgoingPaymentError.InactiveWalletAddress]: GraphQLErrorCode.Inactive, + [OutgoingPaymentError.InvalidAmount]: GraphQLErrorCode.BadUserInput, + [OutgoingPaymentError.NegativeReceiveAmount]: GraphQLErrorCode.BadUserInput, + [OutgoingPaymentError.InvalidReceiver]: GraphQLErrorCode.BadUserInput } export const errorToMessage: { @@ -76,6 +83,11 @@ export const errorToMessage: { export const FundingError = { ...OutgoingPaymentError, ...TransferError } export type FundingError = OutgoingPaymentError | TransferError +export const fundingErrorToMessage = { + ...errorToMessage, + ...transferErrorToMessage +} +export const fundingErrorToCode = { ...errorToCode, ...transferErrorToCode } // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types export const isFundingError = (o: any): o is FundingError => diff --git a/packages/backend/src/payment-method/ilp/auto-peering/errors.ts b/packages/backend/src/payment-method/ilp/auto-peering/errors.ts index ce841365fc..8178bcf37e 100644 --- a/packages/backend/src/payment-method/ilp/auto-peering/errors.ts +++ b/packages/backend/src/payment-method/ilp/auto-peering/errors.ts @@ -40,3 +40,15 @@ export const errorToMessage: { [AutoPeeringError.InvalidPeeringRequest]: 'Invalid peering request', [AutoPeeringError.LiquidityError]: 'Could not deposit liquidity to peer' } + +export const errorToHttpCode: { + [key in AutoPeeringError]: number +} = { + [AutoPeeringError.InvalidIlpConfiguration]: 400, + [AutoPeeringError.InvalidPeerIlpConfiguration]: 400, + [AutoPeeringError.UnknownAsset]: 404, + [AutoPeeringError.PeerUnsupportedAsset]: 400, + [AutoPeeringError.InvalidPeerUrl]: 400, + [AutoPeeringError.InvalidPeeringRequest]: 400, + [AutoPeeringError.LiquidityError]: 400 +} diff --git a/packages/backend/src/payment-method/ilp/auto-peering/routes.ts b/packages/backend/src/payment-method/ilp/auto-peering/routes.ts index c6dd9a9fb6..0d40ba5388 100644 --- a/packages/backend/src/payment-method/ilp/auto-peering/routes.ts +++ b/packages/backend/src/payment-method/ilp/auto-peering/routes.ts @@ -1,6 +1,6 @@ import { AppContext } from '../../../app' import { BaseService } from '../../../shared/baseService' -import { errorToCode, errorToMessage, isAutoPeeringError } from './errors' +import { errorToHttpCode, errorToMessage, isAutoPeeringError } from './errors' import { AutoPeeringService } from './service' interface PeeringRequestArgs { @@ -49,7 +49,7 @@ async function acceptPeerRequest( await deps.autoPeeringService.acceptPeeringRequest(ctx.request.body) if (isAutoPeeringError(peeringDetailsOrError)) { - const errorCode = errorToCode[peeringDetailsOrError] + const errorCode = errorToHttpCode[peeringDetailsOrError] ctx.status = errorCode ctx.body = { error: { diff --git a/packages/frontend/app/generated/graphql.ts b/packages/frontend/app/generated/graphql.ts index 4596b7a67b..120c3a8d69 100644 --- a/packages/frontend/app/generated/graphql.ts +++ b/packages/frontend/app/generated/graphql.ts @@ -92,12 +92,9 @@ export type AssetEdge = { node: Asset; }; -export type AssetMutationResponse = MutationResponse & { +export type AssetMutationResponse = { __typename?: 'AssetMutationResponse'; asset?: Maybe; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type AssetsConnection = { @@ -186,12 +183,9 @@ export type CreateOrUpdatePeerByUrlInput = { peerUrl: Scalars['String']['input']; }; -export type CreateOrUpdatePeerByUrlMutationResponse = MutationResponse & { +export type CreateOrUpdatePeerByUrlMutationResponse = { __typename?: 'CreateOrUpdatePeerByUrlMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateOutgoingPaymentFromIncomingPaymentInput = { @@ -259,12 +253,9 @@ export type CreatePeerLiquidityWithdrawalInput = { timeoutSeconds: Scalars['UInt64']['input']; }; -export type CreatePeerMutationResponse = MutationResponse & { +export type CreatePeerMutationResponse = { __typename?: 'CreatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateQuoteInput = { @@ -322,19 +313,13 @@ export type CreateWalletAddressKeyInput = { walletAddressId: Scalars['String']['input']; }; -export type CreateWalletAddressKeyMutationResponse = MutationResponse & { +export type CreateWalletAddressKeyMutationResponse = { __typename?: 'CreateWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; -export type CreateWalletAddressMutationResponse = MutationResponse & { +export type CreateWalletAddressMutationResponse = { __typename?: 'CreateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -360,11 +345,9 @@ export type DeleteAssetInput = { idempotencyKey?: InputMaybe; }; -export type DeleteAssetMutationResponse = MutationResponse & { +export type DeleteAssetMutationResponse = { __typename?: 'DeleteAssetMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + asset?: Maybe; }; export type DeletePeerInput = { @@ -373,10 +356,8 @@ export type DeletePeerInput = { idempotencyKey?: InputMaybe; }; -export type DeletePeerMutationResponse = MutationResponse & { +export type DeletePeerMutationResponse = { __typename?: 'DeletePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; success: Scalars['Boolean']['output']; }; @@ -596,12 +577,10 @@ export enum LiquidityError { UnknownWalletAddress = 'UnknownWalletAddress' } -export type LiquidityMutationResponse = MutationResponse & { +export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + id: Scalars['ID']['output']; + liquidity?: Maybe; }; export type Model = { @@ -836,12 +815,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; -export type MutationResponse = { - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type OutgoingPayment = BasePayment & Model & { __typename?: 'OutgoingPayment'; /** Information about the wallet address of the Open Payments client that created the outgoing payment. */ @@ -1185,11 +1158,8 @@ export type RevokeWalletAddressKeyInput = { idempotencyKey?: InputMaybe; }; -export type RevokeWalletAddressKeyMutationResponse = MutationResponse & { +export type RevokeWalletAddressKeyMutationResponse = { __typename?: 'RevokeWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; @@ -1204,12 +1174,9 @@ export type SetFeeInput = { type: FeeType; }; -export type SetFeeResponse = MutationResponse & { +export type SetFeeResponse = { __typename?: 'SetFeeResponse'; - code: Scalars['String']['output']; fee?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export enum SortOrder { @@ -1219,13 +1186,6 @@ export enum SortOrder { Desc = 'DESC' } -export type TransferMutationResponse = MutationResponse & { - __typename?: 'TransferMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type TriggerWalletAddressEventsInput = { /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey?: InputMaybe; @@ -1233,13 +1193,10 @@ export type TriggerWalletAddressEventsInput = { limit: Scalars['Int']['input']; }; -export type TriggerWalletAddressEventsMutationResponse = MutationResponse & { +export type TriggerWalletAddressEventsMutationResponse = { __typename?: 'TriggerWalletAddressEventsMutationResponse'; - code: Scalars['String']['output']; /** Number of events triggered */ count?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type UpdateAssetInput = { @@ -1270,12 +1227,9 @@ export type UpdatePeerInput = { staticIlpAddress?: InputMaybe; }; -export type UpdatePeerMutationResponse = MutationResponse & { +export type UpdatePeerMutationResponse = { __typename?: 'UpdatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type UpdateWalletAddressInput = { @@ -1291,11 +1245,8 @@ export type UpdateWalletAddressInput = { status?: InputMaybe; }; -export type UpdateWalletAddressMutationResponse = MutationResponse & { +export type UpdateWalletAddressMutationResponse = { __typename?: 'UpdateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -1419,12 +1370,8 @@ export type WalletAddressWithdrawal = { walletAddress: WalletAddress; }; -export type WalletAddressWithdrawalMutationResponse = MutationResponse & { +export type WalletAddressWithdrawalMutationResponse = { __typename?: 'WalletAddressWithdrawalMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; withdrawal?: Maybe; }; @@ -1541,7 +1488,6 @@ export type DirectiveResolverFn> = { BasePayment: ( Partial ) | ( Partial ) | ( Partial ); Model: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); - MutationResponse: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); }; /** Mapping between all available schema types and the resolvers types */ @@ -1614,7 +1560,6 @@ export type ResolversTypes = { LiquidityMutationResponse: ResolverTypeWrapper>; Model: ResolverTypeWrapper['Model']>; Mutation: ResolverTypeWrapper<{}>; - MutationResponse: ResolverTypeWrapper['MutationResponse']>; OutgoingPayment: ResolverTypeWrapper>; OutgoingPaymentConnection: ResolverTypeWrapper>; OutgoingPaymentEdge: ResolverTypeWrapper>; @@ -1642,7 +1587,6 @@ export type ResolversTypes = { SetFeeResponse: ResolverTypeWrapper>; SortOrder: ResolverTypeWrapper>; String: ResolverTypeWrapper>; - TransferMutationResponse: ResolverTypeWrapper>; TriggerWalletAddressEventsInput: ResolverTypeWrapper>; TriggerWalletAddressEventsMutationResponse: ResolverTypeWrapper>; UInt8: ResolverTypeWrapper>; @@ -1733,7 +1677,6 @@ export type ResolversParentTypes = { LiquidityMutationResponse: Partial; Model: ResolversInterfaceTypes['Model']; Mutation: {}; - MutationResponse: ResolversInterfaceTypes['MutationResponse']; OutgoingPayment: Partial; OutgoingPaymentConnection: Partial; OutgoingPaymentEdge: Partial; @@ -1758,7 +1701,6 @@ export type ResolversParentTypes = { SetFeeInput: Partial; SetFeeResponse: Partial; String: Partial; - TransferMutationResponse: Partial; TriggerWalletAddressEventsInput: Partial; TriggerWalletAddressEventsMutationResponse: Partial; UInt8: Partial; @@ -1820,9 +1762,6 @@ export type AssetEdgeResolvers = { asset?: Resolver, ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1842,18 +1781,12 @@ export type BasePaymentResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1866,31 +1799,21 @@ export type CreateReceiverResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type CreateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeleteAssetMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; + asset?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeletePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1976,10 +1899,8 @@ export type JwkResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; + id?: Resolver; + liquidity?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2023,13 +1944,6 @@ export type MutationResolvers, ParentType, ContextType, RequireFields>; }; -export type MutationResponseResolvers = { - __resolveType: TypeResolveFn<'AssetMutationResponse' | 'CreateOrUpdatePeerByUrlMutationResponse' | 'CreatePeerMutationResponse' | 'CreateWalletAddressKeyMutationResponse' | 'CreateWalletAddressMutationResponse' | 'DeleteAssetMutationResponse' | 'DeletePeerMutationResponse' | 'LiquidityMutationResponse' | 'RevokeWalletAddressKeyMutationResponse' | 'SetFeeResponse' | 'TransferMutationResponse' | 'TriggerWalletAddressEventsMutationResponse' | 'UpdatePeerMutationResponse' | 'UpdateWalletAddressMutationResponse' | 'WalletAddressWithdrawalMutationResponse', ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; -}; - export type OutgoingPaymentResolvers = { client?: Resolver, ParentType, ContextType>; createdAt?: Resolver; @@ -2189,33 +2103,17 @@ export type ReceiverResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type SetFeeResponseResolvers = { - code?: Resolver; fee?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}; - -export type TransferMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type TriggerWalletAddressEventsMutationResponseResolvers = { - code?: Resolver; count?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2228,17 +2126,11 @@ export interface UInt64ScalarConfig extends GraphQLScalarTypeConfig = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type UpdateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2294,10 +2186,6 @@ export type WalletAddressWithdrawalResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; withdrawal?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2357,7 +2245,6 @@ export type Resolvers = { LiquidityMutationResponse?: LiquidityMutationResponseResolvers; Model?: ModelResolvers; Mutation?: MutationResolvers; - MutationResponse?: MutationResponseResolvers; OutgoingPayment?: OutgoingPaymentResolvers; OutgoingPaymentConnection?: OutgoingPaymentConnectionResolvers; OutgoingPaymentEdge?: OutgoingPaymentEdgeResolvers; @@ -2377,7 +2264,6 @@ export type Resolvers = { Receiver?: ReceiverResolvers; RevokeWalletAddressKeyMutationResponse?: RevokeWalletAddressKeyMutationResponseResolvers; SetFeeResponse?: SetFeeResponseResolvers; - TransferMutationResponse?: TransferMutationResponseResolvers; TriggerWalletAddressEventsMutationResponse?: TriggerWalletAddressEventsMutationResponseResolvers; UInt8?: GraphQLScalarType; UInt64?: GraphQLScalarType; @@ -2430,42 +2316,42 @@ export type CreateAssetMutationVariables = Exact<{ }>; -export type CreateAssetMutation = { __typename?: 'Mutation', createAsset: { __typename?: 'AssetMutationResponse', code: string, success: boolean, message: string, asset?: { __typename?: 'Asset', id: string } | null } }; +export type CreateAssetMutation = { __typename?: 'Mutation', createAsset: { __typename?: 'AssetMutationResponse', asset?: { __typename?: 'Asset', id: string, code: string, scale: number, withdrawalThreshold?: bigint | null, liquidity?: bigint | null, createdAt: string, sendingFee?: { __typename?: 'Fee', basisPoints: number, fixed: bigint, createdAt: string } | null } | null } }; export type UpdateAssetMutationVariables = Exact<{ input: UpdateAssetInput; }>; -export type UpdateAssetMutation = { __typename?: 'Mutation', updateAsset: { __typename?: 'AssetMutationResponse', code: string, success: boolean, message: string } }; +export type UpdateAssetMutation = { __typename?: 'Mutation', updateAsset: { __typename?: 'AssetMutationResponse', asset?: { __typename?: 'Asset', id: string, code: string, scale: number, withdrawalThreshold?: bigint | null, liquidity?: bigint | null, createdAt: string, sendingFee?: { __typename?: 'Fee', basisPoints: number, fixed: bigint, createdAt: string } | null } | null } }; export type SetFeeMutationVariables = Exact<{ input: SetFeeInput; }>; -export type SetFeeMutation = { __typename?: 'Mutation', setFee: { __typename?: 'SetFeeResponse', code: string, message: string, success: boolean, fee?: { __typename?: 'Fee', assetId: string, basisPoints: number, createdAt: string, fixed: bigint, id: string, type: FeeType } | null } }; +export type SetFeeMutation = { __typename?: 'Mutation', setFee: { __typename?: 'SetFeeResponse', fee?: { __typename?: 'Fee', assetId: string, basisPoints: number, createdAt: string, fixed: bigint, id: string, type: FeeType } | null } }; export type DepositAssetLiquidityMutationVariables = Exact<{ input: DepositAssetLiquidityInput; }>; -export type DepositAssetLiquidityMutation = { __typename?: 'Mutation', depositAssetLiquidity?: { __typename?: 'LiquidityMutationResponse', code: string, success: boolean, message: string, error?: LiquidityError | null } | null }; +export type DepositAssetLiquidityMutation = { __typename?: 'Mutation', depositAssetLiquidity?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; export type WithdrawAssetLiquidityVariables = Exact<{ input: CreateAssetLiquidityWithdrawalInput; }>; -export type WithdrawAssetLiquidity = { __typename?: 'Mutation', createAssetLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', code: string, success: boolean, message: string, error?: LiquidityError | null } | null }; +export type WithdrawAssetLiquidity = { __typename?: 'Mutation', createAssetLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; export type DeleteAssetMutationVariables = Exact<{ input: DeleteAssetInput; }>; -export type DeleteAssetMutation = { __typename?: 'Mutation', deleteAsset: { __typename?: 'DeleteAssetMutationResponse', code: string, success: boolean, message: string } }; +export type DeleteAssetMutation = { __typename?: 'Mutation', deleteAsset: { __typename?: 'DeleteAssetMutationResponse', asset?: { __typename?: 'Asset', id: string, code: string, scale: number, withdrawalThreshold?: bigint | null, liquidity?: bigint | null, createdAt: string, sendingFee?: { __typename?: 'Fee', basisPoints: number, fixed: bigint, createdAt: string } | null } | null } }; export type GetIncomingPaymentVariables = Exact<{ id: Scalars['String']['input']; @@ -2497,21 +2383,21 @@ export type DepositOutgoingPaymentLiquidityVariables = Exact<{ }>; -export type DepositOutgoingPaymentLiquidity = { __typename?: 'Mutation', depositOutgoingPaymentLiquidity?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; +export type DepositOutgoingPaymentLiquidity = { __typename?: 'Mutation', depositOutgoingPaymentLiquidity?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; export type CreateOutgoingPaymentWithdrawalVariables = Exact<{ input: CreateOutgoingPaymentWithdrawalInput; }>; -export type CreateOutgoingPaymentWithdrawal = { __typename?: 'Mutation', createOutgoingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; +export type CreateOutgoingPaymentWithdrawal = { __typename?: 'Mutation', createOutgoingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; export type CreateIncomingPaymentWithdrawalVariables = Exact<{ input: CreateIncomingPaymentWithdrawalInput; }>; -export type CreateIncomingPaymentWithdrawal = { __typename?: 'Mutation', createIncomingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; +export type CreateIncomingPaymentWithdrawal = { __typename?: 'Mutation', createIncomingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; export type GetPeerQueryVariables = Exact<{ id: Scalars['String']['input']; @@ -2535,35 +2421,35 @@ export type CreatePeerMutationVariables = Exact<{ }>; -export type CreatePeerMutation = { __typename?: 'Mutation', createPeer: { __typename?: 'CreatePeerMutationResponse', code: string, success: boolean, message: string, peer?: { __typename?: 'Peer', id: string } | null } }; +export type CreatePeerMutation = { __typename?: 'Mutation', createPeer: { __typename?: 'CreatePeerMutationResponse', peer?: { __typename?: 'Peer', id: string } | null } }; export type UpdatePeerMutationVariables = Exact<{ input: UpdatePeerInput; }>; -export type UpdatePeerMutation = { __typename?: 'Mutation', updatePeer: { __typename?: 'UpdatePeerMutationResponse', code: string, success: boolean, message: string } }; +export type UpdatePeerMutation = { __typename?: 'Mutation', updatePeer: { __typename?: 'UpdatePeerMutationResponse', peer?: { __typename?: 'Peer', id: string } | null } }; export type DeletePeerMutationVariables = Exact<{ input: DeletePeerInput; }>; -export type DeletePeerMutation = { __typename?: 'Mutation', deletePeer: { __typename?: 'DeletePeerMutationResponse', code: string, success: boolean, message: string } }; +export type DeletePeerMutation = { __typename?: 'Mutation', deletePeer: { __typename?: 'DeletePeerMutationResponse', success: boolean } }; export type DepositPeerLiquidityMutationVariables = Exact<{ input: DepositPeerLiquidityInput; }>; -export type DepositPeerLiquidityMutation = { __typename?: 'Mutation', depositPeerLiquidity?: { __typename?: 'LiquidityMutationResponse', code: string, success: boolean, message: string, error?: LiquidityError | null } | null }; +export type DepositPeerLiquidityMutation = { __typename?: 'Mutation', depositPeerLiquidity?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; export type WithdrawPeerLiquidityVariables = Exact<{ input: CreatePeerLiquidityWithdrawalInput; }>; -export type WithdrawPeerLiquidity = { __typename?: 'Mutation', createPeerLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', code: string, success: boolean, message: string, error?: LiquidityError | null } | null }; +export type WithdrawPeerLiquidity = { __typename?: 'Mutation', createPeerLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; export type GetWalletAddressQueryVariables = Exact<{ id: Scalars['String']['input']; @@ -2587,21 +2473,21 @@ export type UpdateWalletAddressMutationVariables = Exact<{ }>; -export type UpdateWalletAddressMutation = { __typename?: 'Mutation', updateWalletAddress: { __typename?: 'UpdateWalletAddressMutationResponse', code: string, message: string, success: boolean } }; +export type UpdateWalletAddressMutation = { __typename?: 'Mutation', updateWalletAddress: { __typename?: 'UpdateWalletAddressMutationResponse', walletAddress?: { __typename?: 'WalletAddress', id: string } | null } }; export type CreateWalletAddressMutationVariables = Exact<{ input: CreateWalletAddressInput; }>; -export type CreateWalletAddressMutation = { __typename?: 'Mutation', createWalletAddress: { __typename?: 'CreateWalletAddressMutationResponse', code: string, success: boolean, message: string, walletAddress?: { __typename?: 'WalletAddress', id: string } | null } }; +export type CreateWalletAddressMutation = { __typename?: 'Mutation', createWalletAddress: { __typename?: 'CreateWalletAddressMutationResponse', walletAddress?: { __typename?: 'WalletAddress', id: string } | null } }; export type CreateWalletAddressWithdrawalVariables = Exact<{ input: CreateWalletAddressWithdrawalInput; }>; -export type CreateWalletAddressWithdrawal = { __typename?: 'Mutation', createWalletAddressWithdrawal?: { __typename?: 'WalletAddressWithdrawalMutationResponse', success: boolean, message: string } | null }; +export type CreateWalletAddressWithdrawal = { __typename?: 'Mutation', createWalletAddressWithdrawal?: { __typename?: 'WalletAddressWithdrawalMutationResponse', withdrawal?: { __typename?: 'WalletAddressWithdrawal', id: string } | null } | null }; export type ListWebhookEventsVariables = Exact<{ after?: InputMaybe; diff --git a/packages/frontend/app/lib/api/asset.server.ts b/packages/frontend/app/lib/api/asset.server.ts index 8140e098aa..abfca22651 100644 --- a/packages/frontend/app/lib/api/asset.server.ts +++ b/packages/frontend/app/lib/api/asset.server.ts @@ -142,11 +142,18 @@ export const createAsset = async (args: CreateAssetInput) => { mutation: gql` mutation CreateAssetMutation($input: CreateAssetInput!) { createAsset(input: $input) { - code - success - message asset { id + code + scale + withdrawalThreshold + liquidity + sendingFee { + basisPoints + fixed + createdAt + } + createdAt } } } @@ -167,9 +174,19 @@ export const updateAsset = async (args: UpdateAssetInput) => { mutation: gql` mutation UpdateAssetMutation($input: UpdateAssetInput!) { updateAsset(input: $input) { - code - success - message + asset { + id + code + scale + withdrawalThreshold + liquidity + sendingFee { + basisPoints + fixed + createdAt + } + createdAt + } } } `, @@ -189,7 +206,6 @@ export const setFee = async (args: SetFeeInput) => { mutation: gql` mutation SetFeeMutation($input: SetFeeInput!) { setFee(input: $input) { - code fee { assetId basisPoints @@ -198,8 +214,6 @@ export const setFee = async (args: SetFeeInput) => { id type } - message - success } } `, @@ -223,10 +237,8 @@ export const depositAssetLiquidity = async ( $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -250,10 +262,8 @@ export const withdrawAssetLiquidity = async ( $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -292,9 +302,19 @@ export const deleteAsset = async (args: DeleteAssetInput) => { mutation: gql` mutation DeleteAssetMutation($input: DeleteAssetInput!) { deleteAsset(input: $input) { - code - success - message + asset { + id + code + scale + withdrawalThreshold + liquidity + sendingFee { + basisPoints + fixed + createdAt + } + createdAt + } } } `, diff --git a/packages/frontend/app/lib/api/payments.server.ts b/packages/frontend/app/lib/api/payments.server.ts index 11540e527e..ff655b0d17 100644 --- a/packages/frontend/app/lib/api/payments.server.ts +++ b/packages/frontend/app/lib/api/payments.server.ts @@ -151,8 +151,8 @@ export const depositOutgoingPaymentLiquidity = async ( $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - success - message + id + liquidity } } `, @@ -176,8 +176,8 @@ export const createOutgoingPaymentWithdrawal = async ( $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - success - message + id + liquidity } } `, @@ -201,8 +201,8 @@ export const createIncomingPaymentWithdrawal = async ( $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - success - message + id + liquidity } } `, diff --git a/packages/frontend/app/lib/api/peer.server.ts b/packages/frontend/app/lib/api/peer.server.ts index 990b58290f..a92c491631 100644 --- a/packages/frontend/app/lib/api/peer.server.ts +++ b/packages/frontend/app/lib/api/peer.server.ts @@ -111,9 +111,6 @@ export const createPeer = async (args: CreatePeerInput) => { mutation: gql` mutation CreatePeerMutation($input: CreatePeerInput!) { createPeer(input: $input) { - code - success - message peer { id } @@ -136,9 +133,9 @@ export const updatePeer = async (args: UpdatePeerInput) => { mutation: gql` mutation UpdatePeerMutation($input: UpdatePeerInput!) { updatePeer(input: $input) { - code - success - message + peer { + id + } } } `, @@ -158,9 +155,7 @@ export const deletePeer = async (args: MutationDeletePeerArgs) => { mutation: gql` mutation DeletePeerMutation($input: DeletePeerInput!) { deletePeer(input: $input) { - code success - message } } `, @@ -180,10 +175,8 @@ export const depositPeerLiquidity = async (args: DepositPeerLiquidityInput) => { $input: DepositPeerLiquidityInput! ) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -207,10 +200,8 @@ export const withdrawPeerLiquidity = async ( $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } `, diff --git a/packages/frontend/app/lib/api/wallet-address.server.ts b/packages/frontend/app/lib/api/wallet-address.server.ts index 50e6dca4a0..bf3e680ca4 100644 --- a/packages/frontend/app/lib/api/wallet-address.server.ts +++ b/packages/frontend/app/lib/api/wallet-address.server.ts @@ -92,9 +92,9 @@ export const updateWalletAddress = async (args: UpdateWalletAddressInput) => { mutation: gql` mutation UpdateWalletAddressMutation($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - message - success + walletAddress { + id + } } } `, @@ -114,9 +114,6 @@ export const createWalletAddress = async (args: CreateWalletAddressInput) => { mutation: gql` mutation CreateWalletAddressMutation($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id } @@ -143,8 +140,9 @@ export const createWalletAddressWithdrawal = async ( $input: CreateWalletAddressWithdrawalInput! ) { createWalletAddressWithdrawal(input: $input) { - success - message + withdrawal { + id + } } } `, diff --git a/packages/mock-account-service-lib/src/generated/graphql.ts b/packages/mock-account-service-lib/src/generated/graphql.ts index af780bc3ad..1ed9179897 100644 --- a/packages/mock-account-service-lib/src/generated/graphql.ts +++ b/packages/mock-account-service-lib/src/generated/graphql.ts @@ -92,12 +92,9 @@ export type AssetEdge = { node: Asset; }; -export type AssetMutationResponse = MutationResponse & { +export type AssetMutationResponse = { __typename?: 'AssetMutationResponse'; asset?: Maybe; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type AssetsConnection = { @@ -186,12 +183,9 @@ export type CreateOrUpdatePeerByUrlInput = { peerUrl: Scalars['String']['input']; }; -export type CreateOrUpdatePeerByUrlMutationResponse = MutationResponse & { +export type CreateOrUpdatePeerByUrlMutationResponse = { __typename?: 'CreateOrUpdatePeerByUrlMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateOutgoingPaymentFromIncomingPaymentInput = { @@ -259,12 +253,9 @@ export type CreatePeerLiquidityWithdrawalInput = { timeoutSeconds: Scalars['UInt64']['input']; }; -export type CreatePeerMutationResponse = MutationResponse & { +export type CreatePeerMutationResponse = { __typename?: 'CreatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateQuoteInput = { @@ -322,19 +313,13 @@ export type CreateWalletAddressKeyInput = { walletAddressId: Scalars['String']['input']; }; -export type CreateWalletAddressKeyMutationResponse = MutationResponse & { +export type CreateWalletAddressKeyMutationResponse = { __typename?: 'CreateWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; -export type CreateWalletAddressMutationResponse = MutationResponse & { +export type CreateWalletAddressMutationResponse = { __typename?: 'CreateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -360,11 +345,9 @@ export type DeleteAssetInput = { idempotencyKey?: InputMaybe; }; -export type DeleteAssetMutationResponse = MutationResponse & { +export type DeleteAssetMutationResponse = { __typename?: 'DeleteAssetMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + asset?: Maybe; }; export type DeletePeerInput = { @@ -373,10 +356,8 @@ export type DeletePeerInput = { idempotencyKey?: InputMaybe; }; -export type DeletePeerMutationResponse = MutationResponse & { +export type DeletePeerMutationResponse = { __typename?: 'DeletePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; success: Scalars['Boolean']['output']; }; @@ -596,12 +577,10 @@ export enum LiquidityError { UnknownWalletAddress = 'UnknownWalletAddress' } -export type LiquidityMutationResponse = MutationResponse & { +export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + id: Scalars['ID']['output']; + liquidity?: Maybe; }; export type Model = { @@ -836,12 +815,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; -export type MutationResponse = { - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type OutgoingPayment = BasePayment & Model & { __typename?: 'OutgoingPayment'; /** Information about the wallet address of the Open Payments client that created the outgoing payment. */ @@ -1185,11 +1158,8 @@ export type RevokeWalletAddressKeyInput = { idempotencyKey?: InputMaybe; }; -export type RevokeWalletAddressKeyMutationResponse = MutationResponse & { +export type RevokeWalletAddressKeyMutationResponse = { __typename?: 'RevokeWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; @@ -1204,12 +1174,9 @@ export type SetFeeInput = { type: FeeType; }; -export type SetFeeResponse = MutationResponse & { +export type SetFeeResponse = { __typename?: 'SetFeeResponse'; - code: Scalars['String']['output']; fee?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export enum SortOrder { @@ -1219,13 +1186,6 @@ export enum SortOrder { Desc = 'DESC' } -export type TransferMutationResponse = MutationResponse & { - __typename?: 'TransferMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type TriggerWalletAddressEventsInput = { /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey?: InputMaybe; @@ -1233,13 +1193,10 @@ export type TriggerWalletAddressEventsInput = { limit: Scalars['Int']['input']; }; -export type TriggerWalletAddressEventsMutationResponse = MutationResponse & { +export type TriggerWalletAddressEventsMutationResponse = { __typename?: 'TriggerWalletAddressEventsMutationResponse'; - code: Scalars['String']['output']; /** Number of events triggered */ count?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type UpdateAssetInput = { @@ -1270,12 +1227,9 @@ export type UpdatePeerInput = { staticIlpAddress?: InputMaybe; }; -export type UpdatePeerMutationResponse = MutationResponse & { +export type UpdatePeerMutationResponse = { __typename?: 'UpdatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type UpdateWalletAddressInput = { @@ -1291,11 +1245,8 @@ export type UpdateWalletAddressInput = { status?: InputMaybe; }; -export type UpdateWalletAddressMutationResponse = MutationResponse & { +export type UpdateWalletAddressMutationResponse = { __typename?: 'UpdateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -1419,12 +1370,8 @@ export type WalletAddressWithdrawal = { walletAddress: WalletAddress; }; -export type WalletAddressWithdrawalMutationResponse = MutationResponse & { +export type WalletAddressWithdrawalMutationResponse = { __typename?: 'WalletAddressWithdrawalMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; withdrawal?: Maybe; }; @@ -1541,7 +1488,6 @@ export type DirectiveResolverFn> = { BasePayment: ( Partial ) | ( Partial ) | ( Partial ); Model: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); - MutationResponse: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); }; /** Mapping between all available schema types and the resolvers types */ @@ -1614,7 +1560,6 @@ export type ResolversTypes = { LiquidityMutationResponse: ResolverTypeWrapper>; Model: ResolverTypeWrapper['Model']>; Mutation: ResolverTypeWrapper<{}>; - MutationResponse: ResolverTypeWrapper['MutationResponse']>; OutgoingPayment: ResolverTypeWrapper>; OutgoingPaymentConnection: ResolverTypeWrapper>; OutgoingPaymentEdge: ResolverTypeWrapper>; @@ -1642,7 +1587,6 @@ export type ResolversTypes = { SetFeeResponse: ResolverTypeWrapper>; SortOrder: ResolverTypeWrapper>; String: ResolverTypeWrapper>; - TransferMutationResponse: ResolverTypeWrapper>; TriggerWalletAddressEventsInput: ResolverTypeWrapper>; TriggerWalletAddressEventsMutationResponse: ResolverTypeWrapper>; UInt8: ResolverTypeWrapper>; @@ -1733,7 +1677,6 @@ export type ResolversParentTypes = { LiquidityMutationResponse: Partial; Model: ResolversInterfaceTypes['Model']; Mutation: {}; - MutationResponse: ResolversInterfaceTypes['MutationResponse']; OutgoingPayment: Partial; OutgoingPaymentConnection: Partial; OutgoingPaymentEdge: Partial; @@ -1758,7 +1701,6 @@ export type ResolversParentTypes = { SetFeeInput: Partial; SetFeeResponse: Partial; String: Partial; - TransferMutationResponse: Partial; TriggerWalletAddressEventsInput: Partial; TriggerWalletAddressEventsMutationResponse: Partial; UInt8: Partial; @@ -1820,9 +1762,6 @@ export type AssetEdgeResolvers = { asset?: Resolver, ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1842,18 +1781,12 @@ export type BasePaymentResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1866,31 +1799,21 @@ export type CreateReceiverResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type CreateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeleteAssetMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; + asset?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeletePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1976,10 +1899,8 @@ export type JwkResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; + id?: Resolver; + liquidity?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2023,13 +1944,6 @@ export type MutationResolvers, ParentType, ContextType, RequireFields>; }; -export type MutationResponseResolvers = { - __resolveType: TypeResolveFn<'AssetMutationResponse' | 'CreateOrUpdatePeerByUrlMutationResponse' | 'CreatePeerMutationResponse' | 'CreateWalletAddressKeyMutationResponse' | 'CreateWalletAddressMutationResponse' | 'DeleteAssetMutationResponse' | 'DeletePeerMutationResponse' | 'LiquidityMutationResponse' | 'RevokeWalletAddressKeyMutationResponse' | 'SetFeeResponse' | 'TransferMutationResponse' | 'TriggerWalletAddressEventsMutationResponse' | 'UpdatePeerMutationResponse' | 'UpdateWalletAddressMutationResponse' | 'WalletAddressWithdrawalMutationResponse', ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; -}; - export type OutgoingPaymentResolvers = { client?: Resolver, ParentType, ContextType>; createdAt?: Resolver; @@ -2189,33 +2103,17 @@ export type ReceiverResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type SetFeeResponseResolvers = { - code?: Resolver; fee?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}; - -export type TransferMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type TriggerWalletAddressEventsMutationResponseResolvers = { - code?: Resolver; count?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2228,17 +2126,11 @@ export interface UInt64ScalarConfig extends GraphQLScalarTypeConfig = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type UpdateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2294,10 +2186,6 @@ export type WalletAddressWithdrawalResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; withdrawal?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2357,7 +2245,6 @@ export type Resolvers = { LiquidityMutationResponse?: LiquidityMutationResponseResolvers; Model?: ModelResolvers; Mutation?: MutationResolvers; - MutationResponse?: MutationResponseResolvers; OutgoingPayment?: OutgoingPaymentResolvers; OutgoingPaymentConnection?: OutgoingPaymentConnectionResolvers; OutgoingPaymentEdge?: OutgoingPaymentEdgeResolvers; @@ -2377,7 +2264,6 @@ export type Resolvers = { Receiver?: ReceiverResolvers; RevokeWalletAddressKeyMutationResponse?: RevokeWalletAddressKeyMutationResponseResolvers; SetFeeResponse?: SetFeeResponseResolvers; - TransferMutationResponse?: TransferMutationResponseResolvers; TriggerWalletAddressEventsMutationResponse?: TriggerWalletAddressEventsMutationResponseResolvers; UInt8?: GraphQLScalarType; UInt64?: GraphQLScalarType; diff --git a/packages/mock-account-service-lib/src/requesters.ts b/packages/mock-account-service-lib/src/requesters.ts index 515c196073..fdf89971d4 100644 --- a/packages/mock-account-service-lib/src/requesters.ts +++ b/packages/mock-account-service-lib/src/requesters.ts @@ -117,9 +117,6 @@ export async function createAsset( const createAssetMutation = gql` mutation CreateAsset($input: CreateAssetInput!) { createAsset(input: $input) { - code - success - message asset { id code @@ -142,7 +139,7 @@ export async function createAsset( variables: createAssetInput }) .then(({ data }): AssetMutationResponse => { - if (!data.createAsset.success) { + if (!data.createAsset.asset) { throw new Error('Data was empty') } return data.createAsset @@ -162,9 +159,6 @@ export async function createPeer( const createPeerMutation = gql` mutation CreatePeer($input: CreatePeerInput!) { createPeer(input: $input) { - code - success - message peer { id } @@ -190,7 +184,7 @@ export async function createPeer( }) .then(({ data }): CreatePeerMutationResponse => { logger.debug(data) - if (!data.createPeer.success) { + if (!data.createPeer.peer) { throw new Error('Data was empty') } return data.createPeer @@ -206,9 +200,6 @@ export async function createAutoPeer( const createAutoPeerMutation = gql` mutation CreateOrUpdatePeerByUrl($input: CreateOrUpdatePeerByUrlInput!) { createOrUpdatePeerByUrl(input: $input) { - code - success - message peer { id name @@ -237,7 +228,7 @@ export async function createAutoPeer( variables: createPeerInput }) .then(({ data }): CreateOrUpdatePeerByUrlMutationResponse => { - if (!data.createOrUpdatePeerByUrl.success) { + if (!data.createOrUpdatePeerByUrl.peer) { logger.debug(data.createOrUpdatePeerByUrl) throw new Error(`Data was empty for assetId: ${assetId}`) } @@ -255,10 +246,8 @@ export async function depositPeerLiquidity( const depositPeerLiquidityMutation = gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } ` @@ -277,7 +266,7 @@ export async function depositPeerLiquidity( }) .then(({ data }): LiquidityMutationResponse => { logger.debug(data) - if (!data.depositPeerLiquidity.success) { + if (!data.depositPeerLiquidity) { throw new Error('Data was empty') } return data.depositPeerLiquidity @@ -294,10 +283,8 @@ export async function depositAssetLiquidity( const depositAssetLiquidityMutation = gql` mutation DepositAssetLiquidity($input: DepositAssetLiquidityInput!) { depositAssetLiquidity(input: $input) { - code - success - message - error + id + liquidity } } ` @@ -316,7 +303,7 @@ export async function depositAssetLiquidity( }) .then(({ data }): LiquidityMutationResponse => { logger.debug(data) - if (!data.depositAssetLiquidity.success) { + if (!data.depositAssetLiquidity) { throw new Error('Data was empty') } return data.depositAssetLiquidity @@ -333,9 +320,6 @@ export async function createWalletAddress( const createWalletAddressMutation = gql` mutation CreateWalletAddress($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id url @@ -361,10 +345,7 @@ export async function createWalletAddress( .then(({ data }) => { logger.debug(data) - if ( - !data.createWalletAddress.success || - !data.createWalletAddress.walletAddress - ) { + if (!data.createWalletAddress.walletAddress) { throw new Error('Data was empty') } @@ -386,9 +367,9 @@ export async function createWalletAddressKey( const createWalletAddressKeyMutation = gql` mutation CreateWalletAddressKey($input: CreateWalletAddressKeyInput!) { createWalletAddressKey(input: $input) { - code - success - message + walletAddressKey { + id + } } } ` @@ -406,7 +387,7 @@ export async function createWalletAddressKey( }) .then(({ data }): CreateWalletAddressKeyMutationResponse => { logger.debug(data) - if (!data.createWalletAddressKey.success) { + if (!data.createWalletAddressKey.walletAddressKey) { throw new Error('Data was empty') } return data.createWalletAddressKey @@ -424,9 +405,6 @@ export async function setFee( const setFeeMutation = gql` mutation SetFee($input: SetFeeInput!) { setFee(input: $input) { - code - success - message fee { id assetId diff --git a/test/integration/lib/generated/graphql.ts b/test/integration/lib/generated/graphql.ts index af780bc3ad..1ed9179897 100644 --- a/test/integration/lib/generated/graphql.ts +++ b/test/integration/lib/generated/graphql.ts @@ -92,12 +92,9 @@ export type AssetEdge = { node: Asset; }; -export type AssetMutationResponse = MutationResponse & { +export type AssetMutationResponse = { __typename?: 'AssetMutationResponse'; asset?: Maybe; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type AssetsConnection = { @@ -186,12 +183,9 @@ export type CreateOrUpdatePeerByUrlInput = { peerUrl: Scalars['String']['input']; }; -export type CreateOrUpdatePeerByUrlMutationResponse = MutationResponse & { +export type CreateOrUpdatePeerByUrlMutationResponse = { __typename?: 'CreateOrUpdatePeerByUrlMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateOutgoingPaymentFromIncomingPaymentInput = { @@ -259,12 +253,9 @@ export type CreatePeerLiquidityWithdrawalInput = { timeoutSeconds: Scalars['UInt64']['input']; }; -export type CreatePeerMutationResponse = MutationResponse & { +export type CreatePeerMutationResponse = { __typename?: 'CreatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateQuoteInput = { @@ -322,19 +313,13 @@ export type CreateWalletAddressKeyInput = { walletAddressId: Scalars['String']['input']; }; -export type CreateWalletAddressKeyMutationResponse = MutationResponse & { +export type CreateWalletAddressKeyMutationResponse = { __typename?: 'CreateWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; -export type CreateWalletAddressMutationResponse = MutationResponse & { +export type CreateWalletAddressMutationResponse = { __typename?: 'CreateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -360,11 +345,9 @@ export type DeleteAssetInput = { idempotencyKey?: InputMaybe; }; -export type DeleteAssetMutationResponse = MutationResponse & { +export type DeleteAssetMutationResponse = { __typename?: 'DeleteAssetMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + asset?: Maybe; }; export type DeletePeerInput = { @@ -373,10 +356,8 @@ export type DeletePeerInput = { idempotencyKey?: InputMaybe; }; -export type DeletePeerMutationResponse = MutationResponse & { +export type DeletePeerMutationResponse = { __typename?: 'DeletePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; success: Scalars['Boolean']['output']; }; @@ -596,12 +577,10 @@ export enum LiquidityError { UnknownWalletAddress = 'UnknownWalletAddress' } -export type LiquidityMutationResponse = MutationResponse & { +export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; + id: Scalars['ID']['output']; + liquidity?: Maybe; }; export type Model = { @@ -836,12 +815,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; -export type MutationResponse = { - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type OutgoingPayment = BasePayment & Model & { __typename?: 'OutgoingPayment'; /** Information about the wallet address of the Open Payments client that created the outgoing payment. */ @@ -1185,11 +1158,8 @@ export type RevokeWalletAddressKeyInput = { idempotencyKey?: InputMaybe; }; -export type RevokeWalletAddressKeyMutationResponse = MutationResponse & { +export type RevokeWalletAddressKeyMutationResponse = { __typename?: 'RevokeWalletAddressKeyMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddressKey?: Maybe; }; @@ -1204,12 +1174,9 @@ export type SetFeeInput = { type: FeeType; }; -export type SetFeeResponse = MutationResponse & { +export type SetFeeResponse = { __typename?: 'SetFeeResponse'; - code: Scalars['String']['output']; fee?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export enum SortOrder { @@ -1219,13 +1186,6 @@ export enum SortOrder { Desc = 'DESC' } -export type TransferMutationResponse = MutationResponse & { - __typename?: 'TransferMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; -}; - export type TriggerWalletAddressEventsInput = { /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey?: InputMaybe; @@ -1233,13 +1193,10 @@ export type TriggerWalletAddressEventsInput = { limit: Scalars['Int']['input']; }; -export type TriggerWalletAddressEventsMutationResponse = MutationResponse & { +export type TriggerWalletAddressEventsMutationResponse = { __typename?: 'TriggerWalletAddressEventsMutationResponse'; - code: Scalars['String']['output']; /** Number of events triggered */ count?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; }; export type UpdateAssetInput = { @@ -1270,12 +1227,9 @@ export type UpdatePeerInput = { staticIlpAddress?: InputMaybe; }; -export type UpdatePeerMutationResponse = MutationResponse & { +export type UpdatePeerMutationResponse = { __typename?: 'UpdatePeerMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; peer?: Maybe; - success: Scalars['Boolean']['output']; }; export type UpdateWalletAddressInput = { @@ -1291,11 +1245,8 @@ export type UpdateWalletAddressInput = { status?: InputMaybe; }; -export type UpdateWalletAddressMutationResponse = MutationResponse & { +export type UpdateWalletAddressMutationResponse = { __typename?: 'UpdateWalletAddressMutationResponse'; - code: Scalars['String']['output']; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; walletAddress?: Maybe; }; @@ -1419,12 +1370,8 @@ export type WalletAddressWithdrawal = { walletAddress: WalletAddress; }; -export type WalletAddressWithdrawalMutationResponse = MutationResponse & { +export type WalletAddressWithdrawalMutationResponse = { __typename?: 'WalletAddressWithdrawalMutationResponse'; - code: Scalars['String']['output']; - error?: Maybe; - message: Scalars['String']['output']; - success: Scalars['Boolean']['output']; withdrawal?: Maybe; }; @@ -1541,7 +1488,6 @@ export type DirectiveResolverFn> = { BasePayment: ( Partial ) | ( Partial ) | ( Partial ); Model: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); - MutationResponse: ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ) | ( Partial ); }; /** Mapping between all available schema types and the resolvers types */ @@ -1614,7 +1560,6 @@ export type ResolversTypes = { LiquidityMutationResponse: ResolverTypeWrapper>; Model: ResolverTypeWrapper['Model']>; Mutation: ResolverTypeWrapper<{}>; - MutationResponse: ResolverTypeWrapper['MutationResponse']>; OutgoingPayment: ResolverTypeWrapper>; OutgoingPaymentConnection: ResolverTypeWrapper>; OutgoingPaymentEdge: ResolverTypeWrapper>; @@ -1642,7 +1587,6 @@ export type ResolversTypes = { SetFeeResponse: ResolverTypeWrapper>; SortOrder: ResolverTypeWrapper>; String: ResolverTypeWrapper>; - TransferMutationResponse: ResolverTypeWrapper>; TriggerWalletAddressEventsInput: ResolverTypeWrapper>; TriggerWalletAddressEventsMutationResponse: ResolverTypeWrapper>; UInt8: ResolverTypeWrapper>; @@ -1733,7 +1677,6 @@ export type ResolversParentTypes = { LiquidityMutationResponse: Partial; Model: ResolversInterfaceTypes['Model']; Mutation: {}; - MutationResponse: ResolversInterfaceTypes['MutationResponse']; OutgoingPayment: Partial; OutgoingPaymentConnection: Partial; OutgoingPaymentEdge: Partial; @@ -1758,7 +1701,6 @@ export type ResolversParentTypes = { SetFeeInput: Partial; SetFeeResponse: Partial; String: Partial; - TransferMutationResponse: Partial; TriggerWalletAddressEventsInput: Partial; TriggerWalletAddressEventsMutationResponse: Partial; UInt8: Partial; @@ -1820,9 +1762,6 @@ export type AssetEdgeResolvers = { asset?: Resolver, ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1842,18 +1781,12 @@ export type BasePaymentResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1866,31 +1799,21 @@ export type CreateReceiverResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type CreateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeleteAssetMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; + asset?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type DeletePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1976,10 +1899,8 @@ export type JwkResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; + id?: Resolver; + liquidity?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2023,13 +1944,6 @@ export type MutationResolvers, ParentType, ContextType, RequireFields>; }; -export type MutationResponseResolvers = { - __resolveType: TypeResolveFn<'AssetMutationResponse' | 'CreateOrUpdatePeerByUrlMutationResponse' | 'CreatePeerMutationResponse' | 'CreateWalletAddressKeyMutationResponse' | 'CreateWalletAddressMutationResponse' | 'DeleteAssetMutationResponse' | 'DeletePeerMutationResponse' | 'LiquidityMutationResponse' | 'RevokeWalletAddressKeyMutationResponse' | 'SetFeeResponse' | 'TransferMutationResponse' | 'TriggerWalletAddressEventsMutationResponse' | 'UpdatePeerMutationResponse' | 'UpdateWalletAddressMutationResponse' | 'WalletAddressWithdrawalMutationResponse', ParentType, ContextType>; - code?: Resolver; - message?: Resolver; - success?: Resolver; -}; - export type OutgoingPaymentResolvers = { client?: Resolver, ParentType, ContextType>; createdAt?: Resolver; @@ -2189,33 +2103,17 @@ export type ReceiverResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddressKey?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; export type SetFeeResponseResolvers = { - code?: Resolver; fee?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; - __isTypeOf?: IsTypeOfResolverFn; -}; - -export type TransferMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type TriggerWalletAddressEventsMutationResponseResolvers = { - code?: Resolver; count?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2228,17 +2126,11 @@ export interface UInt64ScalarConfig extends GraphQLScalarTypeConfig = { - code?: Resolver; - message?: Resolver; peer?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; export type UpdateWalletAddressMutationResponseResolvers = { - code?: Resolver; - message?: Resolver; - success?: Resolver; walletAddress?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2294,10 +2186,6 @@ export type WalletAddressWithdrawalResolvers = { - code?: Resolver; - error?: Resolver, ParentType, ContextType>; - message?: Resolver; - success?: Resolver; withdrawal?: Resolver, ParentType, ContextType>; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2357,7 +2245,6 @@ export type Resolvers = { LiquidityMutationResponse?: LiquidityMutationResponseResolvers; Model?: ModelResolvers; Mutation?: MutationResolvers; - MutationResponse?: MutationResponseResolvers; OutgoingPayment?: OutgoingPaymentResolvers; OutgoingPaymentConnection?: OutgoingPaymentConnectionResolvers; OutgoingPaymentEdge?: OutgoingPaymentEdgeResolvers; @@ -2377,7 +2264,6 @@ export type Resolvers = { Receiver?: ReceiverResolvers; RevokeWalletAddressKeyMutationResponse?: RevokeWalletAddressKeyMutationResponseResolvers; SetFeeResponse?: SetFeeResponseResolvers; - TransferMutationResponse?: TransferMutationResponseResolvers; TriggerWalletAddressEventsMutationResponse?: TriggerWalletAddressEventsMutationResponseResolvers; UInt8?: GraphQLScalarType; UInt64?: GraphQLScalarType; From c72a1cba90a9dd55ee7f47eee246aee84a9d4f8a Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Wed, 5 Jun 2024 14:43:42 -0700 Subject: [PATCH 17/34] feat(backend): updated logs for graphql resolvers, remove code & message from resolver responses --- .../Create Outgoing Payment.bru | 3 - .../Create Quote.bru | 2 - ...ate Receiver (remote Incoming Payment).bru | 3 - .../Create Outgoing Payment.bru | 3 - .../Peer-to-Peer Payment/Create Quote.bru | 2 - ...ate Receiver -remote Incoming Payment-.bru | 3 - .../Cancel Outgoing Payment.bru | 49 ++++- .../Create Asset Liquidity Withdrawal.bru | 6 +- .../Rafiki/Rafiki Admin APIs/Create Asset.bru | 3 - .../Create Incoming Payment Withdrawal.bru | 6 +- .../Create Incoming Payment.bru | 3 - .../Create Or Update Peer By Url.bru | 3 - ...Outgoing Payment From Incoming Payment.bru | 3 - .../Create Outgoing Payment Withdrawal.bru | 6 +- .../Create Outgoing Payment.bru | 3 - .../Create Peer Liquidity Withdrawal.bru | 6 +- .../Rafiki/Rafiki Admin APIs/Create Peer.bru | 3 - .../Rafiki/Rafiki Admin APIs/Create Quote.bru | 2 - ...ate Receiver (remote Incoming Payment).bru | 3 - .../Create Wallet Address Key.bru | 3 - .../Create Wallet Address Withdrawal.bru | 4 - .../Create Wallet Address.bru | 5 +- .../Rafiki/Rafiki Admin APIs/Delete Asset.bru | 11 +- .../Rafiki/Rafiki Admin APIs/Delete Peer.bru | 2 - .../Deposit Asset Liquidity.bru | 4 +- .../Deposit Event Liquidity.bru | 6 +- .../Deposit Outgoing Payment Liquidity.bru | 6 +- .../Deposit Peer Liquidity.bru | 6 +- .../Post Liquidity Withdrawal.bru | 6 +- .../Revoke Wallet Address Key.bru | 3 - .../Rafiki/Rafiki Admin APIs/Set Fee.bru | 3 - .../Trigger Wallet Address Events.bru | 3 - .../Rafiki/Rafiki Admin APIs/Update Asset.bru | 3 - .../Rafiki/Rafiki Admin APIs/Update Peer.bru | 3 - .../Update Wallet Address.bru | 3 - .../Void Liquidity Withdrawal.bru | 6 +- .../Withdraw Event Liquidity.bru | 6 +- .../Rafiki Admin Auth APIs/Revoke Grant.bru | 4 +- .../generated/graphql.ts | 24 --- packages/backend/src/asset/errors.ts | 2 +- .../src/graphql/generated/graphql.schema.json | 176 ---------------- .../backend/src/graphql/generated/graphql.ts | 24 --- .../src/graphql/middleware/index.test.ts | 143 ++++++------- .../src/graphql/resolvers/asset.test.ts | 50 ++--- .../backend/src/graphql/resolvers/asset.ts | 43 ++-- .../src/graphql/resolvers/liquidity.ts | 191 ++---------------- .../resolvers/outgoing_payment.test.ts | 84 ++++---- .../src/graphql/resolvers/outgoing_payment.ts | 70 +++---- .../src/graphql/resolvers/peer.test.ts | 9 +- .../src/graphql/resolvers/quote.test.ts | 19 +- packages/backend/src/graphql/schema.graphql | 12 -- .../ilp/auto-peering/routes.test.ts | 6 +- packages/frontend/app/generated/graphql.ts | 24 --- .../src/generated/graphql.ts | 24 --- test/integration/lib/generated/graphql.ts | 24 --- 55 files changed, 292 insertions(+), 832 deletions(-) diff --git a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Outgoing Payment.bru b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Outgoing Payment.bru index 274c637fa6..891e215064 100644 --- a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Outgoing Payment.bru +++ b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Outgoing Payment.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateOutgoingPayment($input: CreateOutgoingPaymentInput!) { createOutgoingPayment(input: $input) { - code - message payment { createdAt error @@ -40,7 +38,6 @@ body:graphql { state stateAttempts } - success } } } diff --git a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Quote.bru b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Quote.bru index 9369e20c59..419f0d4424 100644 --- a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Quote.bru +++ b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Quote.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateQuote($input: CreateQuoteInput!) { createQuote(input: $input) { - code - message quote { createdAt expiresAt diff --git a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Receiver (remote Incoming Payment).bru b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Receiver (remote Incoming Payment).bru index 47df598515..df6e3561fd 100644 --- a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Receiver (remote Incoming Payment).bru +++ b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Cross Currency Payment/Create Receiver (remote Incoming Payment).bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateReceiver($input: CreateReceiverInput!) { createReceiver(input: $input) { - code - message receiver { completed createdAt @@ -34,7 +32,6 @@ body:graphql { } updatedAt } - success } } } diff --git a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Outgoing Payment.bru b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Outgoing Payment.bru index 274c637fa6..891e215064 100644 --- a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Outgoing Payment.bru +++ b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Outgoing Payment.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateOutgoingPayment($input: CreateOutgoingPaymentInput!) { createOutgoingPayment(input: $input) { - code - message payment { createdAt error @@ -40,7 +38,6 @@ body:graphql { state stateAttempts } - success } } } diff --git a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Quote.bru b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Quote.bru index 9369e20c59..419f0d4424 100644 --- a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Quote.bru +++ b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Quote.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateQuote($input: CreateQuoteInput!) { createQuote(input: $input) { - code - message quote { createdAt expiresAt diff --git a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Receiver -remote Incoming Payment-.bru b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Receiver -remote Incoming Payment-.bru index a6e4c14083..a060c1e4fc 100644 --- a/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Receiver -remote Incoming Payment-.bru +++ b/bruno/collections/Rafiki/Examples/Admin API - only locally/Peer-to-Peer Payment/Create Receiver -remote Incoming Payment-.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateReceiver($input: CreateReceiverInput!) { createReceiver(input: $input) { - code - message receiver { completed createdAt @@ -34,7 +32,6 @@ body:graphql { } updatedAt } - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Cancel Outgoing Payment.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Cancel Outgoing Payment.bru index c1ae36e746..9d3dc30452 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Cancel Outgoing Payment.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Cancel Outgoing Payment.bru @@ -13,9 +13,52 @@ post { body:graphql { mutation CancelOutgoingPayment($input: CancelOutgoingPaymentInput!) { cancelOutgoingPayment(input: $input) { - code - message - success + payment { + createdAt + error + metadata + id + walletAddressId + quote { + createdAt + expiresAt + highEstimatedExchangeRate + id + lowEstimatedExchangeRate + maxPacketAmount + minExchangeRate + walletAddressId + receiveAmount { + assetCode + assetScale + value + } + receiver + debitAmount { + assetCode + assetScale + value + } + } + receiveAmount { + assetCode + assetScale + value + } + receiver + debitAmount { + assetCode + assetScale + value + } + sentAmount { + assetCode + assetScale + value + } + state + stateAttempts + } } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru index 3ee4d48766..ed51a83919 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation CreateAssetLiquidityWithdrawal ($input: CreateAssetLiquidityWithdrawalInput!) { createAssetLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset.bru index 4a39ff032b..347917ce31 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset.bru @@ -21,9 +21,6 @@ body:graphql { withdrawalThreshold liquidityThreshold } - code - message - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru index 97752f81f3..82b433fe1f 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation CreateIncomingPaymentWithdrawal($input: CreateIncomingPaymentWithdrawalInput!) { createIncomingPaymentWithdrawal(input: $input) { - code - error - message - success + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment.bru index d382f38253..9ba6c4873b 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateIncomingPayment ($input: CreateIncomingPaymentInput!) { createIncomingPayment(input: $input) { - code - message payment { createdAt expiresAt @@ -33,7 +31,6 @@ body:graphql { } state } - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Or Update Peer By Url.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Or Update Peer By Url.bru index de6e5a43d8..f4aa8577a6 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Or Update Peer By Url.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Or Update Peer By Url.bru @@ -13,9 +13,6 @@ post { body:graphql { mutation CreateOrUpdatePeerByUrl ($input: CreateOrUpdatePeerByUrlInput!) { createOrUpdatePeerByUrl (input: $input) { - code - message - success peer { id name diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment From Incoming Payment.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment From Incoming Payment.bru index 6715f7a651..3bbdab9300 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment From Incoming Payment.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment From Incoming Payment.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateOutgoingPaymentFromIncomingPayment($input: CreateOutgoingPaymentFromIncomingPaymentInput!) { createOutgoingPaymentFromIncomingPayment(input: $input) { - code - message payment { createdAt error @@ -61,7 +59,6 @@ body:graphql { state stateAttempts } - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru index 832a1ae9f7..8d105398dd 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation CreateOutgoingPaymentWithdrawal($input: CreateOutgoingPaymentWithdrawalInput!) { createOutgoingPaymentWithdrawal(input: $input) { - code - error - message - success + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment.bru index 275ce0b1bc..4f331a360c 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateOutgoingPayment($input: CreateOutgoingPaymentInput!) { createOutgoingPayment(input: $input) { - code - message payment { createdAt error @@ -61,7 +59,6 @@ body:graphql { state stateAttempts } - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru index d11e557709..9f40b8e534 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation CreatePeerLiquidityWithdrawal ($input: CreatePeerLiquidityWithdrawalInput!) { createPeerLiquidityWithdrawal(input: $input) { - code - success - message - error + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer.bru index f781efc61b..77cbc4164c 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer.bru @@ -13,9 +13,6 @@ post { body:graphql { mutation CreatePeer ($input: CreatePeerInput!) { createPeer (input: $input) { - code - message - success peer { id name diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Quote.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Quote.bru index 81fcd937ca..9588bf3218 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Quote.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Quote.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateQuote($input: CreateQuoteInput!) { createQuote(input: $input) { - code - message quote { createdAt expiresAt diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Receiver (remote Incoming Payment).bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Receiver (remote Incoming Payment).bru index 516e898d10..b29949ef3c 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Receiver (remote Incoming Payment).bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Receiver (remote Incoming Payment).bru @@ -13,8 +13,6 @@ post { body:graphql { mutation CreateReceiver($input: CreateReceiverInput!) { createReceiver(input: $input) { - code - message receiver { completed createdAt @@ -34,7 +32,6 @@ body:graphql { } updatedAt } - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Key.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Key.bru index a803187bd9..1588f72353 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Key.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Key.bru @@ -13,9 +13,6 @@ post { body:graphql { mutation CreateWalletAddressKey ($input: CreateWalletAddressKeyInput!) { createWalletAddressKey(input: $input) { - code - message - success walletAddressKey { id revoked diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru index ff377ab90a..974d5b386a 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru @@ -13,10 +13,6 @@ post { body:graphql { mutation CreateWalletAddressWithdrawal($input: CreateWalletAddressWithdrawalInput!) { createWalletAddressWithdrawal(input: $input) { - code - error - message - success withdrawal { amount id diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address.bru index c3eb9808d5..f7923fd835 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address.bru @@ -13,9 +13,6 @@ post { body:graphql { mutation CreateWalletAddres($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id createdAt @@ -57,7 +54,7 @@ script:pre-request { const { nanoid } = require("nanoid"); const scripts = require('./scripts'); - bru.setVar('randomId', nanoid()); + bru.setVar("randomId", nanoid()); scripts.addApiSignatureHeader(); } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Asset.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Asset.bru index 8aa988638f..b35ceab5e9 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Asset.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Asset.bru @@ -13,9 +13,14 @@ post { body:graphql { mutation DeleteAsset($input: DeleteAssetInput!) { deleteAsset(input: $input) { - code - message - success + asset { + code + createdAt + id + scale + withdrawalThreshold + liquidityThreshold + } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Peer.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Peer.bru index bd8385b05c..3abd964f40 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Peer.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Delete Peer.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation DeletePeer($input: DeletePeerInput!) { deletePeer(input: $input) { - code - message success } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru index 4801ade88b..a71facad84 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru @@ -13,8 +13,8 @@ post { body:graphql { mutation DepositAssetLiquidity ($input: DepositAssetLiquidityInput!) { depositAssetLiquidity(input: $input) { - code - success + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru index 7172470130..ca5a7884b8 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation DepositEventLiquidity($input: DepositEventLiquidityInput!) { depositEventLiquidity(input: $input) { - code - error - message - success + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru index 7e7b48c401..c578c7ff49 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation DepositOutgoingPaymentLiquidity($input: DepositOutgoingPaymentLiquidityInput!) { depositOutgoingPaymentLiquidity(input: $input) { - code - error - message - success + id + liquidity } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru index 84da018d9b..7ffcf701ec 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation DepositPeerLiquidity ($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - code - success - message - error + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru index f4916f076f..009a7d2abb 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation PostLiquidityWithdrawal($input: PostLiquidityWithdrawalInput!) { postLiquidityWithdrawal(input: $input) { - code - error - message - success + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Revoke Wallet Address Key.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Revoke Wallet Address Key.bru index a8757f516d..ceb230c859 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Revoke Wallet Address Key.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Revoke Wallet Address Key.bru @@ -13,9 +13,6 @@ post { body:graphql { mutation RevokeWalletAddressKey ($input: RevokeWalletAddressKeyInput!) { revokeWalletAddressKey (input: $input) { - code - message - success walletAddressKey { id revoked diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Set Fee.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Set Fee.bru index 82f657bb2e..2055395df6 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Set Fee.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Set Fee.bru @@ -13,9 +13,6 @@ post { body:graphql { mutation SetFee($input: SetFeeInput!) { setFee(input: $input) { - code - success - message fee { id assetId diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Trigger Wallet Address Events.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Trigger Wallet Address Events.bru index c0df1c700a..3c8515ca8f 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Trigger Wallet Address Events.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Trigger Wallet Address Events.bru @@ -13,10 +13,7 @@ post { body:graphql { mutation TriggerWalletAddressEvents($input: TriggerWalletAddressEventsInput!) { triggerWalletAddressEvents(input: $input) { - code count - message - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Update Asset.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Update Asset.bru index 3c70f63fbc..f527f0ac9e 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Update Asset.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Update Asset.bru @@ -21,9 +21,6 @@ body:graphql { withdrawalThreshold liquidityThreshold } - code - message - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Update Peer.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Update Peer.bru index 5d37f8c50a..3bc84e7cb7 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Update Peer.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Update Peer.bru @@ -13,9 +13,6 @@ post { body:graphql { mutation UpdatePeer ($input: UpdatePeerInput!){ updatePeer(input: $input) { - code - success - message peer { id name diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Update Wallet Address.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Update Wallet Address.bru index 68f9024d9a..ddfc0376e2 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Update Wallet Address.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Update Wallet Address.bru @@ -13,8 +13,6 @@ post { body:graphql { mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - message walletAddress { id asset { @@ -29,7 +27,6 @@ body:graphql { createdAt status } - success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru index 1e65b829d9..b6f5544944 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation VoidLiquidityWithdrawal($input: VoidLiquidityWithdrawalInput!) { voidLiquidityWithdrawal(input: $input) { - code - error - message - success + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru index de9cc95c34..ccc56d08b5 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru @@ -13,10 +13,8 @@ post { body:graphql { mutation WithdrawEventLiquidity($input: WithdrawEventLiquidityInput!) { withdrawEventLiquidity(input: $input) { - code - error - message - success + id + liquidity } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin Auth APIs/Revoke Grant.bru b/bruno/collections/Rafiki/Rafiki Admin Auth APIs/Revoke Grant.bru index cb655b332b..6b0f15b374 100644 --- a/bruno/collections/Rafiki/Rafiki Admin Auth APIs/Revoke Grant.bru +++ b/bruno/collections/Rafiki/Rafiki Admin Auth APIs/Revoke Grant.bru @@ -13,9 +13,7 @@ post { body:graphql { mutation revokeGrant($input: RevokeGrantInput!) { revokeGrant(input: $input) { - code - message - success + id } } } diff --git a/localenv/mock-account-servicing-entity/generated/graphql.ts b/localenv/mock-account-servicing-entity/generated/graphql.ts index 1ed9179897..9003994529 100644 --- a/localenv/mock-account-servicing-entity/generated/graphql.ts +++ b/localenv/mock-account-servicing-entity/generated/graphql.ts @@ -286,10 +286,7 @@ export type CreateReceiverInput = { export type CreateReceiverResponse = { __typename?: 'CreateReceiverResponse'; - code: Scalars['String']['output']; - message?: Maybe; receiver?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateWalletAddressInput = { @@ -514,10 +511,7 @@ export type IncomingPaymentEdge = { export type IncomingPaymentResponse = { __typename?: 'IncomingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum IncomingPaymentState { @@ -859,10 +853,7 @@ export type OutgoingPaymentEdge = { export type OutgoingPaymentResponse = { __typename?: 'OutgoingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum OutgoingPaymentState { @@ -1123,10 +1114,7 @@ export type QuoteEdge = { export type QuoteResponse = { __typename?: 'QuoteResponse'; - code: Scalars['String']['output']; - message?: Maybe; quote?: Maybe; - success: Scalars['Boolean']['output']; }; export type Receiver = { @@ -1791,10 +1779,7 @@ export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; receiver?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1878,10 +1863,7 @@ export type IncomingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1975,10 +1957,7 @@ export type OutgoingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2082,10 +2061,7 @@ export type QuoteEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; quote?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/packages/backend/src/asset/errors.ts b/packages/backend/src/asset/errors.ts index 5841e94129..7a7c7ff682 100644 --- a/packages/backend/src/asset/errors.ts +++ b/packages/backend/src/asset/errors.ts @@ -21,7 +21,7 @@ export const errorToCode: { export const errorToMessage: { [key in AssetError]: string } = { - [AssetError.UnknownAsset]: 'unknown asset', + [AssetError.UnknownAsset]: 'Asset not found', [AssetError.DuplicateAsset]: 'Asset already exists', [AssetError.CannotDeleteInUseAsset]: 'Cannot delete! Asset in use.' } diff --git a/packages/backend/src/graphql/generated/graphql.schema.json b/packages/backend/src/graphql/generated/graphql.schema.json index 8cf2dfa7df..ed130b93d2 100644 --- a/packages/backend/src/graphql/generated/graphql.schema.json +++ b/packages/backend/src/graphql/generated/graphql.schema.json @@ -1771,34 +1771,6 @@ "name": "CreateReceiverResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "receiver", "description": null, @@ -1810,22 +1782,6 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, @@ -3257,34 +3213,6 @@ "name": "IncomingPaymentResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "payment", "description": null, @@ -3296,22 +3224,6 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, @@ -5087,34 +4999,6 @@ "name": "OutgoingPaymentResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "payment", "description": null, @@ -5126,22 +5010,6 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, @@ -6738,34 +6606,6 @@ "name": "QuoteResponse", "description": null, "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, { "name": "quote", "description": null, @@ -6777,22 +6617,6 @@ }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "success", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, diff --git a/packages/backend/src/graphql/generated/graphql.ts b/packages/backend/src/graphql/generated/graphql.ts index 1ed9179897..9003994529 100644 --- a/packages/backend/src/graphql/generated/graphql.ts +++ b/packages/backend/src/graphql/generated/graphql.ts @@ -286,10 +286,7 @@ export type CreateReceiverInput = { export type CreateReceiverResponse = { __typename?: 'CreateReceiverResponse'; - code: Scalars['String']['output']; - message?: Maybe; receiver?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateWalletAddressInput = { @@ -514,10 +511,7 @@ export type IncomingPaymentEdge = { export type IncomingPaymentResponse = { __typename?: 'IncomingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum IncomingPaymentState { @@ -859,10 +853,7 @@ export type OutgoingPaymentEdge = { export type OutgoingPaymentResponse = { __typename?: 'OutgoingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum OutgoingPaymentState { @@ -1123,10 +1114,7 @@ export type QuoteEdge = { export type QuoteResponse = { __typename?: 'QuoteResponse'; - code: Scalars['String']['output']; - message?: Maybe; quote?: Maybe; - success: Scalars['Boolean']['output']; }; export type Receiver = { @@ -1791,10 +1779,7 @@ export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; receiver?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1878,10 +1863,7 @@ export type IncomingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1975,10 +1957,7 @@ export type OutgoingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2082,10 +2061,7 @@ export type QuoteEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; quote?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/packages/backend/src/graphql/middleware/index.test.ts b/packages/backend/src/graphql/middleware/index.test.ts index 977fa56d5c..545228f8ab 100644 --- a/packages/backend/src/graphql/middleware/index.test.ts +++ b/packages/backend/src/graphql/middleware/index.test.ts @@ -10,7 +10,11 @@ import { Config } from '../../config/app' import { truncateTables } from '../../tests/tableManager' import { AssetService } from '../../asset/service' import { randomAsset } from '../../tests/asset' -import { AssetMutationResponse, CreateAssetInput } from '../generated/graphql' +import { + AssetMutationResponse, + CreateAssetInput, + UpdateAssetInput +} from '../generated/graphql' import { GraphQLError } from 'graphql' describe('GraphQL Middleware', (): void => { @@ -39,9 +43,6 @@ describe('GraphQL Middleware', (): void => { mutation: gql` mutation CreateAsset($input: CreateAssetInput!) { createAsset(input: $input) { - code - success - message asset { id code @@ -64,59 +65,96 @@ describe('GraphQL Middleware', (): void => { }) } + const callUpdateAssetMutation = async (input: UpdateAssetInput) => { + return appContainer.apolloClient + .mutate({ + mutation: gql` + mutation UpdateAsset($input: UpdateAssetInput!) { + updateAsset(input: $input) { + asset { + id + code + scale + withdrawalThreshold + } + } + } + `, + variables: { + input + } + }) + .then((query): AssetMutationResponse => { + if (query.data) { + return query.data.updateAsset + } else { + throw new Error('Data was empty') + } + }) + } + describe('idempotencyGraphQLMiddleware', (): void => { + let createInput: CreateAssetInput + let createResponse: AssetMutationResponse + + beforeEach(async (): Promise => { + createInput = { + ...randomAsset(), + idempotencyKey: uuid() + } + + createResponse = await callCreateAssetMutation(createInput) + assert.ok(createResponse.asset) + }) + test('returns original response on repeat call with same idempotency key', async (): Promise => { const idempotencyKey = uuid() - const input: CreateAssetInput = { - ...randomAsset(), + assert.ok(createResponse.asset) + const input: UpdateAssetInput = { + id: createResponse.asset.id, + withdrawalThreshold: BigInt(10), idempotencyKey } - const createAssetSpy = jest.spyOn(assetService, 'create') + const updateAssetSpy = jest.spyOn(assetService, 'update') - const initialResponse = await callCreateAssetMutation(input) + const initialResponse = await callUpdateAssetMutation(input) - expect(createAssetSpy).toHaveBeenCalledTimes(1) + expect(updateAssetSpy).toHaveBeenCalledTimes(1) assert.ok(initialResponse.asset) expect(initialResponse).toEqual({ __typename: 'AssetMutationResponse', - message: 'Created Asset', - success: true, - code: '200', asset: { __typename: 'Asset', id: initialResponse.asset.id, - code: input.code, - scale: input.scale, - withdrawalThreshold: null + code: createInput.code, + scale: createInput.scale, + withdrawalThreshold: '10' } }) await expect( assetService.get(initialResponse.asset.id) ).resolves.toMatchObject({ id: initialResponse.asset.id, - code: input.code, - scale: input.scale, - withdrawalThreshold: null + code: createInput.code, + scale: createInput.scale, + withdrawalThreshold: BigInt(10) }) - createAssetSpy.mockClear() + updateAssetSpy.mockClear() - const repeatResponse = await callCreateAssetMutation(input) + const repeatResponse = await callUpdateAssetMutation(input) - expect(createAssetSpy).not.toHaveBeenCalled() + expect(updateAssetSpy).not.toHaveBeenCalled() assert.ok(repeatResponse.asset) expect(repeatResponse).toEqual({ __typename: 'AssetMutationResponse', - message: 'Created Asset', - success: true, - code: '200', asset: { __typename: 'Asset', id: initialResponse.asset.id, code: initialResponse.asset.code, scale: initialResponse.asset.scale, - withdrawalThreshold: null + withdrawalThreshold: '10' } }) await expect( @@ -125,50 +163,7 @@ describe('GraphQL Middleware', (): void => { id: initialResponse.asset.id, code: initialResponse.asset.code, scale: initialResponse.asset.scale, - withdrawalThreshold: null - }) - }) - - test('does not return original response on repeat call with different idempotency key', async (): Promise => { - const input: CreateAssetInput = { - ...randomAsset(), - idempotencyKey: uuid() - } - - const createAssetSpy = jest.spyOn(assetService, 'create') - - const initialResponse = await callCreateAssetMutation(input) - - expect(createAssetSpy).toHaveBeenCalledTimes(1) - assert.ok(initialResponse.asset) - expect(initialResponse).toEqual({ - __typename: 'AssetMutationResponse', - message: 'Created Asset', - success: true, - code: '200', - asset: { - __typename: 'Asset', - id: initialResponse.asset.id, - code: input.code, - scale: input.scale, - withdrawalThreshold: null - } - }) - - createAssetSpy.mockClear() - - const repeatResponse = await callCreateAssetMutation({ - ...input, - idempotencyKey: uuid() - }) - - expect(createAssetSpy).toHaveBeenCalledTimes(1) - expect(repeatResponse).toEqual({ - __typename: 'AssetMutationResponse', - message: 'Asset already exists', - success: false, - code: '409', - asset: null + withdrawalThreshold: BigInt(10) }) }) @@ -184,9 +179,6 @@ describe('GraphQL Middleware', (): void => { assert.ok(initialResponse.asset) expect(initialResponse).toEqual({ __typename: 'AssetMutationResponse', - message: 'Created Asset', - success: true, - code: '200', asset: { __typename: 'Asset', id: initialResponse.asset.id, @@ -198,8 +190,8 @@ describe('GraphQL Middleware', (): void => { await expect( callCreateAssetMutation({ - ...input, - scale: (input.scale + 1) % 256 + ...randomAsset(), + idempotencyKey }) ).rejects.toThrow( `Incoming arguments are different than the original request for idempotencyKey: ${idempotencyKey}` @@ -229,9 +221,6 @@ describe('GraphQL Middleware', (): void => { status: 'fulfilled', value: { __typename: 'AssetMutationResponse', - message: 'Created Asset', - success: true, - code: '200', asset: { __typename: 'Asset', id: firstRequest.value?.asset?.id, diff --git a/packages/backend/src/graphql/resolvers/asset.test.ts b/packages/backend/src/graphql/resolvers/asset.test.ts index adc77e7629..8a6312488e 100644 --- a/packages/backend/src/graphql/resolvers/asset.test.ts +++ b/packages/backend/src/graphql/resolvers/asset.test.ts @@ -32,6 +32,7 @@ import { Fee, FeeType } from '../../fee/model' import { isFeeError } from '../../fee/errors' import { createFee } from '../../tests/fee' import { createAsset } from '../../tests/asset' +import { GraphQLError } from 'graphql' describe('Asset Resolvers', (): void => { let deps: IocContract @@ -621,8 +622,13 @@ describe('Asset Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('Asset not found') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[AssetError.UnknownAsset], { + extensions: { + code: errorToCode[AssetError.UnknownAsset] + } + }) + ) }) }) @@ -639,9 +645,9 @@ describe('Asset Resolvers', (): void => { mutation: gql` mutation DeleteAsset($input: DeleteAssetInput!) { deleteAsset(input: $input) { - code - success - message + asset { + id + } } } `, @@ -659,21 +665,19 @@ describe('Asset Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - expect(response.message).toEqual('Asset deleted') + expect(response.asset?.id).toEqual(asset.id) await expect(assetService.get(asset.id)).resolves.toBeUndefined() }) test('Returns error for unknown asset', async (): Promise => { - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DeleteAsset($input: DeleteAssetInput!) { deleteAsset(input: $input) { - code - success - message + asset { + id + } } } `, @@ -691,11 +695,13 @@ describe('Asset Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual( - errorToCode[AssetError.UnknownAsset].toString() + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[AssetError.UnknownAsset], { + extensions: { + code: errorToCode[AssetError.UnknownAsset] + } + }) ) - expect(response.message).toEqual(errorToMessage[AssetError.UnknownAsset]) }) test('Returns error if unexpected error', async (): Promise => { @@ -703,14 +709,14 @@ describe('Asset Resolvers', (): void => { throw new Error('unexpected') }) - const response = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation DeleteAsset($input: DeleteAssetInput!) { deleteAsset(input: $input) { - code - success - message + asset { + id + } } } `, @@ -728,9 +734,7 @@ describe('Asset Resolvers', (): void => { } }) - expect(response.success).toBe(false) - expect(response.code).toEqual('500') - expect(response.message).toEqual('Error trying to delete asset') + await expect(gqlQuery).rejects.toThrow(ApolloError) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/asset.ts b/packages/backend/src/graphql/resolvers/asset.ts index 9ee0972149..52a18a2b30 100644 --- a/packages/backend/src/graphql/resolvers/asset.ts +++ b/packages/backend/src/graphql/resolvers/asset.ts @@ -158,38 +158,21 @@ export const deleteAsset: MutationResolvers['deleteAsset'] = args, ctx ): Promise => { - try { - const assetService = await ctx.container.use('assetService') - const assetOrError = await assetService.delete({ - id: args.input.id, - deletedAt: new Date() - }) + const assetService = await ctx.container.use('assetService') + const assetOrError = await assetService.delete({ + id: args.input.id, + deletedAt: new Date() + }) - if (isAssetError(assetOrError)) { - return { - code: errorToCode[assetOrError].toString(), - message: errorToMessage[assetOrError], - success: false + if (isAssetError(assetOrError)) { + throw new GraphQLError(errorToMessage[assetOrError], { + extensions: { + code: errorToCode[assetOrError] } - } - return { - code: '200', - success: true, - message: 'Asset deleted' - } - } catch (err) { - ctx.logger.error( - { - id: args.input.id, - err - }, - 'error deleting asset' - ) - return { - code: '500', - message: 'Error trying to delete asset', - success: false - } + }) + } + return { + asset: assetToGraphql(assetOrError) } } diff --git a/packages/backend/src/graphql/resolvers/liquidity.ts b/packages/backend/src/graphql/resolvers/liquidity.ts index 5e32ca9814..4f04259f2f 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.ts @@ -170,34 +170,16 @@ export const createPeerLiquidityWithdrawal: MutationResolvers['cr args, ctx ): Promise => { -<<<<<<< HEAD - try { - const { amount, id, timeoutSeconds, peerId } = args.input - if (amount === BigInt(0)) { - return responses[LiquidityError.AmountZero] - } - const peerService = await ctx.container.use('peerService') - const peer = await peerService.get(peerId) - if (!peer) { - return responses[LiquidityError.UnknownPeer] - } - const accountingService = await ctx.container.use('accountingService') - const error = await accountingService.createWithdrawal({ - id, - account: peer, - amount, - timeout: Number(timeoutSeconds) -======= + const { amount, id, timeoutSeconds, peerId } = args.input if (args.input.amount === BigInt(0)) { throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { extensions: { code: errorToCode[LiquidityError.AmountZero] } ->>>>>>> c702654c (feat(wip): backend graphql logs) }) } const peerService = await ctx.container.use('peerService') - const peer = await peerService.get(args.input.peerId) + const peer = await peerService.get(peerId) if (!peer) { throw new GraphQLError(errorToMessage[LiquidityError.UnknownPeer], { extensions: { @@ -207,10 +189,10 @@ export const createPeerLiquidityWithdrawal: MutationResolvers['cr } const accountingService = await ctx.container.use('accountingService') const error = await accountingService.createWithdrawal({ - id: args.input.id, + id, account: peer, - amount: args.input.amount, - timeout: 60 + amount, + timeout: Number(timeoutSeconds) }) if (error) { throw new GraphQLError(transferErrorToMessage[error], { @@ -220,8 +202,8 @@ export const createPeerLiquidityWithdrawal: MutationResolvers['cr }) } return { - id: args.input.id, - liquidity: args.input.amount + id, + liquidity: amount } } @@ -231,34 +213,16 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c args, ctx ): Promise => { -<<<<<<< HEAD - try { - const { amount, id, timeoutSeconds, assetId } = args.input - if (amount === 0n) { - return responses[LiquidityError.AmountZero] - } - const assetService = await ctx.container.use('assetService') - const asset = await assetService.get(assetId) - if (!asset) { - return responses[LiquidityError.UnknownAsset] - } - const accountingService = await ctx.container.use('accountingService') - const error = await accountingService.createWithdrawal({ - id, - account: asset, - amount, - timeout: Number(timeoutSeconds) -======= - if (args.input.amount === BigInt(0)) { + const { amount, id, timeoutSeconds, assetId } = args.input + if (amount === BigInt(0)) { throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { extensions: { code: errorToCode[LiquidityError.AmountZero] } ->>>>>>> c702654c (feat(wip): backend graphql logs) }) } const assetService = await ctx.container.use('assetService') - const asset = await assetService.get(args.input.assetId) + const asset = await assetService.get(assetId) if (!asset) { throw new GraphQLError(errorToMessage[LiquidityError.UnknownAsset], { extensions: { @@ -268,10 +232,10 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c } const accountingService = await ctx.container.use('accountingService') const error = await accountingService.createWithdrawal({ - id: args.input.id, + id, account: asset, - amount: args.input.amount, - timeout: 60 + amount, + timeout: Number(timeoutSeconds) }) if (error) { throw new GraphQLError(transferErrorToMessage[error], { @@ -281,8 +245,8 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c }) } return { - id: args.input.id, - liquidity: args.input.amount + id, + liquidity: amount } } @@ -292,62 +256,12 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr args, ctx ): Promise => { -<<<<<<< HEAD - try { - const { id, walletAddressId, timeoutSeconds } = args.input - const walletAddressService = await ctx.container.use( - 'walletAddressService' - ) - const walletAddress = await walletAddressService.get(walletAddressId) - if (!walletAddress) { - return responses[ - LiquidityError.UnknownWalletAddress - ] as unknown as WalletAddressWithdrawalMutationResponse - } - const accountingService = await ctx.container.use('accountingService') - const amount = await accountingService.getBalance(walletAddress.id) - if (amount === undefined) - throw new Error( - `Could not get balance for wallet address liquidity account. It's likely the liquidity account does not exist.` - ) - else if (amount === 0n) { - return responses[ - LiquidityError.AmountZero - ] as unknown as WalletAddressWithdrawalMutationResponse - } - const error = await accountingService.createWithdrawal({ - id, - account: walletAddress, - amount, - timeout: Number(timeoutSeconds) - }) - - if (error) { - return errorToResponse( - error - ) as unknown as WalletAddressWithdrawalMutationResponse - } - return { - code: '200', - success: true, - message: 'Created account withdrawal', - withdrawal: { - id, - amount, - walletAddress: walletAddressToGraphql(walletAddress) - } - } - } catch (err) { - ctx.logger.error( -======= + const { id, walletAddressId, timeoutSeconds } = args.input const walletAddressService = await ctx.container.use('walletAddressService') - const walletAddress = await walletAddressService.get( - args.input.walletAddressId - ) + const walletAddress = await walletAddressService.get(walletAddressId) if (!walletAddress) { throw new GraphQLError( errorToMessage[LiquidityError.UnknownWalletAddress], ->>>>>>> c702654c (feat(wip): backend graphql logs) { extensions: { code: errorToCode[LiquidityError.UnknownWalletAddress] @@ -355,7 +269,6 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr } ) } - const id = args.input.id const accountingService = await ctx.container.use('accountingService') const amount = await accountingService.getBalance(walletAddress.id) if (amount === undefined) @@ -371,7 +284,7 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr id, account: walletAddress, amount, - timeout: 60 + timeout: Number(timeoutSeconds) }) if (error) { @@ -577,16 +490,7 @@ export const createIncomingPaymentWithdrawal: MutationResolvers[' args, ctx ): Promise => { -<<<<<<< HEAD const { incomingPaymentId, timeoutSeconds } = args.input - try { - const incomingPaymentService = await ctx.container.use( - 'incomingPaymentService' - ) - const incomingPayment = await incomingPaymentService.get({ - id: incomingPaymentId -======= - const { incomingPaymentId } = args.input const incomingPaymentService = await ctx.container.use( 'incomingPaymentService' ) @@ -606,22 +510,9 @@ export const createIncomingPaymentWithdrawal: MutationResolvers[' extensions: { code: errorToCode[LiquidityError.InvalidId] } ->>>>>>> c702654c (feat(wip): backend graphql logs) }) } -<<<<<<< HEAD - const accountingService = await ctx.container.use('accountingService') - const error = await accountingService.createWithdrawal({ - id: event.id, - account: { - id: incomingPaymentId, - asset: incomingPayment.asset - }, - amount: incomingPayment.receivedAmount.value, - timeout: Number(timeoutSeconds) - }) -======= const accountingService = await ctx.container.use('accountingService') const error = await accountingService.createWithdrawal({ id: event.id, @@ -629,9 +520,9 @@ export const createIncomingPaymentWithdrawal: MutationResolvers[' id: incomingPaymentId, asset: incomingPayment.asset }, - amount: incomingPayment.receivedAmount.value + amount: incomingPayment.receivedAmount.value, + timeout: Number(timeoutSeconds) }) ->>>>>>> c702654c (feat(wip): backend graphql logs) if (error) { throw new GraphQLError(fundingErrorToMessage[error], { @@ -652,16 +543,7 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' args, ctx ): Promise => { -<<<<<<< HEAD const { outgoingPaymentId, timeoutSeconds } = args.input - try { - const outgoingPaymentService = await ctx.container.use( - 'outgoingPaymentService' - ) - const outgoingPayment = await outgoingPaymentService.get({ - id: outgoingPaymentId -======= - const { outgoingPaymentId } = args.input const outgoingPaymentService = await ctx.container.use( 'outgoingPaymentService' ) @@ -681,44 +563,14 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' extensions: { code: errorToCode[LiquidityError.InvalidId] } ->>>>>>> c702654c (feat(wip): backend graphql logs) }) } -<<<<<<< HEAD - const accountingService = await ctx.container.use('accountingService') - const balance = await accountingService.getBalance(outgoingPayment.id) - if (!balance) { - return responses[LiquidityError.InsufficientBalance] - } - - const error = await accountingService.createWithdrawal({ - id: event.id, - account: { - id: outgoingPaymentId, - asset: outgoingPayment.asset - }, - amount: balance, - timeout: Number(timeoutSeconds) - }) - - if (error) { - return errorToResponse(error) - } - return { - code: '200', - success: true, - message: 'Withdrew liquidity' - } - } catch (error) { - ctx.logger.error( -======= const accountingService = await ctx.container.use('accountingService') const balance = await accountingService.getBalance(outgoingPayment.id) if (!balance) { throw new GraphQLError( errorToMessage[LiquidityError.InsufficientBalance], ->>>>>>> c702654c (feat(wip): backend graphql logs) { extensions: { code: errorToCode[LiquidityError.InsufficientBalance] @@ -733,7 +585,8 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' id: outgoingPaymentId, asset: outgoingPayment.asset }, - amount: balance + amount: balance, + timeout: Number(timeoutSeconds) }) if (error) { diff --git a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts index 3002c5237b..7c8c32bc4b 100644 --- a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts @@ -13,7 +13,11 @@ import { createAsset } from '../../tests/asset' import { createOutgoingPayment } from '../../tests/outgoingPayment' import { createWalletAddress } from '../../tests/walletAddress' import { truncateTables } from '../../tests/tableManager' -import { OutgoingPaymentError } from '../../open_payments/payment/outgoing/errors' +import { + OutgoingPaymentError, + errorToMessage, + errorToCode +} from '../../open_payments/payment/outgoing/errors' import { OutgoingPaymentService } from '../../open_payments/payment/outgoing/service' import { OutgoingPayment as OutgoingPaymentModel, @@ -27,6 +31,7 @@ import { OutgoingPaymentState as SchemaPaymentState } from '../generated/graphql' import { faker } from '@faker-js/faker' +import { GraphQLError } from 'graphql' describe('OutgoingPayment Resolvers', (): void => { let deps: IocContract @@ -301,11 +306,6 @@ describe('OutgoingPayment Resolvers', (): void => { ) expect(createSpy).toHaveBeenCalledWith(input) -<<<<<<< HEAD - expect(query.code).toBe('201') - expect(query.success).toBe(true) -======= ->>>>>>> d55fecd7 (feat: update outgoing payment resolvers) expect(query.payment?.id).toBe(payment.id) expect(query.payment?.state).toBe(SchemaPaymentState.Funding) }) @@ -382,7 +382,7 @@ describe('OutgoingPayment Resolvers', (): void => { describe('Mutation.createOutgoingPaymentFromIncomingPayment', (): void => { const mockIncomingPaymentUrl = `https://${faker.internet.domainName()}/incoming-payments/${uuid()}` - test('201', async (): Promise => { + test('create', async (): Promise => { const walletAddress = await createWalletAddress(deps, { assetId: asset.id }) @@ -409,8 +409,6 @@ describe('OutgoingPayment Resolvers', (): void => { $input: CreateOutgoingPaymentFromIncomingPaymentInput! ) { createOutgoingPaymentFromIncomingPayment(input: $input) { - code - success payment { id state @@ -426,13 +424,11 @@ describe('OutgoingPayment Resolvers', (): void => { ) expect(createSpy).toHaveBeenCalledWith(input) - expect(query.code).toBe('201') - expect(query.success).toBe(true) expect(query.payment?.id).toBe(payment.id) expect(query.payment?.state).toBe(SchemaPaymentState.Funding) }) - test('400', async (): Promise => { + test('unknown wallet address', async (): Promise => { const createSpy = jest .spyOn(outgoingPaymentService, 'create') .mockResolvedValueOnce(OutgoingPaymentError.UnknownWalletAddress) @@ -447,16 +443,13 @@ describe('OutgoingPayment Resolvers', (): void => { } } - const query = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .query({ query: gql` mutation CreateOutgoingPaymentFromIncomingPayment( $input: CreateOutgoingPaymentFromIncomingPaymentInput! ) { createOutgoingPaymentFromIncomingPayment(input: $input) { - code - success - message payment { id state @@ -470,16 +463,20 @@ describe('OutgoingPayment Resolvers', (): void => { (query): OutgoingPaymentResponse => query.data?.createOutgoingPaymentFromIncomingPayment ) - expect(createSpy).toHaveBeenCalledWith(input) - expect(query.code).toBe('404') - expect(query.success).toBe(false) - expect(query.message).toBe( - errorToMessage[OutgoingPaymentError.UnknownWalletAddress] + await expect(gqlQuery).rejects.toThrow( + new GraphQLError( + errorToMessage[OutgoingPaymentError.UnknownWalletAddress], + { + extensions: { + code: errorToCode[OutgoingPaymentError.UnknownWalletAddress] + } + } + ) ) - expect(query.payment).toBeNull() + expect(createSpy).toHaveBeenCalledWith(input) }) - test('500', async (): Promise => { + test('unknown error', async (): Promise => { const createSpy = jest .spyOn(outgoingPaymentService, 'create') .mockRejectedValueOnce(new Error('unexpected')) @@ -494,16 +491,13 @@ describe('OutgoingPayment Resolvers', (): void => { } } - const query = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .query({ query: gql` mutation CreateOutgoingPaymentFromIncomingPayment( $input: CreateOutgoingPaymentFromIncomingPaymentInput! ) { createOutgoingPaymentFromIncomingPayment(input: $input) { - code - success - message payment { id state @@ -517,11 +511,8 @@ describe('OutgoingPayment Resolvers', (): void => { (query): OutgoingPaymentResponse => query.data?.createOutgoingPaymentFromIncomingPayment ) + await expect(gqlQuery).rejects.toThrow(ApolloError) expect(createSpy).toHaveBeenCalledWith(input) - expect(query.code).toBe('500') - expect(query.success).toBe(false) - expect(query.message).toBe('Error trying to create outgoing payment') - expect(query.payment).toBeNull() }) }) @@ -560,8 +551,6 @@ describe('OutgoingPayment Resolvers', (): void => { $input: CancelOutgoingPaymentInput! ) { cancelOutgoingPayment(input: $input) { - code - success payment { id state @@ -578,8 +567,6 @@ describe('OutgoingPayment Resolvers', (): void => { ) expect(cancelSpy).toHaveBeenCalledWith(input) - expect(mutationResponse.code).toBe('200') - expect(mutationResponse.success).toBe(true) expect(mutationResponse.payment).toEqual({ __typename: 'OutgoingPayment', id: input.id, @@ -591,29 +578,26 @@ describe('OutgoingPayment Resolvers', (): void => { } ) - const errors: [string, OutgoingPaymentError][] = [ - ['409', OutgoingPaymentError.WrongState], - ['404', OutgoingPaymentError.UnknownPayment] + const errors: [OutgoingPaymentError][] = [ + [OutgoingPaymentError.WrongState], + [OutgoingPaymentError.UnknownPayment] ] test.each(errors)( '%s - outgoing payment error', - async (statusCode, paymentError): Promise => { + async (paymentError): Promise => { const cancelSpy = jest .spyOn(outgoingPaymentService, 'cancel') .mockResolvedValueOnce(paymentError) const input = { id: uuid() } - const mutationResponse = await appContainer.apolloClient + const gqlQuery = appContainer.apolloClient .mutate({ mutation: gql` mutation CancelOutgoingPayment( $input: CancelOutgoingPaymentInput! ) { cancelOutgoingPayment(input: $input) { - code - message - success payment { id state @@ -629,14 +613,14 @@ describe('OutgoingPayment Resolvers', (): void => { query.data?.cancelOutgoingPayment ) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[paymentError], { + extensions: { + code: errorToCode[paymentError] + } + }) + ) expect(cancelSpy).toHaveBeenCalledWith(input) - expect(mutationResponse).toEqual({ - __typename: 'OutgoingPaymentResponse', - code: statusCode, - message: errorToMessage[paymentError], - success: false, - payment: null - }) } ) }) diff --git a/packages/backend/src/graphql/resolvers/outgoing_payment.ts b/packages/backend/src/graphql/resolvers/outgoing_payment.ts index 61e0276219..c4907b6e58 100644 --- a/packages/backend/src/graphql/resolvers/outgoing_payment.ts +++ b/packages/backend/src/graphql/resolvers/outgoing_payment.ts @@ -7,7 +7,6 @@ import { ResolversTypes } from '../generated/graphql' import { - OutgoingPaymentError, isOutgoingPaymentError, errorToMessage, errorToCode @@ -47,26 +46,21 @@ export const cancelOutgoingPayment: MutationResolvers['cancelOutg 'outgoingPaymentService' ) - return outgoingPaymentService - .cancel(args.input) - .then((paymentOrError: OutgoingPayment | OutgoingPaymentError) => - isOutgoingPaymentError(paymentOrError) - ? { - code: errorToCode[paymentOrError].toString(), - success: false, - message: errorToMessage[paymentOrError] - } - : { - code: '200', - success: true, - payment: paymentToGraphql(paymentOrError) - } - ) - .catch(() => ({ - code: '500', - success: false, - message: 'Error trying to cancel outgoing payment' - })) + const outgoingPaymentOrError = await outgoingPaymentService.cancel( + args.input + ) + + if (isOutgoingPaymentError(outgoingPaymentOrError)) { + throw new GraphQLError(errorToMessage[outgoingPaymentOrError], { + extensions: { + code: errorToCode[outgoingPaymentOrError] + } + }) + } else { + return { + payment: paymentToGraphql(outgoingPaymentOrError) + } + } } export const createOutgoingPayment: MutationResolvers['createOutgoingPayment'] = @@ -102,24 +96,22 @@ export const createOutgoingPaymentFromIncomingPayment: MutationResolvers - isOutgoingPaymentError(paymentOrErr) - ? { - code: errorToCode[paymentOrErr].toString(), - success: false, - message: errorToMessage[paymentOrErr] - } - : { - payment: paymentToGraphql(paymentOrErr) - } - ) - .catch(() => ({ - code: '500', - success: false, - message: 'Error trying to create outgoing payment' - })) + + const outgoingPaymentOrError = await outgoingPaymentService.create( + args.input + ) + + if (isOutgoingPaymentError(outgoingPaymentOrError)) { + throw new GraphQLError(errorToMessage[outgoingPaymentOrError], { + extensions: { + code: errorToCode[outgoingPaymentOrError] + } + }) + } else { + return { + payment: paymentToGraphql(outgoingPaymentOrError) + } + } } export const getWalletAddressOutgoingPayments: WalletAddressResolvers['outgoingPayments'] = diff --git a/packages/backend/src/graphql/resolvers/peer.test.ts b/packages/backend/src/graphql/resolvers/peer.test.ts index f22fdebd40..2be7f57267 100644 --- a/packages/backend/src/graphql/resolvers/peer.test.ts +++ b/packages/backend/src/graphql/resolvers/peer.test.ts @@ -22,7 +22,8 @@ import { CreatePeerInput, CreatePeerMutationResponse, PeersConnection, - UpdatePeerMutationResponse + UpdatePeerMutationResponse, + DeletePeerMutationResponse } from '../generated/graphql' import { AccountingService } from '../../accounting/service' @@ -604,7 +605,7 @@ describe('Peer Resolvers', (): void => { } } }) - .then((query): UpdatePeerMutationResponse => { + .then((query): DeletePeerMutationResponse => { if (query.data) { return query.data.deletePeer } else { @@ -632,7 +633,7 @@ describe('Peer Resolvers', (): void => { } } }) - .then((query): UpdatePeerMutationResponse => { + .then((query): DeletePeerMutationResponse => { if (query.data) { return query.data.deletePeer } else { @@ -664,7 +665,7 @@ describe('Peer Resolvers', (): void => { } } }) - .then((query): UpdatePeerMutationResponse => { + .then((query): DeletePeerMutationResponse => { if (query.data) { return query.data.deletePeer } else { diff --git a/packages/backend/src/graphql/resolvers/quote.test.ts b/packages/backend/src/graphql/resolvers/quote.test.ts index 80a59205f2..b95ac3c2e6 100644 --- a/packages/backend/src/graphql/resolvers/quote.test.ts +++ b/packages/backend/src/graphql/resolvers/quote.test.ts @@ -1,5 +1,6 @@ import { ApolloError, gql } from '@apollo/client' import { v4 as uuid } from 'uuid' +import { GraphQLError } from 'graphql' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' @@ -12,7 +13,11 @@ import { createAsset } from '../../tests/asset' import { createWalletAddress } from '../../tests/walletAddress' import { createQuote } from '../../tests/quote' import { truncateTables } from '../../tests/tableManager' -import { QuoteError, errorToMessage } from '../../open_payments/quote/errors' +import { + QuoteError, + errorToMessage, + errorToCode +} from '../../open_payments/quote/errors' import { QuoteService } from '../../open_payments/quote/service' import { Quote as QuoteModel } from '../../open_payments/quote/model' import { Amount } from '../../open_payments/amount' @@ -236,13 +241,16 @@ describe('Quote Resolvers', (): void => { }) .then((query): QuoteResponse => query.data?.createQuote) - await expect(gqlQuery).rejects.toThrow(ApolloError) await expect(gqlQuery).rejects.toThrow( - errorToMessage[QuoteError.UnknownWalletAddress] + new GraphQLError(errorToMessage[QuoteError.UnknownWalletAddress], { + extensions: { + code: errorToCode[QuoteError.UnknownWalletAddress] + } + }) ) }) - test('500', async (): Promise => { + test('unknown error', async (): Promise => { const createSpy = jest .spyOn(quoteService, 'create') .mockRejectedValueOnce(new Error('unexpected')) @@ -252,9 +260,6 @@ describe('Quote Resolvers', (): void => { query: gql` mutation CreateQuote($input: CreateQuoteInput!) { createQuote(input: $input) { - code - success - message quote { id } diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index d194a2461c..95b0635efb 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -952,9 +952,6 @@ input CreateQuoteInput { } type QuoteResponse { - code: String! - success: Boolean! - message: String quote: Quote } @@ -1016,23 +1013,14 @@ input CreateReceiverInput { } type OutgoingPaymentResponse { - code: String! - success: Boolean! - message: String payment: OutgoingPayment } type IncomingPaymentResponse { - code: String! - success: Boolean! - message: String payment: IncomingPayment } type CreateReceiverResponse { - code: String! - success: Boolean! - message: String receiver: Receiver } diff --git a/packages/backend/src/payment-method/ilp/auto-peering/routes.test.ts b/packages/backend/src/payment-method/ilp/auto-peering/routes.test.ts index f3bc49b3a9..cbc79b9e60 100644 --- a/packages/backend/src/payment-method/ilp/auto-peering/routes.test.ts +++ b/packages/backend/src/payment-method/ilp/auto-peering/routes.test.ts @@ -6,7 +6,7 @@ import { createTestApp, TestContainer } from '../../../tests/app' import { createAsset } from '../../../tests/asset' import { createContext } from '../../../tests/context' import { truncateTables } from '../../../tests/tableManager' -import { AutoPeeringError, errorToCode, errorToMessage } from './errors' +import { AutoPeeringError, errorToHttpCode, errorToMessage } from './errors' import { AutoPeeringRoutes, PeerRequestContext } from './routes' describe('Auto Peering Routes', (): void => { @@ -74,10 +74,10 @@ describe('Auto Peering Routes', (): void => { await expect( autoPeeringRoutes.acceptPeerRequest(ctx) ).resolves.toBeUndefined() - expect(ctx.status).toBe(errorToCode[AutoPeeringError.UnknownAsset]) + expect(ctx.status).toBe(errorToHttpCode[AutoPeeringError.UnknownAsset]) expect(ctx.body).toEqual({ error: { - code: errorToCode[AutoPeeringError.UnknownAsset], + code: errorToHttpCode[AutoPeeringError.UnknownAsset], message: errorToMessage[AutoPeeringError.UnknownAsset], type: AutoPeeringError.UnknownAsset } diff --git a/packages/frontend/app/generated/graphql.ts b/packages/frontend/app/generated/graphql.ts index 120c3a8d69..0812a092bd 100644 --- a/packages/frontend/app/generated/graphql.ts +++ b/packages/frontend/app/generated/graphql.ts @@ -286,10 +286,7 @@ export type CreateReceiverInput = { export type CreateReceiverResponse = { __typename?: 'CreateReceiverResponse'; - code: Scalars['String']['output']; - message?: Maybe; receiver?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateWalletAddressInput = { @@ -514,10 +511,7 @@ export type IncomingPaymentEdge = { export type IncomingPaymentResponse = { __typename?: 'IncomingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum IncomingPaymentState { @@ -859,10 +853,7 @@ export type OutgoingPaymentEdge = { export type OutgoingPaymentResponse = { __typename?: 'OutgoingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum OutgoingPaymentState { @@ -1123,10 +1114,7 @@ export type QuoteEdge = { export type QuoteResponse = { __typename?: 'QuoteResponse'; - code: Scalars['String']['output']; - message?: Maybe; quote?: Maybe; - success: Scalars['Boolean']['output']; }; export type Receiver = { @@ -1791,10 +1779,7 @@ export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; receiver?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1878,10 +1863,7 @@ export type IncomingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1975,10 +1957,7 @@ export type OutgoingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2082,10 +2061,7 @@ export type QuoteEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; quote?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/packages/mock-account-service-lib/src/generated/graphql.ts b/packages/mock-account-service-lib/src/generated/graphql.ts index 1ed9179897..9003994529 100644 --- a/packages/mock-account-service-lib/src/generated/graphql.ts +++ b/packages/mock-account-service-lib/src/generated/graphql.ts @@ -286,10 +286,7 @@ export type CreateReceiverInput = { export type CreateReceiverResponse = { __typename?: 'CreateReceiverResponse'; - code: Scalars['String']['output']; - message?: Maybe; receiver?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateWalletAddressInput = { @@ -514,10 +511,7 @@ export type IncomingPaymentEdge = { export type IncomingPaymentResponse = { __typename?: 'IncomingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum IncomingPaymentState { @@ -859,10 +853,7 @@ export type OutgoingPaymentEdge = { export type OutgoingPaymentResponse = { __typename?: 'OutgoingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum OutgoingPaymentState { @@ -1123,10 +1114,7 @@ export type QuoteEdge = { export type QuoteResponse = { __typename?: 'QuoteResponse'; - code: Scalars['String']['output']; - message?: Maybe; quote?: Maybe; - success: Scalars['Boolean']['output']; }; export type Receiver = { @@ -1791,10 +1779,7 @@ export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; receiver?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1878,10 +1863,7 @@ export type IncomingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1975,10 +1957,7 @@ export type OutgoingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2082,10 +2061,7 @@ export type QuoteEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; quote?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/test/integration/lib/generated/graphql.ts b/test/integration/lib/generated/graphql.ts index 1ed9179897..9003994529 100644 --- a/test/integration/lib/generated/graphql.ts +++ b/test/integration/lib/generated/graphql.ts @@ -286,10 +286,7 @@ export type CreateReceiverInput = { export type CreateReceiverResponse = { __typename?: 'CreateReceiverResponse'; - code: Scalars['String']['output']; - message?: Maybe; receiver?: Maybe; - success: Scalars['Boolean']['output']; }; export type CreateWalletAddressInput = { @@ -514,10 +511,7 @@ export type IncomingPaymentEdge = { export type IncomingPaymentResponse = { __typename?: 'IncomingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum IncomingPaymentState { @@ -859,10 +853,7 @@ export type OutgoingPaymentEdge = { export type OutgoingPaymentResponse = { __typename?: 'OutgoingPaymentResponse'; - code: Scalars['String']['output']; - message?: Maybe; payment?: Maybe; - success: Scalars['Boolean']['output']; }; export enum OutgoingPaymentState { @@ -1123,10 +1114,7 @@ export type QuoteEdge = { export type QuoteResponse = { __typename?: 'QuoteResponse'; - code: Scalars['String']['output']; - message?: Maybe; quote?: Maybe; - success: Scalars['Boolean']['output']; }; export type Receiver = { @@ -1791,10 +1779,7 @@ export type CreatePeerMutationResponseResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; receiver?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1878,10 +1863,7 @@ export type IncomingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -1975,10 +1957,7 @@ export type OutgoingPaymentEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; payment?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2082,10 +2061,7 @@ export type QuoteEdgeResolvers = { - code?: Resolver; - message?: Resolver, ParentType, ContextType>; quote?: Resolver, ParentType, ContextType>; - success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; From 486ba037d42086ba788c2b272a72413afcdd4930 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Wed, 5 Jun 2024 15:09:15 -0700 Subject: [PATCH 18/34] update frontend types --- .../app/routes/assets.$assetId.deposit-liquidity.tsx | 5 ++--- packages/frontend/app/routes/assets.$assetId.tsx | 11 +++++------ .../app/routes/assets.$assetId.withdraw-liquidity.tsx | 5 ++--- packages/frontend/app/routes/assets.create.tsx | 4 ++-- ...incoming.$incomingPaymentId.withdraw-liquidity.tsx | 5 ++--- ....outgoing.$outgoingPaymentId.deposit-liquidity.tsx | 5 ++--- ...outgoing.$outgoingPaymentId.withdraw-liquidity.tsx | 5 ++--- .../app/routes/peers.$peerId.deposit-liquidity.tsx | 5 ++--- packages/frontend/app/routes/peers.$peerId.tsx | 8 ++++---- .../app/routes/peers.$peerId.withdraw-liquidity.tsx | 5 ++--- packages/frontend/app/routes/peers.create.tsx | 4 ++-- ...-addresses.$walletAddressId.withdraw-liquidity.tsx | 5 ++--- .../frontend/app/routes/wallet-addresses.create.tsx | 4 ++-- 13 files changed, 31 insertions(+), 40 deletions(-) diff --git a/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx b/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx index 011dffcd2d..ef8485807a 100644 --- a/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx @@ -63,12 +63,11 @@ export async function action({ request, params }: ActionFunctionArgs) { idempotencyKey: v4() }) - if (!response?.success) { + if (!response?.id) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not deposit asset liquidity. Please try again!', type: 'error' }, @@ -79,7 +78,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Deposited asset liquidity.', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/assets.$assetId.tsx b/packages/frontend/app/routes/assets.$assetId.tsx index c23fb98ca3..85471da3e9 100644 --- a/packages/frontend/app/routes/assets.$assetId.tsx +++ b/packages/frontend/app/routes/assets.$assetId.tsx @@ -301,9 +301,9 @@ export async function action({ request }: ActionFunctionArgs) { : { withdrawalThreshold: undefined }) }) - if (!response?.success) { + if (!response?.asset) { actionResponse.errors.general.message = [ - response?.message ?? 'Could not update asset. Please try again!' + 'Could not update asset. Please try again!' ] return json({ ...actionResponse }, { status: 400 }) } @@ -327,9 +327,8 @@ export async function action({ request }: ActionFunctionArgs) { } }) - if (!response?.success) { + if (!response?.fee) { actionResponse.errors.sendingFee.message = [ - response?.message ?? 'Could not update asset sending fee. Please try again!' ] return json({ ...actionResponse }, { status: 400 }) @@ -351,11 +350,11 @@ export async function action({ request }: ActionFunctionArgs) { } const response = await deleteAsset({ id: result.data.id }) - if (!response?.success) { + if (!response?.asset) { return setMessageAndRedirect({ session, message: { - content: response?.message || 'Could not delete Asset.', + content: 'Could not delete Asset.', type: 'error' }, location: '.' diff --git a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx index 2bf52d24f4..879c56040c 100644 --- a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx @@ -64,12 +64,11 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.success) { + if (!response?.id) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not withdraw asset liquidity. Please try again!', type: 'error' }, @@ -80,7 +79,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Successfully withdrew asset liquidity.', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/assets.create.tsx b/packages/frontend/app/routes/assets.create.tsx index a89d51257f..ecf7d591f8 100644 --- a/packages/frontend/app/routes/assets.create.tsx +++ b/packages/frontend/app/routes/assets.create.tsx @@ -104,9 +104,9 @@ export async function action({ request }: ActionFunctionArgs) { : { withdrawalThreshold: undefined }) }) - if (!response?.success) { + if (!response?.asset) { errors.message = [ - response?.message ?? 'Could not create asset. Please try again!' + 'Could not create asset. Please try again!' ] return json({ errors }, { status: 400 }) } diff --git a/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx b/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx index 8fe1ba6635..e3dd9cea2a 100644 --- a/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx @@ -49,12 +49,11 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.success) { + if (!response?.id) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not withdraw incoming payment liquidity. Please try again!', type: 'error' }, @@ -65,7 +64,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Withdrew incoming payment liquidity.', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx index e9b0242331..18943dd897 100644 --- a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx @@ -50,12 +50,11 @@ export async function action({ request, params }: ActionFunctionArgs) { idempotencyKey: v4() }) - if (!response?.success) { + if (!response?.id) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not deposit outgoing payment liquidity. Please try again!', type: 'error' }, @@ -66,7 +65,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Deposited outgoing payment liquidity.', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx index f8f0eb993f..9b311d960b 100644 --- a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx @@ -51,12 +51,11 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.success) { + if (!response?.id) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not withdraw outgoing payment liquidity. Please try again!', type: 'error' }, @@ -67,7 +66,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Withdrew outgoing payment liquidity.', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx b/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx index f411562a14..7bdcbf29a9 100644 --- a/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx @@ -63,12 +63,11 @@ export async function action({ request, params }: ActionFunctionArgs) { idempotencyKey: v4() }) - if (!response?.success) { + if (!response?.id) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not deposit peer liquidity. Please try again!', type: 'error' }, @@ -79,7 +78,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Deposited peer liquidity.', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/peers.$peerId.tsx b/packages/frontend/app/routes/peers.$peerId.tsx index 71497ca386..03fa16b501 100644 --- a/packages/frontend/app/routes/peers.$peerId.tsx +++ b/packages/frontend/app/routes/peers.$peerId.tsx @@ -418,9 +418,9 @@ export async function action({ request }: ActionFunctionArgs) { : { maxPacketAmount: undefined }) }) - if (!response?.success) { + if (!response?.peer) { actionResponse.errors.general.message = [ - response?.message ?? 'Could not update peer. Please try again!' + 'Could not update peer. Please try again!' ] return json({ ...actionResponse }, { status: 400 }) } @@ -455,9 +455,9 @@ export async function action({ request }: ActionFunctionArgs) { } }) - if (!response?.success) { + if (!response?.peer) { actionResponse.errors.general.message = [ - response?.message ?? 'Could not update peer. Please try again!' + 'Could not update peer. Please try again!' ] return json({ ...actionResponse }, { status: 400 }) } diff --git a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx index d48a558e14..8173bf5ea0 100644 --- a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx @@ -64,12 +64,11 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.success) { + if (!response?.id) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not withdraw peer liquidity. Please try again!', type: 'error' }, @@ -80,7 +79,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Withdrew peer liquidity', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/peers.create.tsx b/packages/frontend/app/routes/peers.create.tsx index c76d4b90ff..d392520616 100644 --- a/packages/frontend/app/routes/peers.create.tsx +++ b/packages/frontend/app/routes/peers.create.tsx @@ -264,9 +264,9 @@ export async function action({ request }: ActionFunctionArgs) { : { maxPacketAmount: undefined }) }) - if (!response?.success) { + if (!response?.peer) { errors.message = [ - response?.message ?? 'Could not create peer. Please try again!' + 'Could not create peer. Please try again!' ] return json({ errors }, { status: 400 }) } diff --git a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx index 8f15df05db..e54a93ea6b 100644 --- a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx @@ -50,12 +50,11 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.success) { + if (!response?.withdrawal) { return setMessageAndRedirect({ session, message: { content: - response?.message ?? 'Could not withdraw wallet address liquidity. Please try again!', type: 'error' }, @@ -66,7 +65,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: response.message, + content: 'Withdrew wallet address liquidity.', type: 'success' }, location: '..' diff --git a/packages/frontend/app/routes/wallet-addresses.create.tsx b/packages/frontend/app/routes/wallet-addresses.create.tsx index 1d938c54af..b679ad135d 100644 --- a/packages/frontend/app/routes/wallet-addresses.create.tsx +++ b/packages/frontend/app/routes/wallet-addresses.create.tsx @@ -116,9 +116,9 @@ export async function action({ request }: ActionFunctionArgs) { additionalProperties: [] }) - if (!response?.success) { + if (!response?.walletAddress) { errors.message = [ - response?.message ?? 'Could not create wallet address. Please try again!' + 'Could not create wallet address. Please try again!' ] return json({ errors }, { status: 400 }) } From 0cc23ff975b45760301ca6b091c298a8752d79a3 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Wed, 5 Jun 2024 15:11:35 -0700 Subject: [PATCH 19/34] chore: formatting --- .../frontend/app/routes/assets.$assetId.deposit-liquidity.tsx | 3 +-- packages/frontend/app/routes/assets.$assetId.tsx | 2 +- .../app/routes/assets.$assetId.withdraw-liquidity.tsx | 3 +-- packages/frontend/app/routes/assets.create.tsx | 4 +--- .../frontend/app/routes/peers.$peerId.deposit-liquidity.tsx | 3 +-- .../frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx | 3 +-- packages/frontend/app/routes/peers.create.tsx | 4 +--- packages/frontend/app/routes/wallet-addresses.create.tsx | 4 +--- 8 files changed, 8 insertions(+), 18 deletions(-) diff --git a/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx b/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx index ef8485807a..827f81dfb0 100644 --- a/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx @@ -67,8 +67,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: - 'Could not deposit asset liquidity. Please try again!', + content: 'Could not deposit asset liquidity. Please try again!', type: 'error' }, location: '.' diff --git a/packages/frontend/app/routes/assets.$assetId.tsx b/packages/frontend/app/routes/assets.$assetId.tsx index 85471da3e9..2181fb0484 100644 --- a/packages/frontend/app/routes/assets.$assetId.tsx +++ b/packages/frontend/app/routes/assets.$assetId.tsx @@ -329,7 +329,7 @@ export async function action({ request }: ActionFunctionArgs) { if (!response?.fee) { actionResponse.errors.sendingFee.message = [ - 'Could not update asset sending fee. Please try again!' + 'Could not update asset sending fee. Please try again!' ] return json({ ...actionResponse }, { status: 400 }) } diff --git a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx index 879c56040c..8c2846340f 100644 --- a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx @@ -68,8 +68,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: - 'Could not withdraw asset liquidity. Please try again!', + content: 'Could not withdraw asset liquidity. Please try again!', type: 'error' }, location: '.' diff --git a/packages/frontend/app/routes/assets.create.tsx b/packages/frontend/app/routes/assets.create.tsx index ecf7d591f8..de77d8b603 100644 --- a/packages/frontend/app/routes/assets.create.tsx +++ b/packages/frontend/app/routes/assets.create.tsx @@ -105,9 +105,7 @@ export async function action({ request }: ActionFunctionArgs) { }) if (!response?.asset) { - errors.message = [ - 'Could not create asset. Please try again!' - ] + errors.message = ['Could not create asset. Please try again!'] return json({ errors }, { status: 400 }) } diff --git a/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx b/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx index 7bdcbf29a9..c68d593dba 100644 --- a/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx @@ -67,8 +67,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: - 'Could not deposit peer liquidity. Please try again!', + content: 'Could not deposit peer liquidity. Please try again!', type: 'error' }, location: '.' diff --git a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx index 8173bf5ea0..7911c049da 100644 --- a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx @@ -68,8 +68,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return setMessageAndRedirect({ session, message: { - content: - 'Could not withdraw peer liquidity. Please try again!', + content: 'Could not withdraw peer liquidity. Please try again!', type: 'error' }, location: '.' diff --git a/packages/frontend/app/routes/peers.create.tsx b/packages/frontend/app/routes/peers.create.tsx index d392520616..c643078f58 100644 --- a/packages/frontend/app/routes/peers.create.tsx +++ b/packages/frontend/app/routes/peers.create.tsx @@ -265,9 +265,7 @@ export async function action({ request }: ActionFunctionArgs) { }) if (!response?.peer) { - errors.message = [ - 'Could not create peer. Please try again!' - ] + errors.message = ['Could not create peer. Please try again!'] return json({ errors }, { status: 400 }) } diff --git a/packages/frontend/app/routes/wallet-addresses.create.tsx b/packages/frontend/app/routes/wallet-addresses.create.tsx index b679ad135d..08b2935c65 100644 --- a/packages/frontend/app/routes/wallet-addresses.create.tsx +++ b/packages/frontend/app/routes/wallet-addresses.create.tsx @@ -117,9 +117,7 @@ export async function action({ request }: ActionFunctionArgs) { }) if (!response?.walletAddress) { - errors.message = [ - 'Could not create wallet address. Please try again!' - ] + errors.message = ['Could not create wallet address. Please try again!'] return json({ errors }, { status: 400 }) } From bb02bcee441d1164d3d0ff9932edba69838d5a16 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Wed, 5 Jun 2024 15:35:38 -0700 Subject: [PATCH 20/34] feat: update integration tests --- test/integration/lib/admin-client.ts | 15 ++------------- test/integration/lib/integration-server.ts | 4 ++-- test/integration/lib/test-actions/admin.ts | 3 --- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/test/integration/lib/admin-client.ts b/test/integration/lib/admin-client.ts index 42e2314e96..953e3d1ea2 100644 --- a/test/integration/lib/admin-client.ts +++ b/test/integration/lib/admin-client.ts @@ -30,8 +30,6 @@ export class AdminClient { mutation: gql` mutation CreateReceiver($input: CreateReceiverInput!) { createReceiver(input: $input) { - code - message receiver { completed createdAt @@ -51,7 +49,6 @@ export class AdminClient { } updatedAt } - success } } `, @@ -68,8 +65,6 @@ export class AdminClient { mutation: gql` mutation CreateQuote($input: CreateQuoteInput!) { createQuote(input: $input) { - code - message quote { createdAt expiresAt @@ -109,8 +104,6 @@ export class AdminClient { mutation: gql` mutation CreateOutgoingPayment($input: CreateOutgoingPaymentInput!) { createOutgoingPayment(input: $input) { - code - message payment { createdAt error @@ -136,7 +129,6 @@ export class AdminClient { state stateAttempts } - success } } `, @@ -231,10 +223,8 @@ export class AdminClient { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - code - success - message - error + id + liquidity } } `, @@ -253,7 +243,6 @@ export class AdminClient { mutation: gql` mutation CreateWalletAddress($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - success walletAddress { id url diff --git a/test/integration/lib/integration-server.ts b/test/integration/lib/integration-server.ts index 1c5ccd4616..c635118d92 100644 --- a/test/integration/lib/integration-server.ts +++ b/test/integration/lib/integration-server.ts @@ -134,7 +134,7 @@ export class WebhookEventHandler { }) const { walletAddress } = response - if (!response.success) { + if (!response.walletAddress) { throw new Error('Failed to create wallet address') } if (!walletAddress) { @@ -175,7 +175,7 @@ export class WebhookEventHandler { idempotencyKey: crypto.randomUUID() }) - if (response.code !== '200') { + if (!response.id) { const msg = 'Deposit outgoing payment liquidity failed' throw new Error(msg) } diff --git a/test/integration/lib/test-actions/admin.ts b/test/integration/lib/test-actions/admin.ts index c4fffe5f99..15dc6114d6 100644 --- a/test/integration/lib/test-actions/admin.ts +++ b/test/integration/lib/test-actions/admin.ts @@ -57,7 +57,6 @@ async function createReceiver( const response = await sendingASE.adminClient.createReceiver(createReceiverInput) - expect(response.code).toBe('200') assert(response.receiver) await pollCondition( @@ -90,7 +89,6 @@ async function createQuote( receiver: receiver.id }) - expect(response.code).toBe('200') assert(response.quote) return response.quote @@ -111,7 +109,6 @@ async function createOutgoingPayment( quoteId: quote.id }) - expect(response.code).toBe('201') assert(response.payment) await pollCondition( From 7882d1d6f1783fc03ea67df849d2a2647d64c9fa Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Thu, 6 Jun 2024 10:10:52 -0700 Subject: [PATCH 21/34] fix: rebase induced test errors --- .../graphql/resolvers/wallet_address.test.ts | 57 +++++++------------ 1 file changed, 19 insertions(+), 38 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/wallet_address.test.ts b/packages/backend/src/graphql/resolvers/wallet_address.test.ts index c696a36007..3f3948e4dd 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.test.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.test.ts @@ -148,9 +148,6 @@ describe('Wallet Address Resolvers', (): void => { mutation: gql` mutation CreateWalletAddress($input: CreateWalletAddressInput!) { createWalletAddress(input: $input) { - code - success - message walletAddress { id asset { @@ -180,26 +177,25 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') - assert.ok(response.walletAddress) - expect(response.walletAddress).toEqual({ - __typename: 'WalletAddress', - id: response.walletAddress.id, - url: input.url, - asset: { - __typename: 'Asset', - code: asset.code, - scale: asset.scale - }, - publicName: input.publicName, - additionalProperties: validAdditionalProperties.map((property) => { - return { - __typename: 'AdditionalProperty', - key: property.key, - value: property.value, - visibleInOpenPayments: property.visibleInOpenPayments - } + + assert.ok(response.walletAddress) + expect(response.walletAddress).toEqual({ + __typename: 'WalletAddress', + id: response.walletAddress.id, + url: input.url, + asset: { + __typename: 'Asset', + code: asset.code, + scale: asset.scale + }, + publicName: input.publicName, + additionalProperties: validAdditionalProperties.map((property) => { + return { + __typename: 'AdditionalProperty', + key: property.key, + value: property.value, + visibleInOpenPayments: property.visibleInOpenPayments + } }) }) await expect( @@ -370,9 +366,6 @@ describe('Wallet Address Resolvers', (): void => { mutation: gql` mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - success - message walletAddress { id additionalProperties { @@ -396,8 +389,6 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') expect(response.walletAddress?.additionalProperties).toEqual( updateOptions.additionalProperties.map((property) => { return { @@ -440,9 +431,6 @@ describe('Wallet Address Resolvers', (): void => { mutation: gql` mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - success - message walletAddress { id additionalProperties { @@ -466,8 +454,6 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') // Does not include additional properties from create that were not also in the update expect(response.walletAddress?.additionalProperties).toEqual( updateOptions.additionalProperties.map((property) => { @@ -499,9 +485,6 @@ describe('Wallet Address Resolvers', (): void => { mutation: gql` mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { updateWalletAddress(input: $input) { - code - success - message walletAddress { id additionalProperties { @@ -525,8 +508,6 @@ describe('Wallet Address Resolvers', (): void => { } }) - expect(response.success).toBe(true) - expect(response.code).toEqual('200') expect(response.walletAddress?.additionalProperties).toEqual([]) }) }) From 2ecec471065fa9d102ed66e4166ea6c1493182de Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Fri, 7 Jun 2024 10:50:21 -0700 Subject: [PATCH 22/34] fix: frontend wallet address update --- .../app/routes/wallet-addresses.$walletAddressId.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx index 6ded79ef61..28709066e0 100644 --- a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx +++ b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx @@ -239,10 +239,11 @@ export async function action({ request }: ActionFunctionArgs) { ...result.data }) - if (!response?.success) { + console.log('response=', response) + + if (!response?.walletAddress) { actionResponse.errors.message = [ - response?.message ?? - 'Could not update the wallet address. Please try again!' + 'Could not update the wallet address. Please try again!' ] return json({ ...actionResponse }, { status: 400 }) } From febb43db886502c9b3fa9e7daeb227256433440e Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Fri, 7 Jun 2024 17:20:51 -0700 Subject: [PATCH 23/34] fix: reinstate and fix removed test --- .../src/graphql/middleware/index.test.ts | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/backend/src/graphql/middleware/index.test.ts b/packages/backend/src/graphql/middleware/index.test.ts index 545228f8ab..9631870034 100644 --- a/packages/backend/src/graphql/middleware/index.test.ts +++ b/packages/backend/src/graphql/middleware/index.test.ts @@ -16,6 +16,7 @@ import { UpdateAssetInput } from '../generated/graphql' import { GraphQLError } from 'graphql' +import { AssetError, errorToMessage, errorToCode } from '../../asset/errors' describe('GraphQL Middleware', (): void => { let deps: IocContract @@ -167,6 +168,46 @@ describe('GraphQL Middleware', (): void => { }) }) + test('does not return original response on repeat call with different idempotency key', async (): Promise => { + const input: CreateAssetInput = { + ...randomAsset(), + idempotencyKey: uuid() + } + + const createAssetSpy = jest.spyOn(assetService, 'create') + + const initialResponse = await callCreateAssetMutation(input) + + expect(createAssetSpy).toHaveBeenCalledTimes(1) + assert.ok(initialResponse.asset) + expect(initialResponse).toEqual({ + __typename: 'AssetMutationResponse', + asset: { + __typename: 'Asset', + id: initialResponse.asset.id, + code: input.code, + scale: input.scale, + withdrawalThreshold: null + } + }) + + createAssetSpy.mockClear() + + const repeatResponse = callCreateAssetMutation({ + ...input, + idempotencyKey: uuid() + }) + + await expect(repeatResponse).rejects.toThrow( + new GraphQLError(errorToMessage[AssetError.DuplicateAsset], { + extensions: { + code: errorToCode[AssetError.DuplicateAsset] + } + }) + ) + expect(createAssetSpy).toHaveBeenCalledTimes(1) + }) + test('throws if different input parameters for same idempotency key', async (): Promise => { const idempotencyKey = uuid() const input: CreateAssetInput = { From 766aea26cb3557f69d131aca4337378f1c3a4e75 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Mon, 10 Jun 2024 10:27:59 -0700 Subject: [PATCH 24/34] fix: change some payment gql error codes --- packages/backend/src/open_payments/payment/incoming/errors.ts | 2 +- packages/backend/src/open_payments/payment/outgoing/errors.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/open_payments/payment/incoming/errors.ts b/packages/backend/src/open_payments/payment/incoming/errors.ts index af3362ca70..d38b41d761 100644 --- a/packages/backend/src/open_payments/payment/incoming/errors.ts +++ b/packages/backend/src/open_payments/payment/incoming/errors.ts @@ -34,7 +34,7 @@ export const errorToCode: { [IncomingPaymentError.UnknownPayment]: GraphQLErrorCode.NotFound, [IncomingPaymentError.InvalidState]: GraphQLErrorCode.BadUserInput, [IncomingPaymentError.InvalidExpiry]: GraphQLErrorCode.BadUserInput, - [IncomingPaymentError.WrongState]: GraphQLErrorCode.BadUserInput, + [IncomingPaymentError.WrongState]: GraphQLErrorCode.Conflict, [IncomingPaymentError.InactiveWalletAddress]: GraphQLErrorCode.Inactive } diff --git a/packages/backend/src/open_payments/payment/outgoing/errors.ts b/packages/backend/src/open_payments/payment/outgoing/errors.ts index 53b805ac24..30c684b5bf 100644 --- a/packages/backend/src/open_payments/payment/outgoing/errors.ts +++ b/packages/backend/src/open_payments/payment/outgoing/errors.ts @@ -57,7 +57,7 @@ export const errorToCode: { [OutgoingPaymentError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, [OutgoingPaymentError.UnknownPayment]: GraphQLErrorCode.NotFound, [OutgoingPaymentError.UnknownQuote]: GraphQLErrorCode.NotFound, - [OutgoingPaymentError.WrongState]: GraphQLErrorCode.BadUserInput, + [OutgoingPaymentError.WrongState]: GraphQLErrorCode.Conflict, [OutgoingPaymentError.InvalidQuote]: GraphQLErrorCode.BadUserInput, [OutgoingPaymentError.InsufficientGrant]: GraphQLErrorCode.Forbidden, [OutgoingPaymentError.InactiveWalletAddress]: GraphQLErrorCode.Inactive, From 9d34ad59888d7e1f5e340904c7d47bd3f71b2015 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Thu, 13 Jun 2024 13:28:33 -0700 Subject: [PATCH 25/34] feat: change liquidity response to just return success --- .../Create Asset Liquidity Withdrawal.bru | 3 +- .../Create Incoming Payment Withdrawal.bru | 3 +- .../Create Outgoing Payment Withdrawal.bru | 3 +- .../Create Peer Liquidity Withdrawal.bru | 3 +- .../Deposit Asset Liquidity.bru | 3 +- .../Deposit Event Liquidity.bru | 3 +- .../Deposit Outgoing Payment Liquidity.bru | 3 +- .../Deposit Peer Liquidity.bru | 3 +- .../Post Liquidity Withdrawal.bru | 3 +- .../Void Liquidity Withdrawal.bru | 3 +- .../Withdraw Event Liquidity.bru | 3 +- .../app/lib/requesters.ts | 6 +- .../app/lib/webhooks.server.ts | 19 +- .../generated/graphql.ts | 6 +- .../src/graphql/generated/graphql.schema.json | 16 +- .../backend/src/graphql/generated/graphql.ts | 6 +- .../src/graphql/resolvers/liquidity.test.ts | 162 +++++++----------- .../src/graphql/resolvers/liquidity.ts | 31 ++-- packages/backend/src/graphql/schema.graphql | 3 +- packages/frontend/app/generated/graphql.ts | 20 +-- packages/frontend/app/lib/api/asset.server.ts | 6 +- .../frontend/app/lib/api/payments.server.ts | 9 +- packages/frontend/app/lib/api/peer.server.ts | 6 +- .../assets.$assetId.deposit-liquidity.tsx | 2 +- .../assets.$assetId.withdraw-liquidity.tsx | 2 +- ....$incomingPaymentId.withdraw-liquidity.tsx | 2 +- ...g.$outgoingPaymentId.deposit-liquidity.tsx | 2 +- ....$outgoingPaymentId.withdraw-liquidity.tsx | 2 +- .../peers.$peerId.deposit-liquidity.tsx | 2 +- .../peers.$peerId.withdraw-liquidity.tsx | 2 +- .../src/generated/graphql.ts | 6 +- test/integration/lib/generated/graphql.ts | 6 +- 32 files changed, 121 insertions(+), 228 deletions(-) diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru index ed51a83919..552163a6ea 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation CreateAssetLiquidityWithdrawal ($input: CreateAssetLiquidityWithdrawalInput!) { createAssetLiquidityWithdrawal(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru index 82b433fe1f..3c8243c573 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation CreateIncomingPaymentWithdrawal($input: CreateIncomingPaymentWithdrawalInput!) { createIncomingPaymentWithdrawal(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru index 8d105398dd..2e063f382f 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation CreateOutgoingPaymentWithdrawal($input: CreateOutgoingPaymentWithdrawalInput!) { createOutgoingPaymentWithdrawal(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru index 9f40b8e534..d4fcc195a9 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation CreatePeerLiquidityWithdrawal ($input: CreatePeerLiquidityWithdrawalInput!) { createPeerLiquidityWithdrawal(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru index a71facad84..038029f179 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Asset Liquidity.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation DepositAssetLiquidity ($input: DepositAssetLiquidityInput!) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru index ca5a7884b8..48751deca0 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Event Liquidity.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation DepositEventLiquidity($input: DepositEventLiquidityInput!) { depositEventLiquidity(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru index c578c7ff49..a02bc5b8c6 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Outgoing Payment Liquidity.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation DepositOutgoingPaymentLiquidity($input: DepositOutgoingPaymentLiquidityInput!) { depositOutgoingPaymentLiquidity(input: $input) { - id - liquidity + success } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru index 7ffcf701ec..3b2ae41c07 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Deposit Peer Liquidity.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation DepositPeerLiquidity ($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru index 009a7d2abb..6fae5f0df5 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Post Liquidity Withdrawal.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation PostLiquidityWithdrawal($input: PostLiquidityWithdrawalInput!) { postLiquidityWithdrawal(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru index b6f5544944..8b8448bbe8 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Void Liquidity Withdrawal.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation VoidLiquidityWithdrawal($input: VoidLiquidityWithdrawalInput!) { voidLiquidityWithdrawal(input: $input) { - id - liquidity + success } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru index ccc56d08b5..1dfdf8466b 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Event Liquidity.bru @@ -13,8 +13,7 @@ post { body:graphql { mutation WithdrawEventLiquidity($input: WithdrawEventLiquidityInput!) { withdrawEventLiquidity(input: $input) { - id - liquidity + success } } } diff --git a/localenv/mock-account-servicing-entity/app/lib/requesters.ts b/localenv/mock-account-servicing-entity/app/lib/requesters.ts index 5080d392d5..0cb583f4e7 100644 --- a/localenv/mock-account-servicing-entity/app/lib/requesters.ts +++ b/localenv/mock-account-servicing-entity/app/lib/requesters.ts @@ -18,8 +18,7 @@ export async function depositPeerLiquidity( const depositPeerLiquidityMutation = gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } ` @@ -53,8 +52,7 @@ export async function depositAssetLiquidity( const depositAssetLiquidityMutation = gql` mutation DepositAssetLiquidity($input: DepositAssetLiquidityInput!) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } ` diff --git a/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts b/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts index fee90c8291..72c44fd7fc 100644 --- a/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts +++ b/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts @@ -83,9 +83,9 @@ export async function handleOutgoingPaymentCreated(wh: Webhook) { mutation: gql` mutation CancelOutgoingPayment($input: CancelOutgoingPaymentInput!) { cancelOutgoingPayment(input: $input) { - code - success - message + payment { + id + } } } `, @@ -107,8 +107,7 @@ export async function handleOutgoingPaymentCreated(wh: Webhook) { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - id - liquidity + success } } `, @@ -157,8 +156,7 @@ export async function handleIncomingPaymentCompletedExpired(wh: Webhook) { $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -204,10 +202,6 @@ export async function handleWalletAddressWebMonetization(wh: Webhook) { $input: CreateWalletAddressWithdrawalInput! ) { createWalletAddressWithdrawal(input: $input) { - code - error - message - success withdrawal { amount id @@ -243,10 +237,7 @@ export async function handleWalletAddressWebMonetization(wh: Webhook) { $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - code success - message - error } } `, diff --git a/localenv/mock-account-servicing-entity/generated/graphql.ts b/localenv/mock-account-servicing-entity/generated/graphql.ts index 9003994529..46f7835344 100644 --- a/localenv/mock-account-servicing-entity/generated/graphql.ts +++ b/localenv/mock-account-servicing-entity/generated/graphql.ts @@ -573,8 +573,7 @@ export enum LiquidityError { export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - id: Scalars['ID']['output']; - liquidity?: Maybe; + success: Scalars['Boolean']['output']; }; export type Model = { @@ -1881,8 +1880,7 @@ export type JwkResolvers = { - id?: Resolver; - liquidity?: Resolver, ParentType, ContextType>; + success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/packages/backend/src/graphql/generated/graphql.schema.json b/packages/backend/src/graphql/generated/graphql.schema.json index ed130b93d2..30050b3cc7 100644 --- a/packages/backend/src/graphql/generated/graphql.schema.json +++ b/packages/backend/src/graphql/generated/graphql.schema.json @@ -3574,7 +3574,7 @@ "description": null, "fields": [ { - "name": "id", + "name": "success", "description": null, "args": [], "type": { @@ -3582,24 +3582,12 @@ "name": null, "ofType": { "kind": "SCALAR", - "name": "ID", + "name": "Boolean", "ofType": null } }, "isDeprecated": false, "deprecationReason": null - }, - { - "name": "liquidity", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "UInt64", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null } ], "inputFields": null, diff --git a/packages/backend/src/graphql/generated/graphql.ts b/packages/backend/src/graphql/generated/graphql.ts index 9003994529..46f7835344 100644 --- a/packages/backend/src/graphql/generated/graphql.ts +++ b/packages/backend/src/graphql/generated/graphql.ts @@ -573,8 +573,7 @@ export enum LiquidityError { export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - id: Scalars['ID']['output']; - liquidity?: Maybe; + success: Scalars['Boolean']['output']; }; export type Model = { @@ -1881,8 +1880,7 @@ export type JwkResolvers = { - id?: Resolver; - liquidity?: Resolver, ParentType, ContextType>; + success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/packages/backend/src/graphql/resolvers/liquidity.test.ts b/packages/backend/src/graphql/resolvers/liquidity.test.ts index 06fbaf9a7b..9403f6f1d0 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.test.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.test.ts @@ -80,8 +80,7 @@ describe('Liquidity Resolvers', (): void => { mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } `, @@ -102,8 +101,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.id).toEqual(id) - expect(response.liquidity).toEqual('100') + expect(response.success).toBe(true) }) test('Returns an error for invalid id', async (): Promise => { @@ -112,8 +110,7 @@ describe('Liquidity Resolvers', (): void => { mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } `, @@ -149,8 +146,7 @@ describe('Liquidity Resolvers', (): void => { mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } `, @@ -194,8 +190,7 @@ describe('Liquidity Resolvers', (): void => { mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } `, @@ -231,8 +226,7 @@ describe('Liquidity Resolvers', (): void => { mutation: gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } `, @@ -279,8 +273,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } `, @@ -301,8 +294,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.id).toEqual(id) - expect(response.liquidity).toEqual('100') + expect(response.success).toBe(true) }) test('Returns an error for invalid id', async (): Promise => { @@ -313,8 +305,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } `, @@ -352,8 +343,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } `, @@ -399,8 +389,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } `, @@ -438,8 +427,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } `, @@ -494,8 +482,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -517,8 +504,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.id).toEqual(id) - expect(response.liquidity).toEqual(startingBalance.toString()) + expect(response.success).toBe(true) }) test('Returns an error for unknown peer', async (): Promise => { @@ -529,8 +515,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -569,8 +554,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -617,8 +601,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -662,8 +645,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -720,8 +702,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -743,8 +724,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.id).toEqual(id) - expect(response.liquidity).toEqual(startingBalance.toString()) + expect(response.success).toBe(true) }) test('Returns an error for unknown asset', async (): Promise => { @@ -755,8 +735,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -795,8 +774,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -843,8 +821,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -889,8 +866,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -1197,7 +1173,7 @@ describe('Liquidity Resolvers', (): void => { $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - id + success } } `, @@ -1216,7 +1192,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.id).toEqual(withdrawalId) + expect(response.success).toBe(true) }) test("Can't post non-existent withdrawal", async (): Promise => { @@ -1227,8 +1203,7 @@ describe('Liquidity Resolvers', (): void => { $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -1264,8 +1239,7 @@ describe('Liquidity Resolvers', (): void => { $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -1304,8 +1278,7 @@ describe('Liquidity Resolvers', (): void => { $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -1344,8 +1317,7 @@ describe('Liquidity Resolvers', (): void => { $input: PostLiquidityWithdrawalInput! ) { postLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -1409,7 +1381,7 @@ describe('Liquidity Resolvers', (): void => { $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - id + success } } `, @@ -1428,7 +1400,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.id).toEqual(withdrawalId) + expect(response.success).toBe(true) }) test("Can't void non-existent withdrawal", async (): Promise => { @@ -1439,7 +1411,7 @@ describe('Liquidity Resolvers', (): void => { $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - id + success } } `, @@ -1475,7 +1447,7 @@ describe('Liquidity Resolvers', (): void => { $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - id + success } } `, @@ -1514,7 +1486,7 @@ describe('Liquidity Resolvers', (): void => { $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - id + success } } `, @@ -1553,7 +1525,7 @@ describe('Liquidity Resolvers', (): void => { $input: VoidLiquidityWithdrawalInput! ) { voidLiquidityWithdrawal(input: $input) { - id + success } } `, @@ -1644,8 +1616,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositEventLiquidityInput! ) { depositEventLiquidity(input: $input) { - id - liquidity + success } } `, @@ -1664,7 +1635,7 @@ describe('Liquidity Resolvers', (): void => { } }) - assert.ok(response.id) + expect(response.success).toBe(true) assert.ok(payment.debitAmount) await expect(depositSpy).toHaveBeenCalledWith({ id: eventId, @@ -1684,8 +1655,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositEventLiquidityInput! ) { depositEventLiquidity(input: $input) { - id - liquidity + success } } `, @@ -1728,8 +1698,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositEventLiquidityInput! ) { depositEventLiquidity(input: $input) { - id - liquidity + success } } `, @@ -1870,8 +1839,7 @@ describe('Liquidity Resolvers', (): void => { $input: WithdrawEventLiquidityInput! ) { withdrawEventLiquidity(input: $input) { - id - liquidity + success } } `, @@ -1890,8 +1858,7 @@ describe('Liquidity Resolvers', (): void => { } }) - expect(response.id).toEqual(eventId) - expect(response.liquidity).toEqual('10') + expect(response.success).toBe(true) }) test('Returns error for non-existent webhook event id', async (): Promise => { @@ -1902,8 +1869,7 @@ describe('Liquidity Resolvers', (): void => { $input: WithdrawEventLiquidityInput! ) { withdrawEventLiquidity(input: $input) { - id - liquidity + success } } `, @@ -1942,8 +1908,7 @@ describe('Liquidity Resolvers', (): void => { $input: WithdrawEventLiquidityInput! ) { withdrawEventLiquidity(input: $input) { - id - liquidity + success } } `, @@ -2053,8 +2018,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2074,7 +2038,7 @@ describe('Liquidity Resolvers', (): void => { } }) - assert.ok(response.id) + expect(response.success).toBe(true) expect( accountingService.getBalance(incomingPayment.id) ).resolves.toEqual(balance - amount) @@ -2101,8 +2065,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2139,8 +2102,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2196,8 +2158,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2271,8 +2232,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2292,7 +2252,7 @@ describe('Liquidity Resolvers', (): void => { } }) - assert.ok(response.id) + expect(response.success).toBe(true) expect( accountingService.getBalance(outgoingPayment.id) ).resolves.toEqual(balance - amount) @@ -2308,8 +2268,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2352,8 +2311,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2408,8 +2366,7 @@ describe('Liquidity Resolvers', (): void => { $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -2467,8 +2424,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - id - liquidity + success } } `, @@ -2487,7 +2443,7 @@ describe('Liquidity Resolvers', (): void => { } }) - assert.ok(response.id) + expect(response.success).toBe(true) assert.ok(outgoingPayment.debitAmount) await expect(depositSpy).toHaveBeenCalledWith({ id: eventId, @@ -2507,8 +2463,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - id - liquidity + success } } `, @@ -2551,8 +2506,7 @@ describe('Liquidity Resolvers', (): void => { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - id - liquidity + success } } `, diff --git a/packages/backend/src/graphql/resolvers/liquidity.ts b/packages/backend/src/graphql/resolvers/liquidity.ts index 4f04259f2f..8760f24400 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.ts @@ -118,8 +118,7 @@ export const depositPeerLiquidity: MutationResolvers['depositPeer } return { - id: args.input.id, - liquidity: args.input.amount + success: true } } @@ -159,8 +158,7 @@ export const depositAssetLiquidity: MutationResolvers['depositAss }) } return { - id: args.input.id, - liquidity: args.input.amount + success: true } } @@ -202,8 +200,7 @@ export const createPeerLiquidityWithdrawal: MutationResolvers['cr }) } return { - id, - liquidity: amount + success: true } } @@ -245,8 +242,7 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c }) } return { - id, - liquidity: amount + success: true } } @@ -321,7 +317,7 @@ export const postLiquidityWithdrawal: MutationResolvers['postLiqu }) } return { - id: args.input.withdrawalId + success: true } } @@ -343,7 +339,7 @@ export const voidLiquidityWithdrawal: MutationResolvers['voidLiqu }) } return { - id: args.input.withdrawalId + success: true } } @@ -392,8 +388,7 @@ export const depositEventLiquidity: MutationResolvers['depositEve }) } return { - id: event.data.id, - liquidity: BigInt(event.data.debitAmount.value) + success: true } } @@ -435,8 +430,7 @@ export const withdrawEventLiquidity: MutationResolvers['withdrawE } // TODO: check for and handle leftover incoming payment or payment balance return { - id: event.id, - liquidity: event.withdrawal.amount + success: true } } @@ -479,8 +473,7 @@ export const depositOutgoingPaymentLiquidity: MutationResolvers[' }) } return { - id: outgoingPaymentId, - liquidity: BigInt(event.data.debitAmount.value) + success: true } } @@ -532,8 +525,7 @@ export const createIncomingPaymentWithdrawal: MutationResolvers[' }) } return { - id: event.id, - liquidity: incomingPayment.receivedAmount.value + success: true } } @@ -597,8 +589,7 @@ export const createOutgoingPaymentWithdrawal: MutationResolvers[' }) } return { - id: event.id, - liquidity: balance + success: true } } diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index 95b0635efb..f355841f72 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -1232,8 +1232,7 @@ type DeletePeerMutationResponse { } type LiquidityMutationResponse { - id: ID! - liquidity: UInt64 + success: Boolean! } type WalletAddressWithdrawalMutationResponse { diff --git a/packages/frontend/app/generated/graphql.ts b/packages/frontend/app/generated/graphql.ts index 0812a092bd..6ea2f94b0f 100644 --- a/packages/frontend/app/generated/graphql.ts +++ b/packages/frontend/app/generated/graphql.ts @@ -573,8 +573,7 @@ export enum LiquidityError { export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - id: Scalars['ID']['output']; - liquidity?: Maybe; + success: Scalars['Boolean']['output']; }; export type Model = { @@ -1881,8 +1880,7 @@ export type JwkResolvers = { - id?: Resolver; - liquidity?: Resolver, ParentType, ContextType>; + success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; @@ -2313,14 +2311,14 @@ export type DepositAssetLiquidityMutationVariables = Exact<{ }>; -export type DepositAssetLiquidityMutation = { __typename?: 'Mutation', depositAssetLiquidity?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; +export type DepositAssetLiquidityMutation = { __typename?: 'Mutation', depositAssetLiquidity?: { __typename?: 'LiquidityMutationResponse', success: boolean } | null }; export type WithdrawAssetLiquidityVariables = Exact<{ input: CreateAssetLiquidityWithdrawalInput; }>; -export type WithdrawAssetLiquidity = { __typename?: 'Mutation', createAssetLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; +export type WithdrawAssetLiquidity = { __typename?: 'Mutation', createAssetLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean } | null }; export type DeleteAssetMutationVariables = Exact<{ input: DeleteAssetInput; @@ -2359,21 +2357,21 @@ export type DepositOutgoingPaymentLiquidityVariables = Exact<{ }>; -export type DepositOutgoingPaymentLiquidity = { __typename?: 'Mutation', depositOutgoingPaymentLiquidity?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; +export type DepositOutgoingPaymentLiquidity = { __typename?: 'Mutation', depositOutgoingPaymentLiquidity?: { __typename?: 'LiquidityMutationResponse', success: boolean } | null }; export type CreateOutgoingPaymentWithdrawalVariables = Exact<{ input: CreateOutgoingPaymentWithdrawalInput; }>; -export type CreateOutgoingPaymentWithdrawal = { __typename?: 'Mutation', createOutgoingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; +export type CreateOutgoingPaymentWithdrawal = { __typename?: 'Mutation', createOutgoingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean } | null }; export type CreateIncomingPaymentWithdrawalVariables = Exact<{ input: CreateIncomingPaymentWithdrawalInput; }>; -export type CreateIncomingPaymentWithdrawal = { __typename?: 'Mutation', createIncomingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; +export type CreateIncomingPaymentWithdrawal = { __typename?: 'Mutation', createIncomingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean } | null }; export type GetPeerQueryVariables = Exact<{ id: Scalars['String']['input']; @@ -2418,14 +2416,14 @@ export type DepositPeerLiquidityMutationVariables = Exact<{ }>; -export type DepositPeerLiquidityMutation = { __typename?: 'Mutation', depositPeerLiquidity?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; +export type DepositPeerLiquidityMutation = { __typename?: 'Mutation', depositPeerLiquidity?: { __typename?: 'LiquidityMutationResponse', success: boolean } | null }; export type WithdrawPeerLiquidityVariables = Exact<{ input: CreatePeerLiquidityWithdrawalInput; }>; -export type WithdrawPeerLiquidity = { __typename?: 'Mutation', createPeerLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', id: string, liquidity?: bigint | null } | null }; +export type WithdrawPeerLiquidity = { __typename?: 'Mutation', createPeerLiquidityWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean } | null }; export type GetWalletAddressQueryVariables = Exact<{ id: Scalars['String']['input']; diff --git a/packages/frontend/app/lib/api/asset.server.ts b/packages/frontend/app/lib/api/asset.server.ts index abfca22651..25935c531f 100644 --- a/packages/frontend/app/lib/api/asset.server.ts +++ b/packages/frontend/app/lib/api/asset.server.ts @@ -237,8 +237,7 @@ export const depositAssetLiquidity = async ( $input: DepositAssetLiquidityInput! ) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } `, @@ -262,8 +261,7 @@ export const withdrawAssetLiquidity = async ( $input: CreateAssetLiquidityWithdrawalInput! ) { createAssetLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, diff --git a/packages/frontend/app/lib/api/payments.server.ts b/packages/frontend/app/lib/api/payments.server.ts index ff655b0d17..8c330d10a2 100644 --- a/packages/frontend/app/lib/api/payments.server.ts +++ b/packages/frontend/app/lib/api/payments.server.ts @@ -151,8 +151,7 @@ export const depositOutgoingPaymentLiquidity = async ( $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - id - liquidity + success } } `, @@ -176,8 +175,7 @@ export const createOutgoingPaymentWithdrawal = async ( $input: CreateOutgoingPaymentWithdrawalInput! ) { createOutgoingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, @@ -201,8 +199,7 @@ export const createIncomingPaymentWithdrawal = async ( $input: CreateIncomingPaymentWithdrawalInput! ) { createIncomingPaymentWithdrawal(input: $input) { - id - liquidity + success } } `, diff --git a/packages/frontend/app/lib/api/peer.server.ts b/packages/frontend/app/lib/api/peer.server.ts index a92c491631..fd064ed0c5 100644 --- a/packages/frontend/app/lib/api/peer.server.ts +++ b/packages/frontend/app/lib/api/peer.server.ts @@ -175,8 +175,7 @@ export const depositPeerLiquidity = async (args: DepositPeerLiquidityInput) => { $input: DepositPeerLiquidityInput! ) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } `, @@ -200,8 +199,7 @@ export const withdrawPeerLiquidity = async ( $input: CreatePeerLiquidityWithdrawalInput! ) { createPeerLiquidityWithdrawal(input: $input) { - id - liquidity + success } } `, diff --git a/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx b/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx index 827f81dfb0..64b86ac5aa 100644 --- a/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/assets.$assetId.deposit-liquidity.tsx @@ -63,7 +63,7 @@ export async function action({ request, params }: ActionFunctionArgs) { idempotencyKey: v4() }) - if (!response?.id) { + if (!response?.success) { return setMessageAndRedirect({ session, message: { diff --git a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx index 8c2846340f..c8b4a8d7a1 100644 --- a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx @@ -64,7 +64,7 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.id) { + if (!response?.success) { return setMessageAndRedirect({ session, message: { diff --git a/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx b/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx index e3dd9cea2a..66c4bea3f6 100644 --- a/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx @@ -49,7 +49,7 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.id) { + if (!response?.success) { return setMessageAndRedirect({ session, message: { diff --git a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx index 18943dd897..e16ad39ff9 100644 --- a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.deposit-liquidity.tsx @@ -50,7 +50,7 @@ export async function action({ request, params }: ActionFunctionArgs) { idempotencyKey: v4() }) - if (!response?.id) { + if (!response?.success) { return setMessageAndRedirect({ session, message: { diff --git a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx index 9b311d960b..0740ea309e 100644 --- a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx @@ -51,7 +51,7 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.id) { + if (!response?.success) { return setMessageAndRedirect({ session, message: { diff --git a/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx b/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx index c68d593dba..3b1fbd2558 100644 --- a/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx +++ b/packages/frontend/app/routes/peers.$peerId.deposit-liquidity.tsx @@ -63,7 +63,7 @@ export async function action({ request, params }: ActionFunctionArgs) { idempotencyKey: v4() }) - if (!response?.id) { + if (!response?.success) { return setMessageAndRedirect({ session, message: { diff --git a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx index 7911c049da..228651adc9 100644 --- a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx @@ -64,7 +64,7 @@ export async function action({ request, params }: ActionFunctionArgs) { timeoutSeconds: BigInt(0) }) - if (!response?.id) { + if (!response?.success) { return setMessageAndRedirect({ session, message: { diff --git a/packages/mock-account-service-lib/src/generated/graphql.ts b/packages/mock-account-service-lib/src/generated/graphql.ts index 9003994529..46f7835344 100644 --- a/packages/mock-account-service-lib/src/generated/graphql.ts +++ b/packages/mock-account-service-lib/src/generated/graphql.ts @@ -573,8 +573,7 @@ export enum LiquidityError { export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - id: Scalars['ID']['output']; - liquidity?: Maybe; + success: Scalars['Boolean']['output']; }; export type Model = { @@ -1881,8 +1880,7 @@ export type JwkResolvers = { - id?: Resolver; - liquidity?: Resolver, ParentType, ContextType>; + success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/test/integration/lib/generated/graphql.ts b/test/integration/lib/generated/graphql.ts index 9003994529..46f7835344 100644 --- a/test/integration/lib/generated/graphql.ts +++ b/test/integration/lib/generated/graphql.ts @@ -573,8 +573,7 @@ export enum LiquidityError { export type LiquidityMutationResponse = { __typename?: 'LiquidityMutationResponse'; - id: Scalars['ID']['output']; - liquidity?: Maybe; + success: Scalars['Boolean']['output']; }; export type Model = { @@ -1881,8 +1880,7 @@ export type JwkResolvers = { - id?: Resolver; - liquidity?: Resolver, ParentType, ContextType>; + success?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; From 29a48eb4c150de598a0ef7bd9838d9ea9e0752bd Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Thu, 13 Jun 2024 13:44:18 -0700 Subject: [PATCH 26/34] fix: bigints, integration query --- packages/backend/src/graphql/resolvers/liquidity.ts | 6 +++--- test/integration/lib/admin-client.ts | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/liquidity.ts b/packages/backend/src/graphql/resolvers/liquidity.ts index 8760f24400..ba434e31ea 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.ts @@ -128,7 +128,7 @@ export const depositAssetLiquidity: MutationResolvers['depositAss args, ctx ): Promise => { - if (args.input.amount === BigInt(0)) { + if (args.input.amount === 0n) { throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { extensions: { code: errorToCode[LiquidityError.AmountZero] @@ -211,7 +211,7 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c ctx ): Promise => { const { amount, id, timeoutSeconds, assetId } = args.input - if (amount === BigInt(0)) { + if (amount === 0n) { throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { extensions: { code: errorToCode[LiquidityError.AmountZero] @@ -269,7 +269,7 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr const amount = await accountingService.getBalance(walletAddress.id) if (amount === undefined) throw new Error('missing incoming payment wallet address') - if (amount === BigInt(0)) { + if (amount === 0n) { throw new GraphQLError(errorToMessage[LiquidityError.AmountZero], { extensions: { code: errorToCode[LiquidityError.AmountZero] diff --git a/test/integration/lib/admin-client.ts b/test/integration/lib/admin-client.ts index 953e3d1ea2..08f176ad67 100644 --- a/test/integration/lib/admin-client.ts +++ b/test/integration/lib/admin-client.ts @@ -223,8 +223,7 @@ export class AdminClient { $input: DepositOutgoingPaymentLiquidityInput! ) { depositOutgoingPaymentLiquidity(input: $input) { - id - liquidity + success } } `, From 3175268b5c90b581de33637cf1d0364a35e4563c Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Fri, 14 Jun 2024 11:52:54 -0700 Subject: [PATCH 27/34] fix: integration tests --- packages/mock-account-service-lib/src/requesters.ts | 6 ++---- packages/mock-account-service-lib/src/seed.ts | 12 ++++-------- test/integration/lib/integration-server.ts | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/packages/mock-account-service-lib/src/requesters.ts b/packages/mock-account-service-lib/src/requesters.ts index fdf89971d4..e6edd93bb9 100644 --- a/packages/mock-account-service-lib/src/requesters.ts +++ b/packages/mock-account-service-lib/src/requesters.ts @@ -246,8 +246,7 @@ export async function depositPeerLiquidity( const depositPeerLiquidityMutation = gql` mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { depositPeerLiquidity(input: $input) { - id - liquidity + success } } ` @@ -283,8 +282,7 @@ export async function depositAssetLiquidity( const depositAssetLiquidityMutation = gql` mutation DepositAssetLiquidity($input: DepositAssetLiquidityInput!) { depositAssetLiquidity(input: $input) { - id - liquidity + success } } ` diff --git a/packages/mock-account-service-lib/src/seed.ts b/packages/mock-account-service-lib/src/seed.ts index 50a82a2615..eb1fc20515 100644 --- a/packages/mock-account-service-lib/src/seed.ts +++ b/packages/mock-account-service-lib/src/seed.ts @@ -48,14 +48,10 @@ export async function setupFromSeed( throw new Error('asset not defined') } - const initialLiquidity = await depositAssetLiquidity( - asset.id, - liquidity, - v4() - ) + await depositAssetLiquidity(asset.id, liquidity, v4()) assets[code] = asset - logger.debug({ asset, initialLiquidity }) + logger.debug({ asset, liquidity }) const { fees } = config.seed const fee = fees.find((fee) => fee.asset === code && fee.scale == scale) @@ -80,12 +76,12 @@ export async function setupFromSeed( throw new Error('peer response not defined') } const transferUid = v4() - const liquidity = await depositPeerLiquidity( + await depositPeerLiquidity( peerResponse.id, peer.initialLiquidity, transferUid ) - return [peerResponse, liquidity] + return [peerResponse, peer.initialLiquidity] }) ) diff --git a/test/integration/lib/integration-server.ts b/test/integration/lib/integration-server.ts index c635118d92..67d3f76bc0 100644 --- a/test/integration/lib/integration-server.ts +++ b/test/integration/lib/integration-server.ts @@ -175,7 +175,7 @@ export class WebhookEventHandler { idempotencyKey: crypto.randomUUID() }) - if (!response.id) { + if (!response.success) { const msg = 'Deposit outgoing payment liquidity failed' throw new Error(msg) } From 02b5816f2a942f7b48bb50088bc27518f3004b83 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Tue, 18 Jun 2024 15:29:20 -0700 Subject: [PATCH 28/34] fix: asset test --- packages/backend/src/asset/errors.ts | 2 +- packages/backend/src/graphql/plugin/index.ts | 3 +- .../src/graphql/resolvers/asset.test.ts | 29 ++++++++++++++----- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/packages/backend/src/asset/errors.ts b/packages/backend/src/asset/errors.ts index 7a7c7ff682..36334ab1fc 100644 --- a/packages/backend/src/asset/errors.ts +++ b/packages/backend/src/asset/errors.ts @@ -11,7 +11,7 @@ export const isAssetError = (o: any): o is AssetError => Object.values(AssetError).includes(o) export const errorToCode: { - [key in AssetError]: string + [key in AssetError]: GraphQLErrorCode } = { [AssetError.UnknownAsset]: GraphQLErrorCode.NotFound, [AssetError.DuplicateAsset]: GraphQLErrorCode.Duplicate, diff --git a/packages/backend/src/graphql/plugin/index.ts b/packages/backend/src/graphql/plugin/index.ts index 10e4a2ce94..7a02eddc69 100644 --- a/packages/backend/src/graphql/plugin/index.ts +++ b/packages/backend/src/graphql/plugin/index.ts @@ -6,6 +6,7 @@ import { } from '@apollo/server' import { Logger } from 'pino' import { v4 as uuid } from 'uuid' +import { GraphQLErrorCode } from '../errors' export class LoggingPlugin implements ApolloServerPlugin { private logger @@ -34,7 +35,7 @@ export class LoggingPlugin implements ApolloServerPlugin { ): Promise { if (context.errors) { context.errors.forEach((error) => { - if (error.extensions.code === 'INTERNAL_SERVER_ERROR') { + if (error.extensions.code === GraphQLErrorCode.InternalServerError) { logger.error({ requestId, variables: context.request.variables, diff --git a/packages/backend/src/graphql/resolvers/asset.test.ts b/packages/backend/src/graphql/resolvers/asset.test.ts index 8a6312488e..0f04407c50 100644 --- a/packages/backend/src/graphql/resolvers/asset.test.ts +++ b/packages/backend/src/graphql/resolvers/asset.test.ts @@ -1,7 +1,6 @@ import { gql } from '@apollo/client' import assert from 'assert' import { v4 as uuid } from 'uuid' -import { ApolloError } from '@apollo/client' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' @@ -33,6 +32,7 @@ import { isFeeError } from '../../fee/errors' import { createFee } from '../../tests/fee' import { createAsset } from '../../tests/asset' import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' describe('Asset Resolvers', (): void => { let deps: IocContract @@ -156,11 +156,14 @@ describe('Asset Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('Asset already exists') + await expect(gqlQuery).rejects.toThrow(new GraphQLError(errorToMessage[AssetError.DuplicateAsset], { + extensions: { + code: errorToCode[AssetError.DuplicateAsset] + } + })) }) - test('500', async (): Promise => { + test('handles unexpected error', async (): Promise => { jest .spyOn(assetService, 'create') .mockRejectedValueOnce(new Error('unexpected')) @@ -187,7 +190,11 @@ describe('Asset Resolvers', (): void => { throw new Error('Data was empty') } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow(new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + })) }) }) @@ -361,7 +368,11 @@ describe('Asset Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow(new GraphQLError(errorToMessage[AssetError.UnknownAsset], { + extensions: { + code: errorToCode[AssetError.UnknownAsset] + } + })) }) }) @@ -734,7 +745,11 @@ describe('Asset Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow(new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + })) }) }) }) From f308c4a0a94924fdfa3d955f576b6a7c7d82c84d Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Tue, 18 Jun 2024 15:42:26 -0700 Subject: [PATCH 29/34] fix: delete unnecessary code --- packages/backend/src/graphql/plugin/index.ts | 4 +- .../src/graphql/resolvers/asset.test.ts | 48 +++++++++++-------- .../wallet-addresses.$walletAddressId.tsx | 2 - test/integration/lib/integration-server.ts | 3 -- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/backend/src/graphql/plugin/index.ts b/packages/backend/src/graphql/plugin/index.ts index 7a02eddc69..6ae8358612 100644 --- a/packages/backend/src/graphql/plugin/index.ts +++ b/packages/backend/src/graphql/plugin/index.ts @@ -35,7 +35,9 @@ export class LoggingPlugin implements ApolloServerPlugin { ): Promise { if (context.errors) { context.errors.forEach((error) => { - if (error.extensions.code === GraphQLErrorCode.InternalServerError) { + if ( + error.extensions.code === GraphQLErrorCode.InternalServerError + ) { logger.error({ requestId, variables: context.request.variables, diff --git a/packages/backend/src/graphql/resolvers/asset.test.ts b/packages/backend/src/graphql/resolvers/asset.test.ts index 0f04407c50..47820950f7 100644 --- a/packages/backend/src/graphql/resolvers/asset.test.ts +++ b/packages/backend/src/graphql/resolvers/asset.test.ts @@ -156,11 +156,13 @@ describe('Asset Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(new GraphQLError(errorToMessage[AssetError.DuplicateAsset], { - extensions: { - code: errorToCode[AssetError.DuplicateAsset] - } - })) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[AssetError.DuplicateAsset], { + extensions: { + code: errorToCode[AssetError.DuplicateAsset] + } + }) + ) }) test('handles unexpected error', async (): Promise => { @@ -190,11 +192,13 @@ describe('Asset Resolvers', (): void => { throw new Error('Data was empty') } }) - await expect(gqlQuery).rejects.toThrow(new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - })) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) @@ -368,11 +372,13 @@ describe('Asset Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(new GraphQLError(errorToMessage[AssetError.UnknownAsset], { - extensions: { - code: errorToCode[AssetError.UnknownAsset] - } - })) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[AssetError.UnknownAsset], { + extensions: { + code: errorToCode[AssetError.UnknownAsset] + } + }) + ) }) }) @@ -745,11 +751,13 @@ describe('Asset Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - })) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) }) diff --git a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx index 28709066e0..f7850b56cf 100644 --- a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx +++ b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.tsx @@ -239,8 +239,6 @@ export async function action({ request }: ActionFunctionArgs) { ...result.data }) - console.log('response=', response) - if (!response?.walletAddress) { actionResponse.errors.message = [ 'Could not update the wallet address. Please try again!' diff --git a/test/integration/lib/integration-server.ts b/test/integration/lib/integration-server.ts index 67d3f76bc0..54ba96559c 100644 --- a/test/integration/lib/integration-server.ts +++ b/test/integration/lib/integration-server.ts @@ -134,9 +134,6 @@ export class WebhookEventHandler { }) const { walletAddress } = response - if (!response.walletAddress) { - throw new Error('Failed to create wallet address') - } if (!walletAddress) { throw new Error('Could not get wallet address') } From 3d569f4ab9ededbc9a62c906f9980cdf43989d4f Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Thu, 20 Jun 2024 16:08:12 -0700 Subject: [PATCH 30/34] fix: test for graphqlerror instead of apolloerror --- packages/backend/src/accounting/errors.ts | 2 +- packages/backend/src/fee/errors.ts | 2 +- .../graphql/resolvers/auto-peering.test.ts | 20 ++++-- .../backend/src/graphql/resolvers/fee.test.ts | 29 ++++++-- .../resolvers/incoming_payment.test.ts | 30 ++++++-- .../resolvers/outgoing_payment.test.ts | 31 ++++++-- .../src/graphql/resolvers/peer.test.ts | 71 +++++++++++++++---- .../backend/src/graphql/resolvers/peer.ts | 5 +- .../src/graphql/resolvers/quote.test.ts | 11 ++- .../src/graphql/resolvers/receiver.test.ts | 28 ++++++-- .../resolvers/walletAddressKey.test.ts | 22 ++++-- .../graphql/resolvers/wallet_address.test.ts | 60 ++++++++++++---- .../src/graphql/resolvers/wallet_address.ts | 12 ++-- .../open_payments/payment/incoming/errors.ts | 2 +- .../payment/incoming_remote/errors.ts | 2 +- .../open_payments/payment/outgoing/errors.ts | 2 +- .../backend/src/open_payments/quote/errors.ts | 2 +- .../src/open_payments/receiver/errors.ts | 3 +- .../open_payments/wallet_address/errors.ts | 2 +- .../payment-method/ilp/auto-peering/errors.ts | 2 +- .../src/payment-method/ilp/peer/errors.ts | 2 +- 21 files changed, 262 insertions(+), 78 deletions(-) diff --git a/packages/backend/src/accounting/errors.ts b/packages/backend/src/accounting/errors.ts index e54307d8c2..fc3cc3ffc9 100644 --- a/packages/backend/src/accounting/errors.ts +++ b/packages/backend/src/accounting/errors.ts @@ -36,7 +36,7 @@ export enum TransferError { } export const errorToCode: { - [key in TransferError]: string + [key in TransferError]: GraphQLErrorCode } = { [TransferError.AlreadyPosted]: GraphQLErrorCode.Conflict, [TransferError.AlreadyVoided]: GraphQLErrorCode.Conflict, diff --git a/packages/backend/src/fee/errors.ts b/packages/backend/src/fee/errors.ts index a6895bfda4..5de9fb7fff 100644 --- a/packages/backend/src/fee/errors.ts +++ b/packages/backend/src/fee/errors.ts @@ -11,7 +11,7 @@ export const isFeeError = (o: any): o is FeeError => Object.values(FeeError).includes(o) export const errorToCode: { - [key in FeeError]: string + [key in FeeError]: GraphQLErrorCode } = { [FeeError.UnknownAsset]: GraphQLErrorCode.NotFound, [FeeError.InvalidBasisPointFee]: GraphQLErrorCode.BadUserInput, diff --git a/packages/backend/src/graphql/resolvers/auto-peering.test.ts b/packages/backend/src/graphql/resolvers/auto-peering.test.ts index a594ddb60f..b5f09089f6 100644 --- a/packages/backend/src/graphql/resolvers/auto-peering.test.ts +++ b/packages/backend/src/graphql/resolvers/auto-peering.test.ts @@ -1,6 +1,7 @@ import { faker } from '@faker-js/faker' -import { ApolloError, gql } from '@apollo/client' +import { gql } from '@apollo/client' import assert from 'assert' +import { GraphQLError } from 'graphql' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -11,6 +12,7 @@ import { Config } from '../../config/app' import { truncateTables } from '../../tests/tableManager' import { errorToMessage, + errorToCode, AutoPeeringError } from '../../payment-method/ilp/auto-peering/errors' import { createAsset } from '../../tests/asset' @@ -18,6 +20,7 @@ import { CreateOrUpdatePeerByUrlInput } from '../generated/graphql' import { AutoPeeringService } from '../../payment-method/ilp/auto-peering/service' import { v4 as uuid } from 'uuid' import nock from 'nock' +import { GraphQLErrorCode } from '../errors' describe('Auto Peering Resolvers', (): void => { let deps: IocContract @@ -263,9 +266,12 @@ describe('Auto Peering Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) await expect(gqlQuery).rejects.toThrow( - errorToMessage[error as AutoPeeringError] + new GraphQLError(errorToMessage[error as AutoPeeringError], { + extensions: { + code: errorToCode[error as AutoPeeringError] + } + }) ) }) @@ -298,7 +304,13 @@ describe('Auto Peering Resolvers', (): void => { throw new Error('Data was empty') } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/fee.test.ts b/packages/backend/src/graphql/resolvers/fee.test.ts index e617b00e8a..681a0e7f5a 100644 --- a/packages/backend/src/graphql/resolvers/fee.test.ts +++ b/packages/backend/src/graphql/resolvers/fee.test.ts @@ -4,13 +4,16 @@ import { initIocContainer } from '../..' import { Config } from '../../config/app' import { createTestApp, TestContainer } from '../../tests/app' import { truncateTables } from '../../tests/tableManager' -import { ApolloError, gql } from '@apollo/client' +import { gql } from '@apollo/client' import { SetFeeResponse } from '../generated/graphql' import { Asset } from '../../asset/model' import { createAsset } from '../../tests/asset' import { FeeType } from '../../fee/model' import { FeeService } from '../../fee/service' import { v4 } from 'uuid' +import { GraphQLError } from 'graphql' +import { FeeError, errorToMessage, errorToCode } from '../../fee/errors' +import { GraphQLErrorCode } from '../errors' describe('Fee Resolvers', () => { let deps: IocContract @@ -117,8 +120,13 @@ describe('Fee Resolvers', () => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('Unknown asset') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[FeeError.UnknownAsset], { + extensions: { + code: errorToCode[FeeError.UnknownAsset] + } + }) + ) }) test('Returns error for invalid percent fee', async (): Promise => { @@ -156,9 +164,12 @@ describe('Fee Resolvers', () => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) await expect(gqlQuery).rejects.toThrow( - 'Basis point fee must be between 0 and 10000' + new GraphQLError(errorToMessage[FeeError.InvalidBasisPointFee], { + extensions: { + code: errorToCode[FeeError.InvalidBasisPointFee] + } + }) ) }) @@ -200,7 +211,13 @@ describe('Fee Resolvers', () => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Unknown error', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts index 360865d152..aec3884ad4 100644 --- a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts @@ -1,4 +1,4 @@ -import { ApolloError, gql } from '@apollo/client' +import { gql } from '@apollo/client' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -22,8 +22,14 @@ import { IncomingPaymentResponse, IncomingPaymentState as SchemaPaymentState } from '../generated/graphql' -import { IncomingPaymentError } from '../../open_payments/payment/incoming/errors' +import { + IncomingPaymentError, + errorToMessage, + errorToCode +} from '../../open_payments/payment/incoming/errors' import { Amount, serializeAmount } from '../../open_payments/amount' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' describe('Incoming Payment Resolver', (): void => { let deps: IocContract @@ -213,8 +219,16 @@ describe('Incoming Payment Resolver', (): void => { .then( (query): IncomingPaymentResponse => query.data?.createIncomingPayment ) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('unknown wallet address') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError( + errorToMessage[IncomingPaymentError.UnknownWalletAddress], + { + extensions: { + code: errorToCode[IncomingPaymentError.UnknownWalletAddress] + } + } + ) + ) await expect(createSpy).toHaveBeenCalledWith(input) }) @@ -246,7 +260,13 @@ describe('Incoming Payment Resolver', (): void => { .then( (query): IncomingPaymentResponse => query.data?.createIncomingPayment ) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) await expect(createSpy).toHaveBeenCalledWith(input) }) }) diff --git a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts index 7c8c32bc4b..75722c3591 100644 --- a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts @@ -1,4 +1,4 @@ -import { ApolloError, gql } from '@apollo/client' +import { gql } from '@apollo/client' import { PaymentError } from '@interledger/pay' import { v4 as uuid } from 'uuid' import * as Pay from '@interledger/pay' @@ -32,6 +32,7 @@ import { } from '../generated/graphql' import { faker } from '@faker-js/faker' import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' describe('OutgoingPayment Resolvers', (): void => { let deps: IocContract @@ -339,8 +340,16 @@ describe('OutgoingPayment Resolvers', (): void => { .then( (query): OutgoingPaymentResponse => query.data?.createOutgoingPayment ) - await expect(query).rejects.toThrow(ApolloError) - await expect(query).rejects.toThrow('unknown wallet address') + await expect(query).rejects.toThrow( + new GraphQLError( + errorToMessage[OutgoingPaymentError.UnknownWalletAddress], + { + extensions: { + code: errorToCode[OutgoingPaymentError.UnknownWalletAddress] + } + } + ) + ) await expect(createSpy).toHaveBeenCalledWith(input) }) @@ -374,7 +383,13 @@ describe('OutgoingPayment Resolvers', (): void => { (query): OutgoingPaymentResponse => query.data?.createOutgoingPayment ) - await expect(query).rejects.toThrow(ApolloError) + await expect(query).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) expect(createSpy).toHaveBeenCalledWith(input) }) }) @@ -511,7 +526,13 @@ describe('OutgoingPayment Resolvers', (): void => { (query): OutgoingPaymentResponse => query.data?.createOutgoingPaymentFromIncomingPayment ) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) expect(createSpy).toHaveBeenCalledWith(input) }) }) diff --git a/packages/backend/src/graphql/resolvers/peer.test.ts b/packages/backend/src/graphql/resolvers/peer.test.ts index 2be7f57267..5f69c9256b 100644 --- a/packages/backend/src/graphql/resolvers/peer.test.ts +++ b/packages/backend/src/graphql/resolvers/peer.test.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker' import { gql } from '@apollo/client' import assert from 'assert' import { v4 as uuid } from 'uuid' -import { ApolloError } from '@apollo/client' +import { GraphQLError } from 'graphql' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' @@ -12,7 +12,11 @@ import { Asset } from '../../asset/model' import { initIocContainer } from '../..' import { Config } from '../../config/app' import { truncateTables } from '../../tests/tableManager' -import { errorToMessage, PeerError } from '../../payment-method/ilp/peer/errors' +import { + errorToMessage, + errorToCode, + PeerError +} from '../../payment-method/ilp/peer/errors' import { Peer as PeerModel } from '../../payment-method/ilp/peer/model' import { PeerService } from '../../payment-method/ilp/peer/service' import { createAsset } from '../../tests/asset' @@ -26,6 +30,7 @@ import { DeletePeerMutationResponse } from '../generated/graphql' import { AccountingService } from '../../accounting/service' +import { GraphQLErrorCode } from '../errors' describe('Peer Resolvers', (): void => { let deps: IocContract @@ -179,11 +184,16 @@ describe('Peer Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow(errorToMessage[error as PeerError]) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[error as PeerError], { + extensions: { + code: errorToCode[error as PeerError] + } + }) + ) }) - test('500', async (): Promise => { + test('internal server error', async (): Promise => { jest .spyOn(peerService, 'create') .mockImplementationOnce(async (_args) => { @@ -212,7 +222,13 @@ describe('Peer Resolvers', (): void => { throw new Error('Data was empty') } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) @@ -333,8 +349,13 @@ describe('Peer Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('Peer not found') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[PeerError.UnknownPeer], { + extensions: { + code: errorToCode[PeerError.UnknownPeer] + } + }) + ) }) }) @@ -534,8 +555,13 @@ describe('Peer Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow(errorToMessage[error as PeerError]) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[error as PeerError], { + extensions: { + code: errorToCode[error as PeerError] + } + }) + ) }) test('Returns error if unexpected error', async (): Promise => { @@ -578,7 +604,13 @@ describe('Peer Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) @@ -641,8 +673,13 @@ describe('Peer Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('unknown peer') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError(errorToMessage[PeerError.UnknownPeer], { + extensions: { + code: errorToCode[PeerError.UnknownPeer] + } + }) + ) }) test('Returns error if unexpected error', async (): Promise => { @@ -673,7 +710,13 @@ describe('Peer Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/peer.ts b/packages/backend/src/graphql/resolvers/peer.ts index ff18fc9e04..b2296b7a89 100644 --- a/packages/backend/src/graphql/resolvers/peer.ts +++ b/packages/backend/src/graphql/resolvers/peer.ts @@ -16,7 +16,6 @@ import { ApolloContext } from '../../app' import { getPageInfo } from '../../shared/pagination' import { Pagination, SortOrder } from '../../shared/baseModel' import { GraphQLError } from 'graphql' -import { GraphQLErrorCode } from '../errors' export const getPeers: QueryResolvers['peers'] = async ( parent, @@ -50,9 +49,9 @@ export const getPeer: QueryResolvers['peer'] = async ( const peerService = await ctx.container.use('peerService') const peer = await peerService.get(args.id) if (!peer) { - throw new GraphQLError('Peer not found', { + throw new GraphQLError(errorToMessage[PeerError.UnknownPeer], { extensions: { - code: GraphQLErrorCode.NotFound + code: errorToCode[PeerError.UnknownPeer] } }) } diff --git a/packages/backend/src/graphql/resolvers/quote.test.ts b/packages/backend/src/graphql/resolvers/quote.test.ts index b95ac3c2e6..b2b0993ac0 100644 --- a/packages/backend/src/graphql/resolvers/quote.test.ts +++ b/packages/backend/src/graphql/resolvers/quote.test.ts @@ -1,4 +1,4 @@ -import { ApolloError, gql } from '@apollo/client' +import { gql } from '@apollo/client' import { v4 as uuid } from 'uuid' import { GraphQLError } from 'graphql' @@ -22,6 +22,7 @@ import { QuoteService } from '../../open_payments/quote/service' import { Quote as QuoteModel } from '../../open_payments/quote/model' import { Amount } from '../../open_payments/amount' import { CreateQuoteInput, Quote, QuoteResponse } from '../generated/graphql' +import { GraphQLErrorCode } from '../errors' describe('Quote Resolvers', (): void => { let deps: IocContract @@ -269,7 +270,13 @@ describe('Quote Resolvers', (): void => { variables: { input } }) .then((query): QuoteResponse => query.data?.createQuote) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) expect(createSpy).toHaveBeenCalledWith({ ...input, method: 'ilp' }) }) }) diff --git a/packages/backend/src/graphql/resolvers/receiver.test.ts b/packages/backend/src/graphql/resolvers/receiver.test.ts index 368a2541e5..56c20518ec 100644 --- a/packages/backend/src/graphql/resolvers/receiver.test.ts +++ b/packages/backend/src/graphql/resolvers/receiver.test.ts @@ -1,4 +1,4 @@ -import { ApolloError, gql } from '@apollo/client' +import { gql } from '@apollo/client' import { v4 as uuid } from 'uuid' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -13,7 +13,13 @@ import { import { CreateReceiverResponse } from '../generated/graphql' import { ReceiverService } from '../../open_payments/receiver/service' import { Receiver } from '../../open_payments/receiver/model' -import { ReceiverError } from '../../open_payments/receiver/errors' +import { + ReceiverError, + errorToMessage, + errorToCode +} from '../../open_payments/receiver/errors' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' describe('Receiver Resolver', (): void => { let deps: IocContract @@ -169,8 +175,13 @@ describe('Receiver Resolver', (): void => { }) .then((query): CreateReceiverResponse => query.data?.createReceiver) - await expect(query).rejects.toThrow(ApolloError) - await expect(query).rejects.toThrow('unknown wallet address') + await expect(query).rejects.toThrow( + new GraphQLError(errorToMessage(ReceiverError.UnknownWalletAddress), { + extensions: { + code: errorToCode(ReceiverError.UnknownWalletAddress) + } + }) + ) expect(createSpy).toHaveBeenCalledWith(input) }) @@ -216,8 +227,13 @@ describe('Receiver Resolver', (): void => { }) .then((query): CreateReceiverResponse => query.data?.createReceiver) - await expect(query).rejects.toThrow(ApolloError) - await expect(query).rejects.toThrow('Cannot create receiver') + await expect(query).rejects.toThrow( + new GraphQLError('Cannot create receiver', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) expect(createSpy).toHaveBeenCalledWith(input) }) }) diff --git a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts index a9228842ff..f60b7dcafc 100644 --- a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts +++ b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts @@ -1,5 +1,5 @@ import assert from 'assert' -import { ApolloError, gql } from '@apollo/client' +import { gql } from '@apollo/client' import { generateJwk } from '@interledger/http-signature-utils' import { v4 as uuid } from 'uuid' @@ -19,6 +19,8 @@ import { WalletAddressKeyService } from '../../open_payments/wallet_address/key/ import { createWalletAddress } from '../../tests/walletAddress' import { getPageTests } from './page.test' import { createWalletAddressKey } from '../../tests/walletAddressKey' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' const TEST_KEY = generateJwk({ keyId: uuid() }) @@ -145,8 +147,13 @@ describe('Wallet Address Key Resolvers', (): void => { throw new Error('Data was empty') } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('unexpected') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) @@ -237,8 +244,13 @@ describe('Wallet Address Key Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('Wallet address key not found') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('Wallet address key not found', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) + ) }) }) diff --git a/packages/backend/src/graphql/resolvers/wallet_address.test.ts b/packages/backend/src/graphql/resolvers/wallet_address.test.ts index 3f3948e4dd..3652673177 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.test.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.test.ts @@ -2,7 +2,6 @@ import assert from 'assert' import { gql } from '@apollo/client' import { Knex } from 'knex' import { v4 as uuid } from 'uuid' -import { ApolloError } from '@apollo/client' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -13,7 +12,8 @@ import { Config } from '../../config/app' import { truncateTables } from '../../tests/tableManager' import { WalletAddressError, - errorToMessage + errorToMessage, + errorToCode } from '../../open_payments/wallet_address/errors' import { WalletAddress as WalletAddressModel, @@ -34,6 +34,8 @@ import { } from '../generated/graphql' import { getPageTests } from './page.test' import { WalletAddressAdditionalProperty } from '../../open_payments/wallet_address/additional_property/model' +import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' describe('Wallet Address Resolvers', (): void => { let deps: IocContract @@ -239,13 +241,16 @@ describe('Wallet Address Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) await expect(gqlQuery).rejects.toThrow( - errorToMessage[error as WalletAddressError] + new GraphQLError(errorToMessage[error as WalletAddressError], { + extensions: { + code: errorToCode[error as WalletAddressError] + } + }) ) }) - test('500', async (): Promise => { + test('internal server error', async (): Promise => { jest .spyOn(walletAddressService, 'create') .mockImplementationOnce(async (_args) => { @@ -277,8 +282,13 @@ describe('Wallet Address Resolvers', (): void => { throw new Error('Data was empty') } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('unexpected') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) @@ -545,9 +555,12 @@ describe('Wallet Address Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) await expect(gqlQuery).rejects.toThrow( - errorToMessage[error as WalletAddressError] + new GraphQLError(errorToMessage[error as WalletAddressError], { + extensions: { + code: errorToCode[error as WalletAddressError] + } + }) ) }) @@ -583,8 +596,13 @@ describe('Wallet Address Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('unexpected') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) @@ -695,7 +713,16 @@ describe('Wallet Address Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) + await expect(gqlQuery).rejects.toThrow( + new GraphQLError( + errorToMessage[WalletAddressError.UnknownWalletAddress], + { + extensions: { + code: errorToCode[WalletAddressError.UnknownWalletAddress] + } + } + ) + ) }) getPageTests({ @@ -858,8 +885,13 @@ describe('Wallet Address Resolvers', (): void => { throw new Error('Data was empty') } }) - await expect(gqlQuery).rejects.toThrow(ApolloError) - await expect(gqlQuery).rejects.toThrow('unexpected') + await expect(gqlQuery).rejects.toThrow( + new GraphQLError('unexpected', { + extensions: { + code: GraphQLErrorCode.InternalServerError + } + }) + ) }) }) }) diff --git a/packages/backend/src/graphql/resolvers/wallet_address.ts b/packages/backend/src/graphql/resolvers/wallet_address.ts index dfff55bd1e..a5887e4b1d 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.ts @@ -10,6 +10,7 @@ import { } from '../generated/graphql' import { ApolloContext } from '../../app' import { + WalletAddressError, isWalletAddressError, errorToCode, errorToMessage @@ -57,11 +58,14 @@ export const getWalletAddress: QueryResolvers['walletAddress'] = const walletAddressService = await ctx.container.use('walletAddressService') const walletAddress = await walletAddressService.get(args.id) if (!walletAddress) { - throw new GraphQLError('Wallet address not found', { - extensions: { - code: GraphQLErrorCode.NotFound + throw new GraphQLError( + errorToMessage[WalletAddressError.UnknownWalletAddress], + { + extensions: { + code: errorToCode[WalletAddressError.UnknownWalletAddress] + } } - }) + ) } return walletAddressToGraphql(walletAddress) } diff --git a/packages/backend/src/open_payments/payment/incoming/errors.ts b/packages/backend/src/open_payments/payment/incoming/errors.ts index d38b41d761..6d6ea90bbc 100644 --- a/packages/backend/src/open_payments/payment/incoming/errors.ts +++ b/packages/backend/src/open_payments/payment/incoming/errors.ts @@ -27,7 +27,7 @@ export const errorToHTTPCode: { } export const errorToCode: { - [key in IncomingPaymentError]: string + [key in IncomingPaymentError]: GraphQLErrorCode } = { [IncomingPaymentError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, [IncomingPaymentError.InvalidAmount]: GraphQLErrorCode.BadUserInput, diff --git a/packages/backend/src/open_payments/payment/incoming_remote/errors.ts b/packages/backend/src/open_payments/payment/incoming_remote/errors.ts index fde1eea126..599ef02183 100644 --- a/packages/backend/src/open_payments/payment/incoming_remote/errors.ts +++ b/packages/backend/src/open_payments/payment/incoming_remote/errors.ts @@ -21,7 +21,7 @@ export const errorToHTTPCode: { } export const errorToCode: { - [key in RemoteIncomingPaymentError]: string + [key in RemoteIncomingPaymentError]: GraphQLErrorCode } = { [RemoteIncomingPaymentError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, [RemoteIncomingPaymentError.InvalidRequest]: GraphQLErrorCode.BadUserInput, diff --git a/packages/backend/src/open_payments/payment/outgoing/errors.ts b/packages/backend/src/open_payments/payment/outgoing/errors.ts index 30c684b5bf..3537daeb01 100644 --- a/packages/backend/src/open_payments/payment/outgoing/errors.ts +++ b/packages/backend/src/open_payments/payment/outgoing/errors.ts @@ -52,7 +52,7 @@ export const errorToHTTPCode: { } export const errorToCode: { - [key in OutgoingPaymentError]: string + [key in OutgoingPaymentError]: GraphQLErrorCode } = { [OutgoingPaymentError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, [OutgoingPaymentError.UnknownPayment]: GraphQLErrorCode.NotFound, diff --git a/packages/backend/src/open_payments/quote/errors.ts b/packages/backend/src/open_payments/quote/errors.ts index 9fff0b0911..2e624ead9f 100644 --- a/packages/backend/src/open_payments/quote/errors.ts +++ b/packages/backend/src/open_payments/quote/errors.ts @@ -23,7 +23,7 @@ export const errorToHTTPCode: { } export const errorToCode: { - [key in QuoteError]: string + [key in QuoteError]: GraphQLErrorCode } = { [QuoteError.UnknownWalletAddress]: GraphQLErrorCode.NotFound, [QuoteError.InvalidAmount]: GraphQLErrorCode.BadUserInput, diff --git a/packages/backend/src/open_payments/receiver/errors.ts b/packages/backend/src/open_payments/receiver/errors.ts index c0aa018a91..a8e624a686 100644 --- a/packages/backend/src/open_payments/receiver/errors.ts +++ b/packages/backend/src/open_payments/receiver/errors.ts @@ -1,3 +1,4 @@ +import { GraphQLErrorCode } from '../../graphql/errors' import { errorToMessage as incomingPaymentErrorToMessage, errorToCode as incomingPaymentErrorToCode, @@ -20,7 +21,7 @@ export const ReceiverError = { export const isReceiverError = (o: any): o is ReceiverError => Object.values(ReceiverError).includes(o) -export const errorToCode = (error: ReceiverError): string => +export const errorToCode = (error: ReceiverError): GraphQLErrorCode => isIncomingPaymentError(error) ? incomingPaymentErrorToCode[error] : remoteIncomingPaymentErrorToCode[error] diff --git a/packages/backend/src/open_payments/wallet_address/errors.ts b/packages/backend/src/open_payments/wallet_address/errors.ts index 3f13126ad9..f6775dcb21 100644 --- a/packages/backend/src/open_payments/wallet_address/errors.ts +++ b/packages/backend/src/open_payments/wallet_address/errors.ts @@ -11,7 +11,7 @@ export const isWalletAddressError = (o: any): o is WalletAddressError => Object.values(WalletAddressError).includes(o) export const errorToCode: { - [key in WalletAddressError]: string + [key in WalletAddressError]: GraphQLErrorCode } = { [WalletAddressError.InvalidUrl]: GraphQLErrorCode.BadUserInput, [WalletAddressError.UnknownAsset]: GraphQLErrorCode.BadUserInput, diff --git a/packages/backend/src/payment-method/ilp/auto-peering/errors.ts b/packages/backend/src/payment-method/ilp/auto-peering/errors.ts index 8178bcf37e..c6df6c2ded 100644 --- a/packages/backend/src/payment-method/ilp/auto-peering/errors.ts +++ b/packages/backend/src/payment-method/ilp/auto-peering/errors.ts @@ -15,7 +15,7 @@ export const isAutoPeeringError = (o: any): o is AutoPeeringError => Object.values(AutoPeeringError).includes(o) export const errorToCode: { - [key in AutoPeeringError]: string + [key in AutoPeeringError]: GraphQLErrorCode } = { [AutoPeeringError.InvalidIlpConfiguration]: GraphQLErrorCode.BadUserInput, [AutoPeeringError.InvalidPeerIlpConfiguration]: diff --git a/packages/backend/src/payment-method/ilp/peer/errors.ts b/packages/backend/src/payment-method/ilp/peer/errors.ts index c4b81134dd..1c73d6fd8f 100644 --- a/packages/backend/src/payment-method/ilp/peer/errors.ts +++ b/packages/backend/src/payment-method/ilp/peer/errors.ts @@ -15,7 +15,7 @@ export const isPeerError = (o: any): o is PeerError => Object.values(PeerError).includes(o) export const errorToCode: { - [key in PeerError]: string + [key in PeerError]: GraphQLErrorCode } = { [PeerError.DuplicateIncomingToken]: GraphQLErrorCode.Duplicate, [PeerError.DuplicatePeer]: GraphQLErrorCode.Duplicate, From 4a246eada2f8fd9320de8ab68a9dcb774e902d80 Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Thu, 20 Jun 2024 16:25:12 -0700 Subject: [PATCH 31/34] chore: formatting --- .../graphql/resolvers/wallet_address.test.ts | 37 +++++++++---------- .../src/graphql/resolvers/wallet_address.ts | 4 +- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/wallet_address.test.ts b/packages/backend/src/graphql/resolvers/wallet_address.test.ts index 3652673177..22853ad258 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.test.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.test.ts @@ -179,25 +179,24 @@ describe('Wallet Address Resolvers', (): void => { } }) - - assert.ok(response.walletAddress) - expect(response.walletAddress).toEqual({ - __typename: 'WalletAddress', - id: response.walletAddress.id, - url: input.url, - asset: { - __typename: 'Asset', - code: asset.code, - scale: asset.scale - }, - publicName: input.publicName, - additionalProperties: validAdditionalProperties.map((property) => { - return { - __typename: 'AdditionalProperty', - key: property.key, - value: property.value, - visibleInOpenPayments: property.visibleInOpenPayments - } + assert.ok(response.walletAddress) + expect(response.walletAddress).toEqual({ + __typename: 'WalletAddress', + id: response.walletAddress.id, + url: input.url, + asset: { + __typename: 'Asset', + code: asset.code, + scale: asset.scale + }, + publicName: input.publicName, + additionalProperties: validAdditionalProperties.map((property) => { + return { + __typename: 'AdditionalProperty', + key: property.key, + value: property.value, + visibleInOpenPayments: property.visibleInOpenPayments + } }) }) await expect( diff --git a/packages/backend/src/graphql/resolvers/wallet_address.ts b/packages/backend/src/graphql/resolvers/wallet_address.ts index a5887e4b1d..1731699fc9 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.ts @@ -23,7 +23,6 @@ import { CreateOptions, UpdateOptions } from '../../open_payments/wallet_address/service' -import { GraphQLErrorCode } from '../errors' export const getWalletAddresses: QueryResolvers['walletAddresses'] = async ( @@ -129,7 +128,8 @@ export const updateWalletAddress: MutationResolvers['updateWallet } ) } - const walletAddressOrError = await walletAddressService.update(updateOptions) + const walletAddressOrError = + await walletAddressService.update(updateOptions) if (isWalletAddressError(walletAddressOrError)) { throw new GraphQLError(errorToMessage[walletAddressOrError], { extensions: { From a999fb68b44c32de0b9d3858c0dbc932167d805a Mon Sep 17 00:00:00 2001 From: Nathan Lie Date: Mon, 24 Jun 2024 17:46:39 -0700 Subject: [PATCH 32/34] fix: inspect error object in tests --- .../src/graphql/resolvers/asset.test.ts | 358 ++- .../graphql/resolvers/auto-peering.test.ts | 130 +- .../backend/src/graphql/resolvers/fee.test.ts | 197 +- .../resolvers/incoming_payment.test.ts | 130 +- .../src/graphql/resolvers/liquidity.test.ts | 2768 +++++++++-------- .../resolvers/outgoing_payment.test.ts | 298 +- .../src/graphql/resolvers/peer.test.ts | 443 +-- .../src/graphql/resolvers/quote.test.ts | 110 +- .../src/graphql/resolvers/receiver.test.ts | 187 +- .../backend/src/graphql/resolvers/receiver.ts | 7 +- .../resolvers/walletAddressKey.test.ts | 148 +- .../graphql/resolvers/wallet_address.test.ts | 384 +-- 12 files changed, 2761 insertions(+), 2399 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/asset.test.ts b/packages/backend/src/graphql/resolvers/asset.test.ts index 47820950f7..99d2f642ed 100644 --- a/packages/backend/src/graphql/resolvers/asset.test.ts +++ b/packages/backend/src/graphql/resolvers/asset.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import assert from 'assert' import { v4 as uuid } from 'uuid' @@ -31,7 +31,6 @@ import { Fee, FeeType } from '../../fee/model' import { isFeeError } from '../../fee/errors' import { createFee } from '../../tests/fee' import { createAsset } from '../../tests/asset' -import { GraphQLError } from 'graphql' import { GraphQLErrorCode } from '../errors' describe('Asset Resolvers', (): void => { @@ -133,36 +132,40 @@ describe('Asset Resolvers', (): void => { test('Returns error for duplicate asset', async (): Promise => { const input = randomAsset() await expect(assetService.create(input)).resolves.toMatchObject(input) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateAsset($input: CreateAssetInput!) { - createAsset(input: $input) { - asset { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateAsset($input: CreateAssetInput!) { + createAsset(input: $input) { + asset { + id + } } } + `, + variables: { + input } - `, - variables: { - input - } - }) - .then((query): AssetMutationResponse => { - if (query.data) { - return query.data.createAsset - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[AssetError.DuplicateAsset], { - extensions: { - code: errorToCode[AssetError.DuplicateAsset] - } - }) - ) + }) + .then((query): AssetMutationResponse => { + if (query.data) { + return query.data.createAsset + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[AssetError.DuplicateAsset], + extensions: expect.objectContaining({ + code: errorToCode[AssetError.DuplicateAsset] + }) + }) + ) + } }) test('handles unexpected error', async (): Promise => { @@ -170,35 +173,40 @@ describe('Asset Resolvers', (): void => { .spyOn(assetService, 'create') .mockRejectedValueOnce(new Error('unexpected')) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateAsset($input: CreateAssetInput!) { - createAsset(input: $input) { - asset { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateAsset($input: CreateAssetInput!) { + createAsset(input: $input) { + asset { + id + } } } + `, + variables: { + input: randomAsset() } - `, - variables: { - input: randomAsset() - } - }) - .then((query): AssetMutationResponse => { - if (query.data) { - return query.data.createAsset - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + .then((query): AssetMutationResponse => { + if (query.data) { + return query.data.createAsset + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) @@ -351,34 +359,38 @@ describe('Asset Resolvers', (): void => { }) test('Returns error for unknown asset', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - query Asset($assetId: String!) { - asset(id: $assetId) { - id + try { + await appContainer.apolloClient + .query({ + query: gql` + query Asset($assetId: String!) { + asset(id: $assetId) { + id + } } + `, + variables: { + assetId: uuid() } - `, - variables: { - assetId: uuid() - } - }) - .then((query): Asset => { - if (query.data) { - return query.data.asset - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[AssetError.UnknownAsset], { - extensions: { - code: errorToCode[AssetError.UnknownAsset] - } - }) - ) + }) + .then((query): Asset => { + if (query.data) { + return query.data.asset + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[AssetError.UnknownAsset], + extensions: expect.objectContaining({ + code: errorToCode[AssetError.UnknownAsset] + }) + }) + ) + } }) }) @@ -612,40 +624,44 @@ describe('Asset Resolvers', (): void => { ) test('Returns error for unknown asset', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation updateAsset($input: UpdateAssetInput!) { - updateAsset(input: $input) { - asset { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation updateAsset($input: UpdateAssetInput!) { + updateAsset(input: $input) { + asset { + id + } } } + `, + variables: { + input: { + id: uuid(), + withdrawalThreshold: BigInt(10), + liquidityThreshold: BigInt(100) + } } - `, - variables: { - input: { - id: uuid(), - withdrawalThreshold: BigInt(10), - liquidityThreshold: BigInt(100) + }) + .then((query): AssetMutationResponse => { + if (query.data) { + return query.data.updateAsset + } else { + throw new Error('Data was empty') } - } - }) - .then((query): AssetMutationResponse => { - if (query.data) { - return query.data.updateAsset - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[AssetError.UnknownAsset], { - extensions: { - code: errorToCode[AssetError.UnknownAsset] - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[AssetError.UnknownAsset], + extensions: expect.objectContaining({ + code: errorToCode[AssetError.UnknownAsset] + }) + }) + ) + } }) }) @@ -687,38 +703,42 @@ describe('Asset Resolvers', (): void => { }) test('Returns error for unknown asset', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DeleteAsset($input: DeleteAssetInput!) { - deleteAsset(input: $input) { - asset { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DeleteAsset($input: DeleteAssetInput!) { + deleteAsset(input: $input) { + asset { + id + } } } + `, + variables: { + input: { + id: uuid() + } } - `, - variables: { - input: { - id: uuid() + }) + .then((query): AssetMutationResponse => { + if (query.data) { + return query.data.deleteAsset + } else { + throw new Error('Data was empty') } - } - }) - .then((query): AssetMutationResponse => { - if (query.data) { - return query.data.deleteAsset - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[AssetError.UnknownAsset], { - extensions: { - code: errorToCode[AssetError.UnknownAsset] - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[AssetError.UnknownAsset], + extensions: expect.objectContaining({ + code: errorToCode[AssetError.UnknownAsset] + }) + }) + ) + } }) test('Returns error if unexpected error', async (): Promise => { @@ -726,38 +746,42 @@ describe('Asset Resolvers', (): void => { throw new Error('unexpected') }) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DeleteAsset($input: DeleteAssetInput!) { - deleteAsset(input: $input) { - asset { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DeleteAsset($input: DeleteAssetInput!) { + deleteAsset(input: $input) { + asset { + id + } } } + `, + variables: { + input: { + id: asset.id + } } - `, - variables: { - input: { - id: asset.id + }) + .then((query): AssetMutationResponse => { + if (query.data) { + return query.data.deleteAsset + } else { + throw new Error('Data was empty') } - } - }) - .then((query): AssetMutationResponse => { - if (query.data) { - return query.data.deleteAsset - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) }) diff --git a/packages/backend/src/graphql/resolvers/auto-peering.test.ts b/packages/backend/src/graphql/resolvers/auto-peering.test.ts index b5f09089f6..6506b74b5b 100644 --- a/packages/backend/src/graphql/resolvers/auto-peering.test.ts +++ b/packages/backend/src/graphql/resolvers/auto-peering.test.ts @@ -1,7 +1,6 @@ import { faker } from '@faker-js/faker' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import assert from 'assert' -import { GraphQLError } from 'graphql' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -236,43 +235,47 @@ describe('Auto Peering Resolvers', (): void => { ${AutoPeeringError.InvalidPeerUrl} ${AutoPeeringError.InvalidPeeringRequest} ${AutoPeeringError.LiquidityError} - `('Errors with $error', async ({ error }): Promise => { + `('Errors with $error', async ({ error: testError }): Promise => { jest .spyOn(autoPeeringService, 'initiatePeeringRequest') - .mockResolvedValueOnce(error) + .mockResolvedValueOnce(testError) const input = createOrUpdatePeerByUrlInput() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateOrUpdatePeerByUrl( - $input: CreateOrUpdatePeerByUrlInput! - ) { - createOrUpdatePeerByUrl(input: $input) { - peer { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateOrUpdatePeerByUrl( + $input: CreateOrUpdatePeerByUrlInput! + ) { + createOrUpdatePeerByUrl(input: $input) { + peer { + id + } } } + `, + variables: { + input } - `, - variables: { - input - } - }) - .then((query) => { - if (query.data) { - return query.data.createOrUpdatePeerByUrl - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[error as AutoPeeringError], { - extensions: { - code: errorToCode[error as AutoPeeringError] - } - }) - ) + }) + .then((query) => { + if (query.data) { + return query.data.createOrUpdatePeerByUrl + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[testError as AutoPeeringError], + extensions: expect.objectContaining({ + code: errorToCode[testError as AutoPeeringError] + }) + }) + ) + } }) test('Internal server error', async (): Promise => { @@ -280,37 +283,42 @@ describe('Auto Peering Resolvers', (): void => { .spyOn(autoPeeringService, 'initiatePeeringRequest') .mockRejectedValueOnce(new Error('unexpected')) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateOrUpdatePeerByUrl( - $input: CreateOrUpdatePeerByUrlInput! - ) { - createOrUpdatePeerByUrl(input: $input) { - peer { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateOrUpdatePeerByUrl( + $input: CreateOrUpdatePeerByUrlInput! + ) { + createOrUpdatePeerByUrl(input: $input) { + peer { + id + } } } + `, + variables: { + input: createOrUpdatePeerByUrlInput() } - `, - variables: { - input: createOrUpdatePeerByUrlInput() - } - }) - .then((query) => { - if (query.data) { - return query.data.createOrUpdatePeerByUrl - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + .then((query) => { + if (query.data) { + return query.data.createOrUpdatePeerByUrl + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) }) diff --git a/packages/backend/src/graphql/resolvers/fee.test.ts b/packages/backend/src/graphql/resolvers/fee.test.ts index 681a0e7f5a..13a14b9c05 100644 --- a/packages/backend/src/graphql/resolvers/fee.test.ts +++ b/packages/backend/src/graphql/resolvers/fee.test.ts @@ -4,14 +4,13 @@ import { initIocContainer } from '../..' import { Config } from '../../config/app' import { createTestApp, TestContainer } from '../../tests/app' import { truncateTables } from '../../tests/tableManager' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { SetFeeResponse } from '../generated/graphql' import { Asset } from '../../asset/model' import { createAsset } from '../../tests/asset' import { FeeType } from '../../fee/model' import { FeeService } from '../../fee/service' import { v4 } from 'uuid' -import { GraphQLError } from 'graphql' import { FeeError, errorToMessage, errorToCode } from '../../fee/errors' import { GraphQLErrorCode } from '../errors' @@ -94,39 +93,43 @@ describe('Fee Resolvers', () => { basisPoints: 100 } } - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation SetFee($input: SetFeeInput!) { - setFee(input: $input) { - fee { - id - assetId - type - fixed - basisPoints - createdAt + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation SetFee($input: SetFeeInput!) { + setFee(input: $input) { + fee { + id + assetId + type + fixed + basisPoints + createdAt + } } } + `, + variables: { input } + }) + .then((query): SetFeeResponse => { + if (query.data) { + return query.data.setFee + } else { + throw new Error('Data was empty') } - `, - variables: { input } - }) - .then((query): SetFeeResponse => { - if (query.data) { - return query.data.setFee - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[FeeError.UnknownAsset], { - extensions: { - code: errorToCode[FeeError.UnknownAsset] - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[FeeError.UnknownAsset], + extensions: expect.objectContaining({ + code: errorToCode[FeeError.UnknownAsset] + }) + }) + ) + } }) test('Returns error for invalid percent fee', async (): Promise => { @@ -138,42 +141,46 @@ describe('Fee Resolvers', () => { basisPoints: -10_000 } } - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation SetFee($input: SetFeeInput!) { - setFee(input: $input) { - fee { - id - assetId - type - fixed - basisPoints - createdAt + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation SetFee($input: SetFeeInput!) { + setFee(input: $input) { + fee { + id + assetId + type + fixed + basisPoints + createdAt + } } } + `, + variables: { input } + }) + .then((query): SetFeeResponse => { + if (query.data) { + return query.data.setFee + } else { + throw new Error('Data was empty') } - `, - variables: { input } - }) - .then((query): SetFeeResponse => { - if (query.data) { - return query.data.setFee - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[FeeError.InvalidBasisPointFee], { - extensions: { - code: errorToCode[FeeError.InvalidBasisPointFee] - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[FeeError.InvalidBasisPointFee], + extensions: expect.objectContaining({ + code: errorToCode[FeeError.InvalidBasisPointFee] + }) + }) + ) + } }) - test('Returns 500 error for unhandled errors', async (): Promise => { + test('Returns internal server error for unhandled errors', async (): Promise => { jest.spyOn(feeService, 'create').mockImplementationOnce(async () => { throw new Error('Unknown error') }) @@ -185,39 +192,43 @@ describe('Fee Resolvers', () => { basisPoints: -10_000 } } - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation setFee($input: SetFeeInput!) { - setFee(input: $input) { - fee { - id - assetId - type - fixed - basisPoints - createdAt + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation setFee($input: SetFeeInput!) { + setFee(input: $input) { + fee { + id + assetId + type + fixed + basisPoints + createdAt + } } } + `, + variables: { input } + }) + .then((query): SetFeeResponse => { + if (query.data) { + return query.data.setFee + } else { + throw new Error('Data was empty') } - `, - variables: { input } - }) - .then((query): SetFeeResponse => { - if (query.data) { - return query.data.setFee - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Unknown error', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown error', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) }) diff --git a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts index aec3884ad4..3278c9d58c 100644 --- a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -28,7 +28,6 @@ import { errorToCode } from '../../open_payments/payment/incoming/errors' import { Amount, serializeAmount } from '../../open_payments/amount' -import { GraphQLError } from 'graphql' import { GraphQLErrorCode } from '../errors' describe('Incoming Payment Resolver', (): void => { @@ -200,35 +199,38 @@ describe('Incoming Payment Resolver', (): void => { walletAddressId: uuid() } - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - mutation CreateIncomingPayment( - $input: CreateIncomingPaymentInput! - ) { - createIncomingPayment(input: $input) { - payment { - id - state + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateIncomingPayment( + $input: CreateIncomingPaymentInput! + ) { + createIncomingPayment(input: $input) { + payment { + id + state + } } } - } - `, - variables: { input } - }) - .then( - (query): IncomingPaymentResponse => query.data?.createIncomingPayment - ) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError( - errorToMessage[IncomingPaymentError.UnknownWalletAddress], - { - extensions: { + `, + variables: { input } + }) + .then( + (query): IncomingPaymentResponse => + query.data?.createIncomingPayment + ) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[IncomingPaymentError.UnknownWalletAddress], + extensions: expect.objectContaining({ code: errorToCode[IncomingPaymentError.UnknownWalletAddress] - } - } + }) + }) ) - ) + } await expect(createSpy).toHaveBeenCalledWith(input) }) @@ -241,32 +243,38 @@ describe('Incoming Payment Resolver', (): void => { walletAddressId: uuid() } - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - mutation CreateIncomingPayment( - $input: CreateIncomingPaymentInput! - ) { - createIncomingPayment(input: $input) { - payment { - id - state + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateIncomingPayment( + $input: CreateIncomingPaymentInput! + ) { + createIncomingPayment(input: $input) { + payment { + id + state + } } } - } - `, - variables: { input } - }) - .then( - (query): IncomingPaymentResponse => query.data?.createIncomingPayment + `, + variables: { input } + }) + .then( + (query): IncomingPaymentResponse => + query.data?.createIncomingPayment + ) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) ) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + } await expect(createSpy).toHaveBeenCalledWith(input) }) }) @@ -302,7 +310,7 @@ describe('Incoming Payment Resolver', (): void => { // Query with each payment state const states: IncomingPaymentState[] = Object.values(IncomingPaymentState) - test.each(states)('200 - %s', async (state): Promise => { + test.each(states)('%s', async (state): Promise => { const expiresAt = new Date() jest .spyOn(incomingPaymentService, 'get') @@ -368,7 +376,7 @@ describe('Incoming Payment Resolver', (): void => { }) }) - test('200 - with added liquidity', async (): Promise => { + test('with added liquidity', async (): Promise => { await accountingService.createDeposit({ id: uuid(), account: payment, @@ -399,13 +407,13 @@ describe('Incoming Payment Resolver', (): void => { }) }) - test('404', async (): Promise => { + test('not found', async (): Promise => { jest .spyOn(incomingPaymentService, 'get') .mockImplementation(async () => undefined) - await expect( - appContainer.apolloClient.query({ + try { + await appContainer.apolloClient.query({ query: gql` query IncomingPayment($paymentId: String!) { incomingPayment(id: $paymentId) { @@ -415,7 +423,17 @@ describe('Incoming Payment Resolver', (): void => { `, variables: { paymentId: uuid() } }) - ).rejects.toThrow('payment does not exist') + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'payment does not exist', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) }) }) diff --git a/packages/backend/src/graphql/resolvers/liquidity.test.ts b/packages/backend/src/graphql/resolvers/liquidity.test.ts index 9403f6f1d0..26fdfdca3a 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.test.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.test.ts @@ -1,5 +1,5 @@ import assert from 'assert' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { Knex } from 'knex' import { v4 as uuid } from 'uuid' @@ -43,7 +43,6 @@ import { LiquidityMutationResponse, WalletAddressWithdrawalMutationResponse } from '../generated/graphql' -import { GraphQLError } from 'graphql' import { GraphQLErrorCode } from '../errors' describe('Liquidity Resolvers', (): void => { @@ -105,75 +104,87 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for invalid id', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { - depositPeerLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositPeerLiquidity( + $input: DepositPeerLiquidityInput! + ) { + depositPeerLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id: 'not a uuid v4', + peerId: peer.id, + amount: '100', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id: 'not a uuid v4', - peerId: peer.id, - amount: '100', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositPeerLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositPeerLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns an error for unknown peer', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { - depositPeerLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositPeerLiquidity( + $input: DepositPeerLiquidityInput! + ) { + depositPeerLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id: uuid(), + peerId: uuid(), + amount: '100', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id: uuid(), - peerId: uuid(), - amount: '100', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositPeerLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositPeerLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unknown peer', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unknown peer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) test('Returns an error for existing transfer', async (): Promise => { @@ -185,75 +196,87 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { - depositPeerLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositPeerLiquidity( + $input: DepositPeerLiquidityInput! + ) { + depositPeerLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id, + peerId: peer.id, + amount: '100', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id, - peerId: peer.id, - amount: '100', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositPeerLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositPeerLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) + } }) test('Returns an error for zero amount', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositPeerLiquidity($input: DepositPeerLiquidityInput!) { - depositPeerLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositPeerLiquidity( + $input: DepositPeerLiquidityInput! + ) { + depositPeerLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id: 'not a uuid v4', + peerId: peer.id, + amount: '0', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id: 'not a uuid v4', - peerId: peer.id, - amount: '0', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositPeerLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositPeerLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer amount is zero', { - extensions: { - code: GraphQLErrorCode.Forbidden - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer amount is zero', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) + } }) }) @@ -298,79 +321,87 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for invalid id', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositAssetLiquidity( - $input: DepositAssetLiquidityInput! - ) { - depositAssetLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositAssetLiquidity( + $input: DepositAssetLiquidityInput! + ) { + depositAssetLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id: 'not a uuid', + assetId: asset.id, + amount: '100', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id: 'not a uuid', - assetId: asset.id, - amount: '100', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositAssetLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositAssetLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns an error for unknown asset', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositAssetLiquidity( - $input: DepositAssetLiquidityInput! - ) { - depositAssetLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositAssetLiquidity( + $input: DepositAssetLiquidityInput! + ) { + depositAssetLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id: uuid(), + assetId: uuid(), + amount: '100', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id: uuid(), - assetId: uuid(), - amount: '100', - idempotencyKey: uuid() - } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositAssetLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Unknown asset', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - ) + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositAssetLiquidity + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown asset', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) test('Returns an error for existing transfer', async (): Promise => { @@ -382,79 +413,87 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositAssetLiquidity( - $input: DepositAssetLiquidityInput! - ) { - depositAssetLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositAssetLiquidity( + $input: DepositAssetLiquidityInput! + ) { + depositAssetLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id, + assetId: asset.id, + amount: '100', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id, - assetId: asset.id, - amount: '100', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositAssetLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositAssetLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) + } }) test('Returns an error for zero amount', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositAssetLiquidity( - $input: DepositAssetLiquidityInput! - ) { - depositAssetLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositAssetLiquidity( + $input: DepositAssetLiquidityInput! + ) { + depositAssetLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + id: uuid(), + assetId: asset.id, + amount: '0', + idempotencyKey: uuid() } } - `, - variables: { - input: { - id: uuid(), - assetId: asset.id, - amount: '0', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositAssetLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositAssetLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer amount is zero', { - extensions: { - code: GraphQLErrorCode.Forbidden - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer amount is zero', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) + } }) }) @@ -508,137 +547,51 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for unknown peer', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreatePeerLiquidityWithdrawal( - $input: CreatePeerLiquidityWithdrawalInput! - ) { - createPeerLiquidityWithdrawal(input: $input) { - success - } - } - `, - variables: { - input: { - id: uuid(), - peerId: uuid(), - amount: '100', - idempotencyKey: uuid(), - timeoutSeconds: 0 - } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createPeerLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Unknown peer', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - ) - }) - - test('Returns an error for invalid id', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreatePeerLiquidityWithdrawal( - $input: CreatePeerLiquidityWithdrawalInput! - ) { - createPeerLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreatePeerLiquidityWithdrawal( + $input: CreatePeerLiquidityWithdrawalInput! + ) { + createPeerLiquidityWithdrawal(input: $input) { + success + } } - } - `, - variables: { - input: { - id: 'not a uuid', - peerId: peer.id, - amount: startingBalance.toString(), - idempotencyKey: uuid(), - timeoutSeconds: 0 - } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createPeerLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) - }) - - test('Returns an error for existing transfer', async (): Promise => { - const id = uuid() - await expect( - accountingService.createDeposit({ - id, - account: peer, - amount: 10n - }) - ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreatePeerLiquidityWithdrawal( - $input: CreatePeerLiquidityWithdrawalInput! - ) { - createPeerLiquidityWithdrawal(input: $input) { - success + `, + variables: { + input: { + id: uuid(), + peerId: uuid(), + amount: '100', + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - id, - peerId: peer.id, - amount: startingBalance.toString(), - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createPeerLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createPeerLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown peer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) - test.each` - amount | message | code - ${startingBalance + BigInt(1)} | ${'Insufficient transfer balance'} | ${GraphQLErrorCode.Forbidden} - ${BigInt(0)} | ${'Transfer amount is zero'} | ${GraphQLErrorCode.Forbidden} - `( - 'Returns error for $code', - async ({ amount, message, code }): Promise => { - const gqlQuery = appContainer.apolloClient + test('Returns an error for invalid id', async (): Promise => { + try { + await appContainer.apolloClient .mutate({ mutation: gql` mutation CreatePeerLiquidityWithdrawal( @@ -651,9 +604,9 @@ describe('Liquidity Resolvers', (): void => { `, variables: { input: { - id: uuid(), + id: 'not a uuid', peerId: peer.id, - amount: amount.toString(), + amount: startingBalance.toString(), idempotencyKey: uuid(), timeoutSeconds: 0 } @@ -666,16 +619,119 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(message, { - extensions: { - code - } + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) }) ) } - ) + }) + + test('Returns an error for existing transfer', async (): Promise => { + const id = uuid() + await expect( + accountingService.createDeposit({ + id, + account: peer, + amount: 10n + }) + ).resolves.toBeUndefined() + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreatePeerLiquidityWithdrawal( + $input: CreatePeerLiquidityWithdrawalInput! + ) { + createPeerLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + id, + peerId: peer.id, + amount: startingBalance.toString(), + idempotencyKey: uuid(), + timeoutSeconds: 0 + } + } + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createPeerLiquidityWithdrawal + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) + } + }) + + test.each` + amount | message | code + ${startingBalance + BigInt(1)} | ${'Insufficient transfer balance'} | ${GraphQLErrorCode.Forbidden} + ${BigInt(0)} | ${'Transfer amount is zero'} | ${GraphQLErrorCode.Forbidden} + `( + 'Returns error for $code', + async ({ amount, message, code }): Promise => { + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreatePeerLiquidityWithdrawal( + $input: CreatePeerLiquidityWithdrawalInput! + ) { + createPeerLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + id: uuid(), + peerId: peer.id, + amount: amount.toString(), + idempotencyKey: uuid(), + timeoutSeconds: 0 + } + } + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createPeerLiquidityWithdrawal + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message, + extensions: expect.objectContaining({ + code + }) + }) + ) + } + } + ) }) describe('Create asset liquidity withdrawal', (): void => { @@ -728,81 +784,89 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for unknown asset', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateAssetLiquidityWithdrawal( - $input: CreateAssetLiquidityWithdrawalInput! - ) { - createAssetLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateAssetLiquidityWithdrawal( + $input: CreateAssetLiquidityWithdrawalInput! + ) { + createAssetLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + id: uuid(), + assetId: uuid(), + amount: '100', + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - id: uuid(), - assetId: uuid(), - amount: '100', - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createAssetLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createAssetLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Unknown asset', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown asset', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) test('Returns an error for invalid id', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateAssetLiquidityWithdrawal( - $input: CreateAssetLiquidityWithdrawalInput! - ) { - createAssetLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateAssetLiquidityWithdrawal( + $input: CreateAssetLiquidityWithdrawalInput! + ) { + createAssetLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + id: 'not a uuid', + assetId: asset.id, + amount: startingBalance.toString(), + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - id: 'not a uuid', - assetId: asset.id, - amount: startingBalance.toString(), - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createAssetLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createAssetLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns an error for existing transfer', async (): Promise => { @@ -814,52 +878,8 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(10) }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateAssetLiquidityWithdrawal( - $input: CreateAssetLiquidityWithdrawalInput! - ) { - createAssetLiquidityWithdrawal(input: $input) { - success - } - } - `, - variables: { - input: { - id, - assetId: asset.id, - amount: startingBalance.toString(), - idempotencyKey: uuid(), - timeoutSeconds: 0 - } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createAssetLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) - }) - - test.each` - amount | message | code - ${startingBalance + BigInt(1)} | ${'Insufficient transfer balance'} | ${GraphQLErrorCode.Forbidden} - ${BigInt(0)} | ${'Transfer amount is zero'} | ${GraphQLErrorCode.Forbidden} - `( - 'Returns error for $error', - async ({ amount, code, message }): Promise => { - const gqlQuery = appContainer.apolloClient + try { + await appContainer.apolloClient .mutate({ mutation: gql` mutation CreateAssetLiquidityWithdrawal( @@ -872,9 +892,9 @@ describe('Liquidity Resolvers', (): void => { `, variables: { input: { - id: uuid(), + id, assetId: asset.id, - amount: amount.toString(), + amount: startingBalance.toString(), idempotencyKey: uuid(), timeoutSeconds: 0 } @@ -887,171 +907,91 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(message, { - extensions: { - code - } + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) }) ) } - ) - }) - - describe('Create wallet address withdrawal', (): void => { - let walletAddress: WalletAddress - const amount = BigInt(100) - - beforeEach(async (): Promise => { - walletAddress = await createWalletAddress(deps, { - createLiquidityAccount: true - }) - - await expect( - accountingService.createDeposit({ - id: uuid(), - account: walletAddress, - amount - }) - ).resolves.toBeUndefined() }) - test('Can create withdrawal from wallet address', async (): Promise => { - const id = uuid() - const response = await appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateWalletAddressWithdrawal( - $input: CreateWalletAddressWithdrawalInput! - ) { - createWalletAddressWithdrawal(input: $input) { - withdrawal { - id - amount - walletAddress { - id + test.each` + amount | message | code + ${startingBalance + BigInt(1)} | ${'Insufficient transfer balance'} | ${GraphQLErrorCode.Forbidden} + ${BigInt(0)} | ${'Transfer amount is zero'} | ${GraphQLErrorCode.Forbidden} + `( + 'Returns error for $error', + async ({ amount, code, message }): Promise => { + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateAssetLiquidityWithdrawal( + $input: CreateAssetLiquidityWithdrawalInput! + ) { + createAssetLiquidityWithdrawal(input: $input) { + success } } - } - } - `, - variables: { - input: { - id, - walletAddressId: walletAddress.id, - idempotencyKey: uuid(), - timeoutSeconds: 0 - } - } - }) - .then((query): WalletAddressWithdrawalMutationResponse => { - if (query.data) { - return query.data.createWalletAddressWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - expect(response.withdrawal).toMatchObject({ - id, - amount: amount.toString(), - walletAddress: { - id: walletAddress.id - } - }) - }) - - test('Returns an error for unknown wallet address', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateWalletAddressWithdrawal( - $input: CreateWalletAddressWithdrawalInput! - ) { - createWalletAddressWithdrawal(input: $input) { - withdrawal { - id - } - } - } - `, - variables: { - input: { - id: uuid(), - walletAddressId: uuid(), - idempotencyKey: uuid(), - timeoutSeconds: 0 - } - } - }) - .then((query): WalletAddressWithdrawalMutationResponse => { - if (query.data) { - return query.data.createWalletAddressWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Unknown wallet address', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - ) - }) - - test('Returns an error for invalid id', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateWalletAddressWithdrawal( - $input: CreateWalletAddressWithdrawalInput! - ) { - createWalletAddressWithdrawal(input: $input) { - withdrawal { - id + `, + variables: { + input: { + id: uuid(), + assetId: asset.id, + amount: amount.toString(), + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - } - `, - variables: { - input: { - id: 'not a uuid', - walletAddressId: walletAddress.id, - idempotencyKey: uuid(), - timeoutSeconds: 0 - } - } - }) - .then((query): WalletAddressWithdrawalMutationResponse => { - if (query.data) { - return query.data.createWalletAddressWithdrawal - } else { - throw new Error('Data was empty') - } - }) + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createAssetLiquidityWithdrawal + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message, + extensions: expect.objectContaining({ + code + }) + }) + ) + } + } + ) + }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) - }) + describe('Create wallet address withdrawal', (): void => { + let walletAddress: WalletAddress + const amount = BigInt(100) + + beforeEach(async (): Promise => { + walletAddress = await createWalletAddress(deps, { + createLiquidityAccount: true + }) - test('Returns an error for existing transfer', async (): Promise => { - const id = uuid() await expect( accountingService.createDeposit({ - id, + id: uuid(), account: walletAddress, - amount: BigInt(10) + amount }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient + }) + + test('Can create withdrawal from wallet address', async (): Promise => { + const id = uuid() + const response = await appContainer.apolloClient .mutate({ mutation: gql` mutation CreateWalletAddressWithdrawal( @@ -1060,6 +1000,10 @@ describe('Liquidity Resolvers', (): void => { createWalletAddressWithdrawal(input: $input) { withdrawal { id + amount + walletAddress { + id + } } } } @@ -1081,197 +1025,236 @@ describe('Liquidity Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + expect(response.withdrawal).toMatchObject({ + id, + amount: amount.toString(), + walletAddress: { + id: walletAddress.id + } + }) }) - test('Returns an error for empty balance', async (): Promise => { - await expect( - accountingService.createWithdrawal({ - id: uuid(), - account: walletAddress, - amount, - timeout: 0 - }) - ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateWalletAddressWithdrawal( - $input: CreateWalletAddressWithdrawalInput! - ) { - createWalletAddressWithdrawal(input: $input) { - withdrawal { - id + test('Returns an error for unknown wallet address', async (): Promise => { + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateWalletAddressWithdrawal( + $input: CreateWalletAddressWithdrawalInput! + ) { + createWalletAddressWithdrawal(input: $input) { + withdrawal { + id + } } } + `, + variables: { + input: { + id: uuid(), + walletAddressId: uuid(), + idempotencyKey: uuid(), + timeoutSeconds: 0 + } } - `, - variables: { - input: { - id: uuid(), - walletAddressId: walletAddress.id, - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): WalletAddressWithdrawalMutationResponse => { + if (query.data) { + return query.data.createWalletAddressWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): WalletAddressWithdrawalMutationResponse => { - if (query.data) { - return query.data.createWalletAddressWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer amount is zero', { - extensions: { - code: GraphQLErrorCode.Forbidden - } - }) - ) - }) - }) - - describe.each(['peer', 'asset'])( - 'Post %s liquidity withdrawal', - (type): void => { - let withdrawalId: string - - beforeEach(async (): Promise => { - const peer = await createPeer(deps) - const deposit = { - id: uuid(), - account: type === 'peer' ? peer : peer.asset, - amount: BigInt(100) - } - await expect( - accountingService.createDeposit(deposit) - ).resolves.toBeUndefined() - withdrawalId = uuid() - await expect( - accountingService.createWithdrawal({ - ...deposit, - id: withdrawalId, - amount: BigInt(10), - timeout: timeoutTwoPhase }) - ).resolves.toBeUndefined() - }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown wallet address', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } + }) - test(`Can post a(n) ${type} liquidity withdrawal`, async (): Promise => { - const response = await appContainer.apolloClient + test('Returns an error for invalid id', async (): Promise => { + try { + await appContainer.apolloClient .mutate({ mutation: gql` - mutation PostLiquidityWithdrawal( - $input: PostLiquidityWithdrawalInput! + mutation CreateWalletAddressWithdrawal( + $input: CreateWalletAddressWithdrawalInput! ) { - postLiquidityWithdrawal(input: $input) { - success + createWalletAddressWithdrawal(input: $input) { + withdrawal { + id + } } } `, variables: { input: { - withdrawalId, - idempotencyKey: uuid() + id: 'not a uuid', + walletAddressId: walletAddress.id, + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) - .then((query): LiquidityMutationResponse => { + .then((query): WalletAddressWithdrawalMutationResponse => { if (query.data) { - return query.data.postLiquidityWithdrawal + return query.data.createWalletAddressWithdrawal } else { throw new Error('Data was empty') } }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } + }) - expect(response.success).toBe(true) - }) - - test("Can't post non-existent withdrawal", async (): Promise => { - const gqlQuery = appContainer.apolloClient + test('Returns an error for existing transfer', async (): Promise => { + const id = uuid() + await expect( + accountingService.createDeposit({ + id, + account: walletAddress, + amount: BigInt(10) + }) + ).resolves.toBeUndefined() + try { + await appContainer.apolloClient .mutate({ mutation: gql` - mutation PostLiquidityWithdrawal( - $input: PostLiquidityWithdrawalInput! + mutation CreateWalletAddressWithdrawal( + $input: CreateWalletAddressWithdrawalInput! ) { - postLiquidityWithdrawal(input: $input) { - success + createWalletAddressWithdrawal(input: $input) { + withdrawal { + id + } } } `, variables: { input: { - withdrawalId: uuid(), - idempotencyKey: uuid() + id, + walletAddressId: walletAddress.id, + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) - .then((query): LiquidityMutationResponse => { + .then((query): WalletAddressWithdrawalMutationResponse => { if (query.data) { - return query.data.postLiquidityWithdrawal + return query.data.createWalletAddressWithdrawal } else { throw new Error('Data was empty') } }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Unknown transfer', { - extensions: { - code: GraphQLErrorCode.NotFound - } + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) }) ) - }) + } + }) - test("Can't post invalid withdrawal id", async (): Promise => { - const gqlQuery = appContainer.apolloClient + test('Returns an error for empty balance', async (): Promise => { + await expect( + accountingService.createWithdrawal({ + id: uuid(), + account: walletAddress, + amount, + timeout: 0 + }) + ).resolves.toBeUndefined() + try { + await appContainer.apolloClient .mutate({ mutation: gql` - mutation PostLiquidityWithdrawal( - $input: PostLiquidityWithdrawalInput! + mutation CreateWalletAddressWithdrawal( + $input: CreateWalletAddressWithdrawalInput! ) { - postLiquidityWithdrawal(input: $input) { - success + createWalletAddressWithdrawal(input: $input) { + withdrawal { + id + } } } `, variables: { input: { - withdrawalId: 'not a uuid', - idempotencyKey: uuid() + id: uuid(), + walletAddressId: walletAddress.id, + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) - .then((query): LiquidityMutationResponse => { + .then((query): WalletAddressWithdrawalMutationResponse => { if (query.data) { - return query.data.postLiquidityWithdrawal + return query.data.createWalletAddressWithdrawal } else { throw new Error('Data was empty') } }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer amount is zero', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) + } + }) + }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } + describe.each(['peer', 'asset'])( + 'Post %s liquidity withdrawal', + (type): void => { + let withdrawalId: string + + beforeEach(async (): Promise => { + const peer = await createPeer(deps) + const deposit = { + id: uuid(), + account: type === 'peer' ? peer : peer.asset, + amount: BigInt(100) + } + await expect( + accountingService.createDeposit(deposit) + ).resolves.toBeUndefined() + withdrawalId = uuid() + await expect( + accountingService.createWithdrawal({ + ...deposit, + id: withdrawalId, + amount: BigInt(10), + timeout: timeoutTwoPhase }) - ) + ).resolves.toBeUndefined() }) - test("Can't post posted withdrawal", async (): Promise => { - await expect( - accountingService.postWithdrawal(withdrawalId) - ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient + test(`Can post a(n) ${type} liquidity withdrawal`, async (): Promise => { + const response = await appContainer.apolloClient .mutate({ mutation: gql` mutation PostLiquidityWithdrawal( @@ -1297,52 +1280,173 @@ describe('Liquidity Resolvers', (): void => { } }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already posted', { - extensions: { - code: GraphQLErrorCode.Conflict - } - }) - ) + expect(response.success).toBe(true) + }) + + test("Can't post non-existent withdrawal", async (): Promise => { + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation PostLiquidityWithdrawal( + $input: PostLiquidityWithdrawalInput! + ) { + postLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId: uuid(), + idempotencyKey: uuid() + } + } + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.postLiquidityWithdrawal + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown transfer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } + }) + + test("Can't post invalid withdrawal id", async (): Promise => { + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation PostLiquidityWithdrawal( + $input: PostLiquidityWithdrawalInput! + ) { + postLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId: 'not a uuid', + idempotencyKey: uuid() + } + } + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.postLiquidityWithdrawal + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } + }) + + test("Can't post posted withdrawal", async (): Promise => { + await expect( + accountingService.postWithdrawal(withdrawalId) + ).resolves.toBeUndefined() + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation PostLiquidityWithdrawal( + $input: PostLiquidityWithdrawalInput! + ) { + postLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId, + idempotencyKey: uuid() + } + } + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.postLiquidityWithdrawal + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already posted', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) + } }) test("Can't post voided withdrawal", async (): Promise => { await expect( accountingService.voidWithdrawal(withdrawalId) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation PostLiquidityWithdrawal( - $input: PostLiquidityWithdrawalInput! - ) { - postLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation PostLiquidityWithdrawal( + $input: PostLiquidityWithdrawalInput! + ) { + postLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId, + idempotencyKey: uuid() } } - `, - variables: { - input: { - withdrawalId, - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.postLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.postLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already voided', { - extensions: { - code: GraphQLErrorCode.Conflict - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already voided', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) + } }) } ) @@ -1404,153 +1508,169 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't void non-existent withdrawal", async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation VoidLiquidityWithdrawal( - $input: VoidLiquidityWithdrawalInput! - ) { - voidLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation VoidLiquidityWithdrawal( + $input: VoidLiquidityWithdrawalInput! + ) { + voidLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId: uuid(), + idempotencyKey: uuid() } } - `, - variables: { - input: { - withdrawalId: uuid(), - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.voidLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.voidLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Unknown transfer', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown transfer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) test("Can't void invalid withdrawal id", async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation VoidLiquidityWithdrawal( - $input: VoidLiquidityWithdrawalInput! - ) { - voidLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation VoidLiquidityWithdrawal( + $input: VoidLiquidityWithdrawalInput! + ) { + voidLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId: 'not a uuid', + idempotencyKey: uuid() } } - `, - variables: { - input: { - withdrawalId: 'not a uuid', - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.voidLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.voidLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test("Can't void posted withdrawal", async (): Promise => { await expect( accountingService.postWithdrawal(withdrawalId) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation VoidLiquidityWithdrawal( - $input: VoidLiquidityWithdrawalInput! - ) { - voidLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation VoidLiquidityWithdrawal( + $input: VoidLiquidityWithdrawalInput! + ) { + voidLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId, + idempotencyKey: uuid() } } - `, - variables: { - input: { - withdrawalId, - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.voidLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.voidLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already posted', { - extensions: { - code: GraphQLErrorCode.Conflict - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already posted', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) + } }) test("Can't void voided withdrawal", async (): Promise => { await expect( accountingService.voidWithdrawal(withdrawalId) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation voidLiquidityWithdrawal( - $input: VoidLiquidityWithdrawalInput! - ) { - voidLiquidityWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation voidLiquidityWithdrawal( + $input: VoidLiquidityWithdrawalInput! + ) { + voidLiquidityWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + withdrawalId, + idempotencyKey: uuid() } } - `, - variables: { - input: { - withdrawalId, - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.voidLiquidityWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.voidLiquidityWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already voided', { - extensions: { - code: GraphQLErrorCode.Conflict - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already voided', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) + } }) } ) @@ -1648,39 +1768,43 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't deposit for non-existent webhook event id", async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositLiquidity( - $input: DepositEventLiquidityInput! - ) { - depositEventLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositLiquidity( + $input: DepositEventLiquidityInput! + ) { + depositEventLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + eventId: uuid(), + idempotencyKey: uuid() } } - `, - variables: { - input: { - eventId: uuid(), - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositEventLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositEventLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns an error for existing transfer', async (): Promise => { @@ -1691,39 +1815,43 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositLiquidity( - $input: DepositEventLiquidityInput! - ) { - depositEventLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositLiquidity( + $input: DepositEventLiquidityInput! + ) { + depositEventLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + eventId, + idempotencyKey: uuid() } } - `, - variables: { - input: { - eventId, - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositEventLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositEventLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) + } }) } ) @@ -1862,78 +1990,86 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns error for non-existent webhook event id', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation WithdrawLiquidity( - $input: WithdrawEventLiquidityInput! - ) { - withdrawEventLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation WithdrawLiquidity( + $input: WithdrawEventLiquidityInput! + ) { + withdrawEventLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + eventId: uuid(), + idempotencyKey: uuid() } } - `, - variables: { - input: { - eventId: uuid(), - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.withdrawEventLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.withdrawEventLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns error for already completed withdrawal', async (): Promise => { await expect( accountingService.createWithdrawal(withdrawal) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation WithdrawLiquidity( - $input: WithdrawEventLiquidityInput! - ) { - withdrawEventLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation WithdrawLiquidity( + $input: WithdrawEventLiquidityInput! + ) { + withdrawEventLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + eventId, + idempotencyKey: uuid() } } - `, - variables: { - input: { - eventId, - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.withdrawEventLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.withdrawEventLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) + } }) } ) @@ -2058,77 +2194,85 @@ describe('Liquidity Resolvers', (): void => { amount } }) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateIncomingPaymentWithdrawal( - $input: CreateIncomingPaymentWithdrawalInput! - ) { - createIncomingPaymentWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! + ) { + createIncomingPaymentWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + incomingPaymentId: uuid(), + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - incomingPaymentId: uuid(), - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createIncomingPaymentWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createIncomingPaymentWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns error when related webhook not found', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateIncomingPaymentWithdrawal( - $input: CreateIncomingPaymentWithdrawalInput! - ) { - createIncomingPaymentWithdrawal(input: $input) { - success - } - } - `, - variables: { - input: { - incomingPaymentId: incomingPayment.id, - idempotencyKey: uuid(), - timeoutSeconds: 0 - } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createIncomingPaymentWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! + ) { + createIncomingPaymentWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + incomingPaymentId: incomingPayment.id, + idempotencyKey: uuid(), + timeoutSeconds: 0 + } + } + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createIncomingPaymentWithdrawal + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns error for already completed withdrawal', async (): Promise => { @@ -2151,40 +2295,44 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateIncomingPaymentWithdrawal( - $input: CreateIncomingPaymentWithdrawalInput! - ) { - createIncomingPaymentWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! + ) { + createIncomingPaymentWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + incomingPaymentId: incomingPayment.id, + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - incomingPaymentId: incomingPayment.id, - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createIncomingPaymentWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createIncomingPaymentWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) + } }) }) }) @@ -2261,39 +2409,44 @@ describe('Liquidity Resolvers', (): void => { describe('Cannot withdraw liquidity', () => { test('Returns error for non-existent outgoing payment id', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateOutgoingPaymentWithdrawal( - $input: CreateOutgoingPaymentWithdrawalInput! - ) { - createOutgoingPaymentWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateOutgoingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! + ) { + createOutgoingPaymentWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + outgoingPaymentId: uuid(), + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - outgoingPaymentId: uuid(), - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createOutgoingPaymentWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createOutgoingPaymentWithdrawal - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns error when related webhook not found', async (): Promise => { @@ -2304,40 +2457,44 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateIncomingPaymentWithdrawal( - $input: CreateOutgoingPaymentWithdrawalInput! - ) { - createOutgoingPaymentWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateIncomingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! + ) { + createOutgoingPaymentWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + outgoingPaymentId: outgoingPayment.id, + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - outgoingPaymentId: outgoingPayment.id, - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createOutgoingPaymentWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createOutgoingPaymentWithdrawal - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns error for already completed withdrawal', async (): Promise => { @@ -2359,39 +2516,44 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateOutgoingPaymentWithdrawal( - $input: CreateOutgoingPaymentWithdrawalInput! - ) { - createOutgoingPaymentWithdrawal(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateOutgoingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! + ) { + createOutgoingPaymentWithdrawal(input: $input) { + success + } + } + `, + variables: { + input: { + outgoingPaymentId: outgoingPayment.id, + idempotencyKey: uuid(), + timeoutSeconds: 0 } } - `, - variables: { - input: { - outgoingPaymentId: outgoingPayment.id, - idempotencyKey: uuid(), - timeoutSeconds: 0 + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.createOutgoingPaymentWithdrawal + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.createOutgoingPaymentWithdrawal - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Insufficient transfer balance', { - extensions: { - code: GraphQLErrorCode.Forbidden - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Insufficient transfer balance', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) + } }) }) }) @@ -2456,39 +2618,43 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't deposit for non-existent outgoing payment id", async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositLiquidity( - $input: DepositOutgoingPaymentLiquidityInput! - ) { - depositOutgoingPaymentLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositLiquidity( + $input: DepositOutgoingPaymentLiquidityInput! + ) { + depositOutgoingPaymentLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + outgoingPaymentId: uuid(), + idempotencyKey: uuid() } } - `, - variables: { - input: { - outgoingPaymentId: uuid(), - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositOutgoingPaymentLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositOutgoingPaymentLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Invalid transfer id', { - extensions: { - code: GraphQLErrorCode.BadUserInput - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) + } }) test('Returns an error for existing transfer', async (): Promise => { @@ -2499,39 +2665,43 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DepositLiquidity( - $input: DepositOutgoingPaymentLiquidityInput! - ) { - depositOutgoingPaymentLiquidity(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DepositLiquidity( + $input: DepositOutgoingPaymentLiquidityInput! + ) { + depositOutgoingPaymentLiquidity(input: $input) { + success + } + } + `, + variables: { + input: { + outgoingPaymentId: outgoingPayment.id, + idempotencyKey: uuid() } } - `, - variables: { - input: { - outgoingPaymentId: outgoingPayment.id, - idempotencyKey: uuid() + }) + .then((query): LiquidityMutationResponse => { + if (query.data) { + return query.data.depositOutgoingPaymentLiquidity + } else { + throw new Error('Data was empty') } - } - }) - .then((query): LiquidityMutationResponse => { - if (query.data) { - return query.data.depositOutgoingPaymentLiquidity - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Transfer already exists', { - extensions: { - code: GraphQLErrorCode.Duplicate - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) + } }) } ) diff --git a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts index 75722c3591..e7ee1d1b20 100644 --- a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { PaymentError } from '@interledger/pay' import { v4 as uuid } from 'uuid' import * as Pay from '@interledger/pay' @@ -31,7 +31,6 @@ import { OutgoingPaymentState as SchemaPaymentState } from '../generated/graphql' import { faker } from '@faker-js/faker' -import { GraphQLError } from 'graphql' import { GraphQLErrorCode } from '../errors' describe('OutgoingPayment Resolvers', (): void => { @@ -102,7 +101,7 @@ describe('OutgoingPayment Resolvers', (): void => { [state, Pay.PaymentError.ReceiverProtocolViolation] ]) test.each(states)( - '200 - %s, error: %s', + '%s, error: %s', async (state, error): Promise => { const amountSent = BigInt(78) jest @@ -214,7 +213,7 @@ describe('OutgoingPayment Resolvers', (): void => { } ) - test('200 - with added liquidity', async (): Promise => { + test('with added liquidity', async (): Promise => { await accountingService.createDeposit({ id: uuid(), account: payment, @@ -245,13 +244,13 @@ describe('OutgoingPayment Resolvers', (): void => { }) }) - test('404', async (): Promise => { + test('not found', async (): Promise => { jest .spyOn(outgoingPaymentService, 'get') .mockImplementation(async () => undefined) - await expect( - appContainer.apolloClient.query({ + try { + await appContainer.apolloClient.query({ query: gql` query OutgoingPayment($paymentId: String!) { outgoingPayment(id: $paymentId) { @@ -261,7 +260,17 @@ describe('OutgoingPayment Resolvers', (): void => { `, variables: { paymentId: uuid() } }) - ).rejects.toThrow('payment does not exist') + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'payment does not exist', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) }) @@ -271,7 +280,7 @@ describe('OutgoingPayment Resolvers', (): void => { externalRef: '202201' } - test('201 (metadata)', async (): Promise => { + test('success (metadata)', async (): Promise => { const { id: walletAddressId } = await createWalletAddress(deps, { assetId: asset.id }) @@ -321,39 +330,42 @@ describe('OutgoingPayment Resolvers', (): void => { quoteId: uuid() } - const query = appContainer.apolloClient - .query({ - query: gql` - mutation CreateOutgoingPayment( - $input: CreateOutgoingPaymentInput! - ) { - createOutgoingPayment(input: $input) { - payment { - id - state + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateOutgoingPayment( + $input: CreateOutgoingPaymentInput! + ) { + createOutgoingPayment(input: $input) { + payment { + id + state + } } } - } - `, - variables: { input } - }) - .then( - (query): OutgoingPaymentResponse => query.data?.createOutgoingPayment - ) - await expect(query).rejects.toThrow( - new GraphQLError( - errorToMessage[OutgoingPaymentError.UnknownWalletAddress], - { - extensions: { + `, + variables: { input } + }) + .then( + (query): OutgoingPaymentResponse => + query.data?.createOutgoingPayment + ) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[OutgoingPaymentError.UnknownWalletAddress], + extensions: expect.objectContaining({ code: errorToCode[OutgoingPaymentError.UnknownWalletAddress] - } - } + }) + }) ) - ) + } await expect(createSpy).toHaveBeenCalledWith(input) }) - test('500', async (): Promise => { + test('internal server error', async (): Promise => { const createSpy = jest .spyOn(outgoingPaymentService, 'create') .mockRejectedValueOnce(new Error('unexpected')) @@ -363,33 +375,38 @@ describe('OutgoingPayment Resolvers', (): void => { quoteId: uuid() } - const query = appContainer.apolloClient - .query({ - query: gql` - mutation CreateOutgoingPayment( - $input: CreateOutgoingPaymentInput! - ) { - createOutgoingPayment(input: $input) { - payment { - id - state + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateOutgoingPayment( + $input: CreateOutgoingPaymentInput! + ) { + createOutgoingPayment(input: $input) { + payment { + id + state + } } } - } - `, - variables: { input } - }) - .then( - (query): OutgoingPaymentResponse => query.data?.createOutgoingPayment + `, + variables: { input } + }) + .then( + (query): OutgoingPaymentResponse => + query.data?.createOutgoingPayment + ) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) ) - - await expect(query).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + } expect(createSpy).toHaveBeenCalledWith(input) }) }) @@ -458,36 +475,38 @@ describe('OutgoingPayment Resolvers', (): void => { } } - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - mutation CreateOutgoingPaymentFromIncomingPayment( - $input: CreateOutgoingPaymentFromIncomingPaymentInput! - ) { - createOutgoingPaymentFromIncomingPayment(input: $input) { - payment { - id - state + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateOutgoingPaymentFromIncomingPayment( + $input: CreateOutgoingPaymentFromIncomingPaymentInput! + ) { + createOutgoingPaymentFromIncomingPayment(input: $input) { + payment { + id + state + } } } - } - `, - variables: { input } - }) - .then( - (query): OutgoingPaymentResponse => - query.data?.createOutgoingPaymentFromIncomingPayment - ) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError( - errorToMessage[OutgoingPaymentError.UnknownWalletAddress], - { - extensions: { + `, + variables: { input } + }) + .then( + (query): OutgoingPaymentResponse => + query.data?.createOutgoingPaymentFromIncomingPayment + ) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[OutgoingPaymentError.UnknownWalletAddress], + extensions: expect.objectContaining({ code: errorToCode[OutgoingPaymentError.UnknownWalletAddress] - } - } + }) + }) ) - ) + } expect(createSpy).toHaveBeenCalledWith(input) }) @@ -506,33 +525,38 @@ describe('OutgoingPayment Resolvers', (): void => { } } - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - mutation CreateOutgoingPaymentFromIncomingPayment( - $input: CreateOutgoingPaymentFromIncomingPaymentInput! - ) { - createOutgoingPaymentFromIncomingPayment(input: $input) { - payment { - id - state + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateOutgoingPaymentFromIncomingPayment( + $input: CreateOutgoingPaymentFromIncomingPaymentInput! + ) { + createOutgoingPaymentFromIncomingPayment(input: $input) { + payment { + id + state + } } } - } - `, - variables: { input } - }) - .then( - (query): OutgoingPaymentResponse => - query.data?.createOutgoingPaymentFromIncomingPayment + `, + variables: { input } + }) + .then( + (query): OutgoingPaymentResponse => + query.data?.createOutgoingPaymentFromIncomingPayment + ) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) ) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + } expect(createSpy).toHaveBeenCalledWith(input) }) }) @@ -612,35 +636,39 @@ describe('OutgoingPayment Resolvers', (): void => { const input = { id: uuid() } - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CancelOutgoingPayment( - $input: CancelOutgoingPaymentInput! - ) { - cancelOutgoingPayment(input: $input) { - payment { - id - state - metadata + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CancelOutgoingPayment( + $input: CancelOutgoingPaymentInput! + ) { + cancelOutgoingPayment(input: $input) { + payment { + id + state + metadata + } } } - } - `, - variables: { input } - }) - .then( - (query): OutgoingPaymentResponse => - query.data?.cancelOutgoingPayment + `, + variables: { input } + }) + .then( + (query): OutgoingPaymentResponse => + query.data?.cancelOutgoingPayment + ) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[paymentError], + extensions: expect.objectContaining({ + code: errorToCode[paymentError] + }) + }) ) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[paymentError], { - extensions: { - code: errorToCode[paymentError] - } - }) - ) + } expect(cancelSpy).toHaveBeenCalledWith(input) } ) diff --git a/packages/backend/src/graphql/resolvers/peer.test.ts b/packages/backend/src/graphql/resolvers/peer.test.ts index 5f69c9256b..deec0406af 100644 --- a/packages/backend/src/graphql/resolvers/peer.test.ts +++ b/packages/backend/src/graphql/resolvers/peer.test.ts @@ -1,8 +1,7 @@ import { faker } from '@faker-js/faker' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import assert from 'assert' import { v4 as uuid } from 'uuid' -import { GraphQLError } from 'graphql' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' @@ -158,39 +157,43 @@ describe('Peer Resolvers', (): void => { ${PeerError.UnknownAsset} ${PeerError.DuplicatePeer} ${PeerError.InvalidInitialLiquidity} - `('Error - $error', async ({ error }): Promise => { - jest.spyOn(peerService, 'create').mockResolvedValueOnce(error) + `('Error - $error', async ({ error: testError }): Promise => { + jest.spyOn(peerService, 'create').mockResolvedValueOnce(testError) const peer = randomPeer() - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreatePeer($input: CreatePeerInput!) { - createPeer(input: $input) { - peer { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreatePeer($input: CreatePeerInput!) { + createPeer(input: $input) { + peer { + id + } } } + `, + variables: { + input: peer } - `, - variables: { - input: peer - } - }) - .then((query): CreatePeerMutationResponse => { - if (query.data) { - return query.data.createPeer - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[error as PeerError], { - extensions: { - code: errorToCode[error as PeerError] - } - }) - ) + }) + .then((query): CreatePeerMutationResponse => { + if (query.data) { + return query.data.createPeer + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[testError as PeerError], + extensions: expect.objectContaining({ + code: errorToCode[testError as PeerError] + }) + }) + ) + } }) test('internal server error', async (): Promise => { @@ -200,35 +203,40 @@ describe('Peer Resolvers', (): void => { throw new Error('unexpected') }) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreatePeer($input: CreatePeerInput!) { - createPeer(input: $input) { - peer { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreatePeer($input: CreatePeerInput!) { + createPeer(input: $input) { + peer { + id + } } } + `, + variables: { + input: randomPeer() } - `, - variables: { - input: randomPeer() - } - }) - .then((query): CreatePeerMutationResponse => { - if (query.data) { - return query.data.createPeer - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + .then((query): CreatePeerMutationResponse => { + if (query.data) { + return query.data.createPeer + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) @@ -324,38 +332,42 @@ describe('Peer Resolvers', (): void => { }) test('Returns error for unknown peer', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - query Peer($peerId: String!) { - peer(id: $peerId) { - id - asset { - code - scale + try { + await appContainer.apolloClient + .query({ + query: gql` + query Peer($peerId: String!) { + peer(id: $peerId) { + id + asset { + code + scale + } } } + `, + variables: { + peerId: uuid() } - `, - variables: { - peerId: uuid() - } - }) - .then((query): GraphQLPeer => { - if (query.data) { - return query.data.peer - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[PeerError.UnknownPeer], { - extensions: { - code: errorToCode[PeerError.UnknownPeer] - } - }) - ) + }) + .then((query): GraphQLPeer => { + if (query.data) { + return query.data.peer + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[PeerError.UnknownPeer], + extensions: expect.objectContaining({ + code: errorToCode[PeerError.UnknownPeer] + }) + }) + ) + } }) }) @@ -527,41 +539,45 @@ describe('Peer Resolvers', (): void => { ${PeerError.InvalidStaticIlpAddress} ${PeerError.InvalidHTTPEndpoint} ${PeerError.UnknownPeer} - `('Error - $error', async ({ error }): Promise => { - jest.spyOn(peerService, 'update').mockResolvedValueOnce(error) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation UpdatePeer($input: UpdatePeerInput!) { - updatePeer(input: $input) { - peer { - id + `('Error - $error', async ({ error: testError }): Promise => { + jest.spyOn(peerService, 'update').mockResolvedValueOnce(testError) + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation UpdatePeer($input: UpdatePeerInput!) { + updatePeer(input: $input) { + peer { + id + } } } + `, + variables: { + input: { + id: peer.id, + maxPacketAmount: '100' + } } - `, - variables: { - input: { - id: peer.id, - maxPacketAmount: '100' + }) + .then((query): UpdatePeerMutationResponse => { + if (query.data) { + return query.data.updatePeer + } else { + throw new Error('Data was empty') } - } - }) - .then((query): UpdatePeerMutationResponse => { - if (query.data) { - return query.data.updatePeer - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[error as PeerError], { - extensions: { - code: errorToCode[error as PeerError] - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[testError as PeerError], + extensions: expect.objectContaining({ + code: errorToCode[testError as PeerError] + }) + }) + ) + } }) test('Returns error if unexpected error', async (): Promise => { @@ -569,48 +585,52 @@ describe('Peer Resolvers', (): void => { throw new Error('unexpected') }) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation UpdatePeer($input: UpdatePeerInput!) { - updatePeer(input: $input) { - peer { - id - maxPacketAmount - http { - outgoing { - authToken - endpoint + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation UpdatePeer($input: UpdatePeerInput!) { + updatePeer(input: $input) { + peer { + id + maxPacketAmount + http { + outgoing { + authToken + endpoint + } } + staticIlpAddress + name } - staticIlpAddress - name } } + `, + variables: { + input: { + id: peer.id, + maxPacketAmount: '100' + } } - `, - variables: { - input: { - id: peer.id, - maxPacketAmount: '100' + }) + .then((query): UpdatePeerMutationResponse => { + if (query.data) { + return query.data.updatePeer + } else { + throw new Error('Data was empty') } - } - }) - .then((query): UpdatePeerMutationResponse => { - if (query.data) { - return query.data.updatePeer - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) @@ -650,73 +670,80 @@ describe('Peer Resolvers', (): void => { }) test('Returns error for unknown peer', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DeletePeer($input: DeletePeerInput!) { - deletePeer(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DeletePeer($input: DeletePeerInput!) { + deletePeer(input: $input) { + success + } + } + `, + variables: { + input: { + id: uuid() } } - `, - variables: { - input: { - id: uuid() + }) + .then((query): DeletePeerMutationResponse => { + if (query.data) { + return query.data.deletePeer + } else { + throw new Error('Data was empty') } - } - }) - .then((query): DeletePeerMutationResponse => { - if (query.data) { - return query.data.deletePeer - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[PeerError.UnknownPeer], { - extensions: { - code: errorToCode[PeerError.UnknownPeer] - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[PeerError.UnknownPeer], + extensions: expect.objectContaining({ + code: errorToCode[PeerError.UnknownPeer] + }) + }) + ) + } }) test('Returns error if unexpected error', async (): Promise => { jest.spyOn(peerService, 'delete').mockImplementationOnce(async () => { throw new Error('unexpected') }) - - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation DeletePeer($input: DeletePeerInput!) { - deletePeer(input: $input) { - success + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation DeletePeer($input: DeletePeerInput!) { + deletePeer(input: $input) { + success + } + } + `, + variables: { + input: { + id: peer.id } } - `, - variables: { - input: { - id: peer.id + }) + .then((query): DeletePeerMutationResponse => { + if (query.data) { + return query.data.deletePeer + } else { + throw new Error('Data was empty') } - } - }) - .then((query): DeletePeerMutationResponse => { - if (query.data) { - return query.data.deletePeer - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) }) diff --git a/packages/backend/src/graphql/resolvers/quote.test.ts b/packages/backend/src/graphql/resolvers/quote.test.ts index b2b0993ac0..8202a6f410 100644 --- a/packages/backend/src/graphql/resolvers/quote.test.ts +++ b/packages/backend/src/graphql/resolvers/quote.test.ts @@ -1,6 +1,5 @@ -import { gql } from '@apollo/client' +import { gql, ApolloError } from '@apollo/client' import { v4 as uuid } from 'uuid' -import { GraphQLError } from 'graphql' import { getPageTests } from './page.test' import { createTestApp, TestContainer } from '../../tests/app' @@ -70,7 +69,7 @@ describe('Quote Resolvers', (): void => { } describe('Query.quote', (): void => { - test('200', async (): Promise => { + test('success', async (): Promise => { const { id: walletAddressId } = await createWalletAddress(deps, { assetId: asset.id }) @@ -138,8 +137,8 @@ describe('Quote Resolvers', (): void => { test('Not found', async (): Promise => { jest.spyOn(quoteService, 'get').mockImplementation(async () => undefined) - await expect( - appContainer.apolloClient.query({ + try { + await appContainer.apolloClient.query({ query: gql` query Quote($quoteId: String!) { quote(id: $quoteId) { @@ -149,7 +148,17 @@ describe('Quote Resolvers', (): void => { `, variables: { quoteId: uuid() } }) - ).rejects.toThrow('quote does not exist') + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'quote does not exist', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) }) @@ -184,7 +193,7 @@ describe('Quote Resolvers', (): void => { ${true} | ${undefined} | ${'fixed send to incoming payment'} ${false} | ${receiveAmount} | ${'fixed receive to incoming payment'} ${false} | ${undefined} | ${'incoming payment'} - `('200 ($type)', async ({ withAmount, receiveAmount }): Promise => { + `('$type', async ({ withAmount, receiveAmount }): Promise => { const amount = withAmount ? debitAmount : undefined const { id: walletAddressId } = await createWalletAddress(deps, { assetId: asset.id @@ -227,28 +236,32 @@ describe('Quote Resolvers', (): void => { }) test('unknown walletAddress', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - mutation CreateQuote($input: CreateQuoteInput!) { - createQuote(input: $input) { - quote { - id + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateQuote($input: CreateQuoteInput!) { + createQuote(input: $input) { + quote { + id + } } } - } - `, - variables: { input } - }) - .then((query): QuoteResponse => query.data?.createQuote) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[QuoteError.UnknownWalletAddress], { - extensions: { - code: errorToCode[QuoteError.UnknownWalletAddress] - } - }) - ) + `, + variables: { input } + }) + .then((query): QuoteResponse => query.data?.createQuote) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[QuoteError.UnknownWalletAddress], + extensions: expect.objectContaining({ + code: errorToCode[QuoteError.UnknownWalletAddress] + }) + }) + ) + } }) test('unknown error', async (): Promise => { @@ -256,27 +269,32 @@ describe('Quote Resolvers', (): void => { .spyOn(quoteService, 'create') .mockRejectedValueOnce(new Error('unexpected')) - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - mutation CreateQuote($input: CreateQuoteInput!) { - createQuote(input: $input) { - quote { - id + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateQuote($input: CreateQuoteInput!) { + createQuote(input: $input) { + quote { + id + } } } - } - `, - variables: { input } - }) - .then((query): QuoteResponse => query.data?.createQuote) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + `, + variables: { input } + }) + .then((query): QuoteResponse => query.data?.createQuote) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } expect(createSpy).toHaveBeenCalledWith({ ...input, method: 'ilp' }) }) }) diff --git a/packages/backend/src/graphql/resolvers/receiver.test.ts b/packages/backend/src/graphql/resolvers/receiver.test.ts index 56c20518ec..8b0988ea90 100644 --- a/packages/backend/src/graphql/resolvers/receiver.test.ts +++ b/packages/backend/src/graphql/resolvers/receiver.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { v4 as uuid } from 'uuid' import { createTestApp, TestContainer } from '../../tests/app' import { IocContract } from '@adonisjs/fold' @@ -18,7 +18,6 @@ import { errorToMessage, errorToCode } from '../../open_payments/receiver/errors' -import { GraphQLError } from 'graphql' import { GraphQLErrorCode } from '../errors' describe('Receiver Resolver', (): void => { @@ -144,44 +143,48 @@ describe('Receiver Resolver', (): void => { walletAddressUrl: walletAddress.id } - const query = appContainer.apolloClient - .query({ - query: gql` - mutation CreateReceiver($input: CreateReceiverInput!) { - createReceiver(input: $input) { - receiver { - id - walletAddressUrl - completed - expiresAt - incomingAmount { - value - assetCode - assetScale - } - receivedAmount { - value - assetCode - assetScale + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateReceiver($input: CreateReceiverInput!) { + createReceiver(input: $input) { + receiver { + id + walletAddressUrl + completed + expiresAt + incomingAmount { + value + assetCode + assetScale + } + receivedAmount { + value + assetCode + assetScale + } + metadata + createdAt + updatedAt } - metadata - createdAt - updatedAt } } - } - `, - variables: { input } - }) - .then((query): CreateReceiverResponse => query.data?.createReceiver) - - await expect(query).rejects.toThrow( - new GraphQLError(errorToMessage(ReceiverError.UnknownWalletAddress), { - extensions: { - code: errorToCode(ReceiverError.UnknownWalletAddress) - } - }) - ) + `, + variables: { input } + }) + .then((query): CreateReceiverResponse => query.data?.createReceiver) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage(ReceiverError.UnknownWalletAddress), + extensions: expect.objectContaining({ + code: errorToCode(ReceiverError.UnknownWalletAddress) + }) + }) + ) + } expect(createSpy).toHaveBeenCalledWith(input) }) @@ -196,44 +199,48 @@ describe('Receiver Resolver', (): void => { walletAddressUrl: walletAddress.id } - const query = appContainer.apolloClient - .query({ - query: gql` - mutation CreateReceiver($input: CreateReceiverInput!) { - createReceiver(input: $input) { - receiver { - id - walletAddressUrl - completed - expiresAt - incomingAmount { - value - assetCode - assetScale - } - receivedAmount { - value - assetCode - assetScale + try { + await appContainer.apolloClient + .query({ + query: gql` + mutation CreateReceiver($input: CreateReceiverInput!) { + createReceiver(input: $input) { + receiver { + id + walletAddressUrl + completed + expiresAt + incomingAmount { + value + assetCode + assetScale + } + receivedAmount { + value + assetCode + assetScale + } + metadata + createdAt + updatedAt } - metadata - createdAt - updatedAt } } - } - `, - variables: { input } - }) - .then((query): CreateReceiverResponse => query.data?.createReceiver) - - await expect(query).rejects.toThrow( - new GraphQLError('Cannot create receiver', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + `, + variables: { input } + }) + .then((query): CreateReceiverResponse => query.data?.createReceiver) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Cannot create receiver', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } expect(createSpy).toHaveBeenCalledWith(input) }) }) @@ -306,23 +313,35 @@ describe('Receiver Resolver', (): void => { }) }) - test('404', async (): Promise => { + test('not found', async (): Promise => { jest .spyOn(receiverService, 'get') .mockImplementation(async () => undefined) - await expect( - appContainer.apolloClient.query({ - query: gql` - query GetReceiver($id: String!) { - receiver(id: $id) { - id + try { + await expect( + appContainer.apolloClient.query({ + query: gql` + query GetReceiver($id: String!) { + receiver(id: $id) { + id + } } - } - `, - variables: { id: uuid() } - }) - ).rejects.toThrow('receiver does not exist') + `, + variables: { id: uuid() } + }) + ).rejects.toThrow('receiver does not exist') + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'receiver does not exist', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) }) }) diff --git a/packages/backend/src/graphql/resolvers/receiver.ts b/packages/backend/src/graphql/resolvers/receiver.ts index 2a5941e466..b9002c30f1 100644 --- a/packages/backend/src/graphql/resolvers/receiver.ts +++ b/packages/backend/src/graphql/resolvers/receiver.ts @@ -12,6 +12,7 @@ import { errorToMessage as receiverErrorToMessage } from '../../open_payments/receiver/errors' import { GraphQLError } from 'graphql' +import { GraphQLErrorCode } from '../errors' export const getReceiver: QueryResolvers['receiver'] = async ( _, @@ -22,7 +23,11 @@ export const getReceiver: QueryResolvers['receiver'] = async ( const receiver = await receiverService.get(args.id) if (!receiver) { ctx.logger.error(`Receiver "${args.id}" was not found.`) - throw new Error('receiver does not exist') + throw new GraphQLError('receiver does not exist', { + extensions: { + code: GraphQLErrorCode.NotFound + } + }) } return receiverToGraphql(receiver) } diff --git a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts index f60b7dcafc..69db46f44b 100644 --- a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts +++ b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts @@ -1,5 +1,5 @@ import assert from 'assert' -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import { generateJwk } from '@interledger/http-signature-utils' import { v4 as uuid } from 'uuid' @@ -19,7 +19,6 @@ import { WalletAddressKeyService } from '../../open_payments/wallet_address/key/ import { createWalletAddress } from '../../tests/walletAddress' import { getPageTests } from './page.test' import { createWalletAddressKey } from '../../tests/walletAddressKey' -import { GraphQLError } from 'graphql' import { GraphQLErrorCode } from '../errors' const TEST_KEY = generateJwk({ keyId: uuid() }) @@ -100,7 +99,7 @@ describe('Wallet Address Key Resolvers', (): void => { }) }) - test('500', async (): Promise => { + test('internal server error', async (): Promise => { jest .spyOn(walletAddressKeyService, 'create') .mockImplementationOnce(async (_args) => { @@ -114,46 +113,51 @@ describe('Wallet Address Key Resolvers', (): void => { jwk: TEST_KEY } - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateWalletAddressKey( - $input: CreateWalletAddressKeyInput! - ) { - createWalletAddressKey(input: $input) { - walletAddressKey { - id - walletAddressId - jwk { - kid - x - alg - kty - crv + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateWalletAddressKey( + $input: CreateWalletAddressKeyInput! + ) { + createWalletAddressKey(input: $input) { + walletAddressKey { + id + walletAddressId + jwk { + kid + x + alg + kty + crv + } + createdAt } - createdAt } } + `, + variables: { + input } - `, - variables: { - input - } - }) - .then((query): CreateWalletAddressKeyMutationResponse => { - if (query.data) { - return query.data.createWalletAddressKey - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + .then((query): CreateWalletAddressKeyMutationResponse => { + if (query.data) { + return query.data.createWalletAddressKey + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) @@ -216,41 +220,45 @@ describe('Wallet Address Key Resolvers', (): void => { }) test('Returns not found if key does not exist', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation revokeWalletAddressKey( - $input: RevokeWalletAddressKeyInput! - ) { - revokeWalletAddressKey(input: $input) { - walletAddressKey { - id - walletAddressId + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation revokeWalletAddressKey( + $input: RevokeWalletAddressKeyInput! + ) { + revokeWalletAddressKey(input: $input) { + walletAddressKey { + id + walletAddressId + } } } + `, + variables: { + input: { + id: uuid() + } } - `, - variables: { - input: { - id: uuid() + }) + .then((query): RevokeWalletAddressKeyMutationResponse => { + if (query.data) { + return query.data.revokeWalletAddressKey + } else { + throw new Error('Data was empty') } - } - }) - .then((query): RevokeWalletAddressKeyMutationResponse => { - if (query.data) { - return query.data.revokeWalletAddressKey - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('Wallet address key not found', { - extensions: { - code: GraphQLErrorCode.NotFound - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Wallet address key not found', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) + } }) }) diff --git a/packages/backend/src/graphql/resolvers/wallet_address.test.ts b/packages/backend/src/graphql/resolvers/wallet_address.test.ts index 22853ad258..d57e3d71b4 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.test.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.test.ts @@ -1,5 +1,5 @@ import assert from 'assert' -import { gql } from '@apollo/client' +import { gql, ApolloError } from '@apollo/client' import { Knex } from 'knex' import { v4 as uuid } from 'uuid' @@ -34,7 +34,6 @@ import { } from '../generated/graphql' import { getPageTests } from './page.test' import { WalletAddressAdditionalProperty } from '../../open_payments/wallet_address/additional_property/model' -import { GraphQLError } from 'graphql' import { GraphQLErrorCode } from '../errors' describe('Wallet Address Resolvers', (): void => { @@ -211,42 +210,48 @@ describe('Wallet Address Resolvers', (): void => { error ${WalletAddressError.InvalidUrl} ${WalletAddressError.UnknownAsset} - `('Error - $error', async ({ error }): Promise => { - jest.spyOn(walletAddressService, 'create').mockResolvedValueOnce(error) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateWalletAddress($input: CreateWalletAddressInput!) { - createWalletAddress(input: $input) { - walletAddress { - id - asset { - code - scale + `('Error - $error', async ({ error: testError }): Promise => { + jest + .spyOn(walletAddressService, 'create') + .mockResolvedValueOnce(testError) + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateWalletAddress($input: CreateWalletAddressInput!) { + createWalletAddress(input: $input) { + walletAddress { + id + asset { + code + scale + } } } } + `, + variables: { + input } - `, - variables: { - input - } - }) - .then((query): CreateWalletAddressMutationResponse => { - if (query.data) { - return query.data.createWalletAddress - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[error as WalletAddressError], { - extensions: { - code: errorToCode[error as WalletAddressError] - } - }) - ) + }) + .then((query): CreateWalletAddressMutationResponse => { + if (query.data) { + return query.data.createWalletAddress + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[testError as WalletAddressError], + extensions: expect.objectContaining({ + code: errorToCode[testError as WalletAddressError] + }) + }) + ) + } }) test('internal server error', async (): Promise => { @@ -255,39 +260,44 @@ describe('Wallet Address Resolvers', (): void => { .mockImplementationOnce(async (_args) => { throw new Error('unexpected') }) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation CreateWalletAddress($input: CreateWalletAddressInput!) { - createWalletAddress(input: $input) { - walletAddress { - id - asset { - code - scale + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation CreateWalletAddress($input: CreateWalletAddressInput!) { + createWalletAddress(input: $input) { + walletAddress { + id + asset { + code + scale + } } } } + `, + variables: { + input } - `, - variables: { - input - } - }) - .then((query): CreateWalletAddressMutationResponse => { - if (query.data) { - return query.data.createWalletAddress - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + .then((query): CreateWalletAddressMutationResponse => { + if (query.data) { + return query.data.createWalletAddress + } else { + throw new Error('Data was empty') + } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) @@ -526,41 +536,47 @@ describe('Wallet Address Resolvers', (): void => { ${WalletAddressError.InvalidUrl} ${WalletAddressError.UnknownAsset} ${WalletAddressError.UnknownWalletAddress} - `('4XX - $error', async ({ error }): Promise => { - jest.spyOn(walletAddressService, 'update').mockResolvedValueOnce(error) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { - updateWalletAddress(input: $input) { - walletAddress { - id + `('$error', async ({ error: testError }): Promise => { + jest + .spyOn(walletAddressService, 'update') + .mockResolvedValueOnce(testError) + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { + updateWalletAddress(input: $input) { + walletAddress { + id + } } } + `, + variables: { + input: { + id: walletAddress.id, + status: WalletAddressStatus.Inactive + } } - `, - variables: { - input: { - id: walletAddress.id, - status: WalletAddressStatus.Inactive + }) + .then((query): UpdateWalletAddressMutationResponse => { + if (query.data) { + return query.data.updateWalletAddress + } else { + throw new Error('Data was empty') } - } - }) - .then((query): UpdateWalletAddressMutationResponse => { - if (query.data) { - return query.data.updateWalletAddress - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError(errorToMessage[error as WalletAddressError], { - extensions: { - code: errorToCode[error as WalletAddressError] - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[testError as WalletAddressError], + extensions: expect.objectContaining({ + code: errorToCode[testError as WalletAddressError] + }) + }) + ) + } }) test('Returns error if unexpected error', async (): Promise => { @@ -569,39 +585,43 @@ describe('Wallet Address Resolvers', (): void => { .mockImplementationOnce(async () => { throw new Error('unexpected') }) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { - updateWalletAddress(input: $input) { - walletAddress { - id + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation UpdateWalletAddress($input: UpdateWalletAddressInput!) { + updateWalletAddress(input: $input) { + walletAddress { + id + } } } + `, + variables: { + input: { + id: walletAddress.id, + status: WalletAddressStatus.Inactive + } } - `, - variables: { - input: { - id: walletAddress.id, - status: WalletAddressStatus.Inactive + }) + .then((query): UpdateWalletAddressMutationResponse => { + if (query.data) { + return query.data.updateWalletAddress + } else { + throw new Error('Data was empty') } - } - }) - .then((query): UpdateWalletAddressMutationResponse => { - if (query.data) { - return query.data.updateWalletAddress - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) @@ -691,37 +711,38 @@ describe('Wallet Address Resolvers', (): void => { ) test('Returns error for unknown wallet address', async (): Promise => { - const gqlQuery = appContainer.apolloClient - .query({ - query: gql` - query WalletAddress($walletAddressId: String!) { - walletAddress(id: $walletAddressId) { - id + try { + await appContainer.apolloClient + .query({ + query: gql` + query WalletAddress($walletAddressId: String!) { + walletAddress(id: $walletAddressId) { + id + } } + `, + variables: { + walletAddressId: uuid() } - `, - variables: { - walletAddressId: uuid() - } - }) - .then((query): WalletAddress => { - if (query.data) { - return query.data.walletAddress - } else { - throw new Error('Data was empty') - } - }) - - await expect(gqlQuery).rejects.toThrow( - new GraphQLError( - errorToMessage[WalletAddressError.UnknownWalletAddress], - { - extensions: { - code: errorToCode[WalletAddressError.UnknownWalletAddress] + }) + .then((query): WalletAddress => { + if (query.data) { + return query.data.walletAddress + } else { + throw new Error('Data was empty') } - } + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[WalletAddressError.UnknownWalletAddress], + extensions: expect.objectContaining({ + code: errorToCode[WalletAddressError.UnknownWalletAddress] + }) + }) ) - ) + } }) getPageTests({ @@ -856,41 +877,46 @@ describe('Wallet Address Resolvers', (): void => { } ) - test('500', async (): Promise => { + test('internal server error', async (): Promise => { jest .spyOn(walletAddressService, 'triggerEvents') .mockRejectedValueOnce(new Error('unexpected')) - const gqlQuery = appContainer.apolloClient - .mutate({ - mutation: gql` - mutation TriggerWalletAddressEvents( - $input: TriggerWalletAddressEventsInput! - ) { - triggerWalletAddressEvents(input: $input) { - count + try { + await appContainer.apolloClient + .mutate({ + mutation: gql` + mutation TriggerWalletAddressEvents( + $input: TriggerWalletAddressEventsInput! + ) { + triggerWalletAddressEvents(input: $input) { + count + } + } + `, + variables: { + input: { + limit: 1 } } - `, - variables: { - input: { - limit: 1 + }) + .then((query): TriggerWalletAddressEventsMutationResponse => { + if (query.data) { + return query.data.triggerWalletAddressEvents + } else { + throw new Error('Data was empty') } - } - }) - .then((query): TriggerWalletAddressEventsMutationResponse => { - if (query.data) { - return query.data.triggerWalletAddressEvents - } else { - throw new Error('Data was empty') - } - }) - await expect(gqlQuery).rejects.toThrow( - new GraphQLError('unexpected', { - extensions: { - code: GraphQLErrorCode.InternalServerError - } - }) - ) + }) + } catch (error) { + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unexpected', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.InternalServerError + }) + }) + ) + } }) }) }) From a470603af0781da647ff225dadebddc430127e75 Mon Sep 17 00:00:00 2001 From: Max Kurapov Date: Tue, 25 Jun 2024 13:31:18 +0200 Subject: [PATCH 33/34] chore(backend, auth): verify try-catches in tests --- .../auth/src/graphql/resolvers/grant.test.ts | 25 +- .../src/graphql/middleware/index.test.ts | 26 +- .../src/graphql/resolvers/asset.test.ts | 10 +- .../graphql/resolvers/auto-peering.test.ts | 2 + .../backend/src/graphql/resolvers/fee.test.ts | 6 + .../resolvers/incoming_payment.test.ts | 7 +- .../src/graphql/resolvers/liquidity.test.ts | 895 ++++++++++-------- .../resolvers/outgoing_payment.test.ts | 8 +- .../src/graphql/resolvers/peer.test.ts | 8 + .../src/graphql/resolvers/quote.test.ts | 3 + .../src/graphql/resolvers/receiver.test.ts | 23 +- .../resolvers/walletAddressKey.test.ts | 2 + .../graphql/resolvers/wallet_address.test.ts | 11 + .../src/payment-method/ilp/service.test.ts | 1 + 14 files changed, 585 insertions(+), 442 deletions(-) diff --git a/packages/auth/src/graphql/resolvers/grant.test.ts b/packages/auth/src/graphql/resolvers/grant.test.ts index 55a46eecf1..e72e5fd7d2 100644 --- a/packages/auth/src/graphql/resolvers/grant.test.ts +++ b/packages/auth/src/graphql/resolvers/grant.test.ts @@ -483,9 +483,9 @@ describe('Grant Resolvers', (): void => { }) test('Returns error for unknown grant', async (): Promise => { - let gqlQuery + expect.assertions(2) try { - gqlQuery = appContainer.apolloClient + await appContainer.apolloClient .mutate({ mutation: gql` query GetGrant($id: ID!) { @@ -515,8 +515,6 @@ describe('Grant Resolvers', (): void => { throw new Error('Data was empty') } }) - - await gqlQuery // throw error to inspect error object } catch (error) { assert.ok(error instanceof ApolloError) expect(error.message).toBe('No grant') @@ -563,13 +561,13 @@ describe('Grant Resolvers', (): void => { }) test('Returns error if grant id is not provided', async (): Promise => { - let gqlQuery + expect.assertions(2) try { const input: RevokeGrantInput = { grantId: '' } - gqlQuery = appContainer.apolloClient + await appContainer.apolloClient .mutate({ mutation: gql` mutation revokeGrant($input: RevokeGrantInput!) { @@ -589,8 +587,6 @@ describe('Grant Resolvers', (): void => { throw new Error('Data was empty') } }) - - await gqlQuery // throw error to inspect error object } catch (error) { assert.ok(error instanceof ApolloError) expect(error.message).toBe('Grant id is not provided') @@ -601,13 +597,13 @@ describe('Grant Resolvers', (): void => { }) test('Returns error if id does not exist', async (): Promise => { - let gqlQuery + expect.assertions(2) try { const input: RevokeGrantInput = { grantId: uuid() } - gqlQuery = appContainer.apolloClient + await appContainer.apolloClient .mutate({ mutation: gql` mutation revokeGrant($input: RevokeGrantInput!) { @@ -627,8 +623,6 @@ describe('Grant Resolvers', (): void => { throw new Error('Data was empty') } }) - - await gqlQuery // throw error to inspect error object } catch (error) { assert.ok(error instanceof ApolloError) expect(error.message).toBe('Revoke grant was not successful') @@ -639,13 +633,14 @@ describe('Grant Resolvers', (): void => { }) test('Returns error if grant id is in invalid format', async (): Promise => { - let gqlQuery + expect.assertions(1) + try { const input: RevokeGrantInput = { grantId: '123' } - gqlQuery = appContainer.apolloClient + await appContainer.apolloClient .mutate({ mutation: gql` mutation revokeGrant($input: RevokeGrantInput!) { @@ -665,8 +660,6 @@ describe('Grant Resolvers', (): void => { throw new Error('Data was empty') } }) - - await gqlQuery // throw error to inspect error object } catch (error) { assert.ok(error instanceof ApolloError) expect(error.graphQLErrors[0].extensions.code).toEqual( diff --git a/packages/backend/src/graphql/middleware/index.test.ts b/packages/backend/src/graphql/middleware/index.test.ts index 9631870034..1c816dd1cd 100644 --- a/packages/backend/src/graphql/middleware/index.test.ts +++ b/packages/backend/src/graphql/middleware/index.test.ts @@ -1,4 +1,4 @@ -import { gql } from '@apollo/client' +import { ApolloError, gql } from '@apollo/client' import assert from 'assert' import { v4 as uuid } from 'uuid' @@ -193,16 +193,22 @@ describe('GraphQL Middleware', (): void => { createAssetSpy.mockClear() - const repeatResponse = callCreateAssetMutation({ - ...input, - idempotencyKey: uuid() - }) - - await expect(repeatResponse).rejects.toThrow( - new GraphQLError(errorToMessage[AssetError.DuplicateAsset], { - extensions: { + let error + try { + await callCreateAssetMutation({ + ...input, + idempotencyKey: uuid() + }) + } catch (err) { + error = err + } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: errorToMessage[AssetError.DuplicateAsset], + extensions: expect.objectContaining({ code: errorToCode[AssetError.DuplicateAsset] - } + }) }) ) expect(createAssetSpy).toHaveBeenCalledTimes(1) diff --git a/packages/backend/src/graphql/resolvers/asset.test.ts b/packages/backend/src/graphql/resolvers/asset.test.ts index 99d2f642ed..d174e32a2b 100644 --- a/packages/backend/src/graphql/resolvers/asset.test.ts +++ b/packages/backend/src/graphql/resolvers/asset.test.ts @@ -131,7 +131,10 @@ describe('Asset Resolvers', (): void => { test('Returns error for duplicate asset', async (): Promise => { const input = randomAsset() - await expect(assetService.create(input)).resolves.toMatchObject(input) + + await assetService.create(input) + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -173,6 +176,7 @@ describe('Asset Resolvers', (): void => { .spyOn(assetService, 'create') .mockRejectedValueOnce(new Error('unexpected')) + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -359,6 +363,7 @@ describe('Asset Resolvers', (): void => { }) test('Returns error for unknown asset', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .query({ @@ -624,6 +629,7 @@ describe('Asset Resolvers', (): void => { ) test('Returns error for unknown asset', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -703,6 +709,7 @@ describe('Asset Resolvers', (): void => { }) test('Returns error for unknown asset', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -746,6 +753,7 @@ describe('Asset Resolvers', (): void => { throw new Error('unexpected') }) + expect.assertions(2) try { await appContainer.apolloClient .mutate({ diff --git a/packages/backend/src/graphql/resolvers/auto-peering.test.ts b/packages/backend/src/graphql/resolvers/auto-peering.test.ts index 6506b74b5b..bce600e767 100644 --- a/packages/backend/src/graphql/resolvers/auto-peering.test.ts +++ b/packages/backend/src/graphql/resolvers/auto-peering.test.ts @@ -240,6 +240,7 @@ describe('Auto Peering Resolvers', (): void => { .spyOn(autoPeeringService, 'initiatePeeringRequest') .mockResolvedValueOnce(testError) const input = createOrUpdatePeerByUrlInput() + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -283,6 +284,7 @@ describe('Auto Peering Resolvers', (): void => { .spyOn(autoPeeringService, 'initiatePeeringRequest') .mockRejectedValueOnce(new Error('unexpected')) + expect.assertions(2) try { await appContainer.apolloClient .mutate({ diff --git a/packages/backend/src/graphql/resolvers/fee.test.ts b/packages/backend/src/graphql/resolvers/fee.test.ts index 13a14b9c05..ee7306f2ef 100644 --- a/packages/backend/src/graphql/resolvers/fee.test.ts +++ b/packages/backend/src/graphql/resolvers/fee.test.ts @@ -93,6 +93,8 @@ describe('Fee Resolvers', () => { basisPoints: 100 } } + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -141,6 +143,8 @@ describe('Fee Resolvers', () => { basisPoints: -10_000 } } + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -192,6 +196,8 @@ describe('Fee Resolvers', () => { basisPoints: -10_000 } } + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ diff --git a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts index 3278c9d58c..61a185980c 100644 --- a/packages/backend/src/graphql/resolvers/incoming_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/incoming_payment.test.ts @@ -199,6 +199,7 @@ describe('Incoming Payment Resolver', (): void => { walletAddressId: uuid() } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -231,7 +232,7 @@ describe('Incoming Payment Resolver', (): void => { }) ) } - await expect(createSpy).toHaveBeenCalledWith(input) + expect(createSpy).toHaveBeenCalledWith(input) }) test('Internal server error', async (): Promise => { @@ -243,6 +244,7 @@ describe('Incoming Payment Resolver', (): void => { walletAddressId: uuid() } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -275,7 +277,7 @@ describe('Incoming Payment Resolver', (): void => { }) ) } - await expect(createSpy).toHaveBeenCalledWith(input) + expect(createSpy).toHaveBeenCalledWith(input) }) }) @@ -412,6 +414,7 @@ describe('Incoming Payment Resolver', (): void => { .spyOn(incomingPaymentService, 'get') .mockImplementation(async () => undefined) + expect.assertions(2) try { await appContainer.apolloClient.query({ query: gql` diff --git a/packages/backend/src/graphql/resolvers/liquidity.test.ts b/packages/backend/src/graphql/resolvers/liquidity.test.ts index 26fdfdca3a..e0968b27e1 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.test.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.test.ts @@ -104,6 +104,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for invalid id', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -132,20 +133,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns an error for unknown peer', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -174,17 +177,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'unknown peer', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.NotFound - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'unknown peer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -196,6 +200,8 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -224,20 +230,23 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) test('Returns an error for zero amount', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -266,17 +275,19 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer amount is zero', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Forbidden - }) - }) - ) + } catch (err) { + error = err } + + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer amount is zero', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) }) }) @@ -321,6 +332,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for invalid id', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -349,20 +361,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns an error for unknown asset', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -391,17 +405,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Unknown asset', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.NotFound - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown asset', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -413,6 +428,8 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -441,20 +458,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) test('Returns an error for zero amount', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -483,17 +502,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer amount is zero', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Forbidden - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer amount is zero', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) }) }) @@ -547,6 +567,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for unknown peer', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -576,20 +597,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Unknown peer', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.NotFound - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown peer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) }) test('Returns an error for invalid id', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -619,17 +642,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -641,6 +665,8 @@ describe('Liquidity Resolvers', (): void => { amount: 10n }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -670,17 +696,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) test.each` @@ -690,6 +717,7 @@ describe('Liquidity Resolvers', (): void => { `( 'Returns error for $code', async ({ amount, message, code }): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -719,17 +747,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message, - extensions: expect.objectContaining({ - code - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message, + extensions: expect.objectContaining({ + code + }) + }) + ) } ) }) @@ -784,6 +813,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for unknown asset', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -813,20 +843,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Unknown asset', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.NotFound - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown asset', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) }) test('Returns an error for invalid id', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -856,17 +888,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -878,6 +911,8 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(10) }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -907,17 +942,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) test.each` @@ -927,6 +963,7 @@ describe('Liquidity Resolvers', (): void => { `( 'Returns error for $error', async ({ amount, code, message }): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -956,17 +993,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message, - extensions: expect.objectContaining({ - code - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message, + extensions: expect.objectContaining({ + code + }) + }) + ) } ) }) @@ -1035,6 +1073,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns an error for unknown wallet address', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -1065,20 +1104,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Unknown wallet address', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.NotFound - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown wallet address', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) }) test('Returns an error for invalid id', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -1109,17 +1150,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -1131,6 +1173,8 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(10) }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -1161,17 +1205,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) test('Returns an error for empty balance', async (): Promise => { @@ -1183,6 +1228,8 @@ describe('Liquidity Resolvers', (): void => { timeout: 0 }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -1213,17 +1260,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer amount is zero', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Forbidden - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer amount is zero', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) }) }) @@ -1284,6 +1332,7 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't post non-existent withdrawal", async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -1310,20 +1359,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Unknown transfer', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.NotFound - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown transfer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) }) test("Can't post invalid withdrawal id", async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -1350,23 +1401,26 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test("Can't post posted withdrawal", async (): Promise => { await expect( accountingService.postWithdrawal(withdrawalId) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -1391,25 +1445,28 @@ describe('Liquidity Resolvers', (): void => { return query.data.postLiquidityWithdrawal } else { throw new Error('Data was empty') - } - }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already posted', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Conflict - }) + } }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already posted', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) }) test("Can't post voided withdrawal", async (): Promise => { await expect( accountingService.voidWithdrawal(withdrawalId) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -1436,17 +1493,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already voided', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Conflict - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already voided', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) }) } ) @@ -1508,6 +1566,7 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't void non-existent withdrawal", async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -1534,20 +1593,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Unknown transfer', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.NotFound - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Unknown transfer', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.NotFound + }) + }) + ) }) test("Can't void invalid withdrawal id", async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -1574,23 +1635,25 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test("Can't void posted withdrawal", async (): Promise => { await expect( accountingService.postWithdrawal(withdrawalId) ).resolves.toBeUndefined() + let error try { await appContainer.apolloClient .mutate({ @@ -1617,23 +1680,25 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already posted', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Conflict - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already posted', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) }) test("Can't void voided withdrawal", async (): Promise => { await expect( accountingService.voidWithdrawal(withdrawalId) ).resolves.toBeUndefined() + let error try { await appContainer.apolloClient .mutate({ @@ -1660,17 +1725,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already voided', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Conflict - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already voided', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Conflict + }) + }) + ) }) } ) @@ -1768,6 +1834,7 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't deposit for non-existent webhook event id", async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -1794,17 +1861,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -1815,6 +1883,7 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() + let error try { await appContainer.apolloClient .mutate({ @@ -1841,17 +1910,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) } ) @@ -1990,6 +2060,7 @@ describe('Liquidity Resolvers', (): void => { }) test('Returns error for non-existent webhook event id', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -2016,23 +2087,26 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns error for already completed withdrawal', async (): Promise => { await expect( accountingService.createWithdrawal(withdrawal) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -2059,17 +2133,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) } ) @@ -2194,6 +2269,7 @@ describe('Liquidity Resolvers', (): void => { amount } }) + let error try { await appContainer.apolloClient .mutate({ @@ -2221,20 +2297,22 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns error when related webhook not found', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -2262,17 +2340,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns error for already completed withdrawal', async (): Promise => { @@ -2295,6 +2374,8 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -2322,17 +2403,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) }) }) @@ -2409,6 +2491,7 @@ describe('Liquidity Resolvers', (): void => { describe('Cannot withdraw liquidity', () => { test('Returns error for non-existent outgoing payment id', async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -2436,17 +2519,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns error when related webhook not found', async (): Promise => { @@ -2457,6 +2541,7 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() + let error try { await appContainer.apolloClient .mutate({ @@ -2484,17 +2569,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns error for already completed withdrawal', async (): Promise => { @@ -2516,6 +2602,8 @@ describe('Liquidity Resolvers', (): void => { amount: amount }) ).resolves.toBeUndefined() + + let error try { await appContainer.apolloClient .mutate({ @@ -2543,17 +2631,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Insufficient transfer balance', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Forbidden - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Insufficient transfer balance', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Forbidden + }) + }) + ) }) }) }) @@ -2618,6 +2707,7 @@ describe('Liquidity Resolvers', (): void => { }) test("Can't deposit for non-existent outgoing payment id", async (): Promise => { + let error try { await appContainer.apolloClient .mutate({ @@ -2644,17 +2734,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Invalid transfer id', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.BadUserInput - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Invalid transfer id', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.BadUserInput + }) + }) + ) }) test('Returns an error for existing transfer', async (): Promise => { @@ -2665,6 +2756,7 @@ describe('Liquidity Resolvers', (): void => { amount: BigInt(100) }) ).resolves.toBeUndefined() + let error try { await appContainer.apolloClient .mutate({ @@ -2691,17 +2783,18 @@ describe('Liquidity Resolvers', (): void => { throw new Error('Data was empty') } }) - } catch (error) { - expect(error).toBeInstanceOf(ApolloError) - expect((error as ApolloError).graphQLErrors).toContainEqual( - expect.objectContaining({ - message: 'Transfer already exists', - extensions: expect.objectContaining({ - code: GraphQLErrorCode.Duplicate - }) - }) - ) + } catch (err) { + error = err } + expect(error).toBeInstanceOf(ApolloError) + expect((error as ApolloError).graphQLErrors).toContainEqual( + expect.objectContaining({ + message: 'Transfer already exists', + extensions: expect.objectContaining({ + code: GraphQLErrorCode.Duplicate + }) + }) + ) }) } ) diff --git a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts index e7ee1d1b20..53d7d9bb48 100644 --- a/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts +++ b/packages/backend/src/graphql/resolvers/outgoing_payment.test.ts @@ -249,6 +249,7 @@ describe('OutgoingPayment Resolvers', (): void => { .spyOn(outgoingPaymentService, 'get') .mockImplementation(async () => undefined) + expect.assertions(2) try { await appContainer.apolloClient.query({ query: gql` @@ -330,6 +331,7 @@ describe('OutgoingPayment Resolvers', (): void => { quoteId: uuid() } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -362,7 +364,7 @@ describe('OutgoingPayment Resolvers', (): void => { }) ) } - await expect(createSpy).toHaveBeenCalledWith(input) + expect(createSpy).toHaveBeenCalledWith(input) }) test('internal server error', async (): Promise => { @@ -375,6 +377,7 @@ describe('OutgoingPayment Resolvers', (): void => { quoteId: uuid() } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -475,6 +478,7 @@ describe('OutgoingPayment Resolvers', (): void => { } } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -525,6 +529,7 @@ describe('OutgoingPayment Resolvers', (): void => { } } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -636,6 +641,7 @@ describe('OutgoingPayment Resolvers', (): void => { const input = { id: uuid() } + expect.assertions(3) try { await appContainer.apolloClient .mutate({ diff --git a/packages/backend/src/graphql/resolvers/peer.test.ts b/packages/backend/src/graphql/resolvers/peer.test.ts index deec0406af..8fc24012d2 100644 --- a/packages/backend/src/graphql/resolvers/peer.test.ts +++ b/packages/backend/src/graphql/resolvers/peer.test.ts @@ -160,6 +160,8 @@ describe('Peer Resolvers', (): void => { `('Error - $error', async ({ error: testError }): Promise => { jest.spyOn(peerService, 'create').mockResolvedValueOnce(testError) const peer = randomPeer() + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -203,6 +205,7 @@ describe('Peer Resolvers', (): void => { throw new Error('unexpected') }) + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -332,6 +335,7 @@ describe('Peer Resolvers', (): void => { }) test('Returns error for unknown peer', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .query({ @@ -541,6 +545,7 @@ describe('Peer Resolvers', (): void => { ${PeerError.UnknownPeer} `('Error - $error', async ({ error: testError }): Promise => { jest.spyOn(peerService, 'update').mockResolvedValueOnce(testError) + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -585,6 +590,7 @@ describe('Peer Resolvers', (): void => { throw new Error('unexpected') }) + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -670,6 +676,7 @@ describe('Peer Resolvers', (): void => { }) test('Returns error for unknown peer', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -710,6 +717,7 @@ describe('Peer Resolvers', (): void => { jest.spyOn(peerService, 'delete').mockImplementationOnce(async () => { throw new Error('unexpected') }) + expect.assertions(2) try { await appContainer.apolloClient .mutate({ diff --git a/packages/backend/src/graphql/resolvers/quote.test.ts b/packages/backend/src/graphql/resolvers/quote.test.ts index 8202a6f410..39efdac43c 100644 --- a/packages/backend/src/graphql/resolvers/quote.test.ts +++ b/packages/backend/src/graphql/resolvers/quote.test.ts @@ -137,6 +137,7 @@ describe('Quote Resolvers', (): void => { test('Not found', async (): Promise => { jest.spyOn(quoteService, 'get').mockImplementation(async () => undefined) + expect.assertions(2) try { await appContainer.apolloClient.query({ query: gql` @@ -236,6 +237,7 @@ describe('Quote Resolvers', (): void => { }) test('unknown walletAddress', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .query({ @@ -269,6 +271,7 @@ describe('Quote Resolvers', (): void => { .spyOn(quoteService, 'create') .mockRejectedValueOnce(new Error('unexpected')) + expect.assertions(3) try { await appContainer.apolloClient .query({ diff --git a/packages/backend/src/graphql/resolvers/receiver.test.ts b/packages/backend/src/graphql/resolvers/receiver.test.ts index 8b0988ea90..2ee01cb326 100644 --- a/packages/backend/src/graphql/resolvers/receiver.test.ts +++ b/packages/backend/src/graphql/resolvers/receiver.test.ts @@ -143,6 +143,7 @@ describe('Receiver Resolver', (): void => { walletAddressUrl: walletAddress.id } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -199,6 +200,7 @@ describe('Receiver Resolver', (): void => { walletAddressUrl: walletAddress.id } + expect.assertions(3) try { await appContainer.apolloClient .query({ @@ -318,19 +320,18 @@ describe('Receiver Resolver', (): void => { .spyOn(receiverService, 'get') .mockImplementation(async () => undefined) + expect.assertions(2) try { - await expect( - appContainer.apolloClient.query({ - query: gql` - query GetReceiver($id: String!) { - receiver(id: $id) { - id - } + await appContainer.apolloClient.query({ + query: gql` + query GetReceiver($id: String!) { + receiver(id: $id) { + id } - `, - variables: { id: uuid() } - }) - ).rejects.toThrow('receiver does not exist') + } + `, + variables: { id: uuid() } + }) } catch (error) { expect(error).toBeInstanceOf(ApolloError) expect((error as ApolloError).graphQLErrors).toContainEqual( diff --git a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts index 69db46f44b..660ffbd5ba 100644 --- a/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts +++ b/packages/backend/src/graphql/resolvers/walletAddressKey.test.ts @@ -113,6 +113,7 @@ describe('Wallet Address Key Resolvers', (): void => { jwk: TEST_KEY } + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -220,6 +221,7 @@ describe('Wallet Address Key Resolvers', (): void => { }) test('Returns not found if key does not exist', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .mutate({ diff --git a/packages/backend/src/graphql/resolvers/wallet_address.test.ts b/packages/backend/src/graphql/resolvers/wallet_address.test.ts index d57e3d71b4..ff51dd0d1f 100644 --- a/packages/backend/src/graphql/resolvers/wallet_address.test.ts +++ b/packages/backend/src/graphql/resolvers/wallet_address.test.ts @@ -214,6 +214,8 @@ describe('Wallet Address Resolvers', (): void => { jest .spyOn(walletAddressService, 'create') .mockResolvedValueOnce(testError) + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -260,6 +262,8 @@ describe('Wallet Address Resolvers', (): void => { .mockImplementationOnce(async (_args) => { throw new Error('unexpected') }) + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -540,6 +544,8 @@ describe('Wallet Address Resolvers', (): void => { jest .spyOn(walletAddressService, 'update') .mockResolvedValueOnce(testError) + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -585,6 +591,8 @@ describe('Wallet Address Resolvers', (): void => { .mockImplementationOnce(async () => { throw new Error('unexpected') }) + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ @@ -711,6 +719,7 @@ describe('Wallet Address Resolvers', (): void => { ) test('Returns error for unknown wallet address', async (): Promise => { + expect.assertions(2) try { await appContainer.apolloClient .query({ @@ -881,6 +890,8 @@ describe('Wallet Address Resolvers', (): void => { jest .spyOn(walletAddressService, 'triggerEvents') .mockRejectedValueOnce(new Error('unexpected')) + + expect.assertions(2) try { await appContainer.apolloClient .mutate({ diff --git a/packages/backend/src/payment-method/ilp/service.test.ts b/packages/backend/src/payment-method/ilp/service.test.ts index 728a9e5b12..6c0fcb1a4f 100644 --- a/packages/backend/src/payment-method/ilp/service.test.ts +++ b/packages/backend/src/payment-method/ilp/service.test.ts @@ -638,6 +638,7 @@ describe('IlpPaymentService', (): void => { mockIlpPay({}, Object.keys(retryableIlpErrors)[0] as Pay.PaymentError) + expect.assertions(4) try { await ilpPaymentService.pay({ receiver, From 2fadf08b4a4725642be3241d97e5009b1b7b0ab8 Mon Sep 17 00:00:00 2001 From: Max Kurapov Date: Tue, 25 Jun 2024 19:22:37 +0200 Subject: [PATCH 34/34] chore(backend): fix auto-peering test --- .../backend/src/graphql/resolvers/auto-peering.test.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/graphql/resolvers/auto-peering.test.ts b/packages/backend/src/graphql/resolvers/auto-peering.test.ts index bce600e767..49715fdfe0 100644 --- a/packages/backend/src/graphql/resolvers/auto-peering.test.ts +++ b/packages/backend/src/graphql/resolvers/auto-peering.test.ts @@ -109,7 +109,7 @@ describe('Auto Peering Resolvers', (): void => { const peerDetails = { staticIlpAddress: 'test.peer2', - ilpConnectorAddress: 'http://peer-two.com', + ilpConnectorUrl: 'http://peer-two.com', name: 'Test Peer', httpToken: 'httpToken' } @@ -132,7 +132,7 @@ describe('Auto Peering Resolvers', (): void => { outgoing: { __typename: 'HttpOutgoing', authToken: expect.any(String), - endpoint: peerDetails.ilpConnectorAddress + endpoint: peerDetails.ilpConnectorUrl } }, maxPacketAmount: input.maxPacketAmount?.toString(), @@ -148,7 +148,7 @@ describe('Auto Peering Resolvers', (): void => { const peerDetails = { staticIlpAddress: 'test.peer2', - ilpConnectorAddress: 'http://peer-two.com', + ilpConnectorUrl: 'http://peer-two.com', name: 'Test Peer', httpToken: 'httpToken' } @@ -180,7 +180,7 @@ describe('Auto Peering Resolvers', (): void => { outgoing: { __typename: 'HttpOutgoing', authToken: expect.any(String), - endpoint: peerDetails.ilpConnectorAddress + endpoint: peerDetails.ilpConnectorUrl } }, maxPacketAmount: input.maxPacketAmount?.toString(), @@ -212,7 +212,7 @@ describe('Auto Peering Resolvers', (): void => { outgoing: { __typename: 'HttpOutgoing', authToken: expect.any(String), - endpoint: peerDetails.ilpConnectorAddress + endpoint: peerDetails.ilpConnectorUrl } }, maxPacketAmount: secondInput.maxPacketAmount?.toString(),