Skip to content

Commit 0eccafa

Browse files
committed
fix: remove hip-3 stocks list all filter
feat: Remove stocks/commodities dropdown and fix FlashList gaps Changes: - Remove conditional stocks/commodities dropdown in market list view - Set showStocksCommoditiesDropdown to false (always hidden) - Add tests to verify dropdown is not shown regardless of market type filter - Fix FlashList layout gaps in market lists - Add drawDistance={200} and removeClippedSubviews props to PerpsMarketList - Create marketListConfig.ts for FlashList configuration constants - Prevents blank space gaps when searching or scrolling - Fix pre-existing test failure - Refactor "handles search with whitespace" test to use proper mocking - Rename to "filters markets with whitespace-only query" for clarity
1 parent 01739ee commit 0eccafa

File tree

4 files changed

+154
-37
lines changed

4 files changed

+154
-37
lines changed

app/components/UI/Perps/Views/PerpsMarketListView/PerpsMarketListView.test.tsx

Lines changed: 143 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,18 @@ jest.mock('./components/PerpsMarketFiltersBar', () => {
218218
selectedOptionId,
219219
onSortPress,
220220
onWatchlistToggle,
221+
showStocksCommoditiesDropdown,
222+
stocksCommoditiesFilter,
223+
onStocksCommoditiesPress,
221224
testID,
222225
}: {
223226
selectedOptionId: string;
224227
onSortPress: () => void;
225228
showWatchlistOnly: boolean;
226229
onWatchlistToggle: () => void;
230+
showStocksCommoditiesDropdown?: boolean;
231+
stocksCommoditiesFilter?: 'all' | 'equity' | 'commodity';
232+
onStocksCommoditiesPress?: () => void;
227233
testID?: string;
228234
}) {
229235
// Map sort option IDs to display labels
@@ -251,14 +257,31 @@ jest.mock('./components/PerpsMarketFiltersBar', () => {
251257
displayText,
252258
),
253259
),
254-
MockReact.createElement(
255-
RNTouchableOpacity,
256-
{
257-
testID: testID ? `${testID}-watchlist-toggle` : undefined,
258-
onPress: onWatchlistToggle,
259-
},
260-
MockReact.createElement(Text, null, 'Watchlist'),
261-
),
260+
onWatchlistToggle &&
261+
MockReact.createElement(
262+
RNTouchableOpacity,
263+
{
264+
testID: testID ? `${testID}-watchlist-toggle` : undefined,
265+
onPress: onWatchlistToggle,
266+
},
267+
MockReact.createElement(Text, null, 'Watchlist'),
268+
),
269+
showStocksCommoditiesDropdown &&
270+
onStocksCommoditiesPress &&
271+
MockReact.createElement(
272+
RNTouchableOpacity,
273+
{
274+
testID: testID
275+
? `${testID}-stocks-commodities-dropdown`
276+
: undefined,
277+
onPress: onStocksCommoditiesPress,
278+
},
279+
MockReact.createElement(
280+
Text,
281+
null,
282+
`Stocks/Commodities: ${stocksCommoditiesFilter || 'all'}`,
283+
),
284+
),
262285
);
263286
};
264287
});
@@ -1196,41 +1219,127 @@ describe('PerpsMarketListView', () => {
11961219
// Note: TabBar Navigation tests removed - PerpsMarketListView does not render a bottom tab bar
11971220
// The component only renders market type tabs (All, Crypto, Stocks) for filtering markets
11981221

1199-
describe('Edge Cases', () => {
1200-
it('handles search with whitespace', async () => {
1201-
const { rerender } = renderWithProvider(<PerpsMarketListView />, {
1202-
state: mockState,
1222+
describe('Stocks/Commodities Dropdown', () => {
1223+
it('does not show stocks/commodities dropdown when showStocksCommoditiesDropdown is false', async () => {
1224+
renderWithProvider(<PerpsMarketListView />, { state: mockState });
1225+
1226+
// Wait for filter bar to render
1227+
await waitFor(() => {
1228+
expect(screen.getByText('Volume')).toBeOnTheScreen();
12031229
});
12041230

1205-
const searchButton = screen.getByTestId(
1206-
`${PerpsMarketListViewSelectorsIDs.CLOSE_BUTTON}-search-toggle`,
1207-
);
1231+
// Verify stocks/commodities dropdown is not present
1232+
expect(
1233+
screen.queryByTestId(
1234+
`${PerpsMarketListViewSelectorsIDs.SORT_FILTERS}-stocks-commodities-dropdown`,
1235+
),
1236+
).not.toBeOnTheScreen();
1237+
});
12081238

1209-
// Press search button - this updates mockSearchVisible
1210-
await act(async () => {
1211-
fireEvent.press(searchButton);
1212-
// Force re-render to pick up updated mockSearchVisible
1213-
rerender(<PerpsMarketListView />);
1239+
it('does not show stocks/commodities dropdown regardless of market type filter', async () => {
1240+
const { usePerpsMarketListView } = jest.requireMock('../../hooks');
1241+
1242+
// Mock the hook to return stocks_and_commodities as the active filter
1243+
usePerpsMarketListView.mockReturnValue({
1244+
markets: mockMarketData,
1245+
searchState: {
1246+
searchQuery: '',
1247+
setSearchQuery: jest.fn(),
1248+
isSearchVisible: false,
1249+
setIsSearchVisible: jest.fn(),
1250+
toggleSearchVisibility: jest.fn(),
1251+
clearSearch: jest.fn(),
1252+
},
1253+
sortState: {
1254+
selectedOptionId: 'volume',
1255+
sortBy: 'volume',
1256+
direction: 'desc',
1257+
handleOptionChange: jest.fn(),
1258+
},
1259+
favoritesState: {
1260+
showFavoritesOnly: false,
1261+
setShowFavoritesOnly: jest.fn(),
1262+
},
1263+
marketTypeFilterState: {
1264+
marketTypeFilter: 'stocks_and_commodities',
1265+
setMarketTypeFilter: jest.fn(),
1266+
},
1267+
marketCounts: {
1268+
crypto: 3,
1269+
equity: 2,
1270+
commodity: 1,
1271+
forex: 0,
1272+
},
1273+
isLoading: false,
1274+
error: null,
1275+
});
1276+
1277+
renderWithProvider(<PerpsMarketListView />, { state: mockState });
1278+
1279+
// Wait for filter bar to render
1280+
await waitFor(() => {
1281+
expect(screen.getByText('Volume')).toBeOnTheScreen();
12141282
});
12151283

1216-
// Wait for search input to appear (mock should now return isSearchVisible: true)
1217-
await waitFor(
1218-
() => {
1219-
const searchInput = screen.getByPlaceholderText(
1220-
'Search by token symbol',
1221-
);
1222-
expect(searchInput).toBeOnTheScreen();
1284+
// Verify stocks/commodities dropdown is still not present even with stocks_and_commodities filter
1285+
expect(
1286+
screen.queryByTestId(
1287+
`${PerpsMarketListViewSelectorsIDs.SORT_FILTERS}-stocks-commodities-dropdown`,
1288+
),
1289+
).not.toBeOnTheScreen();
1290+
});
1291+
});
1292+
1293+
describe('Edge Cases', () => {
1294+
it('filters markets with whitespace-only query', async () => {
1295+
const { usePerpsMarketListView } = jest.requireMock('../../hooks');
1296+
1297+
// Start with search visible
1298+
mockSearchVisible = true;
1299+
mockSearchQuery = ' ';
1300+
1301+
// Mock to return empty results when search query is whitespace
1302+
usePerpsMarketListView.mockReturnValue({
1303+
markets: mockMarketData, // Whitespace is trimmed, so all markets show
1304+
searchState: {
1305+
searchQuery: ' ',
1306+
setSearchQuery: mockSetSearchQuery,
1307+
isSearchVisible: true,
1308+
setIsSearchVisible: mockSetIsSearchVisible,
1309+
toggleSearchVisibility: mockToggleSearchVisibility,
1310+
clearSearch: mockClearSearch,
12231311
},
1224-
{ timeout: 3000 },
1225-
);
1312+
sortState: {
1313+
selectedOptionId: 'volume',
1314+
sortBy: 'volume',
1315+
direction: 'desc',
1316+
handleOptionChange: jest.fn(),
1317+
},
1318+
favoritesState: {
1319+
showFavoritesOnly: false,
1320+
setShowFavoritesOnly: jest.fn(),
1321+
},
1322+
marketTypeFilterState: {
1323+
marketTypeFilter: 'all',
1324+
setMarketTypeFilter: jest.fn(),
1325+
},
1326+
marketCounts: {
1327+
crypto: 3,
1328+
equity: 0,
1329+
commodity: 0,
1330+
forex: 0,
1331+
},
1332+
isLoading: false,
1333+
error: null,
1334+
});
12261335

1336+
renderWithProvider(<PerpsMarketListView />, { state: mockState });
1337+
1338+
// Verify search input is visible
12271339
const searchInput = screen.getByPlaceholderText('Search by token symbol');
1228-
await act(async () => {
1229-
fireEvent.changeText(searchInput, ' ');
1230-
});
1340+
expect(searchInput).toBeOnTheScreen();
12311341

1232-
// Wait for markets to appear (whitespace should be trimmed, so all markets show)
1233-
// Note: Multiple tabs may render, so we check that at least one instance exists
1342+
// Verify all markets are still displayed (whitespace is trimmed)
12341343
await waitFor(() => {
12351344
const btcRows = screen.queryAllByTestId('market-row-BTC');
12361345
const ethRows = screen.queryAllByTestId('market-row-ETH');

app/components/UI/Perps/Views/PerpsMarketListView/PerpsMarketListView.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,7 @@ const PerpsMarketListView = ({
466466
<PerpsMarketFiltersBar
467467
selectedOptionId={selectedOptionId}
468468
onSortPress={() => setIsSortFieldSheetVisible(true)}
469-
showStocksCommoditiesDropdown={
470-
marketTypeFilter === 'stocks_and_commodities'
471-
}
469+
showStocksCommoditiesDropdown={false}
472470
stocksCommoditiesFilter={stocksCommoditiesFilter}
473471
onStocksCommoditiesPress={() =>
474472
setIsStocksCommoditiesSheetVisible(true)

app/components/UI/Perps/components/PerpsMarketList/PerpsMarketList.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useStyles } from '../../../../../component-library/hooks';
99
import { strings } from '../../../../../../locales/i18n';
1010
import PerpsMarketRowItem from '../PerpsMarketRowItem';
1111
import { HOME_SCREEN_CONFIG } from '../../constants/perpsConfig';
12+
import { PERPS_MARKET_LIST_CONSTANTS } from '../../constants/marketListConfig';
1213
import styleSheet from './PerpsMarketList.styles';
1314
import type { PerpsMarketListProps } from './PerpsMarketList.types';
1415
import type { PerpsMarketData } from '../../controllers/types';
@@ -84,6 +85,8 @@ const PerpsMarketList: React.FC<PerpsMarketListProps> = ({
8485
contentContainerStyle={[styles.contentContainer, contentContainerStyle]}
8586
keyboardShouldPersistTaps="handled"
8687
ListHeaderComponent={ListHeaderComponent}
88+
drawDistance={PERPS_MARKET_LIST_CONSTANTS.FLASH_LIST_DRAW_DISTANCE}
89+
removeClippedSubviews
8790
testID={testID}
8891
/>
8992
);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Market list component configuration constants
3+
*/
4+
export const PERPS_MARKET_LIST_CONSTANTS = {
5+
FLASH_LIST_DRAW_DISTANCE: 200,
6+
FLASH_LIST_SCROLL_EVENT_THROTTLE: 16,
7+
} as const;

0 commit comments

Comments
 (0)