Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,21 @@ const createStyles = (params: {
paddingHorizontal: 16,
paddingBottom: 16,
},
list: {
listContainerOuter: {
height: screenHeight * 0.8,
overflow: 'hidden', // Hides off-screen list
},
listContainerInner: {
flexDirection: 'row',
width: '200%', // Twice the width to hold both panels
height: '100%',
},
listPanel: {
width: '50%', // Each panel takes half of the inner container
height: '100%',
},
list: {
flex: 1,
},
region: {
flexDirection: 'row',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,53 +137,83 @@ describe('RegionSelectorModal', () => {
});

it('renders the modal with region list', () => {
const { toJSON } = render(RegionSelectorModal);
expect(toJSON()).toMatchSnapshot();
const { getByText, getByPlaceholderText } = render(RegionSelectorModal);

// Then all regions should be visible
expect(getByText('Portugal')).toBeOnTheScreen();
expect(getByText('France')).toBeOnTheScreen();
expect(getByText('Spain')).toBeOnTheScreen();
expect(getByText('United States of America')).toBeOnTheScreen();

// And the search field should be present
expect(getByPlaceholderText('Search by country')).toBeOnTheScreen();
});
Comment on lines 139 to 150
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests for this component weren't asserting for what the tests were describing but instead just checking snapshots matched!?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I think the snapshots are a valid way to test the UI here. Your assertions are fine too but the snapshots should cover it.


it('renders the modal with selected region in list', () => {
mockUseRampSDKValues.selectedRegion = mockRegions[0] as Region; // Portugal
const { toJSON } = render(RegionSelectorModal);
expect(toJSON()).toMatchSnapshot();
const { getByText } = render(RegionSelectorModal);

// Then Portugal should be visible (selected state is visual, hard to assert without snapshots)
expect(getByText('Portugal')).toBeOnTheScreen();
expect(getByText('France')).toBeOnTheScreen();
});

it('renders the modal with selected state in list', () => {
mockUseRampSDKValues.selectedRegion = mockedCaliforniaState as Region; // Portugal
const { toJSON } = render(RegionSelectorModal);
expect(toJSON()).toMatchSnapshot();
mockUseRampSDKValues.selectedRegion = mockedCaliforniaState as Region;
const { getByText } = render(RegionSelectorModal);

// Then all regions should still be visible in country view
expect(getByText('Portugal')).toBeOnTheScreen();
expect(getByText('United States of America')).toBeOnTheScreen();
});

it('filters regions based on search input', () => {
const { getByPlaceholderText, toJSON } = render(RegionSelectorModal);
const { getByPlaceholderText, getByText, queryByText } =
render(RegionSelectorModal);

// Given the user types a search query
const searchInput = getByPlaceholderText('Search by country');
fireEvent.changeText(searchInput, 'Port');
expect(toJSON()).toMatchSnapshot();

// Then only matching regions should be visible
expect(getByText('Portugal')).toBeOnTheScreen();
expect(queryByText('France')).toBeNull();
expect(queryByText('Spain')).toBeNull();
});

it('shows empty state when search returns no results', () => {
const { getByPlaceholderText, toJSON } = render(RegionSelectorModal);
const { getByPlaceholderText, getAllByText, queryByText } =
render(RegionSelectorModal);

// Given the user searches for a non-existent country
const searchInput = getByPlaceholderText('Search by country');
fireEvent.changeText(searchInput, 'NonExistentCountry');

expect(toJSON()).toMatchSnapshot();
// Then the empty state message should be displayed (appears in both FlatLists due to animation)
expect(getAllByText('No region matches').length).toBeGreaterThan(0);
Comment thread
georgewrmarshall marked this conversation as resolved.
expect(queryByText('Portugal')).toBeNull();
expect(queryByText('France')).toBeNull();
});

it('clears search when clear button is pressed', () => {
const { getByPlaceholderText, toJSON } = render(RegionSelectorModal);
const { getByPlaceholderText, getByText, queryByText } =
render(RegionSelectorModal);

// Given the user has typed a search query
const searchInput = getByPlaceholderText('Search by country');
fireEvent.changeText(searchInput, 'Port');

// Should show filtered results
expect(toJSON()).toMatchSnapshot();
// Then only Portugal should be visible
expect(getByText('Portugal')).toBeOnTheScreen();
expect(queryByText('France')).toBeNull();

// Clear the search
// When the user clears the search
fireEvent.changeText(searchInput, '');

// Should show all regions again
expect(toJSON()).toMatchSnapshot();
// Then all regions should be visible again
expect(getByText('Portugal')).toBeOnTheScreen();
expect(getByText('France')).toBeOnTheScreen();
expect(getByText('Spain')).toBeOnTheScreen();
});

it('calls setSelectedRegion when a region is selected', () => {
Expand All @@ -203,23 +233,141 @@ describe('RegionSelectorModal', () => {

it('handles empty regions list gracefully', () => {
mockUseParams.mockReturnValue({ regions: [] });
const { toJSON } = render(RegionSelectorModal);
expect(toJSON()).toMatchSnapshot();
const { getByPlaceholderText, queryByText } = render(RegionSelectorModal);

// Then no regions should be visible
expect(queryByText('Portugal')).toBeNull();
expect(queryByText('France')).toBeNull();

// But the search field should still be present
expect(getByPlaceholderText('Search by country')).toBeOnTheScreen();
});

it('handles undefined regions gracefully', () => {
mockUseParams.mockReturnValue({ regions: undefined });
const { toJSON } = render(RegionSelectorModal);
expect(toJSON()).toMatchSnapshot();
const { getByPlaceholderText, queryByText } = render(RegionSelectorModal);

// Then no regions should be visible
expect(queryByText('Portugal')).toBeNull();
expect(queryByText('France')).toBeNull();

// But the search field should still be present
expect(getByPlaceholderText('Search by country')).toBeOnTheScreen();
});

it('navigates back to country view when back button is pressed from state view', () => {
const { getByText, getByTestId, toJSON } = render(RegionSelectorModal);
const { getByText, getByTestId, queryByText } = render(RegionSelectorModal);

// Given the user navigates to state view
const usRegion = getByText('United States of America');
fireEvent.press(usRegion);
expect(toJSON()).toMatchSnapshot();

// Then the state (California) should be visible
expect(getByText('California')).toBeOnTheScreen();

// When the user presses the back button
const backButton = getByTestId('back-button');
fireEvent.press(backButton);
expect(toJSON()).toMatchSnapshot();

// Then the country list should be visible again
expect(getByText('United States of America')).toBeOnTheScreen();
expect(getByText('Portugal')).toBeOnTheScreen();
expect(queryByText('California')).toBeNull();
});

it('searches within state list when in state view', () => {
const mockRegionWithStates: DeepPartial<Region> = {
currencies: ['/currencies/fiat/usd'],
emoji: '🇺🇸',
id: '/regions/us',
name: 'United States of America',
states: [
{
id: '/regions/us-ca',
name: 'California',
stateId: 'ca',
support: { buy: true, sell: true },
unsupported: false,
detected: false,
recommended: true,
},
{
id: '/regions/us-ny',
name: 'New York',
stateId: 'ny',
support: { buy: true, sell: true },
unsupported: false,
detected: false,
recommended: false,
},
],
support: { buy: false, sell: false },
unsupported: true,
detected: true,
recommended: false,
};

mockUseParams.mockReturnValue({ regions: [mockRegionWithStates] });
const { getByText, getByPlaceholderText, getAllByText, queryByText } =
render(RegionSelectorModal);

// Given the user navigates to state view
const usRegion = getByText('United States of America');
fireEvent.press(usRegion);

// When the user searches for a specific state
const searchInput = getByPlaceholderText('Search by state');
fireEvent.changeText(searchInput, 'Cali');

// Then California should be visible (appears in both FlatLists due to animation)
expect(getAllByText('California').length).toBeGreaterThan(0);
expect(queryByText('New York')).toBeNull();
});

it('sorts states by recommended when displaying state list', () => {
const mockRegionWithStates: DeepPartial<Region> = {
currencies: ['/currencies/fiat/usd'],
emoji: '🇺🇸',
id: '/regions/us',
name: 'United States of America',
states: [
{
id: '/regions/us-ny',
name: 'New York',
stateId: 'ny',
support: { buy: true, sell: true },
unsupported: false,
detected: false,
recommended: false,
},
{
id: '/regions/us-ca',
name: 'California',
stateId: 'ca',
support: { buy: true, sell: true },
unsupported: false,
detected: false,
recommended: true,
},
],
support: { buy: false, sell: false },
unsupported: true,
detected: true,
recommended: false,
};

mockUseParams.mockReturnValue({ regions: [mockRegionWithStates] });
const { getByText } = render(RegionSelectorModal);

// Given the user navigates to state view
const usRegion = getByText('United States of America');
fireEvent.press(usRegion);

// Then both states should be visible (we can't easily assert order, but we verify both are present)
expect(getByText('California')).toBeOnTheScreen();
expect(getByText('New York')).toBeOnTheScreen();

// Note: In a real scenario, recommended states would appear first in the list
// but testing DOM order in React Native tests is complex without snapshot testing
});
});
Loading
Loading