Skip to content

Commit

Permalink
fix: Hide Security&Login from settings if not a social signer (#2734)
Browse files Browse the repository at this point in the history
* fix: Hide Security&Login from settings if not a social signer

* refactor: Remove Boolean expression

* fix: Add tooltip to info text on welcome page

* fix: Close popover when password recovery opens

* fix: Failing tests
  • Loading branch information
usame-algan authored Nov 2, 2023
1 parent 842836f commit c81b9fb
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 30 deletions.
2 changes: 1 addition & 1 deletion cypress/e2e/pages/create_wallet.pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const changeNetworkWarningStr = 'Change your wallet network'
const safeAccountSetupStr = 'Safe Account setup'
const policy1_2 = '1/1 policy'
export const walletName = 'test1-sepolia-safe'
export const defaltSepoliaPlaceholder = 'sepolia-safe'
export const defaltSepoliaPlaceholder = 'Sepolia Safe'

export function verifyPolicy1_1() {
cy.contains(policy1_2).should('exist')
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/ConnectWallet/WalletDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const WalletDetails = ({ onConnect }: { onConnect: () => void }): ReactElement =
</Typography>
</Divider>

<SocialSigner />
<SocialSigner onRequirePassword={onConnect} />
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ describe('SocialSignerLogin', () => {
/>,
)

expect(
result.getByText('Currently only supported on Goerli. More network support coming soon.'),
).toBeInTheDocument()
expect(result.getByText('Currently only supported on Goerli')).toBeInTheDocument()
expect(await result.findByRole('button')).toBeDisabled()
})

Expand Down
44 changes: 23 additions & 21 deletions src/components/common/SocialSigner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Button, SvgIcon, Typography } from '@mui/material'
import { Box, Button, SvgIcon, Tooltip, Typography } from '@mui/material'
import { useCallback, useContext, useMemo, useState } from 'react'
import { PasswordRecovery } from '@/components/common/SocialSigner/PasswordRecovery'
import GoogleLogo from '@/public/images/welcome/logo-google.svg'
Expand Down Expand Up @@ -46,6 +46,7 @@ type SocialSignerLoginProps = {
supportedChains: ReturnType<typeof useGetSupportedChains>
isMPCLoginEnabled: ReturnType<typeof useIsSocialWalletEnabled>
onLogin?: () => void
onRequirePassword?: () => void
}

export const SocialSigner = ({
Expand All @@ -54,6 +55,7 @@ export const SocialSigner = ({
supportedChains,
isMPCLoginEnabled,
onLogin,
onRequirePassword,
}: SocialSignerLoginProps) => {
const [loginPending, setLoginPending] = useState<boolean>(false)
const [loginError, setLoginError] = useState<string | undefined>(undefined)
Expand Down Expand Up @@ -90,15 +92,11 @@ export const SocialSigner = ({
}

if (status === COREKIT_STATUS.REQUIRED_SHARE) {
onRequirePassword?.()

setTxFlow(
<PasswordRecovery
recoverFactorWithPassword={recoverPassword}
onSuccess={() => {
onLogin?.()
setLoginPending(false)
}}
/>,
() => {},
<PasswordRecovery recoverFactorWithPassword={recoverPassword} onSuccess={onLogin} />,
() => setLoginPending(false),
false,
)
return
Expand Down Expand Up @@ -163,18 +161,22 @@ export const SocialSigner = ({
</Box>

{!isMPCLoginEnabled && (
<Typography variant="body2" color="text.secondary" display="flex" gap={1} alignItems="center">
<SvgIcon
component={InfoIcon}
inheritViewBox
color="border"
fontSize="small"
sx={{
verticalAlign: 'middle',
ml: 0.5,
}}
/>
Currently only supported on {supportedChains.join(', ')}. More network support coming soon.
<Typography variant="body2" color="text.secondary" display="flex" gap={1}>
<Tooltip title="More network support coming soon." arrow placement="top">
<span>
<SvgIcon
component={InfoIcon}
inheritViewBox
color="border"
fontSize="small"
sx={{
verticalAlign: 'middle',
ml: 0.5,
}}
/>
</span>
</Tooltip>
<span>Currently only supported on {supportedChains.join(supportedChains.length === 2 ? ' and ' : ', ')}</span>
</Typography>
)}
</>
Expand Down
78 changes: 78 additions & 0 deletions src/components/settings/SettingsHeader/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import SettingsHeader from '@/components/settings/SettingsHeader/index'
import * as safeAddress from '@/hooks/useSafeAddress'
import * as feature from '@/hooks/useChains'
import * as wallet from '@/hooks/wallets/useWallet'
import { ONBOARD_MPC_MODULE_LABEL } from '@/services/mpc/SocialLoginModule'
import { connectedWalletBuilder } from '@/tests/builders/wallet'

import { render } from '@/tests/test-utils'
import { faker } from '@faker-js/faker'

describe('SettingsHeader', () => {
beforeEach(() => {
jest.resetAllMocks()
})

describe('A safe is open', () => {
beforeEach(() => {
jest.resetAllMocks()
jest.spyOn(safeAddress, 'default').mockReturnValue(faker.finance.ethereumAddress())
})

it('displays safe specific preferences if on a safe', () => {
const result = render(<SettingsHeader />)

expect(result.getByText('Setup')).toBeInTheDocument()
})

it('displays Notifications if feature is enabled', () => {
jest.spyOn(feature, 'useHasFeature').mockReturnValue(true)

const result = render(<SettingsHeader />)

expect(result.getByText('Notifications')).toBeInTheDocument()
})

it('displays Security & Login if connected wallet is a social signer', () => {
const mockWallet = connectedWalletBuilder().with({ label: ONBOARD_MPC_MODULE_LABEL }).build()
jest.spyOn(wallet, 'default').mockReturnValue(mockWallet)

const result = render(<SettingsHeader />)

expect(result.getByText('Security & Login')).toBeInTheDocument()
})
})

describe('No safe is open', () => {
beforeEach(() => {
jest.resetAllMocks()
jest.spyOn(safeAddress, 'default').mockReturnValue('')
})

it('displays general preferences if no safe is open', () => {
const result = render(<SettingsHeader />)

expect(result.getByText('Cookies')).toBeInTheDocument()
expect(result.getByText('Appearance')).toBeInTheDocument()
expect(result.getByText('Data')).toBeInTheDocument()
expect(result.getByText('Environment variables')).toBeInTheDocument()
})

it('displays Notifications if feature is enabled', () => {
jest.spyOn(feature, 'useHasFeature').mockReturnValue(true)

const result = render(<SettingsHeader />)

expect(result.getByText('Notifications')).toBeInTheDocument()
})

it('displays Security & Login if connected wallet is a social signer', () => {
const mockWallet = connectedWalletBuilder().with({ label: ONBOARD_MPC_MODULE_LABEL }).build()
jest.spyOn(wallet, 'default').mockReturnValue(mockWallet)

const result = render(<SettingsHeader />)

expect(result.getByText('Security & Login')).toBeInTheDocument()
})
})
})
28 changes: 24 additions & 4 deletions src/components/settings/SettingsHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import useWallet from '@/hooks/wallets/useWallet'
import { isSocialLoginWallet } from '@/services/mpc/SocialLoginModule'
import { useMemo } from 'react'
import type { ReactElement } from 'react'

import NavTabs from '@/components/common/NavTabs'
Expand All @@ -9,21 +12,38 @@ import { AppRoutes } from '@/config/routes'
import { useHasFeature } from '@/hooks/useChains'
import { FEATURES } from '@/utils/chains'

type NavItem = {
href: string
label: string
}

type HideConditions = Record<string, boolean>

const filterRoutes = (navItems: NavItem[], hideConditions: HideConditions) => {
return navItems.filter((item) => !hideConditions[item.href])
}

const SettingsHeader = (): ReactElement => {
const wallet = useWallet()
const safeAddress = useSafeAddress()
const isNotificationFeatureEnabled = useHasFeature(FEATURES.PUSH_NOTIFICATIONS)
const isSocialLogin = isSocialLoginWallet(wallet?.label)

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

const filteredItems = useMemo(() => {
return filterRoutes(navItems, {
[AppRoutes.settings.notifications]: !isNotificationFeatureEnabled,
[AppRoutes.settings.securityLogin]: !isSocialLogin,
})
}, [isNotificationFeatureEnabled, isSocialLogin, navItems])

return (
<PageHeader
title={safeAddress ? 'Settings' : 'Preferences'}
action={
<div className={css.navWrapper}>
<NavTabs tabs={filteredNavItems} />
<NavTabs tabs={filteredItems} />
</div>
}
/>
Expand Down

0 comments on commit c81b9fb

Please sign in to comment.