import React from 'react'; import { render, screen } from '@testing-library/react'; import { SocialMediaEmbed, SocialMediaEmbedProps } from '../SocialMediaEmbed'; import { BlockedEmbedMessage } from '../BlockedEmbedMessage'; import { Vendor } from '../SocialVendor'; import { checkVendorConsentAsync } from '../helpers/vendorConsent'; import { eventStatus } from '../constants'; import '@testing-library/jest-dom/extend-expect'; import { useSocialEmbedsContext } from '../../../contexts/SocialEmbedsProvider'; jest.mock('../../../contexts/SocialEmbedsProvider', () => ({ useSocialEmbedsContext: jest.fn() })); jest.mock('../BlockedEmbedMessage', () => ({ BlockedEmbedMessage: jest.fn(() =>
Blocked Embed Message
) })); jest.mock('../SocialVendor', () => ({ Vendor: jest.fn(() =>
Vendor Component
) })); jest.mock('../helpers/vendorConsent', () => ({ checkVendorConsentAsync: jest.fn() })); describe('SocialMediaEmbed Component', () => { const vendorName = 'twitter'; const defaultProps: SocialMediaEmbedProps = { id: 'test-id', url: 'https://twitter.com/test/status/12345', vendorName }; const mockContext = { setIsSocialEmbedAllowed: jest.fn(), isAllowedOnce: { twitter: false }, isSocialEmbedAllowed: { twitter: false } }; beforeEach(() => { jest.clearAllMocks(); (useSocialEmbedsContext as jest.Mock).mockReturnValue(mockContext); // Mock __tcfapi (window as any).__tcfapi = jest.fn(); }); afterEach(() => { delete (window as any).__tcfapi; }); it('renders BlockedEmbedMessage when social embed is not allowed', () => { render(); expect(screen.getByText('Blocked Embed Message')).toBeInTheDocument(); expect(BlockedEmbedMessage).toHaveBeenCalledWith( expect.objectContaining({ vendorName: defaultProps.vendorName }), {} ); }); it('renders Vendor component when social embed is allowed', () => { (useSocialEmbedsContext as jest.Mock).mockReturnValue({ ...mockContext, isSocialEmbedAllowed: { twitter: true } }); render(); expect(screen.getByText('Vendor Component')).toBeInTheDocument(); expect(Vendor).toHaveBeenCalledWith( expect.objectContaining({ vendorName: defaultProps.vendorName, url: defaultProps.url }), {} ); }); it('calls checkVendorConsentAsync and updates context state when __tcfapi is available', () => { const tcData = { eventStatus: eventStatus.tcLoaded }; const updatedProps = { ...defaultProps }; render(); // First call is from the mount useEffect expect(checkVendorConsentAsync).toHaveBeenCalledWith( vendorName, mockContext.setIsSocialEmbedAllowed ); // Find the addEventListener call const addEventListenerCall = (window.__tcfapi as jest.Mock).mock.calls.find( (call: any[]) => call[0] === 'addEventListener' ); expect(addEventListenerCall).toBeDefined(); expect(addEventListenerCall[1]).toBe(2); // Simulate the callback addEventListenerCall[2](tcData, true); // Should have been called again from the event listener expect(checkVendorConsentAsync).toHaveBeenCalledWith( vendorName, mockContext.setIsSocialEmbedAllowed ); }); it('does not render Twitter widget if __tcfapi is unavailable', () => { delete (window as any).__tcfapi; render(); expect(screen.getByText('Blocked Embed Message')).toBeInTheDocument(); expect(BlockedEmbedMessage).toHaveBeenCalled(); }); it('renders Vendor component if isAllowedOnce for the vendor is true', () => { (useSocialEmbedsContext as jest.Mock).mockReturnValue({ ...mockContext, isAllowedOnce: { twitter: true } }); render(); expect(screen.getByText('Vendor Component')).toBeInTheDocument(); expect(Vendor).toHaveBeenCalledWith( expect.objectContaining({ vendorName: defaultProps.vendorName, url: defaultProps.url }), {} ); }); });