Skip to content

Commit 6c3a2fd

Browse files
committed
Add unit tests
1 parent 24d0519 commit 6c3a2fd

File tree

6 files changed

+112
-9
lines changed

6 files changed

+112
-9
lines changed

packages/transaction-pay-controller/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export type {
22
TransactionPayControllerActions,
33
TransactionPayControllerEvents,
4+
TransactionPayControllerGetDelegationTransactionAction,
45
TransactionPayControllerGetStateAction,
56
TransactionPayControllerGetStrategyAction,
67
TransactionPayControllerMessenger,

packages/transaction-pay-controller/src/strategy/relay/relay-quotes.test.ts

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import { getRelayQuotes } from './relay-quotes';
1313
import type { RelayQuote } from './types';
1414
import { NATIVE_TOKEN_ADDRESS } from '../../constants';
1515
import { getMessengerMock } from '../../tests/messenger-mock';
16-
import type { QuoteRequest } from '../../types';
16+
import type {
17+
GetDelegationTransactionCallback,
18+
QuoteRequest,
19+
} from '../../types';
1720
import { calculateGasCost, calculateTransactionGasCost } from '../../utils/gas';
1821
import { getNativeToken, getTokenFiatRate } from '../../utils/token';
1922

@@ -26,14 +29,14 @@ jest.mock('@metamask/controller-utils', () => ({
2629
}));
2730

2831
const QUOTE_REQUEST_MOCK: QuoteRequest = {
29-
from: '0x123',
32+
from: '0x1234567890123456789012345678901234567891',
3033
sourceBalanceRaw: '10000000000000000000',
3134
sourceChainId: '0x1',
3235
sourceTokenAddress: '0xabc',
3336
sourceTokenAmount: '1000000000000000000',
3437
targetAmountMinimum: '123',
3538
targetChainId: '0x2',
36-
targetTokenAddress: '0xdef',
39+
targetTokenAddress: '0x1234567890123456789012345678901234567890',
3740
};
3841

3942
const QUOTE_MOCK = {
@@ -81,6 +84,19 @@ const QUOTE_MOCK = {
8184

8285
const TRANSACTION_META_MOCK = { txParams: {} } as TransactionMeta;
8386

87+
const DELEGATION_RESULT_MOCK = {
88+
authorizationList: [
89+
{
90+
chainId: '0x1' as Hex,
91+
nonce: '0x2' as Hex,
92+
yParity: '0x1' as Hex,
93+
},
94+
],
95+
data: '0x111' as Hex,
96+
to: '0x222' as Hex,
97+
value: '0x333' as Hex,
98+
} as Awaited<ReturnType<GetDelegationTransactionCallback>>;
99+
84100
describe('Relay Quotes Utils', () => {
85101
const successfulFetchMock = jest.mocked(successfulFetch);
86102
const getTokenFiatRateMock = jest.mocked(getTokenFiatRate);
@@ -91,8 +107,11 @@ describe('Relay Quotes Utils', () => {
91107
calculateTransactionGasCost,
92108
);
93109

94-
const { messenger, getRemoteFeatureFlagControllerStateMock } =
95-
getMessengerMock();
110+
const {
111+
messenger,
112+
getDelegationTransactionMock,
113+
getRemoteFeatureFlagControllerStateMock,
114+
} = getMessengerMock();
96115

97116
beforeEach(() => {
98117
jest.resetAllMocks();
@@ -116,6 +135,8 @@ describe('Relay Quotes Utils', () => {
116135
cacheTimestamp: 0,
117136
remoteFeatureFlags: {},
118137
});
138+
139+
getDelegationTransactionMock.mockResolvedValue(DELEGATION_RESULT_MOCK);
119140
});
120141

121142
describe('getRelayQuotes', () => {
@@ -165,6 +186,52 @@ describe('Relay Quotes Utils', () => {
165186
);
166187
});
167188

189+
it('includes transactions in request', async () => {
190+
successfulFetchMock.mockResolvedValue({
191+
json: async () => QUOTE_MOCK,
192+
} as never);
193+
194+
await getRelayQuotes({
195+
messenger,
196+
requests: [QUOTE_REQUEST_MOCK],
197+
transaction: {
198+
...TRANSACTION_META_MOCK,
199+
txParams: {
200+
data: '0xabc' as Hex,
201+
},
202+
} as TransactionMeta,
203+
});
204+
205+
const body = JSON.parse(
206+
successfulFetchMock.mock.calls[0][1]?.body as string,
207+
);
208+
209+
expect(body).toStrictEqual(
210+
expect.objectContaining({
211+
authorizationList: [
212+
{
213+
chainId: 1,
214+
nonce: 2,
215+
yParity: 1,
216+
},
217+
],
218+
tradeType: 'EXACT_OUTPUT',
219+
txs: [
220+
{
221+
to: QUOTE_REQUEST_MOCK.targetTokenAddress,
222+
data: '0xa9059cbb0000000000000000000000001234567890123456789012345678901234567891000000000000000000000000000000000000000000000000000000000000007b',
223+
value: '0x0',
224+
},
225+
{
226+
to: DELEGATION_RESULT_MOCK.to,
227+
data: DELEGATION_RESULT_MOCK.data,
228+
value: DELEGATION_RESULT_MOCK.value,
229+
},
230+
],
231+
}),
232+
);
233+
});
234+
168235
it('sends request to url from feature flag', async () => {
169236
successfulFetchMock.mockResolvedValue({
170237
json: async () => QUOTE_MOCK,

packages/transaction-pay-controller/src/strategy/relay/relay-quotes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ async function processTransactions(
122122
messenger: TransactionPayControllerMessenger,
123123
) {
124124
const { data, value } = transaction.txParams;
125+
126+
/* istanbul ignore next */
125127
const hasNoParams = (!data || data === '0x') && (!value || value === '0x0');
126128

127129
const skipDelegation =

packages/transaction-pay-controller/src/strategy/relay/relay-submit.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,14 @@ describe('Relay Submit Utils', () => {
245245
);
246246
});
247247

248+
it('does not wait for relay status if same chain', async () => {
249+
request.quotes[0].original.details.currencyOut.currency.chainId = 1;
250+
251+
await submitRelayQuotes(request);
252+
253+
expect(successfulFetchMock).toHaveBeenCalledTimes(0);
254+
});
255+
248256
it('throws if transaction fails to confirm', async () => {
249257
waitForTransactionConfirmedMock.mockRejectedValue(
250258
new Error('Transaction failed'),
@@ -297,6 +305,18 @@ describe('Relay Submit Utils', () => {
297305
expect(result.transactionHash).toBe(TRANSACTION_HASH_MOCK);
298306
});
299307

308+
it('returns fallback hash if none included', async () => {
309+
successfulFetchMock.mockResolvedValue({
310+
json: async () => ({
311+
...STATUS_RESPONSE_MOCK,
312+
txHashes: [],
313+
}),
314+
} as Response);
315+
316+
const result = await submitRelayQuotes(request);
317+
expect(result.transactionHash).toBe('0x0');
318+
});
319+
300320
it('adds required transaction IDs', async () => {
301321
await submitRelayQuotes(request);
302322

packages/transaction-pay-controller/src/strategy/relay/relay-submit.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929
waitForTransactionConfirmed,
3030
} from '../../utils/transaction';
3131

32-
const FALLBCAK_HASH = '0x0' as Hex;
32+
const FALLBACK_HASH = '0x0' as Hex;
3333

3434
const log = createModuleLogger(projectLogger, 'relay-strategy');
3535

@@ -127,7 +127,7 @@ async function waitForRelayCompletion(quote: RelayQuote): Promise<Hex> {
127127
quote.details.currencyOut.currency.chainId
128128
) {
129129
log('Skipping polling as same chain');
130-
return FALLBCAK_HASH;
130+
return FALLBACK_HASH;
131131
}
132132

133133
const { endpoint, method } = quote.steps
@@ -144,7 +144,7 @@ async function waitForRelayCompletion(quote: RelayQuote): Promise<Hex> {
144144

145145
if (status.status === 'success') {
146146
const targetHash = status.txHashes?.slice(-1)[0] as Hex;
147-
return targetHash ?? FALLBCAK_HASH;
147+
return targetHash ?? FALLBACK_HASH;
148148
}
149149

150150
if (['failure', 'refund', 'fallback'].includes(status.status)) {

packages/transaction-pay-controller/src/tests/messenger-mock.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ import type { TransactionControllerUpdateTransactionAction } from '@metamask/tra
2121

2222
import type { TransactionPayControllerMessenger } from '..';
2323
import type { BridgeStatusControllerSubmitTxAction } from '../../../bridge-status-controller/src/types';
24-
import type { TransactionPayControllerGetStrategyAction } from '../types';
24+
import type {
25+
TransactionPayControllerGetDelegationTransactionAction,
26+
TransactionPayControllerGetStrategyAction,
27+
} from '../types';
2528
import { type TransactionPayControllerGetStateAction } from '../types';
2629

2730
type AllActions = MessengerActions<TransactionPayControllerMessenger>;
@@ -104,6 +107,10 @@ export function getMessengerMock({
104107
NetworkControllerGetNetworkClientByIdAction['handler']
105108
> = jest.fn();
106109

110+
const getDelegationTransactionMock: jest.MockedFn<
111+
TransactionPayControllerGetDelegationTransactionAction['handler']
112+
> = jest.fn();
113+
107114
const messenger: RootMessenger = new Messenger({
108115
namespace: MOCK_ANY_NAMESPACE,
109116
});
@@ -198,6 +205,11 @@ export function getMessengerMock({
198205
'NetworkController:getNetworkClientById',
199206
getNetworkClientByIdMock,
200207
);
208+
209+
messenger.registerActionHandler(
210+
'TransactionPayController:getDelegationTransaction',
211+
getDelegationTransactionMock,
212+
);
201213
}
202214

203215
const publish = messenger.publish.bind(messenger);
@@ -211,6 +223,7 @@ export function getMessengerMock({
211223
getBridgeStatusControllerStateMock,
212224
getControllerStateMock,
213225
getCurrencyRateControllerStateMock,
226+
getDelegationTransactionMock,
214227
getGasFeeControllerStateMock,
215228
getNetworkClientByIdMock,
216229
getRemoteFeatureFlagControllerStateMock,

0 commit comments

Comments
 (0)