Skip to content

Commit

Permalink
Merge branch 'dev' into track-banner-once
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacook committed Oct 6, 2023
2 parents d89aa80 + bcd8354 commit 0201451
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import 'fake-indexeddb/auto'
import { hexZeroPad } from 'ethers/lib/utils'
import * as tracking from '@/services/analytics'
import { set } from 'idb-keyval'
import * as navigation from 'next/navigation'
import type { ChainInfo, SafeInfo } from '@safe-global/safe-gateway-typescript-sdk'

import { PushNotificationsBanner, _getSafesToRegister } from '.'
import { createPushNotificationPrefsIndexedDb } from '@/services/push-notifications/preferences'
import { render } from '@/tests/test-utils'
import type { AddedSafesOnChain } from '@/store/addedSafesSlice'
import type { PushNotificationPreferences } from '@/services/push-notifications/preferences'
Expand Down Expand Up @@ -140,5 +142,220 @@ describe('PushNotificationsBanner', () => {

expect(tracking.trackEvent).toHaveBeenCalledTimes(1)
})
it('should display the banner', () => {
const result = render(
<PushNotificationsBanner>
<></>
</PushNotificationsBanner>,
{
routerProps: {
query: {
safe: `eth:${hexZeroPad('0x123', 20)}`,
},
},
initialReduxState: {
chains: {
loading: false,
error: undefined,
data: [
{
chainId: '1',
features: ['PUSH_NOTIFICATIONS'],
} as unknown as ChainInfo,
],
},
addedSafes: {
'1': {
[hexZeroPad('0x123', 20)]: {},
} as unknown as AddedSafesOnChain,
},
safeInfo: {
loading: false,
error: undefined,
data: {
chainId: '1',
address: {
value: hexZeroPad('0x123', 20),
},
} as unknown as SafeInfo,
},
},
},
)

expect(result.getByText('Get notified about pending signatures', { exact: false })).toBeInTheDocument()
})

it('should not show the banner if notifications are not enabled', () => {
const result = render(
<PushNotificationsBanner>
<></>
</PushNotificationsBanner>,
{
routerProps: {
query: {
safe: `eth:${hexZeroPad('0x123', 20)}`,
},
},
initialReduxState: {
chains: {
loading: false,
error: undefined,
data: [
{
chainId: '1',
features: [], // Not enabled
} as unknown as ChainInfo,
],
},
addedSafes: {
'1': {
[hexZeroPad('0x123', 20)]: {},
} as unknown as AddedSafesOnChain,
},
safeInfo: {
loading: false,
error: undefined,
data: {
chainId: '1',
address: {
value: hexZeroPad('0x123', 20),
},
} as unknown as SafeInfo,
},
},
},
)

expect(result.queryByText('Get notified about pending signatures', { exact: false })).not.toBeInTheDocument()
})

it('should not show the banner if the user has dismissed it', () => {
window.localStorage.setItem(
'SAFE_v2__dismissPushNotifications',
JSON.stringify({ '1': { [hexZeroPad('0x123', 20)]: true } }),
)

const result = render(
<PushNotificationsBanner>
<></>
</PushNotificationsBanner>,
{
initialReduxState: {
chains: {
loading: false,
error: undefined,
data: [
{
chainId: '1',
features: ['PUSH_NOTIFICATIONS'],
} as unknown as ChainInfo,
],
},
addedSafes: {
'1': {
[hexZeroPad('0x123', 20)]: {},
} as unknown as AddedSafesOnChain,
},
safeInfo: {
loading: false,
error: undefined,
data: {
chainId: '1',
address: {
value: hexZeroPad('0x123', 20),
},
} as unknown as SafeInfo,
},
},
},
)

expect(result.queryByText('Get notified about pending signatures', { exact: false })).not.toBeInTheDocument()
})

it('should not show the banner if the Safe is not added', () => {
const result = render(
<PushNotificationsBanner>
<></>
</PushNotificationsBanner>,
{
initialReduxState: {
chains: {
loading: false,
error: undefined,
data: [
{
chainId: '1',
features: ['PUSH_NOTIFICATIONS'],
} as unknown as ChainInfo,
],
},
addedSafes: {}, // Not added
safeInfo: {
loading: false,
error: undefined,
data: {
chainId: '1',
address: {
value: hexZeroPad('0x123', 20),
},
} as unknown as SafeInfo,
},
},
},
)

expect(result.queryByText('Get notified about pending signatures', { exact: false })).not.toBeInTheDocument()
})

it('should not show the banner if the user has already registered for notifications', () => {
set(
`1:${hexZeroPad('0x123', 20)}`, // Registered
{
safeAddress: hexZeroPad('0x123', 20),
chainId: '1',
preferences: {},
},
createPushNotificationPrefsIndexedDb(),
)

const result = render(
<PushNotificationsBanner>
<></>
</PushNotificationsBanner>,
{
initialReduxState: {
chains: {
loading: false,
error: undefined,
data: [
{
chainId: '1',
features: ['PUSH_NOTIFICATIONS'],
} as unknown as ChainInfo,
],
},
addedSafes: {
'1': {
[hexZeroPad('0x123', 20)]: {},
} as unknown as AddedSafesOnChain,
},
safeInfo: {
loading: false,
error: undefined,
data: {
chainId: '1',
address: {
value: hexZeroPad('0x123', 20),
},
} as unknown as SafeInfo,
},
},
},
)

expect(result.queryByText('Get notified about pending signatures', { exact: false })).not.toBeInTheDocument()
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -102,21 +102,23 @@ const TrackBanner = (): null => {
}

export const PushNotificationsBanner = ({ children }: { children: ReactElement }): ReactElement => {
const isNotificationsEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)
const isNotificationFeatureEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)
const chain = useCurrentChain()
const totalAddedSafes = useAppSelector(selectTotalAdded)
const { safe, safeAddress } = useSafeInfo()
const addedSafesOnChain = useAppSelector((state) => selectAddedSafes(state, safe.chainId))
const { query } = useRouter()
const onboard = useOnboard()

const { getPreferences, getAllPreferences } = useNotificationPreferences()
const { dismissPushNotificationBanner, isPushNotificationBannerDismissed } = useDismissPushNotificationsBanner()

const isSafeAdded = !!addedSafesOnChain?.[safeAddress]
const shouldShowBanner = isNotificationsEnabled && !isPushNotificationBannerDismissed && isSafeAdded
const isSafeRegistered = getPreferences(safe.chainId, safeAddress)
const shouldShowBanner =
isNotificationFeatureEnabled && !isPushNotificationBannerDismissed && isSafeAdded && !isSafeRegistered

const { registerNotifications } = useNotificationRegistrations()
const { getAllPreferences } = useNotificationPreferences()

const dismissBanner = useCallback(() => {
trackEvent(PUSH_NOTIFICATION_EVENTS.DISMISS_BANNER)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ const handleTrackCachedNotificationEvents = async (
}

export const useNotificationTracking = (): void => {
const isNotificationsEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)
const isNotificationFeatureEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)

useEffect(() => {
if (typeof indexedDB !== 'undefined' && isNotificationsEnabled) {
if (typeof indexedDB !== 'undefined' && isNotificationFeatureEnabled) {
handleTrackCachedNotificationEvents(createNotificationTrackingIndexedDb())
}
}, [isNotificationsEnabled])
}, [isNotificationFeatureEnabled])
}
4 changes: 2 additions & 2 deletions src/components/settings/SettingsHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { FEATURES } from '@/utils/chains'

const SettingsHeader = (): ReactElement => {
const safeAddress = useSafeAddress()
const isNotificationsEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)
const isNotificationFeatureEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)

const navItems = safeAddress ? settingsNavItems : generalSettingsNavItems
const filteredNavItems = isNotificationsEnabled
const filteredNavItems = isNotificationFeatureEnabled
? navItems
: navItems.filter((item) => item.href !== AppRoutes.settings.notifications)

Expand Down
3 changes: 0 additions & 3 deletions src/hooks/Beamer/useBeamer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ import { useAppSelector } from '@/store'
import { CookieType, selectCookies } from '@/store/cookiesSlice'
import { loadBeamer, unloadBeamer, updateBeamer } from '@/services/beamer'
import { useCurrentChain } from '@/hooks/useChains'
import { useBeamerNps } from '@/hooks/Beamer/useBeamerNps'

const useBeamer = () => {
const cookies = useAppSelector(selectCookies)
const isBeamerEnabled = cookies[CookieType.UPDATES]
const chain = useCurrentChain()

useBeamerNps()

useEffect(() => {
if (!chain?.shortName) {
return
Expand Down
31 changes: 0 additions & 31 deletions src/hooks/Beamer/useBeamerNps.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/pages/settings/notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { useHasFeature } from '@/hooks/useChains'
import { FEATURES } from '@/utils/chains'

const NotificationsPage: NextPage = () => {
const isNotificationsEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)
const isNotificationFeatureEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)

if (!isNotificationsEnabled) {
if (!isNotificationFeatureEnabled) {
return null
}

Expand Down

0 comments on commit 0201451

Please sign in to comment.