Skip to content

Commit a9b2a3c

Browse files
authored
Merge pull request #949 from ensdomains/fix-safe
Fix safe
2 parents 7f83628 + 4abf749 commit a9b2a3c

15 files changed

Lines changed: 139 additions & 87 deletions

File tree

next.config.mjs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,40 @@ const nextConfig = {
4343
images: {
4444
domains: ['metadata.ens.domains'],
4545
},
46+
async headers() {
47+
// keep this in case we need to debug Safe in the future
48+
if (process.env.NODE_ENV === 'development') {
49+
return [
50+
{
51+
source: '/manifest.json',
52+
headers: [
53+
{
54+
key: 'Access-Control-Allow-Origin',
55+
value: '*',
56+
},
57+
{
58+
key: 'Access-Control-Allow-Methods',
59+
value: 'GET, OPTIONS',
60+
},
61+
{
62+
key: 'Access-Control-Allow-Headers',
63+
value: 'X-Requested-With, content-type, Authorization',
64+
},
65+
],
66+
},
67+
{
68+
source: '/(.*)',
69+
headers: [
70+
{
71+
key: 'Content-Security-Policy',
72+
value: "frame-ancestors 'self' https://app.safe.global;",
73+
},
74+
],
75+
},
76+
]
77+
}
78+
return []
79+
},
4680
async rewrites() {
4781
return [
4882
{

public/manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
],
1616
"theme_color": "#5298FF",
1717
"background_color": "#F6F6F6",
18-
"display": "standalone"
18+
"display": "standalone",
19+
"description": "Decentralised naming for wallets, websites, & more"
1920
}
Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,37 @@
1-
import { describe, it, expect } from 'vitest'
21
import { render, screen } from '@testing-library/react'
3-
import { TextWithTooltip } from './TextWithTooltip'
42
import { userEvent } from '@testing-library/user-event'
53
import { ThemeProvider } from 'styled-components'
4+
import { describe, expect, it } from 'vitest'
5+
66
import { lightTheme } from '@ensdomains/thorin'
77

8+
import { TextWithTooltip } from './TextWithTooltip'
9+
810
const renderWithTheme = (component: React.ReactNode) => {
9-
return render(
10-
<ThemeProvider theme={lightTheme}>
11-
{component}
12-
</ThemeProvider>
13-
)
11+
return render(<ThemeProvider theme={lightTheme}>{component}</ThemeProvider>)
1412
}
1513

1614
describe('TextWithTooltip', () => {
1715
it('should render children and show tooltip on hover', async () => {
18-
renderWithTheme(
19-
<TextWithTooltip tooltipContent="This is a tooltip">
20-
Hover me
21-
</TextWithTooltip>
22-
)
23-
16+
renderWithTheme(<TextWithTooltip tooltipContent="This is a tooltip">Hover me</TextWithTooltip>)
17+
2418
const button = screen.getByText('Hover me')
2519
expect(button).toBeInTheDocument()
26-
20+
2721
await userEvent.hover(button)
2822
expect(screen.getByText('This is a tooltip')).toBeInTheDocument()
2923
})
3024

3125
it('should render learn more link when link prop is provided', async () => {
3226
renderWithTheme(
33-
<TextWithTooltip
34-
tooltipContent="Tooltip with link"
35-
link="https://example.com"
36-
>
27+
<TextWithTooltip tooltipContent="Tooltip with link" link="https://example.com">
3728
With link
38-
</TextWithTooltip>
29+
</TextWithTooltip>,
3930
)
40-
31+
4132
const button = screen.getByText('With link')
4233
await userEvent.hover(button)
43-
34+
4435
const learnMoreLink = screen.getByText('action.learnMore')
4536
expect(learnMoreLink).toBeInTheDocument()
4637
expect(learnMoreLink.closest('a')).toHaveAttribute('href', 'https://example.com')
@@ -50,14 +41,12 @@ describe('TextWithTooltip', () => {
5041

5142
it('should not render learn more link when link prop is not provided', async () => {
5243
renderWithTheme(
53-
<TextWithTooltip tooltipContent="Tooltip without link">
54-
No link
55-
</TextWithTooltip>
44+
<TextWithTooltip tooltipContent="Tooltip without link">No link</TextWithTooltip>,
5645
)
57-
46+
5847
const button = screen.getByText('No link')
5948
await userEvent.hover(button)
60-
49+
6150
expect(screen.queryByText('action.learnMore')).not.toBeInTheDocument()
6251
})
6352
})

src/components/@molecules/DateSelection/DateSelection.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Typography } from '@ensdomains/thorin'
77
import { Calendar } from '@app/components/@atoms/Calendar/Calendar'
88
import { PlusMinusControl } from '@app/components/@atoms/PlusMinusControl/PlusMinusControl'
99
import { roundDurationWithDay, secondsFromDateDiff } from '@app/utils/date'
10+
import { isInsideSafe } from '@app/utils/safe'
1011
import { formatDurationOfDates, secondsToYears } from '@app/utils/utils'
1112

1213
const YearsViewSwitch = styled.button(
@@ -73,9 +74,11 @@ export const DateSelection = ({
7374
// eslint-disable-next-line react-hooks/exhaustive-deps
7475
}, [dateInYears, durationType])
7576

77+
const isSafeApp = isInsideSafe()
78+
7679
return (
7780
<Container>
78-
{durationType === 'date' ? (
81+
{durationType === 'date' && !isSafeApp ? (
7982
<Calendar
8083
value={currentTime + seconds}
8184
onChange={(e) => {
@@ -113,13 +116,15 @@ export const DateSelection = ({
113116
postFix: mode === 'register' ? ' registration. ' : ' extension. ',
114117
t,
115118
})}
116-
<YearsViewSwitch
117-
type="button"
118-
data-testid="date-selection"
119-
onClick={() => onChangeDurationType?.(durationType === 'years' ? 'date' : 'years')}
120-
>
121-
{t(`calendar.pick_by_${durationType === 'date' ? 'years' : 'date'}`, { ns: 'common' })}
122-
</YearsViewSwitch>
119+
{!isSafeApp && (
120+
<YearsViewSwitch
121+
type="button"
122+
data-testid="date-selection"
123+
onClick={() => onChangeDurationType?.(durationType === 'years' ? 'date' : 'years')}
124+
>
125+
{t(`calendar.pick_by_${durationType === 'date' ? 'years' : 'date'}`, { ns: 'common' })}
126+
</YearsViewSwitch>
127+
)}
123128
</Typography>
124129
</Container>
125130
)

src/components/@molecules/NetworkNotifications/NetworkNotifications.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('NetworkNotifications', () => {
2626
it('should show notification if shouldOpenModal sets true', () => {
2727
vi.mocked(shouldOpenModal).mockReturnValue(true)
2828
mockUseAccount.mockReturnValue({
29-
chainId: 1
29+
chainId: 1,
3030
})
3131
mockUseChainId.mockReturnValue(1)
3232
render(<NetworkNotifications />)
@@ -36,7 +36,7 @@ describe('NetworkNotifications', () => {
3636
it('should not show notification if shouldOpenModal sets false', () => {
3737
vi.mocked(shouldOpenModal).mockReturnValue(false)
3838
mockUseAccount.mockReturnValue({
39-
chainId: 1
39+
chainId: 1,
4040
})
4141
mockUseChainId.mockReturnValue(1)
4242

src/components/@molecules/NetworkNotifications/utils.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
2-
import { shouldOpenModal } from './utils'
1+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2+
33
import * as chains from '@app/constants/chains'
44

5+
import { shouldOpenModal } from './utils'
6+
57
describe('shouldOpenModal', () => {
68
beforeEach(() => {
79
vi.resetModules()

src/components/@molecules/ProfileEditor/Avatar/AvatarNFT.test.tsx

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
import { fireEvent, mockFunction, render, screen, userEvent, waitFor } from '@app/test-utils'
33

44
import * as ReactQuery from '@tanstack/react-query'
5+
import React from 'react'
56
import { beforeEach, describe, expect, it, Mock, vi } from 'vitest'
67
import { useAccount, useClient } from 'wagmi'
78

8-
99
import * as UseInfiniteQuery from '@app/utils/query/useInfiniteQuery'
1010

1111
import { makeMockIntersectionObserver } from '../../../../../test/mock/makeMockIntersectionObserver'
1212
import { AvatarNFT } from './AvatarNFT'
13-
import React from 'react'
1413

1514
vi.mock('wagmi')
1615
vi.mock('@app/hooks/chain/useCurrentBlockTimestamp', () => ({
@@ -20,8 +19,6 @@ vi.mock('@app/hooks/chain/useChainName', () => ({
2019
useChainName: () => 'mainnet',
2120
}))
2221

23-
24-
2522
const mockUseClient = mockFunction(useClient)
2623
const mockUseAccount = mockFunction(useAccount)
2724

@@ -197,7 +194,6 @@ describe('<AvatarNFT />', () => {
197194
it('show load more data on page load trigger', async () => {
198195
const useInfiniteQuerySpy = vi.spyOn(UseInfiniteQuery, 'useInfiniteQuery')
199196

200-
201197
mockFetch
202198
.mockImplementationOnce(() =>
203199
Promise.resolve({
@@ -214,15 +210,19 @@ describe('<AvatarNFT />', () => {
214210
}),
215211
)
216212
vi.mock('@ensdomains/thorin', async (importActual) => ({
217-
...(await importActual() as any),
218-
ScrollBox: () => ({ children, onReachedBottom }: React.PropsWithChildren<{
219-
onReachedBottom?: () => void;
220-
}>) => {
221-
onReachedBottom!()
222-
return <div>{children}</div>
223-
},
213+
...((await importActual()) as any),
214+
ScrollBox:
215+
() =>
216+
({
217+
children,
218+
onReachedBottom,
219+
}: React.PropsWithChildren<{
220+
onReachedBottom?: () => void
221+
}>) => {
222+
onReachedBottom!()
223+
return <div>{children}</div>
224+
},
224225
}))
225-
226226

227227
render(<AvatarNFT {...props} />)
228228
await waitFor(() => expect(mockFetch).toHaveBeenCalled())
@@ -255,13 +255,18 @@ describe('<AvatarNFT />', () => {
255255
)
256256

257257
vi.mock('@ensdomains/thorin', async (importActual) => ({
258-
...(await importActual() as any),
259-
ScrollBox: () => ({ children, onReachedBottom }: React.PropsWithChildren<{
260-
onReachedBottom?: () => void;
261-
}>) => {
262-
onReachedBottom!()
263-
return <div>{children}</div>
264-
},
258+
...((await importActual()) as any),
259+
ScrollBox:
260+
() =>
261+
({
262+
children,
263+
onReachedBottom,
264+
}: React.PropsWithChildren<{
265+
onReachedBottom?: () => void
266+
}>) => {
267+
onReachedBottom!()
268+
return <div>{children}</div>
269+
},
265270
}))
266271

267272
render(<AvatarNFT {...props} />)

src/components/@molecules/TransactionDialogManager/stage/TransactionStageModal.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ describe('TransactionStageModal', () => {
230230
)
231231
expect(screen.getByTestId('transaction-modal-confirm-button')).toBeDisabled()
232232
await waitFor(() =>
233-
expect(screen.getByTestId('transaction-modal-confirm-button')).toBeEnabled()
233+
expect(screen.getByTestId('transaction-modal-confirm-button')).toBeEnabled(),
234234
)
235235
expect(mockEstimateGas).toHaveBeenCalledTimes(1)
236236
})

src/components/pages/import/[name]/steps/SelectImportType.test.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { useAccount } from 'wagmi'
1010
import { lightTheme } from '@ensdomains/thorin'
1111

1212
import { useDnsOffchainStatus } from '@app/hooks/dns/useDnsOffchainStatus'
13-
import { useUnmanagedTLD } from '@app/hooks/useUnmanagedTLD'
1413
import { useResolver } from '@app/hooks/ensjs/public/useResolver'
14+
import { useUnmanagedTLD } from '@app/hooks/useUnmanagedTLD'
1515
import i18n from '@app/i18n'
1616

1717
import { calculateDnsSteps, SelectImportType } from './SelectImportType'
@@ -208,7 +208,11 @@ describe('SelectImportType component', () => {
208208
</ThemeProvider>
209209
</QueryClientProvider>,
210210
)
211-
expect(screen.getByText("The team behind .club have customized their ENS experience, so we're unable to help you import the name at this time")).toBeInTheDocument()
211+
expect(
212+
screen.getByText(
213+
"The team behind .club have customized their ENS experience, so we're unable to help you import the name at this time",
214+
),
215+
).toBeInTheDocument()
212216
})
213217

214218
it('should show customized TLD message for TLDs not managed by DNSRegistrar', () => {
@@ -230,7 +234,11 @@ describe('SelectImportType component', () => {
230234
</ThemeProvider>
231235
</QueryClientProvider>,
232236
)
233-
expect(screen.getByText("The team behind .xyz have customized their ENS experience, so we're unable to help you import the name at this time")).toBeInTheDocument()
237+
expect(
238+
screen.getByText(
239+
"The team behind .xyz have customized their ENS experience, so we're unable to help you import the name at this time",
240+
),
241+
).toBeInTheDocument()
234242
})
235243

236244
it('should show normal import options for managed TLDs', () => {

src/hooks/abilities/useAbilities.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { mockFunction, renderHook } from '@app/test-utils'
22

3+
import { dequal } from 'dequal'
34
import { match, P } from 'ts-pattern'
45
import { Address } from 'viem'
56
// import { writeFileSync} from 'fs'
@@ -20,7 +21,6 @@ import { useBasicName } from '../useBasicName'
2021
import { useHasSubnames } from '../useHasSubnames'
2122
import { useParentBasicName } from '../useParentBasicName'
2223
import { useAbilities } from './useAbilities'
23-
import { dequal } from 'dequal'
2424

2525
vi.mock('@app/hooks/account/useAccountSafely')
2626
vi.mock('@app/hooks/useBasicName')

0 commit comments

Comments
 (0)