diff --git a/src/signer.spec.ts b/src/signer.spec.ts index 3c855de7..619df53e 100644 --- a/src/signer.spec.ts +++ b/src/signer.spec.ts @@ -1,4 +1,5 @@ import {type MockInstance} from 'vitest'; +import * as signerHandlers from './handlers/signer.handlers'; import {Signer, type SignerParameters} from './signer'; import {ICRC29_STATUS} from './types/icrc'; import {JSON_RPC_VERSION_2} from './types/rpc'; @@ -69,12 +70,14 @@ describe('Signer', () => { let originalOpener: typeof window.opener; + let notifyReadySpy: MockInstance; let signer: Signer; let postMessageMock: MockInstance; beforeEach(() => { signer = Signer.init(mockParameters); + notifyReadySpy = vi.spyOn(signerHandlers, 'notifyReady'); postMessageMock = vi.fn(); vi.stubGlobal('opener', {postMessage: postMessageMock}); }); @@ -88,7 +91,25 @@ describe('Signer', () => { vi.restoreAllMocks(); }); - // TODO: it('should use the origin and respond with a post message', () => void) -> this can be assert with the first message, READY + it('should use the origin and respond with a post message', () => { + const testOrigin = 'https://hello.com'; + + const messageEvent = new MessageEvent('message', { + data: { + id: testId, + jsonrpc: JSON_RPC_VERSION_2, + method: ICRC29_STATUS + }, + origin: testOrigin + }); + + window.dispatchEvent(messageEvent); + + expect(notifyReadySpy).toHaveBeenCalledWith({ + id: testId, + origin: testOrigin + }); + }); it('should notify an error if a message from different origin is dispatched', () => { const testOrigin = 'https://hello.com'; @@ -147,4 +168,56 @@ describe('Signer', () => { }).not.toThrow(); }); }); + + describe('READY postMessage', () => { + const testId = 'test-123'; + + let originalOpener: typeof window.opener; + + let signer: Signer; + + let postMessageMock: MockInstance; + + beforeEach(() => { + signer = Signer.init(mockParameters); + + postMessageMock = vi.fn(); + + vi.stubGlobal('opener', {postMessage: postMessageMock}); + }); + + afterEach(() => { + signer.disconnect(); + + window.opener = originalOpener; + + vi.clearAllMocks(); + vi.restoreAllMocks(); + }); + + it('should notify READY', () => { + const testOrigin = 'https://hello.com'; + + const msg = { + data: { + id: testId, + jsonrpc: JSON_RPC_VERSION_2, + method: ICRC29_STATUS + }, + origin: testOrigin + }; + + const messageEvent = new MessageEvent('message', msg); + window.dispatchEvent(messageEvent); + + expect(postMessageMock).toHaveBeenCalledWith( + { + jsonrpc: JSON_RPC_VERSION_2, + id: testId, + result: 'ready' + }, + testOrigin + ); + }); + }); }); diff --git a/src/signer.ts b/src/signer.ts index af47a9df..d646fd5b 100644 --- a/src/signer.ts +++ b/src/signer.ts @@ -1,7 +1,8 @@ import {nonNullish} from '@dfinity/utils'; import {SignerErrorCode} from './constants/signer.constants'; -import {notifyError} from './handlers/signer.handlers'; +import {notifyError, notifyReady} from './handlers/signer.handlers'; import { + IcrcWalletStatusRequest, type IcrcWalletPermissionsRequestType, type IcrcWalletRequestPermissionsRequestType, type IcrcWalletSupportedStandardsRequestType @@ -63,6 +64,13 @@ export class Signer { // TODO: assert messages to notify error if methods are not supported. this.assertAndSetOrigin({msgData, origin}); + + const {success: isStatusRequest, data} = IcrcWalletStatusRequest.safeParse(msgData); + + if (isStatusRequest) { + const {id} = data; + notifyReady({id, origin}); + } }; private assertAndSetOrigin({