Skip to content

Commit

Permalink
Merge pull request #1826 from ExchangeUnion/feat/connext-404-lookupin…
Browse files Browse the repository at this point in the history
…voice

feat(connext): mark payment as failed when receiving 404 status
  • Loading branch information
Karl Ranna authored Aug 20, 2020
2 parents 9afe7d1 + d1f1f2c commit df87c50
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/connextclient/ConnextClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,8 +433,6 @@ class ConnextClient extends SwapClient {
try {
const assetId = this.getTokenAddress(currency);
const transferStatusResponse = await this.getHashLockStatus(rHash, assetId);
// TODO: Edge case. Once https://github.com/connext/rest-api-client/issues/31 is
// implemented check for the response code 404 and set the payment as failed.

switch (transferStatusResponse.status) {
case 'PENDING':
Expand All @@ -451,6 +449,9 @@ class ConnextClient extends SwapClient {
return { state: PaymentState.Pending };
}
} catch (err) {
if (err.code === errorCodes.PAYMENT_NOT_FOUND) {
return { state: PaymentState.Failed };
}
this.logger.error(`could not lookup payment for ${rHash}`, err);
return { state: PaymentState.Pending }; // return pending if we hit an error
}
Expand Down Expand Up @@ -702,6 +703,9 @@ class ConnextClient extends SwapClient {
case 402:
err = errors.INSUFFICIENT_BALANCE;
break;
case 404:
err = errors.PAYMENT_NOT_FOUND;
break;
case 408:
err = errors.TIMEOUT;
break;
Expand Down
133 changes: 133 additions & 0 deletions test/jest/Connext.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import ConnextClient from '../../lib/connextclient/ConnextClient';
import { UnitConverter } from '../../lib/utils/UnitConverter';
import Logger from '../../lib/Logger';
import { SwapClientType } from '../../lib/constants/enums';
import { CurrencyInstance } from '../../lib/db/types';
import { PaymentState } from '../../lib/swaps/SwapClient';
import errors from '../../lib/connextclient/errors';

jest.mock('../../lib/Logger');
const mockedLogger = <jest.Mock<Logger>>(<any>Logger);

jest.mock('http', () => {
return {
request: jest.fn().mockImplementation((options, cb) => {
if (options.path === '/deposit') {
cb({
statusCode: 404,
});
}
return {
write: jest.fn(),
on: jest.fn(),
end: jest.fn(),
};
}),
};
});

const ETH_ASSET_ID = '0x0000000000000000000000000000000000000000';

describe('ConnextClient', () => {
let connext: ConnextClient;

beforeEach(() => {
const config = {
disable: false,
host: 'http://tester',
port: 1337,
webhookhost: 'http://testerson',
webhookport: 7331,
};
const logger = new mockedLogger();
logger.trace = jest.fn();
logger.error = jest.fn();
const currencyInstances = [
{
id: 'ETH',
tokenAddress: ETH_ASSET_ID,
swapClient: SwapClientType.Connext,
},
] as CurrencyInstance[];
connext = new ConnextClient({
config,
currencyInstances,
logger,
unitConverter: new UnitConverter(),
});
});

describe('sendRequest', () => {
it('deposit fails with 404', async () => {
expect.assertions(1);
try {
await connext['sendRequest']('/deposit', 'POST', {
assetId: ETH_ASSET_ID,
amount: BigInt('100000').toString(),
});
} catch (e) {
expect(e).toMatchSnapshot();
}
});
});

describe('lookupPayment', () => {
it('returns PaymentState.Pending', async () => {
expect.assertions(1);
connext['getHashLockStatus'] = jest
.fn()
.mockReturnValue({ status: 'PENDING' });
const result = await connext['lookupPayment']('0x12345', 'ETH');
expect(result).toEqual({ state: PaymentState.Pending });
});

it('returns PaymentState.Completed with preimage', async () => {
expect.assertions(1);
connext['getHashLockStatus'] = jest
.fn()
.mockReturnValue({ status: 'COMPLETED', preImage: '0x1337' });
const result = await connext['lookupPayment']('0x12345', 'ETH');
expect(result).toEqual({ state: PaymentState.Succeeded, preimage: '1337' });
});

it('returns PaymentState.Failed when EXPIRED', async () => {
expect.assertions(1);
connext['getHashLockStatus'] = jest
.fn()
.mockReturnValue({ status: 'EXPIRED' });
const result = await connext['lookupPayment']('0x12345', 'ETH');
expect(result).toEqual({ state: PaymentState.Failed });
});

it('returns PaymentState.Failed when FAILED', async () => {
expect.assertions(1);
connext['getHashLockStatus'] = jest
.fn()
.mockReturnValue({ status: 'FAILED' });
const result = await connext['lookupPayment']('0x12345', 'ETH');
expect(result).toEqual({ state: PaymentState.Failed });
});

it('returns PaymentState.Pending when error is unknown', async () => {
expect.assertions(1);
connext['getHashLockStatus'] = jest
.fn()
.mockImplementation(() => {
throw new Error('unknown error');
});
const result = await connext['lookupPayment']('0x12345', 'ETH');
expect(result).toEqual({ state: PaymentState.Pending });
});

it('returns PaymentState.Failed when error is PAYMENT_NOT_FOUND', async () => {
expect.assertions(1);
connext['getHashLockStatus'] = jest
.fn()
.mockImplementation(() => {
throw errors.PAYMENT_NOT_FOUND;
});
const result = await connext['lookupPayment']('0x12345', 'ETH');
expect(result).toEqual({ state: PaymentState.Failed });
});
});
});
8 changes: 8 additions & 0 deletions test/jest/__snapshots__/Connext.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ConnextClient sendRequest deposit fails with 404 1`] = `
Object {
"code": "8.8",
"message": "connext payment not found",
}
`;

0 comments on commit df87c50

Please sign in to comment.