🏑 index : quine-global/quintodrome.git

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)

// The percentage is wrapped in a left-to-right isolate, so it reads the same
// next to right-to-left language names
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'])
  })
})