import React from 'react'
import { describe, expect, it } from 'vitest'
import { renderWithProviders, screen } from '../../test/utils'
import MessageBubble from '.'
describe('MessageBubble', () => {
it('renders the message text', () => {
renderWithProviders()
expect(screen.getByText('Hello there')).toBeInTheDocument()
})
it('preserves newlines with whitespace-pre-wrap', () => {
renderWithProviders()
const paragraph = screen.getByText(/line one/)
expect(paragraph.textContent).toBe('line one\nline two')
expect(paragraph.className).toContain('whitespace-pre-wrap')
})
it('draws the tail by default and omits it when tail is false', () => {
const { rerender } = renderWithProviders(
)
// The bubble box wraps the text; its last child is the tail .
const bubble = screen.getByText('tailed').parentElement as HTMLElement
expect(bubble.querySelector('span[aria-hidden="true"]')).not.toBeNull()
rerender()
const bubbleNoTail = screen.getByText('tailed').parentElement as HTMLElement
expect(bubbleNoTail.querySelector('span[aria-hidden="true"]')).toBeNull()
})
it('renders the optional header on the received variant', () => {
renderWithProviders(
)
expect(screen.getByTestId('message-bubble-header')).toHaveTextContent(
'Brie'
)
})
it('does not render a header slot when no header is provided', () => {
renderWithProviders()
expect(screen.queryByTestId('message-bubble-header')).toBeNull()
})
it('applies the sent and received surface treatments from theme vars', () => {
const { rerender } = renderWithProviders()
const sent = screen.getByText('mine').parentElement as HTMLElement
expect(sent.style.backgroundColor).toBe(
'var(--str-chat__own-message-bubble-background-color, #1e2330)'
)
rerender()
const received = screen.getByText('theirs').parentElement as HTMLElement
expect(received.style.backgroundColor).toBe(
'var(--str-chat__message-bubble-background-color, #f1f0ee)'
)
})
it('masks message content from session replay by default', () => {
renderWithProviders()
const bubble = screen.getByText('secret').parentElement as HTMLElement
expect(bubble.getAttribute('data-dd-privacy')).toBe('mask')
})
it('forwards width/className onto the bubble box (width is caller-controlled)', () => {
renderWithProviders(
)
const bubble = screen.getByText('wide').parentElement as HTMLElement
expect(bubble.classList.contains('w-fit')).toBe(true)
expect(bubble.className).toContain('max-w-[520px]')
})
})