// mlLocale (Phase 15): the ML field type predicates, the locale -> text map // sent on save and the window event that keeps every ML control on one locale. import { afterEach, describe, expect, it } from 'vitest' import { ML_LOCALE_CHANGE, broadcastMLLocale, isMLField, isMLFieldType, localeRecord, } from '../../src/components/form/mlLocale' describe('isMLFieldType', () => { it('accepts the three ML types', () => { expect(isMLFieldType('mltext')).toBe(true) expect(isMLFieldType('mltextarea')).toBe(true) expect(isMLFieldType('mlmarkdown')).toBe(true) }) it('refuses plain types and a missing type', () => { expect(isMLFieldType('text')).toBe(false) expect(isMLFieldType('markdown')).toBe(false) expect(isMLFieldType(undefined)).toBe(false) }) }) describe('isMLField', () => { it('accepts a built-in ML type', () => { expect(isMLField({ type: 'mltext' })).toBe(true) }) it('accepts a translatable plugin field with an element', () => { expect(isMLField({ type: 'acme-color', element: 'acme-color', translatable: true })).toBe(true) }) it('refuses a translatable field without an element', () => { expect(isMLField({ type: 'acme-color', translatable: true })).toBe(false) }) it('refuses a plugin field that is not translatable', () => { expect(isMLField({ type: 'acme-color', element: 'acme-color' })).toBe(false) expect(isMLField({ type: 'acme-color', element: 'acme-color', translatable: false })).toBe(false) }) it('refuses a missing field', () => { expect(isMLField(undefined)).toBe(false) }) }) describe('localeRecord', () => { it('keeps only string values', () => { expect(localeRecord({ en: 'Hello', pl: 'Cześć', de: 3, fr: null, es: '' })).toEqual({ en: 'Hello', pl: 'Cześć', es: '', }) }) it('returns an empty map for null, an array and a string', () => { expect(localeRecord(null)).toEqual({}) expect(localeRecord(undefined)).toEqual({}) expect(localeRecord(['Hello'])).toEqual({}) expect(localeRecord('Hello')).toEqual({}) }) }) describe('broadcastMLLocale', () => { const seen: string[] = [] const listener = (event: Event) => seen.push((event as CustomEvent).detail) afterEach(() => { window.removeEventListener(ML_LOCALE_CHANGE, listener) seen.length = 0 }) it('dispatches the locale as a window event', () => { window.addEventListener(ML_LOCALE_CHANGE, listener) broadcastMLLocale('pl') expect(seen).toEqual(['pl']) }) it('dispatches nothing for an empty locale', () => { window.addEventListener(ML_LOCALE_CHANGE, listener) broadcastMLLocale('') expect(seen).toEqual([]) }) })