test: unit tests for activity tab createGroups, and update cloud test snapshots (#7364)
* test: unit tests for activity tab createGroups * fix: update cloud test snapshots
This commit is contained in:
parent
b9fc65ec9a
commit
e81b0a4d1f
@ -37,7 +37,8 @@ exports[`should inject metadata for valid assets 1`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -184,7 +185,8 @@ exports[`should inject metadata for valid assets 2`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -331,7 +333,8 @@ exports[`should inject metadata for valid assets 3`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
|
@ -37,7 +37,8 @@ exports[`should inject metadata for collections 1`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -184,7 +185,8 @@ exports[`should inject metadata for collections 2`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -331,7 +333,8 @@ exports[`should inject metadata for collections 3`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -478,7 +481,8 @@ exports[`should inject metadata for collections 4`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
|
@ -37,7 +37,8 @@ exports[`should inject metadata for valid tokens 1`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -184,7 +185,8 @@ exports[`should inject metadata for valid tokens 2`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -331,7 +333,8 @@ exports[`should inject metadata for valid tokens 3`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
@ -478,7 +481,8 @@ exports[`should inject metadata for valid tokens 4`] = `
|
|||||||
-->
|
-->
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
|
||||||
<link rel="preconnect" href="https://api.uniswap.org/v1/amplitude-proxy" />
|
<link rel="preconnect" href="https://api.uniswap.org/" crossorigin/>
|
||||||
|
<link rel="preconnect" href="https://mainnet.infura.io/" crossorigin/>
|
||||||
|
|
||||||
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Book.woff" as="font" type="font/woff" crossorigin />
|
||||||
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
<link rel="preload" href="/fonts/Basel-Medium.woff" as="font" type="font/woff" crossorigin />
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
import { t } from '@lingui/macro'
|
|
||||||
import { useAccountDrawer } from 'components/AccountDrawer'
|
import { useAccountDrawer } from 'components/AccountDrawer'
|
||||||
import Column from 'components/Column'
|
import Column from 'components/Column'
|
||||||
import { LoadingBubble } from 'components/Tokens/loading'
|
import { LoadingBubble } from 'components/Tokens/loading'
|
||||||
import { getYear, isSameDay, isSameMonth, isSameWeek, isSameYear } from 'date-fns'
|
|
||||||
import { TransactionStatus } from 'graphql/data/__generated__/types-and-hooks'
|
|
||||||
import { PollingInterval } from 'graphql/data/util'
|
import { PollingInterval } from 'graphql/data/util'
|
||||||
import { atom, useAtom } from 'jotai'
|
import { atom, useAtom } from 'jotai'
|
||||||
import { EmptyWalletModule } from 'nft/components/profile/view/EmptyWalletContent'
|
import { EmptyWalletModule } from 'nft/components/profile/view/EmptyWalletContent'
|
||||||
@ -14,67 +11,7 @@ import { ThemedText } from 'theme'
|
|||||||
import { PortfolioSkeleton, PortfolioTabWrapper } from '../PortfolioRow'
|
import { PortfolioSkeleton, PortfolioTabWrapper } from '../PortfolioRow'
|
||||||
import { ActivityRow } from './ActivityRow'
|
import { ActivityRow } from './ActivityRow'
|
||||||
import { useAllActivities } from './hooks'
|
import { useAllActivities } from './hooks'
|
||||||
import { Activity } from './types'
|
import { createGroups } from './utils'
|
||||||
|
|
||||||
interface ActivityGroup {
|
|
||||||
title: string
|
|
||||||
transactions: Array<Activity>
|
|
||||||
}
|
|
||||||
|
|
||||||
const sortActivities = (a: Activity, b: Activity) => b.timestamp - a.timestamp
|
|
||||||
|
|
||||||
const createGroups = (activities?: Array<Activity>) => {
|
|
||||||
if (!activities) return undefined
|
|
||||||
const now = Date.now()
|
|
||||||
|
|
||||||
const pending: Array<Activity> = []
|
|
||||||
const today: Array<Activity> = []
|
|
||||||
const currentWeek: Array<Activity> = []
|
|
||||||
const last30Days: Array<Activity> = []
|
|
||||||
const currentYear: Array<Activity> = []
|
|
||||||
const yearMap: { [key: string]: Array<Activity> } = {}
|
|
||||||
|
|
||||||
// TODO(cartcrom): create different time bucket system for activities to fall in based on design wants
|
|
||||||
activities.forEach((activity) => {
|
|
||||||
if (activity.status === TransactionStatus.Pending) {
|
|
||||||
pending.push(activity)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const addedTime = activity.timestamp * 1000
|
|
||||||
|
|
||||||
if (isSameDay(now, addedTime)) {
|
|
||||||
today.push(activity)
|
|
||||||
} else if (isSameWeek(addedTime, now)) {
|
|
||||||
currentWeek.push(activity)
|
|
||||||
} else if (isSameMonth(addedTime, now)) {
|
|
||||||
last30Days.push(activity)
|
|
||||||
} else if (isSameYear(addedTime, now)) {
|
|
||||||
currentYear.push(activity)
|
|
||||||
} else {
|
|
||||||
const year = getYear(addedTime)
|
|
||||||
|
|
||||||
if (!yearMap[year]) {
|
|
||||||
yearMap[year] = [activity]
|
|
||||||
} else {
|
|
||||||
yearMap[year].push(activity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const sortedYears = Object.keys(yearMap)
|
|
||||||
.sort((a, b) => parseInt(b) - parseInt(a))
|
|
||||||
.map((year) => ({ title: year, transactions: yearMap[year] }))
|
|
||||||
|
|
||||||
const transactionGroups: Array<ActivityGroup> = [
|
|
||||||
{ title: t`Pending`, transactions: pending.sort(sortActivities) },
|
|
||||||
{ title: t`Today`, transactions: today.sort(sortActivities) },
|
|
||||||
{ title: t`This week`, transactions: currentWeek.sort(sortActivities) },
|
|
||||||
{ title: t`This month`, transactions: last30Days.sort(sortActivities) },
|
|
||||||
{ title: t`This year`, transactions: currentYear.sort(sortActivities) },
|
|
||||||
...sortedYears,
|
|
||||||
]
|
|
||||||
|
|
||||||
return transactionGroups.filter((transactionInformation) => transactionInformation.transactions.length > 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ActivityGroupWrapper = styled(Column)`
|
const ActivityGroupWrapper = styled(Column)`
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
import { TransactionStatus } from 'graphql/data/__generated__/types-and-hooks' // Replace with the actual import if this is incorrect
|
||||||
|
|
||||||
|
import { Activity } from './types'
|
||||||
|
import { createGroups } from './utils'
|
||||||
|
|
||||||
|
describe('createGroups', () => {
|
||||||
|
it('should return undefined if activities is undefined', () => {
|
||||||
|
expect(createGroups(undefined)).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return an empty array if activities is empty', () => {
|
||||||
|
expect(createGroups([])).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should sort and group activities based on status and time', () => {
|
||||||
|
const mockActivities = [
|
||||||
|
{ timestamp: 1700000000, status: TransactionStatus.Pending },
|
||||||
|
{ timestamp: 1650000000, status: TransactionStatus.Confirmed },
|
||||||
|
{ timestamp: Date.now() / 1000 - 300, status: TransactionStatus.Confirmed },
|
||||||
|
] as Activity[]
|
||||||
|
|
||||||
|
const result = createGroups(mockActivities)
|
||||||
|
|
||||||
|
expect(result).toContainEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
title: 'Pending',
|
||||||
|
transactions: expect.arrayContaining([
|
||||||
|
expect.objectContaining({ timestamp: 1700000000, status: TransactionStatus.Pending }),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result).toContainEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
title: 'Today',
|
||||||
|
transactions: expect.arrayContaining([
|
||||||
|
expect.objectContaining({ timestamp: expect.any(Number), status: TransactionStatus.Confirmed }),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
65
src/components/AccountDrawer/MiniPortfolio/Activity/utils.ts
Normal file
65
src/components/AccountDrawer/MiniPortfolio/Activity/utils.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import { t } from '@lingui/macro'
|
||||||
|
import { getYear, isSameDay, isSameMonth, isSameWeek, isSameYear } from 'date-fns'
|
||||||
|
import { TransactionStatus } from 'graphql/data/__generated__/types-and-hooks'
|
||||||
|
|
||||||
|
import { Activity } from './types'
|
||||||
|
|
||||||
|
interface ActivityGroup {
|
||||||
|
title: string
|
||||||
|
transactions: Array<Activity>
|
||||||
|
}
|
||||||
|
|
||||||
|
const sortActivities = (a: Activity, b: Activity) => b.timestamp - a.timestamp
|
||||||
|
|
||||||
|
export const createGroups = (activities?: Array<Activity>) => {
|
||||||
|
if (!activities) return undefined
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
const pending: Array<Activity> = []
|
||||||
|
const today: Array<Activity> = []
|
||||||
|
const currentWeek: Array<Activity> = []
|
||||||
|
const last30Days: Array<Activity> = []
|
||||||
|
const currentYear: Array<Activity> = []
|
||||||
|
const yearMap: { [key: string]: Array<Activity> } = {}
|
||||||
|
|
||||||
|
// TODO(cartcrom): create different time bucket system for activities to fall in based on design wants
|
||||||
|
activities.forEach((activity) => {
|
||||||
|
if (activity.status === TransactionStatus.Pending) {
|
||||||
|
pending.push(activity)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const addedTime = activity.timestamp * 1000
|
||||||
|
|
||||||
|
if (isSameDay(now, addedTime)) {
|
||||||
|
today.push(activity)
|
||||||
|
} else if (isSameWeek(addedTime, now)) {
|
||||||
|
currentWeek.push(activity)
|
||||||
|
} else if (isSameMonth(addedTime, now)) {
|
||||||
|
last30Days.push(activity)
|
||||||
|
} else if (isSameYear(addedTime, now)) {
|
||||||
|
currentYear.push(activity)
|
||||||
|
} else {
|
||||||
|
const year = getYear(addedTime)
|
||||||
|
|
||||||
|
if (!yearMap[year]) {
|
||||||
|
yearMap[year] = [activity]
|
||||||
|
} else {
|
||||||
|
yearMap[year].push(activity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const sortedYears = Object.keys(yearMap)
|
||||||
|
.sort((a, b) => parseInt(b) - parseInt(a))
|
||||||
|
.map((year) => ({ title: year, transactions: yearMap[year] }))
|
||||||
|
|
||||||
|
const transactionGroups: Array<ActivityGroup> = [
|
||||||
|
{ title: t`Pending`, transactions: pending.sort(sortActivities) },
|
||||||
|
{ title: t`Today`, transactions: today.sort(sortActivities) },
|
||||||
|
{ title: t`This week`, transactions: currentWeek.sort(sortActivities) },
|
||||||
|
{ title: t`This month`, transactions: last30Days.sort(sortActivities) },
|
||||||
|
{ title: t`This year`, transactions: currentYear.sort(sortActivities) },
|
||||||
|
...sortedYears,
|
||||||
|
]
|
||||||
|
|
||||||
|
return transactionGroups.filter((transactionInformation) => transactionInformation.transactions.length > 0)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user