Files
RenewCMS/web/src/i18n/roleMessages.spec.ts
T

229 lines
8.2 KiB
TypeScript

import { afterEach, describe, expect, it } from 'vitest'
import { messages } from './messages'
import { setLocale, t } from './index'
const ROLE_KEYS = [
'Access',
'Roles',
'New role',
'Who can do what on this site. Each user has one role.',
'No custom roles yet',
"Couldn't load roles",
'You can see roles but not change them',
'Content permissions',
'Quick presets',
'Read only',
'Write own',
'Full content',
'General permissions',
'Expand all',
'{0} unsaved changes',
'Give the role a name.',
'A role named "{0}" already exists. Choose a different name.',
'This role changed while you were editing',
'Your access changed',
'The Owner role is locked',
'Only the owner can edit built-in roles',
'What this role can do',
'Role created',
'{0} is ready. Assign it from Users.',
'Role saved',
'{0} members have this role. Move them to another role first. Then {1} can be deleted.',
'Move {0} members and delete role',
"No one has this role. This can't be undone.",
'Can {0}.',
"Can't {0}.",
] as const
const PLACEHOLDER = /\{\d+\}/g
afterEach(() => setLocale('en'))
describe('Roles screens copy', () => {
it.each(ROLE_KEYS)('"%s" has a French entry', (key) => {
expect((messages as Record<string, string>)[key]).toMatch(/\S/)
})
it('keeps the same placeholders in French as in English for every entry', () => {
const mismatches = Object.entries(messages).filter(([english, french]) => {
const expected = (english.match(PLACEHOLDER) ?? []).sort().join()
const actual = (french.match(PLACEHOLDER) ?? []).sort().join()
return expected !== actual
})
expect(mismatches.map(([english]) => english)).toEqual([])
})
it('renders French with its values', () => {
setLocale('fr')
expect(t('{0} unsaved changes', [3])).toBe('3 modifications non enregistrées')
expect(t('Roles')).toBe('Rôles')
})
})
const USERS_ROLES_KEYS = [
'Your role',
'See what I can do',
'What you can do',
'A summary of your role, {0}. Read-only.',
'Change role',
'Change role for {0}',
'Their API keys follow the new role.',
'Transfer ownership to {0}',
'Type {0} to confirm',
'The email must match exactly.',
"Keys follow their creator's role",
'Follows role',
'What changed',
'Role {0} created',
'Role {0} edited',
'Role {0} deleted',
"{0}'s role changed from {1} to {2}",
'Ownership transferred from {0} to {1}',
'They get an email with a link to set a password.',
'Writer is the default. You can change a role later.',
] as const
describe('Users, Profile, API keys and Activity copy for roles', () => {
it.each(USERS_ROLES_KEYS)('"%s" has a French entry', (key) => {
expect((messages as Record<string, string>)[key]).toMatch(/\S/)
})
})
const FINAL_COPY: [string, (string | number)[], string][] = [
[
'{0} is now {1}, and their API keys follow the new role.',
['Ines Duarte', 'Content lead'],
'Ines Duarte a maintenant le rôle Content lead, et ses clés API suivent le nouveau rôle.',
],
["Couldn't save the role", [], "Impossible d'enregistrer le rôle"],
[
'Your changes are still here. Try again in a moment.',
[],
'Vos modifications sont toujours là. Réessayez dans un instant.',
],
['Try again', [], 'Réessayer'],
["Couldn't change the role", [], 'Impossible de modifier le rôle'],
[
'Nothing was changed. Try again in a moment.',
[],
"Rien n'a été modifié. Réessayez dans un instant.",
],
[
"Your role can't assign a role with more power than yours.",
[],
'Votre rôle ne peut pas attribuer un rôle plus puissant que le vôtre.',
],
['{0} no longer exists', ['Writer'], "Writer n'existe plus"],
[
'It was deleted somewhere else. Choose another role to move the members to.',
[],
'Il a été supprimé ailleurs. Choisissez un autre rôle pour y déplacer les membres.',
],
['Role still has members', [], 'Le rôle a encore des membres'],
[
'{0} now has 1 member. Move them to another role first.',
['Intern'],
"Intern a maintenant 1 membre. Déplacez-le d'abord vers un autre rôle.",
],
[
'{0} now has {1} members. Move them to another role first.',
['Intern', 3],
"Intern a maintenant 3 membres. Déplacez-les d'abord vers un autre rôle.",
],
["Couldn't move the members", [], 'Impossible de déplacer les membres'],
['Enter a valid email address.', [], 'Saisissez une adresse e-mail valide.'],
['This address already has an account.', [], 'Cette adresse a déjà un compte.'],
["Couldn't send the invite", [], "Impossible d'envoyer l'invitation"],
['Try again in a moment.', [], 'Réessayez dans un instant.'],
['Role changed elsewhere', [], 'Rôle modifié ailleurs'],
[
'{0} edited {1}, so nothing was saved. Reload and try again.',
['Jonas Weber', 'Contributor'],
"Jonas Weber a modifié Contributor, donc rien n'a été enregistré. Rechargez et réessayez.",
],
['Reload', [], 'Recharger'],
['That role no longer exists', [], "Ce rôle n'existe plus"],
['Role not changed', [], 'Rôle non modifié'],
[
"{0}'s role changed in the meantime, so nothing was saved. Reload and try again.",
['Ines Duarte'],
"Le rôle de Ines Duarte a changé entre-temps, donc rien n'a été enregistré. Rechargez et réessayez.",
],
['Ownership not transferred', [], 'Propriété non transférée'],
[
"{0}'s role changed in the meantime, so nothing was transferred. Check it and try again.",
['Jonas Weber'],
"Le rôle de Jonas Weber a changé entre-temps, donc rien n'a été transféré. Vérifiez-le et réessayez.",
],
['User not removed', [], 'Utilisateur non retiré'],
[
"{0}'s role changed in the meantime, so nothing was removed. Check it and try again.",
['Ines Duarte'],
"Le rôle de Ines Duarte a changé entre-temps, donc rien n'a été retiré. Vérifiez-le et réessayez.",
],
['Role changed in the meantime', [], 'Rôle modifié entre-temps'],
[
'{0} is now {1}. Your choice is kept. Check it and try again.',
['Ines Duarte', 'Admin'],
'Ines Duarte a maintenant le rôle Admin. Votre choix est conservé. Vérifiez-le et réessayez.',
],
[
'{0} is now {1}. What you typed is kept. Check the change, then try again.',
['Jonas Weber', 'Writer'],
'Jonas Weber a maintenant le rôle Writer. Ce que vous avez saisi est conservé. Vérifiez le changement, puis réessayez.',
],
['Reload member', [], 'Recharger le membre'],
['Role reloaded', [], 'Rôle rechargé'],
[
'Your {0} changes are still here. Review them, then save.',
[2],
'Vos 2 modifications sont toujours là. Relisez-les, puis enregistrez.',
],
['Use the saved role', [], 'Utiliser le rôle enregistré'],
['Keep my edits', [], 'Garder mes modifications'],
['Loading…', [], 'Chargement…'],
['Locked', [], 'Verrouillé'],
]
describe('Final copy: toasts and errors, EN and FR', () => {
it.each(FINAL_COPY)('"%s" reads in English and in French', (key, values, french) => {
expect(t(key as keyof typeof messages, values)).toContain(
key.replace(/\{(\d+)\}/g, (_, index) => String(values[Number(index)])),
)
setLocale('fr')
expect(t(key as keyof typeof messages, values).replace(/\u2019/g, "'")).toBe(french)
})
})
const PROPOSED_COPY = [
'Remove user',
'Remove {0}?',
'They lose access straight away, and the API keys they created stop working. Their articles, entries and media stay.',
"Couldn't remove the user",
'User removed',
'{0} no longer has access.',
"You can't remove yourself. Ask another owner or admin.",
'Online articles and the drafts you created.',
'Drafts by others are hidden',
'Your role reads online articles and the drafts you created. The counts follow the same rule.',
'You have no drafts',
"Drafts you create appear here. Your role can't see drafts by other people.",
'Your role shows only entries you created.',
"Entries by others aren't shown",
'Your role reads only entries you created. Ask an owner or admin if you need to see more.',
"You haven't created {0} yet",
"Your role shows only entries you created, so other people's {0} aren't listed here. Use New entry to add one.",
'{0} saved changes to {1} at {2}.',
'Your 1 change is still here. Review it, then save.',
'read online articles and their own drafts',
'read only entries they created',
] as const
describe('Proposed copy that the design does not give', () => {
it.each(PROPOSED_COPY)('"%s" has a French entry', (key) => {
expect((messages as Record<string, string>)[key]).toMatch(/\S/)
})
})