import { beforeEach, describe, expect, it, vi } from 'vitest'; import ActionCableConnector from '../actionCable'; import { playNewMessageNotificationInWidget } from '../WidgetAudioNotificationHelper'; import { IFrameHelper } from '../utils'; import { emitter } from 'shared/helpers/mitt'; vi.mock('../WidgetAudioNotificationHelper', () => ({ playNewMessageNotificationInWidget: vi.fn(), })); vi.mock('../utils', () => ({ IFrameHelper: { sendMessage: vi.fn(), }, })); vi.mock('shared/helpers/mitt', () => ({ emitter: { emit: vi.fn(), }, })); describe('Widget ActionCableConnector', () => { let actionCable; let dispatch; beforeEach(() => { dispatch = vi.fn(); actionCable = new ActionCableConnector( { $store: { dispatch, getters: { getCurrentAccountId: 1, getCurrentUserID: 1, 'conversationAttributes/getConversationParams': { id: 7 }, }, }, }, 'test-token' ); }); it('emits message side effects only once when realtime replays a message', async () => { const message = { id: 42, conversation_id: 7, sender_type: 'User', }; dispatch .mockResolvedValueOnce({ applied: true, isNew: true }) .mockResolvedValueOnce({ applied: false, isNew: false }); await actionCable.onMessageCreated(message); await actionCable.onMessageCreated(message); expect(emitter.emit).toHaveBeenCalledTimes(1); expect(IFrameHelper.sendMessage).toHaveBeenCalledTimes(1); expect(playNewMessageNotificationInWidget).toHaveBeenCalledTimes(1); }); it('does not emit the SDK callback for an older message update', async () => { const message = { id: 42, conversation_id: 7, previous_changes: { content_attributes: [{}, { submitted_values: ['yes'] }], }, }; dispatch.mockResolvedValue({ applied: false, isNew: false }); await actionCable.onMessageUpdated(message); expect(IFrameHelper.sendMessage).not.toHaveBeenCalled(); }); });