Skip to content

Commit 4656d42

Browse files
authored
Merge branch 'main' into sdkui
2 parents 94f0fab + ab2e5a8 commit 4656d42

37 files changed

+1450
-11759
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- feat(multi-srp): enable multi-srp in main and beta ([#14558](https://github.com/MetaMask/metamask-mobile/pull/14558))
13+
- feat(ramp): Update ramp data flow to fetch cryptos before payment methods ([#14437](https://github.com/MetaMask/metamask-mobile/pull/14437))
1314
- feat(bridge): add destination account picker ([#14656](https://github.com/MetaMask/metamask-mobile/pull/14656))
1415
- feat(bridge): add Solana assets to bridge token pickers ([#14365](https://github.com/MetaMask/metamask-mobile/pull/14365))
1516
- feat: add AppMetadataController controller ([#14513](https://github.com/MetaMask/metamask-mobile/pull/14513))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
import React from 'react';
2+
import { fireEvent, render } from '@testing-library/react-native';
3+
import { SnapUIAddressInput } from './SnapUIAddressInput';
4+
import { useSnapInterfaceContext } from '../SnapInterfaceContext';
5+
import { useDisplayName } from '../SnapUIAddress/useDisplayName';
6+
import { INPUT_TEST_ID } from '../../../component-library/components/Form/TextField/foundation/Input/Input.constants';
7+
import renderWithProvider from '../../../util/test/renderWithProvider';
8+
9+
const mockInitialState = {
10+
settings: {
11+
useBlockieIcon: false,
12+
},
13+
};
14+
15+
jest.mock('../SnapInterfaceContext');
16+
jest.mock('../SnapUIAddress/useDisplayName');
17+
18+
describe('SnapUIAddressInput', () => {
19+
const mockHandleInputChange = jest.fn();
20+
const mockSetCurrentFocusedInput = jest.fn();
21+
const mockGetValue = jest.fn();
22+
23+
// Define a valid Ethereum chain ID for testing
24+
const testChainId = `eip155:0`;
25+
const testAddress = '0xabcd5d886577d5081b0c52e242ef29e70be3e7bc';
26+
27+
beforeEach(() => {
28+
(useSnapInterfaceContext as jest.Mock).mockReturnValue({
29+
handleInputChange: mockHandleInputChange,
30+
getValue: mockGetValue,
31+
setCurrentFocusedInput: mockSetCurrentFocusedInput,
32+
focusedInput: null,
33+
});
34+
35+
(useDisplayName as jest.Mock).mockReturnValue(undefined);
36+
37+
jest.clearAllMocks();
38+
});
39+
40+
it('will render', () => {
41+
const { getByTestId } = render(
42+
<SnapUIAddressInput name="testAddress" chainId={testChainId} />,
43+
);
44+
45+
expect(getByTestId(INPUT_TEST_ID)).toBeTruthy();
46+
});
47+
48+
it('supports existing state', () => {
49+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
50+
51+
const { getByDisplayValue } = renderWithProvider(
52+
<SnapUIAddressInput name="testAddress" chainId={testChainId} />,
53+
{ state: mockInitialState },
54+
);
55+
56+
expect(getByDisplayValue(testAddress)).toBeTruthy();
57+
});
58+
59+
it('can accept input', () => {
60+
const { getByTestId } = renderWithProvider(
61+
<SnapUIAddressInput name="testAddress" chainId={testChainId} />,
62+
{ state: mockInitialState },
63+
);
64+
65+
const textfield = getByTestId(INPUT_TEST_ID);
66+
fireEvent.changeText(textfield, '0x');
67+
expect(mockHandleInputChange).toHaveBeenCalledWith(
68+
'testAddress',
69+
`${testChainId}:0x`,
70+
undefined,
71+
);
72+
});
73+
74+
it('supports a placeholder', () => {
75+
const placeholder = 'Enter ETH address';
76+
const { getByTestId } = renderWithProvider(
77+
<SnapUIAddressInput
78+
name="testAddress"
79+
chainId={testChainId}
80+
placeholder={placeholder}
81+
/>,
82+
{ state: mockInitialState },
83+
);
84+
85+
const textfield = getByTestId(INPUT_TEST_ID);
86+
expect(textfield.props.placeholder).toBe(placeholder);
87+
});
88+
89+
it('supports the disabled prop', () => {
90+
const { getByTestId } = renderWithProvider(
91+
<SnapUIAddressInput
92+
name="testAddress"
93+
chainId={testChainId}
94+
disabled
95+
/>,
96+
{ state: mockInitialState },
97+
);
98+
99+
const textfield = getByTestId(INPUT_TEST_ID);
100+
expect(textfield.props.editable).toBe(false);
101+
});
102+
103+
it('will render within a field', () => {
104+
const label = 'Address Field';
105+
const { getByText } = renderWithProvider(
106+
<SnapUIAddressInput
107+
name="testAddress"
108+
chainId={testChainId}
109+
label={label}
110+
/>,
111+
{ state: mockInitialState },
112+
);
113+
114+
expect(getByText(label)).toBeTruthy();
115+
});
116+
117+
it('will render a matched address name', () => {
118+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
119+
const displayName = 'Vitalik.eth';
120+
(useDisplayName as jest.Mock).mockReturnValue(displayName);
121+
122+
const { getByText } = renderWithProvider(
123+
<SnapUIAddressInput name="testAddress" chainId={testChainId} />,
124+
{ state: mockInitialState },
125+
);
126+
127+
expect(getByText(displayName)).toBeTruthy();
128+
expect(getByText(testAddress)).toBeTruthy();
129+
});
130+
131+
it('will render avatar when displayAvatar is true', () => {
132+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
133+
const displayName = 'Vitalik.eth';
134+
(useDisplayName as jest.Mock).mockReturnValue(displayName);
135+
136+
const { toJSON } = renderWithProvider(
137+
<SnapUIAddressInput
138+
name="testAddress"
139+
chainId={testChainId}
140+
displayAvatar
141+
/>,
142+
{ state: mockInitialState },
143+
);
144+
145+
146+
const tree = JSON.stringify(toJSON());
147+
expect(tree.includes('RNSVGSvgView')).toBe(true);
148+
});
149+
150+
it('will not render avatar when displayAvatar is false', () => {
151+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
152+
const displayName = 'Vitalik.eth';
153+
(useDisplayName as jest.Mock).mockReturnValue(displayName);
154+
155+
const { toJSON } = renderWithProvider(
156+
<SnapUIAddressInput
157+
name="testAddress"
158+
chainId={testChainId}
159+
displayAvatar={false}
160+
/>,
161+
{ state: mockInitialState },
162+
);
163+
164+
const tree = JSON.stringify(toJSON());
165+
expect(tree.includes('RNSVGSvgView')).toBe(false);
166+
});
167+
168+
it('renders with an invalid CAIP Account ID', () => {
169+
mockGetValue.mockReturnValue('eip155:0:https://foobar.baz/foobar');
170+
171+
const { toJSON } = renderWithProvider(<SnapUIAddressInput name="input" chainId="eip155:0" displayAvatar={false} />);
172+
173+
expect(toJSON()).toMatchSnapshot();
174+
});
175+
176+
it('renders the matched address info in a disabled state', () => {
177+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
178+
const displayName = 'Vitalik.eth';
179+
(useDisplayName as jest.Mock).mockReturnValue(displayName);
180+
181+
const { getByText, toJSON, getByTestId } = renderWithProvider(
182+
<SnapUIAddressInput name="testAddress" chainId={testChainId} disabled />,
183+
{ state: mockInitialState },
184+
);
185+
186+
expect(getByText(displayName)).toBeTruthy();
187+
expect(getByText(testAddress)).toBeTruthy();
188+
const closeButton = getByTestId('snap-ui-address-input__clear-button');
189+
expect(closeButton).toBeTruthy();
190+
191+
const tree = JSON.stringify(toJSON());
192+
193+
expect(tree).toContain('"opacity":0.5');
194+
expect(tree).toContain('"disabled":true');
195+
expect(toJSON()).toMatchSnapshot();
196+
});
197+
198+
it('does not render the matched address info if there is an error', () => {
199+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
200+
const displayName = 'Vitalik.eth';
201+
(useDisplayName as jest.Mock).mockReturnValue(displayName);
202+
203+
const { queryByText, queryByTestId, getByText, toJSON } = renderWithProvider(
204+
<SnapUIAddressInput name="testAddress" chainId={testChainId} error="Error" />,
205+
{ state: mockInitialState },
206+
);
207+
208+
expect(queryByText(displayName)).toBeFalsy();
209+
210+
const input = queryByTestId(INPUT_TEST_ID);
211+
212+
expect(input.props.value).toBe(testAddress);
213+
expect(getByText('Error')).toBeTruthy();
214+
215+
const tree = JSON.stringify(toJSON());
216+
217+
expect(tree.includes('RNSVGSvgView')).toBe(true);
218+
});
219+
220+
it('disables clear button for the input when disabled', () => {
221+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
222+
223+
const { getByTestId, toJSON } = renderWithProvider(
224+
<SnapUIAddressInput name="testAddress" chainId={testChainId} disabled />,
225+
);
226+
227+
const input = getByTestId(INPUT_TEST_ID);
228+
expect(input.props.editable).toBe(false);
229+
expect(input.props.value).toBe(testAddress);
230+
231+
const closeButton = getByTestId('snap-ui-address-input__clear-button');
232+
expect(closeButton).toBeTruthy();
233+
234+
const tree = JSON.stringify(toJSON());
235+
expect(tree).toContain('"disabled":true');
236+
});
237+
238+
it('disables clear button for the matched address info when disabled', () => {
239+
mockGetValue.mockReturnValue(`${testChainId}:${testAddress}`);
240+
const displayName = 'Vitalik.eth';
241+
(useDisplayName as jest.Mock).mockReturnValue(displayName);
242+
243+
const { getByText, getByTestId, toJSON } = renderWithProvider(
244+
<SnapUIAddressInput name="testAddress" chainId={testChainId} disabled />,
245+
{ state: mockInitialState },
246+
);
247+
248+
expect(getByText(displayName)).toBeTruthy();
249+
expect(getByText(testAddress)).toBeTruthy();
250+
251+
const closeButton = getByTestId('snap-ui-address-input__clear-button');
252+
expect(closeButton).toBeTruthy();
253+
254+
const tree = JSON.stringify(toJSON());
255+
expect(tree).toContain('"disabled":true');
256+
});
257+
});

0 commit comments

Comments
 (0)