From d61021da823c77f46a27f43ffa24936a25fcaf70 Mon Sep 17 00:00:00 2001 From: Aaron Cook Date: Mon, 16 Dec 2024 12:01:56 +0000 Subject: [PATCH] fix: rank featured Safe Apps first on dashboard (#4644) * fix: show featured Safe Apps first on dashboard * fix: add test coverage * fix: only return featured/pinned Safe Apps * Remove unnecessary test --- .../__tests__/SafeAppsDashboardSection.test.tsx | 7 +++++-- src/hooks/__tests__/useRankedSafeApps.test.ts | 16 +++++++++------- src/hooks/safe-apps/useRankedSafeApps.ts | 6 +++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx b/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx index 047ce6e3bf..d235037244 100644 --- a/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx +++ b/src/components/dashboard/SafeAppsDashboardSection/__tests__/SafeAppsDashboardSection.test.tsx @@ -23,6 +23,7 @@ jest.mock('@safe-global/safe-gateway-typescript-sdk', () => ({ features: [], socialProfiles: [], developerWebsite: '', + featured: true, }, { id: 3, @@ -40,6 +41,7 @@ jest.mock('@safe-global/safe-gateway-typescript-sdk', () => ({ features: [], socialProfiles: [], developerWebsite: '', + featured: true, }, { id: 14, @@ -56,6 +58,7 @@ jest.mock('@safe-global/safe-gateway-typescript-sdk', () => ({ features: [], socialProfiles: [], developerWebsite: '', + featured: false, }, { id: 24, @@ -73,6 +76,7 @@ jest.mock('@safe-global/safe-gateway-typescript-sdk', () => ({ features: [], socialProfiles: [], developerWebsite: '', + featured: true, }, ]), })) @@ -116,8 +120,7 @@ describe('Safe Apps Dashboard Section', () => { expect(screen.getByText('Decentralised naming for wallets, websites, & more.')).toBeInTheDocument(), ) - await waitFor(() => expect(screen.getByText('Synthetix')).toBeInTheDocument()) - await waitFor(() => expect(screen.getByText('Trade synthetic assets on Ethereum')).toBeInTheDocument()) + // Synthetix is not displayed as it is not featured await waitFor(() => expect(screen.getByText('Transaction Builder')).toBeInTheDocument()) await waitFor(() => expect(screen.getByText('A Safe app to compose custom transactions')).toBeInTheDocument()) diff --git a/src/hooks/__tests__/useRankedSafeApps.test.ts b/src/hooks/__tests__/useRankedSafeApps.test.ts index 0ce767eba3..2aa30b5eb8 100644 --- a/src/hooks/__tests__/useRankedSafeApps.test.ts +++ b/src/hooks/__tests__/useRankedSafeApps.test.ts @@ -17,7 +17,7 @@ describe('useRankedSafeApps', () => { }) it('returns 5 safe apps at most', () => { - const mockSafeApp1 = getMockSafeApp({ id: 1 }) + const mockSafeApp1 = getMockSafeApp({ id: 1, featured: true } as Partial) const mockSafeApp2 = getMockSafeApp({ id: 2 }) const mockSafeApp3 = getMockSafeApp({ id: 3 }) const mockSafeApp4 = getMockSafeApp({ id: 4 }) @@ -25,16 +25,16 @@ describe('useRankedSafeApps', () => { const mockSafeApp6 = getMockSafeApp({ id: 6 }) const { result } = renderHook(() => - useRankedSafeApps([mockSafeApp1, mockSafeApp2, mockSafeApp3, mockSafeApp4, mockSafeApp5, mockSafeApp6], []), + useRankedSafeApps([mockSafeApp1], [mockSafeApp2, mockSafeApp3, mockSafeApp4, mockSafeApp5, mockSafeApp6]), ) expect(result.current.length).toEqual(5) }) - it('returns pinned apps first', () => { + it('returns featured, then pinned apps', () => { const mockSafeApp1 = getMockSafeApp({ id: 1 }) - const mockSafeApp2 = getMockSafeApp({ id: 2 }) - const mockSafeApp3 = getMockSafeApp({ id: 3 }) + const mockSafeApp2 = getMockSafeApp({ id: 2, featured: true } as Partial) + const mockSafeApp3 = getMockSafeApp({ id: 3, featured: true } as Partial) const mockSafeApp4 = getMockSafeApp({ id: 4 }) const mockSafeApp5 = getMockSafeApp({ id: 5 }) @@ -48,7 +48,9 @@ describe('useRankedSafeApps', () => { ), ) - expect(result.current[0]).toStrictEqual(mockPinnedApp1) - expect(result.current[1]).toStrictEqual(mockPinnedApp2) + expect(result.current[0]).toStrictEqual(mockSafeApp2) + expect(result.current[1]).toStrictEqual(mockSafeApp3) + expect(result.current[2]).toStrictEqual(mockPinnedApp1) + expect(result.current[3]).toStrictEqual(mockPinnedApp2) }) }) diff --git a/src/hooks/safe-apps/useRankedSafeApps.ts b/src/hooks/safe-apps/useRankedSafeApps.ts index f598b86546..cab112ed75 100644 --- a/src/hooks/safe-apps/useRankedSafeApps.ts +++ b/src/hooks/safe-apps/useRankedSafeApps.ts @@ -9,11 +9,11 @@ const useRankedSafeApps = (safeApps: SafeAppData[], pinnedSafeApps: SafeAppData[ return useMemo(() => { if (!safeApps.length) return [] - const mostUsedApps = rankSafeApps(safeApps) + // TODO: Remove assertion after migrating to new SDK + const featuredApps = safeApps.filter((app) => (app as SafeAppData & { featured: boolean }).featured) const rankedPinnedApps = rankSafeApps(pinnedSafeApps) - const randomApps = safeApps.slice().sort(() => Math.random() - 0.5) - const allRankedApps = rankedPinnedApps.concat(pinnedSafeApps, mostUsedApps, randomApps) + const allRankedApps = featuredApps.concat(rankedPinnedApps, pinnedSafeApps) // Use a Set to remove duplicates return [...new Set(allRankedApps)].slice(0, NUMBER_OF_SAFE_APPS)