UNPKG

@sanity/sdk

Version:
107 lines (85 loc) 3.42 kB
import * as comlink from '@sanity/comlink' import {type Node} from '@sanity/comlink' import {beforeEach, describe, expect, it, vi} from 'vitest' import {createSanityInstance} from '../../../store/createSanityInstance' import {createStoreState} from '../../../store/createStoreState' import {type FrameMessage, type WindowMessage} from '../../types' import {type ComlinkNodeState} from '../comlinkNodeStore' import {getOrCreateNode} from './getOrCreateNode' vi.mock('@sanity/comlink', () => ({ createNode: vi.fn(() => ({ start: vi.fn(), stop: vi.fn(), onStatus: vi.fn(), })), })) const nodeConfig = { name: 'test-node', connectTo: 'parent', } describe('getOrCreateNode', () => { const instance = createSanityInstance({ projectId: 'test-project-id', dataset: 'test-dataset', }) let state: ReturnType<typeof createStoreState<ComlinkNodeState>> let mockNode: Partial<Node<WindowMessage, FrameMessage>> & { start: ReturnType<typeof vi.fn> stop: ReturnType<typeof vi.fn> } beforeEach(() => { mockNode = {start: vi.fn(), stop: vi.fn(), onStatus: vi.fn()} vi.mocked(comlink.createNode).mockReturnValue(mockNode as Node<WindowMessage, FrameMessage>) state = createStoreState<ComlinkNodeState>({nodes: new Map(), subscriptions: new Map()}) vi.clearAllMocks() }) it('should create and start a node', () => { const node = getOrCreateNode({state, instance, key: null}, nodeConfig) expect(comlink.createNode).toHaveBeenCalledWith(nodeConfig) expect(node.start).toHaveBeenCalled() }) it('should store the node in nodeStore', () => { const node = getOrCreateNode({state, instance, key: null}, nodeConfig) expect(getOrCreateNode({state, instance, key: null}, nodeConfig)).toBe(node) }) it('should throw error when trying to create node with different options', () => { getOrCreateNode({state, instance, key: null}, nodeConfig) expect(() => getOrCreateNode( {state, instance, key: null}, { ...nodeConfig, connectTo: 'window', }, ), ).toThrow('Node "test-node" already exists with different options') }) it('should subscribe to status changes and update state', () => { let statusCallback: ((status: string) => void) | undefined const statusUnsubMock = vi.fn() mockNode.onStatus = vi.fn((cb) => { statusCallback = cb return statusUnsubMock }) getOrCreateNode({state, instance, key: null}, nodeConfig) expect(mockNode.onStatus).toHaveBeenCalled() expect(state.get().nodes.get(nodeConfig.name)?.statusUnsub).toBe(statusUnsubMock) statusCallback?.('connected') expect(state.get().nodes.get(nodeConfig.name)?.status).toBe('connected') }) it('should not update state if node entry is missing when status changes', () => { let statusCallback: ((status: string) => void) | undefined const statusUnsubMock = vi.fn() mockNode.onStatus = vi.fn((cb) => { statusCallback = cb return statusUnsubMock }) getOrCreateNode({state, instance, key: null}, nodeConfig) // Remove the node entry before triggering the status callback state.get().nodes.delete(nodeConfig.name) // Simulate a status change statusCallback?.('connected') // Assert: node entry is still missing, so no update occurred expect(state.get().nodes.has(nodeConfig.name)).toBe(false) }) })