@reown/appkit-scaffold-ui
Version:
The full stack toolkit to build onchain app UX.
341 lines • 15.5 kB
JavaScript
import { fixture } from '@open-wc/testing';
import { beforeAll, describe, expect, it, vi } from 'vitest';
import { html } from 'lit';
import { ChainController, ConnectionController, ConnectorController, EventsController, ModalController, OptionsController, RouterController, SnackController } from '@reown/appkit-controllers';
import { W3mConnectingSocialView } from '../../src/views/w3m-connecting-social-view';
describe('W3mConnectingSocialView - disconnectedCallback', () => {
it('should call socialWindow.close when component unmounts', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
const mockAuthConnector = {
provider: {
connectSocial: vi.fn()
}
};
vi.spyOn(ConnectionController, 'connectExternal').mockImplementation(() => Promise.resolve(undefined));
vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue(mockAuthConnector);
vi.spyOn(ChainController, 'getAccountData').mockReturnValue({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow
});
vi.spyOn(RouterController, 'state', 'get').mockReturnValue({
...RouterController.state,
view: 'ConnectingSocial'
});
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
const setSocialWindowSpy = vi.spyOn(ChainController, 'setAccountProp');
const element = await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
element.disconnectedCallback();
expect(mockSocialWindow.close).toHaveBeenCalled();
expect(setSocialWindowSpy).toHaveBeenCalledWith('socialWindow', undefined, 'eip155');
});
});
describe('W3mConnectingSocialView - Error Handling', () => {
it('should handle error in resultUri and call handleSocialError', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
const mockAuthConnector = {
id: 'auth',
type: 'AUTH',
chain: 'eip155'
};
vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue(mockAuthConnector);
vi.spyOn(ChainController, 'getAccountData').mockReturnValue({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow,
socialProvider: 'discord'
});
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
const sendEventSpy = vi.spyOn(EventsController, 'sendEvent');
const setAccountPropSpy = vi.spyOn(ChainController, 'setAccountProp');
const element = await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
const mockEvent = new MessageEvent('message', {
data: {
resultUri: 'https://secure.walletconnect.org/social?error=access_denied'
},
origin: 'https://secure.walletconnect.org'
});
window.dispatchEvent(mockEvent);
await new Promise(resolve => setTimeout(resolve, 100));
expect(sendEventSpy).toHaveBeenCalledWith({
type: 'track',
event: 'SOCIAL_LOGIN_ERROR',
properties: { provider: 'discord', message: 'access_denied' }
});
expect(mockSocialWindow.close).toHaveBeenCalled();
expect(setAccountPropSpy).toHaveBeenCalledWith('socialWindow', undefined, 'eip155');
expect(element['error']).toBe(true);
expect(element['message']).toBe('Something went wrong');
});
it('should handle connection error and send SOCIAL_LOGIN_ERROR event', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
const mockAuthConnector = {
id: 'auth',
type: 'AUTH',
chain: 'eip155'
};
const connectionError = new Error('Connection failed');
vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue(mockAuthConnector);
vi.spyOn(ChainController, 'getAccountData').mockReturnValue({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow,
socialProvider: 'google'
});
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
vi.spyOn(ConnectionController, 'connectExternal').mockRejectedValue(connectionError);
const sendEventSpy = vi.spyOn(EventsController, 'sendEvent');
const element = await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
const mockEvent = new MessageEvent('message', {
data: {
resultUri: 'https://secure.walletconnect.org/social?code=123'
},
origin: 'https://secure.walletconnect.org'
});
window.dispatchEvent(mockEvent);
await new Promise(resolve => setTimeout(resolve, 100));
expect(sendEventSpy).toHaveBeenCalledWith({
type: 'track',
event: 'SOCIAL_LOGIN_ERROR',
properties: { provider: 'google', message: 'Connection failed' }
});
expect(element['error']).toBe(true);
expect(element['message']).toBe('Something went wrong');
});
it('should handle untrusted origin and show error', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
const mockAuthConnector = {
id: 'auth',
type: 'AUTH',
chain: 'eip155'
};
vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue(mockAuthConnector);
vi.spyOn(ChainController, 'getAccountData').mockReturnValue({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow,
socialProvider: 'x'
});
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
const sendEventSpy = vi.spyOn(EventsController, 'sendEvent');
const goBackSpy = vi.spyOn(RouterController, 'goBack').mockImplementation(() => { });
const showErrorSpy = vi.spyOn(SnackController, 'showError').mockImplementation(() => { });
await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
const mockEvent = new MessageEvent('message', {
data: {
resultUri: 'https://secure.walletconnect.org/social?code=123'
},
origin: 'https://malicious-site.com'
});
window.dispatchEvent(mockEvent);
await new Promise(resolve => setTimeout(resolve, 100));
expect(goBackSpy).toHaveBeenCalled();
expect(showErrorSpy).toHaveBeenCalledWith('Untrusted Origin');
expect(sendEventSpy).toHaveBeenCalledWith({
type: 'track',
event: 'SOCIAL_LOGIN_ERROR',
properties: { provider: 'x', message: 'Untrusted Origin' }
});
});
it('should parse error from URL correctly', async () => {
const mockAuthConnector = {
id: 'auth',
type: 'AUTH',
chain: 'eip155'
};
vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue(mockAuthConnector);
vi.spyOn(ChainController, 'getAccountData').mockReturnValue({
...ChainController.getAccountData()
});
const element = await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
const errorUrl1 = 'https://secure.walletconnect.org/social?error=access_denied';
const errorUrl2 = 'https://secure.walletconnect.org/social?code=123&error=server_error';
const validUrl = 'https://secure.walletconnect.org/social?code=123';
const invalidUrl = 'not-a-url';
expect(element['parseURLError'](errorUrl1)).toBe('access_denied');
expect(element['parseURLError'](errorUrl2)).toBe('server_error');
expect(element['parseURLError'](validUrl)).toBe(null);
expect(element['parseURLError'](invalidUrl)).toBe(null);
});
it('should close social window when closeSocialWindow is called', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
const mockAuthConnector = {
id: 'auth',
type: 'AUTH',
chain: 'eip155'
};
vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue(mockAuthConnector);
vi.spyOn(ChainController, 'getAccountData').mockReturnValue({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow
});
vi.spyOn(ChainController, 'state', 'get').mockReturnValue({
...ChainController.state,
activeChain: 'eip155'
});
const setAccountPropSpy = vi.spyOn(ChainController, 'setAccountProp');
const element = await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
element['closeSocialWindow']();
expect(mockSocialWindow.close).toHaveBeenCalled();
expect(setAccountPropSpy).toHaveBeenCalledWith('socialWindow', undefined, 'eip155');
});
it('should not throw when closeSocialWindow is called without window', async () => {
const mockAuthConnector = {
id: 'auth',
type: 'AUTH',
chain: 'eip155'
};
vi.spyOn(ConnectorController, 'getAuthConnector').mockReturnValue(mockAuthConnector);
vi.spyOn(ChainController, 'getAccountData').mockReturnValue({
...ChainController.getAccountData(),
socialWindow: undefined
});
const element = await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
expect(() => element['closeSocialWindow']()).not.toThrow();
});
});
describe('W3mConnectingSocialView - Embedded Modal Behavior', () => {
beforeAll(() => {
ConnectionController.state.connections = ConnectionController.state.connections;
});
it('closes the modal if no connections exist, an address is set and embedded mode is enabled', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
let subscriptionCallback;
vi.spyOn(ModalController, 'close').mockImplementation(() => { });
vi.spyOn(RouterController, 'reset').mockImplementation(() => { });
vi.spyOn(RouterController, 'push').mockImplementation(() => { });
vi.spyOn(RouterController, 'replace').mockImplementation(() => { });
vi.spyOn(OptionsController, 'state', 'get').mockReturnValueOnce({
...OptionsController.state,
enableEmbedded: true
});
vi.spyOn(ChainController, 'getAccountData').mockReturnValueOnce({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow
});
vi.spyOn(ModalController, 'state', 'get').mockReturnValueOnce({
...ModalController.state,
open: true
});
vi.spyOn(ChainController, 'subscribe').mockImplementationOnce(() => {
return () => { };
});
vi.spyOn(ChainController, 'subscribeChainProp').mockImplementationOnce((_property, callback) => {
subscriptionCallback = callback;
return () => { };
});
await fixture(html `<w3m-connecting-social-view></w3m-connecting-social-view>`);
if (subscriptionCallback) {
subscriptionCallback({ address: '0x123' });
}
expect(ModalController.close).toHaveBeenCalled();
expect(RouterController.reset).not.toHaveBeenCalled();
expect(RouterController.push).not.toHaveBeenCalled();
});
it('redirects to the profile wallets page if connections exist, address is set and multiWallet is enabled', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
const mockConnections = new Map([
[
'eip155',
[
{
connectorId: 'auth'
}
]
]
]);
vi.spyOn(OptionsController, 'state', 'get').mockReturnValueOnce({
...OptionsController.state,
remoteFeatures: { multiWallet: true }
});
let subscriptionCallback;
ConnectionController.state.connections = mockConnections;
vi.spyOn(RouterController, 'reset').mockImplementation(() => { });
vi.spyOn(RouterController, 'push').mockImplementation(() => { });
vi.spyOn(ModalController, 'close').mockImplementation(() => { });
vi.spyOn(OptionsController, 'state', 'get').mockReturnValueOnce({
...OptionsController.state,
enableEmbedded: true
});
vi.spyOn(ChainController, 'getAccountData').mockReturnValueOnce({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow
});
vi.spyOn(ModalController, 'state', 'get').mockReturnValueOnce({
...ModalController.state,
open: true
});
vi.spyOn(ChainController, 'subscribe').mockImplementationOnce(() => {
return () => { };
});
vi.spyOn(ChainController, 'subscribeChainProp').mockImplementationOnce((_property, 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();
expect(RouterController.replace).toHaveBeenCalledWith('ProfileWallets');
});
it('should not close modal when address is set but enableEmbedded is false', async () => {
const mockSocialWindow = {
close: vi.fn(),
closed: false
};
let subscriptionCallback;
vi.spyOn(ModalController, 'close').mockImplementationOnce(() => { });
vi.spyOn(OptionsController, 'state', 'get').mockReturnValueOnce({
...OptionsController.state,
enableEmbedded: false
});
vi.spyOn(ChainController, 'getAccountData').mockReturnValueOnce({
...ChainController.getAccountData(),
socialWindow: mockSocialWindow
});
vi.spyOn(ModalController, 'state', 'get').mockReturnValueOnce({
...ModalController.state,
open: false
});
vi.spyOn(ChainController, '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();
});
});
//# sourceMappingURL=w3m-connecting-social-view.test.js.map