Skip to content

Commit

Permalink
fix: demo social not redirecting to account view (#3809)
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvoskamp authored Feb 6, 2025
1 parent 4f4f48b commit d6ae370
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 2 deletions.
3 changes: 3 additions & 0 deletions packages/appkit/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,9 @@ export class AppKit {

public setUser: (typeof AccountController)['setUser'] = user => {
AccountController.setUser(user)
if (OptionsController.state.enableEmbedded) {
ModalController.close()
}
}

public resetAccount: (typeof AccountController)['resetAccount'] = (chain: ChainNamespace) => {
Expand Down
5 changes: 4 additions & 1 deletion packages/scaffold-ui/src/partials/w3m-header/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ export class W3mHeader extends LitElement {
this.onHistoryChange()
}),
ConnectionController.subscribeKey('buffering', val => (this.buffering = val)),
ChainController.subscribeKey('activeCaipNetwork', val => (this.network = val))
ChainController.subscribeKey('activeCaipNetwork', val => {
this.network = val
this.networkImage = AssetUtil.getNetworkImage(this.network)
})
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ConnectorController,
EventsController,
ModalController,
OptionsController,
RouterController,
SnackController,
StorageUtil,
Expand Down Expand Up @@ -52,7 +53,7 @@ export class W3mConnectingSocialView extends LitElement {
this.socialWindow = val.socialWindow
}
if (val.address) {
if (ModalController.state.open) {
if (ModalController.state.open || OptionsController.state.enableEmbedded) {
ModalController.close()
}
}
Expand Down
233 changes: 233 additions & 0 deletions packages/scaffold-ui/test/partials/w3m-header.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import { elementUpdated, fixture } from '@open-wc/testing'
import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'

import { html } from 'lit'

import type { CaipNetwork } from '@reown/appkit-common'
import {
AssetController,
AssetUtil,
ChainController,
EventsController,
ModalController,
OptionsController,
RouterController,
SIWXUtil
} from '@reown/appkit-core'

import { W3mHeader } from '../../src/partials/w3m-header'
import { HelpersUtil } from '../utils/HelpersUtil'

describe('W3mHeader', () => {
let element: W3mHeader

beforeAll(() => {
Element.prototype.animate = vi.fn().mockReturnValue({ finished: Promise.resolve() })
})

beforeEach(async () => {
vi.clearAllMocks()
RouterController.reset('Connect')
element = await fixture(html`<w3m-header></w3m-header>`)
await element.updateComplete
})

describe('Network Selection', () => {
const mockNetwork = {
id: '1',
name: 'Test Network',
chainNamespace: 'eip155',
caipNetworkId: 'eip155:1',
nativeCurrency: { name: 'Test', symbol: 'TEST', decimals: 18 },
rpcUrls: { default: { http: ['https://test.com'] } }
} as unknown as CaipNetwork

it('should render network select in Account view', async () => {
RouterController.state.view = 'Account'
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const networkSelect = HelpersUtil.getByTestId(element, 'w3m-account-select-network')
expect(networkSelect).toBeTruthy()
})

it('should update network image when network changes', async () => {
RouterController.state.view = 'Account'
element.requestUpdate()
await element.updateComplete

const getNetworkImageSpy = vi.spyOn(AssetUtil, 'getNetworkImage')
ChainController.setActiveCaipNetwork(mockNetwork)
await elementUpdated(element)

const networkSelect = HelpersUtil.getByTestId(element, 'w3m-account-select-network')
expect(networkSelect?.getAttribute('active-network')).toBe('Test Network')
expect(getNetworkImageSpy).toHaveBeenCalledWith(mockNetwork)
})

it('should update network image when AssetController emits new images', async () => {
RouterController.state.view = 'Account'
element.requestUpdate()
await element.updateComplete

let subscriberCallback: Function | undefined
vi.spyOn(AssetController, 'subscribeNetworkImages').mockImplementation(callback => {
subscriberCallback = callback
return () => undefined
})

element = await fixture(html`<w3m-header></w3m-header>`)
await element.updateComplete

ChainController.setActiveCaipNetwork(mockNetwork)
await elementUpdated(element)

const getNetworkImageSpy = vi.spyOn(AssetUtil, 'getNetworkImage')

// Simulate AssetController emitting new network images
if (subscriberCallback) {
subscriberCallback()
}

expect(getNetworkImageSpy).toHaveBeenCalledWith(mockNetwork)
})
})

describe('Back Button', () => {
it('should show back button when history length > 1', async () => {
RouterController.push('Networks')
await element.updateComplete
await elementUpdated(element)

const backButton = HelpersUtil.getByTestId(element, 'header-back')
expect(backButton).toBeTruthy()
})

it('should not show back button in ApproveTransaction view', async () => {
RouterController.state.view = 'ApproveTransaction'
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const backButton = HelpersUtil.getByTestId(element, 'header-back')
expect(backButton).toBeFalsy()
})

it('should call RouterController.goBack when back button is clicked', async () => {
const goBackSpy = vi.spyOn(RouterController, 'goBack')
RouterController.push('Networks')
await element.updateComplete
await elementUpdated(element)

const backButton = HelpersUtil.getByTestId(element, 'header-back')
backButton?.click()

expect(goBackSpy).toHaveBeenCalled()
})
})

describe('Close Button', () => {
it('should render close button', async () => {
const closeButton = HelpersUtil.getByTestId(element, 'w3m-header-close')
expect(closeButton).toBeTruthy()
})

it('should call ModalController.close when close button is clicked', async () => {
const closeSpy = vi.spyOn(ModalController, 'close')
vi.spyOn(SIWXUtil, 'isSIWXCloseDisabled').mockResolvedValue(false)

const closeButton = HelpersUtil.getByTestId(element, 'w3m-header-close')
await closeButton?.click()

expect(closeSpy).toHaveBeenCalled()
})

it('should shake modal when trying to close in UnsupportedChain view', async () => {
const shakeSpy = vi.spyOn(ModalController, 'shake')
RouterController.state.view = 'UnsupportedChain'
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const closeButton = HelpersUtil.getByTestId(element, 'w3m-header-close')
await closeButton?.click()

expect(shakeSpy).toHaveBeenCalled()
})
})

describe('Smart Sessions', () => {
it('should show smart sessions button in Account view when enabled', async () => {
RouterController.state.view = 'Account'
OptionsController.state.features = { smartSessions: true }
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const smartSessionsButton = HelpersUtil.getByTestId(element, 'w3m-header-smart-sessions')
expect(smartSessionsButton).toBeTruthy()
})

it('should not show smart sessions button when disabled', async () => {
RouterController.state.view = 'Account'
OptionsController.state.features = { smartSessions: false }
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const smartSessionsButton = HelpersUtil.getByTestId(element, 'w3m-header-smart-sessions')
expect(smartSessionsButton).toBeFalsy()
})

it('should navigate to SmartSessionList when smart sessions button is clicked', async () => {
RouterController.state.view = 'Account'
OptionsController.state.features = { smartSessions: true }
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const smartSessionsButton = HelpersUtil.getByTestId(element, 'w3m-header-smart-sessions')
smartSessionsButton?.dispatchEvent(new Event('click'))

expect(RouterController.state.view).toBe('SmartSessionList')
})
})

describe('Help Button', () => {
it('should show help button in Connect view', async () => {
RouterController.state.view = 'Connect'
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const helpButton = element.shadowRoot?.querySelector('wui-icon-link[icon="helpCircle"]')
expect(helpButton).toBeTruthy()
})

it('should navigate to WhatIsAWallet when help button is clicked', async () => {
RouterController.state.view = 'Connect'
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const helpButton = element.shadowRoot?.querySelector('wui-icon-link[icon="helpCircle"]')
helpButton?.dispatchEvent(new Event('click'))

expect(RouterController.state.view).toBe('WhatIsAWallet')
})

it('should track help button click event', async () => {
const trackSpy = vi.spyOn(EventsController, 'sendEvent')
RouterController.state.view = 'Connect'
element.requestUpdate()
await element.updateComplete
await elementUpdated(element)

const helpButton = element.shadowRoot?.querySelector('wui-icon-link[icon="helpCircle"]')
helpButton?.dispatchEvent(new Event('click'))

expect(trackSpy).toHaveBeenCalledWith({ type: 'track', event: 'CLICK_WALLET_HELP' })
})
})
})
74 changes: 74 additions & 0 deletions packages/scaffold-ui/test/views/w3m-connecting-social-view.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
ChainController,
ConnectionController,
ConnectorController,
ModalController,
OptionsController,
RouterController
} from '@reown/appkit-core'

Expand Down Expand Up @@ -54,3 +56,75 @@ describe('W3mConnectingSocialView - disconnectedCallback', () => {
expect(setSocialWindowSpy).toHaveBeenCalledWith(undefined, 'eip155')
})
})

describe('W3mConnectingSocialView - Embedded Modal Behavior', () => {
it('should close modal when address is set and enableEmbedded is true', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
} as unknown as Window

let subscriptionCallback: ((val: any) => void) | undefined

vi.spyOn(ModalController, 'close').mockImplementation(() => {})
vi.spyOn(OptionsController, 'state', 'get').mockReturnValueOnce({
...OptionsController.state,
enableEmbedded: true
})
vi.spyOn(AccountController, 'state', 'get').mockReturnValueOnce({
...AccountController.state,
socialWindow: mockSocialWindow
})
vi.spyOn(ModalController, 'state', 'get').mockReturnValueOnce({
...ModalController.state,
open: true
})
vi.spyOn(AccountController, 'subscribe').mockImplementationOnce(callback => {
subscriptionCallback = callback
return () => {}
})

await fixture(html`<w3m-connecting-social-view></w3m-connecting-social-view>`)

if (subscriptionCallback) {
subscriptionCallback({ address: '0x123' })
}

expect(ModalController.close).toHaveBeenCalled()
})

it('should not close modal when address is set but enableEmbedded is false', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
} as unknown as Window

let subscriptionCallback: ((val: any) => void) | undefined

vi.spyOn(ModalController, 'close').mockImplementationOnce(() => {})
vi.spyOn(OptionsController, 'state', 'get').mockReturnValueOnce({
...OptionsController.state,
enableEmbedded: false
})
vi.spyOn(AccountController, 'state', 'get').mockReturnValueOnce({
...AccountController.state,
socialWindow: mockSocialWindow
})
vi.spyOn(ModalController, 'state', 'get').mockReturnValueOnce({
...ModalController.state,
open: false
})
vi.spyOn(AccountController, 'subscribe').mockImplementationOnce(callback => {
subscriptionCallback = callback
return () => {}
})

await fixture(html`<w3m-connecting-social-view></w3m-connecting-social-view>`)

if (subscriptionCallback) {
subscriptionCallback({ address: '0x123' })
}

expect(ModalController.close).not.toHaveBeenCalled()
})
})

0 comments on commit d6ae370

Please sign in to comment.