import React from 'react' import { render, screen } from '@testing-library/react' import { describe, it, expect, beforeEach, vi } from 'vitest' import { ReadOnlyDateField, ReadOnlyDurationField, ReadOnlyNumberField, ReadOnlySizeField, ReadOnlyTextField, } from './ReadOnlyFields' vi.mock('react-admin', async (importOriginal) => ({ ...(await importOriginal()), useLocale: vi.fn(), })) describe('ReadOnlyFields', () => { const record = { id: '1', client: 'NavidromeUI', createdAt: '2026-09-17T14:30:00Z', lastVisitedAt: '0001-01-01T00:00:00Z', count: 1234567, zero: 0, size: 1536000, duration: 3725, } beforeEach(async () => { vi.clearAllMocks() vi.spyOn(navigator, 'languages', 'get').mockReturnValue([]) const { useLocale } = await import('react-admin') vi.mocked(useLocale).mockReturnValue('de') }) const renderField = (Field, props) => render() describe('', () => { it('shows the record value with the translated field label', () => { renderField(ReadOnlyTextField, { source: 'client' }) const input = screen.getByLabelText('resources.player.fields.client') expect(input).toHaveValue('NavidromeUI') }) it('cannot be edited or reached with the Tab key', () => { renderField(ReadOnlyTextField, { source: 'client' }) const input = screen.getByRole('textbox') expect(input).toHaveAttribute('readonly') expect(input).toHaveAttribute('tabindex', '-1') }) it('shows an empty value when the record has no value', () => { renderField(ReadOnlyTextField, { source: 'userName' }) expect(screen.getByRole('textbox')).toHaveValue('') }) it('uses an explicit label when given', () => { renderField(ReadOnlyTextField, { source: 'client', label: 'Custom' }) expect(screen.getByLabelText('Custom')).toBeInTheDocument() }) it('applies a custom format', () => { renderField(ReadOnlyTextField, { source: 'client', format: (v) => v.toUpperCase(), }) expect(screen.getByRole('textbox')).toHaveValue('NAVIDROMEUI') }) it('exposes theme-overridable class names', () => { const { container } = renderField(ReadOnlyTextField, { source: 'client', }) expect( container.querySelector('[class*="NDReadOnlyField-inputRoot"]'), ).toBeInTheDocument() expect( container.querySelector('[class*="NDReadOnlyField-notchedOutline"]'), ).toBeInTheDocument() }) }) describe('', () => { it('formats the date using the selected language', () => { renderField(ReadOnlyDateField, { source: 'createdAt' }) expect(screen.getByRole('textbox').value).toMatch(/^17\.9\.2026, /) }) it('shows an empty value when the date is not set', () => { renderField(ReadOnlyDateField, { source: 'lastVisitedAt' }) expect(screen.getByRole('textbox')).toHaveValue('') }) }) describe('', () => { it('formats the number using the selected language', () => { renderField(ReadOnlyNumberField, { source: 'count' }) expect(screen.getByRole('textbox')).toHaveValue('1.234.567') }) it('shows zero', () => { renderField(ReadOnlyNumberField, { source: 'zero' }) expect(screen.getByRole('textbox')).toHaveValue('0') }) }) describe('', () => { it('formats bytes as a human-readable size', () => { renderField(ReadOnlySizeField, { source: 'size' }) expect(screen.getByRole('textbox')).toHaveValue('1.46 MB') }) }) describe('', () => { it('formats seconds as a human-readable duration', () => { renderField(ReadOnlyDurationField, { source: 'duration' }) expect(screen.getByRole('textbox')).toHaveValue('1h 2m 5s') }) }) })