import { describe, it, expect, vi } from 'vitest'
import { renderHook } from '@testing-library/react-hooks'
import { useGetList } from 'react-admin'
import en from './en.json'
import useGetLanguageChoices from './useGetLanguageChoices'
vi.mock('react-admin', () => ({
useGetList: vi.fn(),
}))
const countLeaves = (obj) =>
Object.values(obj).reduce(
(sum, v) =>
sum + (typeof v === 'object' && v !== null ? countLeaves(v) : v ? 1 : 0),
0,
)
const enTermCount = countLeaves(en)
const label = (pct) => `β¦(${pct}%)β©`
const mockLanguages = (languages) => {
const data = {}
languages.forEach((l) => (data[l.id] = l))
useGetList.mockReturnValue({
ids: languages.map((l) => l.id),
data,
loaded: true,
loading: false,
})
}
const choiceFor = (id) => {
const { result } = renderHook(() => useGetLanguageChoices())
return result.current.choices.find((c) => c.id === id)
}
describe('useGetLanguageChoices', () => {
it('appends the completion percentage to incomplete languages', () => {
const termCount = Math.round(enTermCount * 0.62)
mockLanguages([{ id: 'cs', name: 'ΔeΕ‘tina', termCount }])
const pct = Math.round((100 * termCount) / enTermCount)
expect(choiceFor('cs').name).toEqual(`ΔeΕ‘tina ${label(pct)}`)
})
it('shows 100% for a complete language', () => {
mockLanguages([{ id: 'de', name: 'Deutsch', termCount: enTermCount }])
expect(choiceFor('de').name).toEqual(`Deutsch ${label(100)}`)
})
it('caps the percentage at 100 when a language has extra terms', () => {
mockLanguages([
{ id: 'pt', name: 'PortuguΓͺs', termCount: enTermCount + 20 },
])
expect(choiceFor('pt').name).toEqual(`PortuguΓͺs ${label(100)}`)
})
it('isolates the percentage next to a right-to-left name', () => {
const termCount = Math.round(enTermCount * 0.61)
mockLanguages([{ id: 'ar', name: 'Ψ§ΩΨΉΨ±Ψ¨ΩΨ©', termCount }])
const pct = Math.round((100 * termCount) / enTermCount)
expect(choiceFor('ar').name).toEqual(`Ψ§ΩΨΉΨ±Ψ¨ΩΨ© β¦(${pct}%)β©`)
})
it('omits the percentage when the server does not send a term count', () => {
mockLanguages([{ id: 'fr', name: 'FranΓ§ais' }])
expect(choiceFor('fr').name).toEqual('FranΓ§ais')
})
it('shows 100% for the bundled English', () => {
mockLanguages([])
expect(choiceFor('en').name).toEqual(`English ${label(100)}`)
})
it('sorts by language name, ignoring the percentage', () => {
mockLanguages([
{ id: 'no', name: 'Norsk', termCount: enTermCount },
{ id: 'da', name: 'Dansk', termCount: 1 },
])
const { result } = renderHook(() => useGetLanguageChoices())
expect(result.current.choices.map((c) => c.id)).toEqual(['da', 'en', 'no'])
})
})