/* eslint-env jest */ import { act } from 'react'; import { createRoot, type Root } from 'react-dom/client'; import type { IAgentDashboardData, IJourneyListItem, } from '../../../service/agent-analytics/agent-analytics.interface'; import { useContentSite } from '../../../lib/content-site'; import AnalyticsTab from '../AnalyticsTab'; import ConversationsTab from '../ConversationsTab'; import JourneyDetailModal from '../JourneyDetailModal'; import LiveSyncBanner from '../LiveSyncBanner'; import OverviewTab from '../OverviewTab'; jest.mock('../../../env', () => ({ recomaze_ai_personalization_env: {} })); jest.mock('../../../lib/content-site', () => ({ useContentSite: jest.fn(() => false), })); jest.mock('../../../service/agent-analytics/agent-analytics.service', () => ({ fetchAgentJourneys: jest.fn(), fetchAgentJourneyDetail: jest.fn(), })); // eslint-disable-next-line @typescript-eslint/no-var-requires const service = require('../../../service/agent-analytics/agent-analytics.service'); ( globalThis as unknown as { IS_REACT_ACT_ENVIRONMENT: boolean } ).IS_REACT_ACT_ENVIRONMENT = true; /** The store's parts a content site must not read on these screens. */ const STORE_PARTS = /Product Clicks|Add to Cart|Added to Cart|Product Funnel|Ready to Buy|Conversion Rate|add-to-cart/; /** A range with conversations in it, every figure the tabs read present. */ const DASHBOARD = { overview: { total_conversations: 12, unique_visitors: 9, real_conversion_rate: 0, satisfaction_rate: 80, product_clicks: 0, add_to_cart_count: 0, avg_messages_per_conversation: 4, avg_duration_minutes: 3, high_intent_conversations: 2, high_intent_rate: 16, returning_rate: 0, returning_visitors: 0, }, overview_trends: {}, funnel: { total_conversations: 12, reached_discovery: 12, reached_consideration: 6, reached_ready: 2, }, engagement_patterns: { daily_conversations: [] }, } as unknown as IAgentDashboardData; /** One conversation, as the Conversations tab lists it. */ const JOURNEY: IJourneyListItem = { fingerprint: 'fp-1', first_message_at: '2026-10-16T18:30:00Z', duration_minutes: 3, message_count: 4, outcome: 'question_answered', sentiment: 'positive', purchase_intent_score: 0.4, product_clicks: 0, add_to_cart_count: 0, clicked_products: [], carted_products: [], liked_messages_count: 1, disliked_messages_count: 0, last_stage: 'consideration', }; let root: Root; let host: HTMLDivElement; beforeEach(() => { host = document.createElement('div'); document.body.appendChild(host); root = createRoot(host); service.fetchAgentJourneys.mockResolvedValue({ journeys: [JOURNEY] }); service.fetchAgentJourneyDetail.mockResolvedValue({ ...JOURNEY, messages: [], sentiment_progression: [], }); }); afterEach(() => { act(() => root.unmount()); host.remove(); (useContentSite as jest.Mock).mockReturnValue(false); }); const textOf = async (element: JSX.Element): Promise => { await act(async () => { root.render(element); }); return host.textContent ?? ''; }; const noop = (): void => undefined; const RANGE = { start: '2026-10-01', end: '2026-10-20' }; describe('agent analytics for a content site', () => { it('reads the overview without the store figures or the product funnel', async () => { const text = await textOf( ); expect(text).not.toMatch(STORE_PARTS); expect(text).toContain('Conversation Funnel'); expect(text).toContain('Ready to get in touch'); expect(text).toContain('Satisfaction'); }); it('leaves the products and the catalog out of the analytics', async () => { const text = await textOf( ); expect(text).not.toContain('Product Performance'); expect(text).not.toContain('Missing Products'); expect(text).not.toContain('With Products'); expect(text).not.toContain('Product Engagement'); expect(text).toContain('Avg User Message'); }); it('lists conversations without clicks or carts', async () => { const text = await textOf( ); expect(text).toContain('Feedback'); expect(text).not.toContain('Carts'); expect(text).not.toContain('Clicks'); }); it('opens a conversation without clicks or add to cart', async () => { (useContentSite as jest.Mock).mockReturnValue(true); const text = await textOf( ); expect(text).toContain('Likes'); expect(text).not.toContain('Add to Cart'); }); it('says what is collected without a cart', async () => { const text = await textOf(); expect(text).not.toMatch(STORE_PARTS); expect(text).toContain('every conversation on your website'); }); }); describe('agent analytics for a store', () => { it('keeps every store figure', async () => { const overview = await textOf( ); expect(overview).toContain('Product Clicks'); expect(overview).toContain('Ready to Buy'); const conversations = await textOf(); expect(conversations).toContain('Carts'); const detail = await textOf( ); expect(detail).toContain('Add to Cart'); }); });