import { describe, test, expect, beforeEach } from 'vitest' import { render, screen } from '@testing-library/react' import { Suffix } from './suffix' import { useWidgetStore } from '../../stores/widget-store' import type { FormulaWidgetState } from '../types' describe('Suffix', () => { beforeEach(() => { useWidgetStore.getState().clearWidgets() }) test('renders suffix from widget data at default index 0', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'USD' }], }) render() expect(screen.getByText('USD')).toBeTruthy() }) test('renders suffix at specified index', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [ { value: 100, suffix: 'units' }, { value: 200, suffix: 'items' }, { value: 300, suffix: 'pieces' }, ], }) render() expect(screen.getByText('items')).toBeTruthy() }) test('renders suffix at index 0 when index not specified', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [ { value: 100, suffix: 'first' }, { value: 200, suffix: 'second' }, ], }) render() expect(screen.getByText('first')).toBeTruthy() }) test('returns null when widget does not exist', () => { const { container } = render() expect(container.firstChild).toBeNull() }) test('returns null when widget data is undefined', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', }) const { container } = render() expect(container.firstChild).toBeNull() }) test('returns null when suffix is undefined', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100 }], }) const { container } = render() expect(container.firstChild).toBeNull() }) test('returns null when index is out of bounds', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'USD' }], }) const { container } = render() expect(container.firstChild).toBeNull() }) test('returns null for empty data array', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [], }) const { container } = render() expect(container.firstChild).toBeNull() }) test('returns null for empty string suffix', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: '' }], }) const { container } = render() expect(container.firstChild).toBeNull() }) test('renders string suffix', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'meters' }], }) render() expect(screen.getByText('meters')).toBeTruthy() }) test('renders single character suffix', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: '%' }], }) render() expect(screen.getByText('%')).toBeTruthy() }) test('renders multi-word suffix', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'square meters' }], }) render() expect(screen.getByText('square meters')).toBeTruthy() }) test('renders as Typography h5', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: '%' }], }) render() const element = screen.getByText('%') expect(element.tagName).toBe('H5') }) test('applies secondary text color', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'USD' }], }) render() const element = screen.getByText('USD') // TypographyProps receives a function for color, so we check the element exists expect(element).toBeTruthy() }) test('passes disabled prop to Item', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: '%' }], }) render() const element = screen.getByText('%') expect(element.getAttribute('data-disabled')).toBe('true') }) test('passes TypographyProps to Item', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: '%' }], }) render( , ) const element = screen.getByText('%') expect(element.classList.contains('custom')).toBe(true) }) test('handles all data properties together', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [ { value: 100, color: '#FF0000', prefix: '$', suffix: 'USD', }, ], }) render() expect(screen.getByText('USD')).toBeTruthy() }) test('updates when widget data changes', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'USD' }], }) const { rerender } = render() expect(screen.getByText('USD')).toBeTruthy() useWidgetStore.getState().setWidget('test-suffix', { data: [{ value: 200, suffix: 'EUR' }], }) rerender() expect(screen.queryByText('USD')).toBeNull() expect(screen.getByText('EUR')).toBeTruthy() }) test('updates when suffix is removed', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'USD' }], }) const { container, rerender } = render() expect(screen.getByText('USD')).toBeTruthy() useWidgetStore.getState().setWidget('test-suffix', { data: [{ value: 100 }], }) rerender() expect(container.firstChild).toBeNull() }) test('updates when index changes', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [ { value: 100, suffix: 'USD' }, { value: 200, suffix: 'EUR' }, ], }) const { rerender } = render() expect(screen.getByText('USD')).toBeTruthy() rerender() expect(screen.queryByText('USD')).toBeNull() expect(screen.getByText('EUR')).toBeTruthy() }) test('handles widget removal gracefully', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'USD' }], }) const { container, rerender } = render() expect(screen.getByText('USD')).toBeTruthy() useWidgetStore.getState().removeWidget('test-suffix') rerender() expect(container.firstChild).toBeNull() }) test('handles suffix with special characters', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'm²' }], }) render() expect(screen.getByText('m²')).toBeTruthy() }) test('handles suffix with unicode characters', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: '€ coins' }], }) render() expect(screen.getByText(/€ coins/)).toBeTruthy() }) test('handles suffix with numbers', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'x10' }], }) render() expect(screen.getByText('x10')).toBeTruthy() }) test('handles long suffix text', () => { const longSuffix = ' units per square meter per second' useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: longSuffix }], }) render() expect(screen.getByText(longSuffix.trim())).toBeTruthy() }) test('renders different suffixes for different items', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [ { value: 100, suffix: 'USD' }, { value: 200, suffix: 'EUR' }, { value: 300, suffix: 'GBP' }, ], }) const { unmount } = render() expect(screen.getByText('USD')).toBeTruthy() unmount() render() expect(screen.getByText('EUR')).toBeTruthy() }) test('handles negative index (invalid but should not crash)', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'USD' }], }) const { container } = render() expect(container.firstChild).toBeNull() }) test('handles suffix with only whitespace', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: ' ' }], }) const { container } = render() // Whitespace is normalized by text content, just verify component renders expect(container.querySelector('.MuiTypography-root')).toBeTruthy() }) test('suffix is sanitized to string only in store', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'Valid String' }], }) render() expect(screen.getByText('Valid String')).toBeTruthy() }) test('secondary color is applied via TypographyProps', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'units' }], }) render() const element = screen.getByText('units') // The component passes a function for color, so we just verify it renders expect(element).toBeTruthy() }) test('combines disabled and TypographyProps', () => { useWidgetStore.getState().setWidget('test-suffix', { type: 'formula', data: [{ value: 100, suffix: 'units' }], }) render( , ) const element = screen.getByText('units') expect(element.getAttribute('data-disabled')).toBe('true') expect(element.classList.contains('custom')).toBe(true) }) })