From 93298ef533864c1d772d1f16904aac7e0d7b5f4c Mon Sep 17 00:00:00 2001 From: lupusA Date: Sun, 17 Mar 2024 20:35:54 +0100 Subject: [PATCH] Added tests and additional translations --- public/locales/de/translation.json | 38 +++++++++++ public/locales/en/translation.json | 38 +++++++++++ public/locales/es/translation.json | 38 +++++++++++ public/locales/fr/translation.json | 38 +++++++++++ public/locales/it/translation.json | 38 +++++++++++ public/locales/jp/translation.json | 38 +++++++++++ public/locales/pl/translation.json | 38 +++++++++++ public/locales/ru/translation.json | 38 +++++++++++ src/components/SetupRepository.jsx | 49 +++++++------ src/components/SetupRepositoryAzure.jsx | 13 ++-- src/components/SetupRepositoryB2.jsx | 9 +-- src/components/SetupRepositoryFilesystem.jsx | 3 +- src/components/SetupRepositoryGCS.jsx | 9 +-- src/pages/SnapshotDirectory.jsx | 17 ++--- src/tests/Language.test.jsx | 72 ++++++++++++++------ 15 files changed, 409 insertions(+), 67 deletions(-) diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json index 7ea8f5d..40c6229 100644 --- a/public/locales/de/translation.json +++ b/public/locales/de/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Repository-Token", "feedback.provider.webdav-server": "WebDAV-Server", "feedback.repository.configuration": "Speicherkonfiguration", + "feedback.repository.create-repository-new": "Neues Repository erstellen", + "feedback.repository.create-repository-new-help": "Geben Sie ein sicheres Passwort ein, um das Kopia-Repository im bereitgestellten Speicher zu erstellen.", + "feedback.repository.encryption": "Verschlüsselung", "feedback.repository.kopia-server-parameters": "Kopia-Serverparameter", "feedback.repository.name-default": "Mein Repository", "feedback.repository.provider-selection": "Wählen Sie ein Repository aus", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "Design", "feedback.ui.theme-help": "Das aktuell ausgewählte Design", "feedback.ui.theme-select": "Select theme", + "feedback.validation.azure.access-key": "Zugangsschlüssel", + "feedback.validation.azure.access-key-hint": "Geben Sie den geheimen Zugangsschlüssel ein", + "feedback.validation.azure.azure-storage-domain": "Azure Storage-Domäne", + "feedback.validation.azure.azure-storage-domain-hint": "Geben Sie die Speicherdomäne ein oder lassen Sie sie leer, um die Standardeinstellung „blob.core.windows.net“ zu verwenden.", + "feedback.validation.azure.container": "Container", + "feedback.validation.azure.container-hint": "Geben Sie den Containernamen ein", + "feedback.validation.azure.object-name-prefix": "Präfix des Objektnamens", + "feedback.validation.azure.object-name-prefix-hint": "Geben Sie das Präfix für den Objektnamen ein oder lassen Sie es leer", + "feedback.validation.azure.sas-token": "SAS-Token", + "feedback.validation.azure.sas-token-hint": "Geben Sie den geheimen SAS-Token ein", + "feedback.validation.azure.storage-account": "Speicherkonto", + "feedback.validation.azure.storage-account-hint": "Geben Sie den Namen des Speicherkontos ein", + "feedback.validation.b2.bucket-name": "B2-Bucket", + "feedback.validation.b2.bucket-name-hint": "Geben Sie den Bucket-Namen ein", + "feedback.validation.b2.key": "Schlüssel", + "feedback.validation.b2.key-hint": "Geben Sie den geheimen Anwendungs- oder Kontoschlüssel ein", + "feedback.validation.b2.key-id": "Schlüssel-ID", + "feedback.validation.b2.key-id-hint": "Geben Sie die Anwendungs- oder Kontoschlüssel-ID ein", + "feedback.validation.b2.object-name-prefix": "Präfix des Objektnamens", + "feedback.validation.b2.object-name-prefix-hint": "Geben Sie das Präfix für den Objektnamen ein oder lassen Sie es leer", + "feedback.validation.gcs.bucket-name": "GCS-Bucket", + "feedback.validation.gcs.bucket-name-hint": "Geben Sie den Bucket-Namen ein", + "feedback.validation.gcs.credentials-file": "Anmeldeinformationsdatei", + "feedback.validation.gcs.credentials-file-hint": "Geben Sie den Namen der JSON-Datei mit den Anmeldeinformationen ein", + "feedback.validation.gcs.credentials-json": "Anmeldeinformationen JSON", + "feedback.validation.gcs.credentials-json-paste": "Fügen Sie hier JSON-Anmeldeinformationen ein", + "feedback.validation.gcs.object-name-prefix": "Präfix des Objektnamens", + "feedback.validation.gcs.object-name-prefix-hint": "Geben Sie das Präfix für den Objektnamen ein oder lassen Sie es leer", "feedback.validation.invalid-times-of-day": "Ungültige Tageszeiten", + "feedback.validation.local.directory-path": "Verzeichnispfad", + "feedback.validation.local.directory-path-hint": "Geben Sie den Verzeichnispfad ein, in dem Sie die Repository-Dateien speichern möchten", "feedback.validation.optional.valid-number-or-empty": "Muss eine gültige Zahl sein oder leer sein", "feedback.validation.passwords-dont-match": "Passwörter stimmen nicht überein", "feedback.validation.required.directory": "Pflichtfeld", "feedback.validation.required.field": "Pflichtfeld", + "feedback.validation.required.password-repository": "Repository-Passwort", + "feedback.validation.required.password-repository-help": "Wird zum Verschlüsseln des Repository-Inhalts verwendet", + "feedback.validation.required.password-repository-hint": "Geben Sie das Repository-Passwort ein", + "feedback.validation.required.repository-password-confirm": "Bestätigen Sie das Repository-Passwort", + "feedback.validation.required.repository-password-confirm-again": "Geben Sie das Repository-Passwort erneut ein", "feedback.validation.required.valid-number-or-empty": "Muss eine gültige Zahl oder leer sein", "policies.feedback.find.count_one": "{{count}} Richtlinie gefunden, die den Kriterien entspricht", "policies.feedback.find.count_other": "{{count}} Richtlinien gefunden, die den Kriterien entsprechen", diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 5db7031..4eb4cd0 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Use Repository Token", "feedback.provider.webdav-server": "WebDAV Server", "feedback.repository.configuration": "Storage Configuration", + "feedback.repository.create-repository-new": "Create New Repository", + "feedback.repository.create-repository-new-help": "Enter a strong password to create Kopia repository in the provided storage.", + "feedback.repository.encryption": "Encryption", "feedback.repository.kopia-server-parameters": "Kopia Server Parameters", "feedback.repository.name-default": "My Repository", "feedback.repository.provider-selection": "Select Storage Type", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "Theme", "feedback.ui.theme-help": "The current active theme", "feedback.ui.theme-select": "Select theme", + "feedback.validation.azure.access-key": "Access Key", + "feedback.validation.azure.access-key-hint": "Enter secret access key", + "feedback.validation.azure.azure-storage-domain": "Azure Storage Domain", + "feedback.validation.azure.azure-storage-domain-hint": "Enter storage domain or leave empty for default 'blob.core.windows.net'", + "feedback.validation.azure.container": "Container", + "feedback.validation.azure.container-hint": "Enter container name", + "feedback.validation.azure.object-name-prefix": "Object Name Prefix", + "feedback.validation.azure.object-name-prefix-hint": "Enter object name prefix or leave empty", + "feedback.validation.azure.sas-token": "SAS Token", + "feedback.validation.azure.sas-token-hint": "Enter secret SAS Token", + "feedback.validation.azure.storage-account": "Storage Account", + "feedback.validation.azure.storage-account-hint": "Enter storage account name", + "feedback.validation.b2.bucket-name": "B2 Bucket", + "feedback.validation.b2.bucket-name-hint": "Enter bucket name", + "feedback.validation.b2.key": "Key", + "feedback.validation.b2.key-hint": "Enter secret application or account key", + "feedback.validation.b2.key-id": "Key ID", + "feedback.validation.b2.key-id-hint": "Enter application or account key ID", + "feedback.validation.b2.object-name-prefix": "Object Name Prefix", + "feedback.validation.b2.object-name-prefix-hint": "Enter object name prefix or leave empty", + "feedback.validation.gcs.bucket-name": "GCS Bucket", + "feedback.validation.gcs.bucket-name-hint": "Enter bucket name", + "feedback.validation.gcs.credentials-file": "Credentials File", + "feedback.validation.gcs.credentials-file-hint": "Enter name of credentials JSON file", + "feedback.validation.gcs.credentials-json": "Credentials JSON", + "feedback.validation.gcs.credentials-json-paste": "Paste JSON credentials here", + "feedback.validation.gcs.object-name-prefix": "Object Name Prefix", + "feedback.validation.gcs.object-name-prefix-hint": "Enter object name prefix or leave empty", "feedback.validation.invalid-times-of-day": "Invalid Times of Day", + "feedback.validation.local.directory-path": "Directory Path", + "feedback.validation.local.directory-path-hint": "Enter directory path where you want to store repository files", "feedback.validation.optional.valid-number-or-empty": "Must be a valid number or empty", "feedback.validation.passwords-dont-match": "Passwords don't match", "feedback.validation.required.directory": "Required field", "feedback.validation.required.field": "Required field", + "feedback.validation.required.password-repository": "Repository Password", + "feedback.validation.required.password-repository-help": "Used to encrypt the repository's contents", + "feedback.validation.required.password-repository-hint": "Enter repository password", + "feedback.validation.required.repository-password-confirm": "Confirm Repository Password", + "feedback.validation.required.repository-password-confirm-again": "enter repository password again", "feedback.validation.required.valid-number-or-empty": "Must be a valid number or empty", "policies.feedback.find.count_one": "Found {{count}} policy matching the criteria", "policies.feedback.find.count_other": "Found {{count}} policies matching the criteria", diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json index 95a0ada..dc31443 100644 --- a/public/locales/es/translation.json +++ b/public/locales/es/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Usar token de repositorio", "feedback.provider.webdav-server": "Servidor WebDAV", "feedback.repository.configuration": "Configuración de almacenamiento", + "feedback.repository.create-repository-new": "Crear nuevo repositorio", + "feedback.repository.create-repository-new-help": "Ingrese una contraseña segura para crear el repositorio de Kopia en el almacenamiento proporcionado.", + "feedback.repository.encryption": "Cifrado", "feedback.repository.kopia-server-parameters": "Parámetros del servidor Kopia", "feedback.repository.name-default": "Mi repositorio", "feedback.repository.provider-selection": "Seleccione el tipo de almacenamiento", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "Tema", "feedback.ui.theme-help": "El tema activo actual", "feedback.ui.theme-select": "Seleccionar tema", + "feedback.validation.azure.access-key": "Llave de acceso", + "feedback.validation.azure.access-key-hint": "Introduzca la clave de acceso secreta", + "feedback.validation.azure.azure-storage-domain": "Dominio de almacenamiento de Azure", + "feedback.validation.azure.azure-storage-domain-hint": "Ingrese el dominio de almacenamiento o déjelo vacío para el valor predeterminado 'blob.core.windows.net'", + "feedback.validation.azure.container": "Envase", + "feedback.validation.azure.container-hint": "Introduzca el nombre del contenedor", + "feedback.validation.azure.object-name-prefix": "Prefijo del nombre del objeto", + "feedback.validation.azure.object-name-prefix-hint": "Introduzca el prefijo del nombre del objeto o déjelo vacío", + "feedback.validation.azure.sas-token": "Ficha SAS", + "feedback.validation.azure.sas-token-hint": "Ingrese el token SAS secreto", + "feedback.validation.azure.storage-account": "Cuenta de almacenamiento", + "feedback.validation.azure.storage-account-hint": "Ingrese el nombre de la cuenta de almacenamiento", + "feedback.validation.b2.bucket-name": "Balde B2", + "feedback.validation.b2.bucket-name-hint": "Introduce el nombre del depósito", + "feedback.validation.b2.key": "Llave", + "feedback.validation.b2.key-hint": "Ingrese la aplicación secreta o la clave de cuenta", + "feedback.validation.b2.key-id": "ID de clave", + "feedback.validation.b2.key-id-hint": "Ingrese la ID de la clave de la aplicación o de la cuenta", + "feedback.validation.b2.object-name-prefix": "Prefijo del nombre del objeto", + "feedback.validation.b2.object-name-prefix-hint": "Introduzca el prefijo del nombre del objeto o déjelo vacío", + "feedback.validation.gcs.bucket-name": "Cucharón GCS", + "feedback.validation.gcs.bucket-name-hint": "Introduce el nombre del depósito", + "feedback.validation.gcs.credentials-file": "Archivo de credenciales", + "feedback.validation.gcs.credentials-file-hint": "Ingrese el nombre del archivo JSON de credenciales", + "feedback.validation.gcs.credentials-json": "Credenciales JSON", + "feedback.validation.gcs.credentials-json-paste": "Pegue las credenciales JSON aquí", + "feedback.validation.gcs.object-name-prefix": "Prefijo del nombre del objeto", + "feedback.validation.gcs.object-name-prefix-hint": "Introduzca el prefijo del nombre del objeto o déjelo vacío", "feedback.validation.invalid-times-of-day": "Horas del día no válidas", + "feedback.validation.local.directory-path": "Ruta de directorio", + "feedback.validation.local.directory-path-hint": "Ingrese la ruta del directorio donde desea almacenar los archivos del repositorio", "feedback.validation.optional.valid-number-or-empty": "Debe ser un número válido o vacío.", "feedback.validation.passwords-dont-match": "Las contraseñas no coinciden", "feedback.validation.required.directory": "Campo requerido", "feedback.validation.required.field": "Campo requerido", + "feedback.validation.required.password-repository": "Contraseña del repositorio", + "feedback.validation.required.password-repository-help": "Se utiliza para cifrar el contenido del repositorio.", + "feedback.validation.required.password-repository-hint": "Ingrese la contraseña del repositorio", + "feedback.validation.required.repository-password-confirm": "Confirmar contraseña del repositorio", + "feedback.validation.required.repository-password-confirm-again": "ingrese la contraseña del repositorio nuevamente", "feedback.validation.required.valid-number-or-empty": "Debe ser un número válido o vacío.", "policies.feedback.find.count_one": "Se encontró {{count}} política que coincide con los criterios", "policies.feedback.find.count_other": "Se encontraron {{count}} políticas que coinciden con los criterios", diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index 0f72e94..64f16d3 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Utiliser le jeton de référentiel", "feedback.provider.webdav-server": "Serveur WebDAV", "feedback.repository.configuration": "Configuration du stockage", + "feedback.repository.create-repository-new": "Créer un nouveau référentiel", + "feedback.repository.create-repository-new-help": "Entrez un mot de passe fort pour créer le référentiel Kopia dans le stockage fourni.", + "feedback.repository.encryption": "Chiffrement", "feedback.repository.kopia-server-parameters": "Paramètres du serveur Kopia", "feedback.repository.name-default": "Mon référentiel", "feedback.repository.provider-selection": "Sélectionnez le type de stockage", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "Thème", "feedback.ui.theme-help": "Le thème actif actuel", "feedback.ui.theme-select": "Sélectionnez un thème", + "feedback.validation.azure.access-key": "Clef d'accès", + "feedback.validation.azure.access-key-hint": "Entrez la clé d'accès secrète", + "feedback.validation.azure.azure-storage-domain": "Domaine de stockage Azure", + "feedback.validation.azure.azure-storage-domain-hint": "Entrez le domaine de stockage ou laissez vide pour « blob.core.windows.net » par défaut.", + "feedback.validation.azure.container": "Récipient", + "feedback.validation.azure.container-hint": "Entrez le nom du conteneur", + "feedback.validation.azure.object-name-prefix": "Préfixe du nom de l'objet", + "feedback.validation.azure.object-name-prefix-hint": "Entrez le préfixe du nom de l'objet ou laissez vide", + "feedback.validation.azure.sas-token": "Jeton SAS", + "feedback.validation.azure.sas-token-hint": "Entrez le jeton SAS secret", + "feedback.validation.azure.storage-account": "Compte de stockage", + "feedback.validation.azure.storage-account-hint": "Saisissez le nom du compte de stockage", + "feedback.validation.b2.bucket-name": "Godet B2", + "feedback.validation.b2.bucket-name-hint": "Saisissez le nom du compartiment", + "feedback.validation.b2.key": "Clé", + "feedback.validation.b2.key-hint": "Entrez l'application secrète ou la clé de compte", + "feedback.validation.b2.key-id": "ID de clé", + "feedback.validation.b2.key-id-hint": "Saisissez l'ID de la clé de l'application ou du compte", + "feedback.validation.b2.object-name-prefix": "Préfixe du nom de l'objet", + "feedback.validation.b2.object-name-prefix-hint": "Entrez le préfixe du nom de l'objet ou laissez vide", + "feedback.validation.gcs.bucket-name": "Godet GCS", + "feedback.validation.gcs.bucket-name-hint": "Saisissez le nom du compartiment", + "feedback.validation.gcs.credentials-file": "Fichier d'informations d'identification", + "feedback.validation.gcs.credentials-file-hint": "Entrez le nom du fichier JSON d'informations d'identification", + "feedback.validation.gcs.credentials-json": "Identifiants JSON", + "feedback.validation.gcs.credentials-json-paste": "Collez les informations d'identification JSON ici", + "feedback.validation.gcs.object-name-prefix": "Préfixe du nom de l'objet", + "feedback.validation.gcs.object-name-prefix-hint": "Entrez le préfixe du nom de l'objet ou laissez vide", "feedback.validation.invalid-times-of-day": "Heures de la journée invalides", + "feedback.validation.local.directory-path": "Chemin du répertoire", + "feedback.validation.local.directory-path-hint": "Entrez le chemin du répertoire dans lequel vous souhaitez stocker les fichiers du référentiel", "feedback.validation.optional.valid-number-or-empty": "Doit être un numéro valide ou vide", "feedback.validation.passwords-dont-match": "Les mots de passe ne correspondent pas", "feedback.validation.required.directory": "champs requis", "feedback.validation.required.field": "champs requis", + "feedback.validation.required.password-repository": "Mot de passe du référentiel", + "feedback.validation.required.password-repository-help": "Utilisé pour chiffrer le contenu du référentiel", + "feedback.validation.required.password-repository-hint": "Entrez le mot de passe du référentiel", + "feedback.validation.required.repository-password-confirm": "Confirmer le mot de passe du référentiel", + "feedback.validation.required.repository-password-confirm-again": "entrez à nouveau le mot de passe du référentiel", "feedback.validation.required.valid-number-or-empty": "Doit être un numéro valide ou vide", "policies.feedback.find.count_one": "{{count}} politiques correspondant aux critères ont été trouvées", "policies.feedback.find.count_other": "{{count}} politiques correspondant aux critères ont été trouvées", diff --git a/public/locales/it/translation.json b/public/locales/it/translation.json index 4cdcb1a..32f8339 100644 --- a/public/locales/it/translation.json +++ b/public/locales/it/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Utilizza token di archivio", "feedback.provider.webdav-server": "Server WebDAV", "feedback.repository.configuration": "Configurazione di archiviazione", + "feedback.repository.create-repository-new": "Crea nuovo archivio", + "feedback.repository.create-repository-new-help": "Inserisci una password complessa per creare il repository Kopia nello spazio di archiviazione fornito.", + "feedback.repository.encryption": "Crittografia", "feedback.repository.kopia-server-parameters": "Parametri del server Copia", "feedback.repository.name-default": "Il mio deposito", "feedback.repository.provider-selection": "Seleziona il tipo di archiviazione", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "Tema", "feedback.ui.theme-help": "Il tema attivo corrente", "feedback.ui.theme-select": "Seleziona il tema", + "feedback.validation.azure.access-key": "Chiave di accesso", + "feedback.validation.azure.access-key-hint": "Inserisci la chiave di accesso segreta", + "feedback.validation.azure.azure-storage-domain": "Dominio di archiviazione di Azure", + "feedback.validation.azure.azure-storage-domain-hint": "Inserisci il dominio di archiviazione o lascia vuoto il campo predefinito \"blob.core.windows.net\"", + "feedback.validation.azure.container": "Contenitore", + "feedback.validation.azure.container-hint": "Inserisci il nome del contenitore", + "feedback.validation.azure.object-name-prefix": "Prefisso nome oggetto", + "feedback.validation.azure.object-name-prefix-hint": "Inserisci il prefisso del nome dell'oggetto o lascia vuoto", + "feedback.validation.azure.sas-token": "Gettone SAS", + "feedback.validation.azure.sas-token-hint": "Inserisci il token SAS segreto", + "feedback.validation.azure.storage-account": "Conto di archiviazione", + "feedback.validation.azure.storage-account-hint": "Immettere il nome dell'account di archiviazione", + "feedback.validation.b2.bucket-name": "Benna B2", + "feedback.validation.b2.bucket-name-hint": "Inserisci il nome del bucket", + "feedback.validation.b2.key": "Chiave", + "feedback.validation.b2.key-hint": "Inserisci l'applicazione segreta o la chiave dell'account", + "feedback.validation.b2.key-id": "ID chiave", + "feedback.validation.b2.key-id-hint": "Inserisci l'ID della chiave dell'applicazione o dell'account", + "feedback.validation.b2.object-name-prefix": "Prefisso nome oggetto", + "feedback.validation.b2.object-name-prefix-hint": "Inserisci il prefisso del nome dell'oggetto o lascia vuoto", + "feedback.validation.gcs.bucket-name": "Benna GCS", + "feedback.validation.gcs.bucket-name-hint": "Inserisci il nome del bucket", + "feedback.validation.gcs.credentials-file": "File delle credenziali", + "feedback.validation.gcs.credentials-file-hint": "Immettere il nome del file JSON delle credenziali", + "feedback.validation.gcs.credentials-json": "Credenziali JSON", + "feedback.validation.gcs.credentials-json-paste": "Incolla qui le credenziali JSON", + "feedback.validation.gcs.object-name-prefix": "Prefisso nome oggetto", + "feedback.validation.gcs.object-name-prefix-hint": "Inserisci il prefisso del nome dell'oggetto o lascia vuoto", "feedback.validation.invalid-times-of-day": "Orari del giorno non validi", + "feedback.validation.local.directory-path": "Percorso della directory", + "feedback.validation.local.directory-path-hint": "Inserisci il percorso della directory in cui desideri archiviare i file del repository", "feedback.validation.optional.valid-number-or-empty": "Deve essere un numero valido o vuoto", "feedback.validation.passwords-dont-match": "Le password non corrispondono", "feedback.validation.required.directory": "campo obbligatorio", "feedback.validation.required.field": "campo obbligatorio", + "feedback.validation.required.password-repository": "Password dell'archivio", + "feedback.validation.required.password-repository-help": "Utilizzato per crittografare il contenuto del repository", + "feedback.validation.required.password-repository-hint": "Inserisci la password dell'archivio", + "feedback.validation.required.repository-password-confirm": "Conferma la password dell'archivio", + "feedback.validation.required.repository-password-confirm-again": "immettere nuovamente la password del repository", "feedback.validation.required.valid-number-or-empty": "Deve essere un numero valido o vuoto", "policies.feedback.find.count_one": "Trovata {{count}} policy corrispondente ai criteri", "policies.feedback.find.count_other": "Trovate {{count}} politiche che corrispondono ai criteri", diff --git a/public/locales/jp/translation.json b/public/locales/jp/translation.json index 4d2e366..0acdd5b 100644 --- a/public/locales/jp/translation.json +++ b/public/locales/jp/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Use Repository Token", "feedback.provider.webdav-server": "WebDAV Server", "feedback.repository.configuration": "Storage Configuration", + "feedback.repository.create-repository-new": "Create New Repository", + "feedback.repository.create-repository-new-help": "Enter a strong password to create Kopia repository in the provided storage.", + "feedback.repository.encryption": "Encryption", "feedback.repository.kopia-server-parameters": "Kopia Server Parameters", "feedback.repository.name-default": "My Repository", "feedback.repository.provider-selection": "Select Storage Type", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "テーマ", "feedback.ui.theme-help": "現在のアクティブなテーマ", "feedback.ui.theme-select": "テーマを選択", + "feedback.validation.azure.access-key": "Access Key", + "feedback.validation.azure.access-key-hint": "Enter secret access key", + "feedback.validation.azure.azure-storage-domain": "Azure Storage Domain", + "feedback.validation.azure.azure-storage-domain-hint": "feedback.validation.azure.azure-storage-domain-hint", + "feedback.validation.azure.container": "Container", + "feedback.validation.azure.container-hint": "Enter container name", + "feedback.validation.azure.object-name-prefix": "Object Name Prefix", + "feedback.validation.azure.object-name-prefix-hint": "Enter object name prefix or leave empty", + "feedback.validation.azure.sas-token": "SAS Token", + "feedback.validation.azure.sas-token-hint": "Enter secret SAS Token", + "feedback.validation.azure.storage-account": "Storage Account", + "feedback.validation.azure.storage-account-hint": "Enter storage account name", + "feedback.validation.b2.bucket-name": "B2 Bucket", + "feedback.validation.b2.bucket-name-hint": "Enter bucket name", + "feedback.validation.b2.key": "Key", + "feedback.validation.b2.key-hint": "Enter secret application or account key", + "feedback.validation.b2.key-id": "Key ID", + "feedback.validation.b2.key-id-hint": "Enter application or account key ID", + "feedback.validation.b2.object-name-prefix": "Object Name Prefix", + "feedback.validation.b2.object-name-prefix-hint": "Enter object name prefix or leave empty", + "feedback.validation.gcs.bucket-name": "GCS Bucket", + "feedback.validation.gcs.bucket-name-hint": "Enter bucket name", + "feedback.validation.gcs.credentials-file": "Credentials File", + "feedback.validation.gcs.credentials-file-hint": "Enter name of credentials JSON file", + "feedback.validation.gcs.credentials-json": "Credentials JSON", + "feedback.validation.gcs.credentials-json-paste": "Paste JSON credentials here", + "feedback.validation.gcs.object-name-prefix": "Object Name Prefix", + "feedback.validation.gcs.object-name-prefix-hint": "Enter object name prefix or leave empty", "feedback.validation.invalid-times-of-day": "Invalid Times of Day", + "feedback.validation.local.directory-path": "Directory Path", + "feedback.validation.local.directory-path-hint": "Enter directory path where you want to store repository files", "feedback.validation.optional.valid-number-or-empty": "Must be a valid number or empty", "feedback.validation.passwords-dont-match": "Passwords don't match", "feedback.validation.required.directory": "Required field", "feedback.validation.required.field": "Required field", + "feedback.validation.required.password-repository": "Repository Password", + "feedback.validation.required.password-repository-help": "Used to encrypt the repository's contents", + "feedback.validation.required.password-repository-hint": "Enter repository password", + "feedback.validation.required.repository-password-confirm": "Confirm Repository Password", + "feedback.validation.required.repository-password-confirm-again": "enter repository password again", "feedback.validation.required.valid-number-or-empty": "Must be a valid number or empty", "policies.feedback.find.count_one": "Found {{count}} policy matching the criteria", "policies.feedback.find.count_other": "Found {{count}} policies matching the criteria", diff --git a/public/locales/pl/translation.json b/public/locales/pl/translation.json index 8cb6506..482270c 100644 --- a/public/locales/pl/translation.json +++ b/public/locales/pl/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Użyj tokena repozytorium", "feedback.provider.webdav-server": "Serwer WebDAV", "feedback.repository.configuration": "Konfiguracja pamięci", + "feedback.repository.create-repository-new": "Utwórz nowe repozytorium", + "feedback.repository.create-repository-new-help": "Wprowadź silne hasło, aby utworzyć repozytorium Kopia w udostępnionym magazynie.", + "feedback.repository.encryption": "Szyfrowanie", "feedback.repository.kopia-server-parameters": "Parametry serwera Kopia", "feedback.repository.name-default": "Moje repozytorium", "feedback.repository.provider-selection": "Wybierz Typ przechowywania", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "Kolorystyka", "feedback.ui.theme-help": "Aktywny schemat kolorów", "feedback.ui.theme-select": "Wybierz schemat kolorów", + "feedback.validation.azure.access-key": "Klucz dostępu", + "feedback.validation.azure.access-key-hint": "Wprowadź tajny klucz dostępu", + "feedback.validation.azure.azure-storage-domain": "Domena magazynu Azure", + "feedback.validation.azure.azure-storage-domain-hint": "Wprowadź domenę magazynu lub pozostaw puste dla domyślnego „blob.core.windows.net”", + "feedback.validation.azure.container": "Pojemnik", + "feedback.validation.azure.container-hint": "Wpisz nazwę kontenera", + "feedback.validation.azure.object-name-prefix": "Przedrostek nazwy obiektu", + "feedback.validation.azure.object-name-prefix-hint": "Wprowadź przedrostek nazwy obiektu lub pozostaw puste", + "feedback.validation.azure.sas-token": "Token SAS-owy", + "feedback.validation.azure.sas-token-hint": "Wprowadź tajny token SAS", + "feedback.validation.azure.storage-account": "Konto magazynu", + "feedback.validation.azure.storage-account-hint": "Wprowadź nazwę konta magazynu", + "feedback.validation.b2.bucket-name": "Wiadro B2", + "feedback.validation.b2.bucket-name-hint": "Wpisz nazwę zasobnika", + "feedback.validation.b2.key": "Klucz", + "feedback.validation.b2.key-hint": "Wprowadź tajną aplikację lub klucz konta", + "feedback.validation.b2.key-id": "Identyfikator klucza", + "feedback.validation.b2.key-id-hint": "Wprowadź identyfikator klucza aplikacji lub konta", + "feedback.validation.b2.object-name-prefix": "Przedrostek nazwy obiektu", + "feedback.validation.b2.object-name-prefix-hint": "Wprowadź przedrostek nazwy obiektu lub pozostaw puste", + "feedback.validation.gcs.bucket-name": "Wiadro GCS", + "feedback.validation.gcs.bucket-name-hint": "Wpisz nazwę zasobnika", + "feedback.validation.gcs.credentials-file": "Plik poświadczeń", + "feedback.validation.gcs.credentials-file-hint": "Wprowadź nazwę pliku JSON poświadczeń", + "feedback.validation.gcs.credentials-json": "Poświadczenia JSON", + "feedback.validation.gcs.credentials-json-paste": "Wklej tutaj dane uwierzytelniające JSON", + "feedback.validation.gcs.object-name-prefix": "Przedrostek nazwy obiektu", + "feedback.validation.gcs.object-name-prefix-hint": "Wprowadź przedrostek nazwy obiektu lub pozostaw puste", "feedback.validation.invalid-times-of-day": "Nieprawidłowe pory dnia", + "feedback.validation.local.directory-path": "Ścieżka katalogu", + "feedback.validation.local.directory-path-hint": "Wprowadź ścieżkę katalogu, w którym chcesz przechowywać pliki repozytorium", "feedback.validation.optional.valid-number-or-empty": "Musi to być prawidłowy numer lub pusty", "feedback.validation.passwords-dont-match": "Hasła nie pasują", "feedback.validation.required.directory": "Pole wymagane", "feedback.validation.required.field": "Pole wymagane", + "feedback.validation.required.password-repository": "Hasło do repozytorium", + "feedback.validation.required.password-repository-help": "Służy do szyfrowania zawartości repozytorium", + "feedback.validation.required.password-repository-hint": "Wprowadź hasło do repozytorium", + "feedback.validation.required.repository-password-confirm": "Potwierdź hasło do repozytorium", + "feedback.validation.required.repository-password-confirm-again": "wprowadź ponownie hasło do repozytorium", "feedback.validation.required.valid-number-or-empty": "Musi to być prawidłowy numer lub pusty", "policies.feedback.find.count_one": "Znaleziono {{count}} zasad spełniających kryteria", "policies.feedback.find.count_other": "Znaleziono {{count}} zasad spełniających kryteria", diff --git a/public/locales/ru/translation.json b/public/locales/ru/translation.json index 4a100c8..d74b64b 100644 --- a/public/locales/ru/translation.json +++ b/public/locales/ru/translation.json @@ -43,6 +43,9 @@ "feedback.provider.use-repository-token": "Использовать токен репозитория", "feedback.provider.webdav-server": "ВебДАВ-сервер", "feedback.repository.configuration": "Конфигурация хранилища", + "feedback.repository.create-repository-new": "Создать новый репозиторий", + "feedback.repository.create-repository-new-help": "Введите надежный пароль, чтобы создать репозиторий Kopia в предоставленном хранилище.", + "feedback.repository.encryption": "Шифрование", "feedback.repository.kopia-server-parameters": "Параметры сервера Копия", "feedback.repository.name-default": "Мой репозиторий", "feedback.repository.provider-selection": "Выберите тип хранилища", @@ -66,11 +69,46 @@ "feedback.ui.theme-description": "Тема", "feedback.ui.theme-help": "Текущая активная тема", "feedback.ui.theme-select": "Выберите тему", + "feedback.validation.azure.access-key": "Ключ доступа", + "feedback.validation.azure.access-key-hint": "Введите секретный ключ доступа", + "feedback.validation.azure.azure-storage-domain": "Домен хранилища Azure", + "feedback.validation.azure.azure-storage-domain-hint": "Введите домен хранения или оставьте пустым для значения по умолчанию «blob.core.windows.net».", + "feedback.validation.azure.container": "Контейнер", + "feedback.validation.azure.container-hint": "Введите имя контейнера", + "feedback.validation.azure.object-name-prefix": "Префикс имени объекта", + "feedback.validation.azure.object-name-prefix-hint": "Введите префикс имени объекта или оставьте пустым.", + "feedback.validation.azure.sas-token": "Токен SAS", + "feedback.validation.azure.sas-token-hint": "Введите секретный токен SAS", + "feedback.validation.azure.storage-account": "Учетная запись хранения", + "feedback.validation.azure.storage-account-hint": "Введите имя учетной записи хранения", + "feedback.validation.b2.bucket-name": "Ведро Б2", + "feedback.validation.b2.bucket-name-hint": "Введите название сегмента", + "feedback.validation.b2.key": "Ключ", + "feedback.validation.b2.key-hint": "Введите секретный ключ приложения или аккаунта", + "feedback.validation.b2.key-id": "Идентификатор ключа", + "feedback.validation.b2.key-id-hint": "Введите идентификатор ключа приложения или учетной записи", + "feedback.validation.b2.object-name-prefix": "Префикс имени объекта", + "feedback.validation.b2.object-name-prefix-hint": "Введите префикс имени объекта или оставьте пустым.", + "feedback.validation.gcs.bucket-name": "Сегмент ГКС", + "feedback.validation.gcs.bucket-name-hint": "Введите название сегмента", + "feedback.validation.gcs.credentials-file": "Файл учетных данных", + "feedback.validation.gcs.credentials-file-hint": "Введите имя файла JSON учетных данных", + "feedback.validation.gcs.credentials-json": "Учетные данные JSON", + "feedback.validation.gcs.credentials-json-paste": "Вставьте сюда учетные данные JSON.", + "feedback.validation.gcs.object-name-prefix": "Префикс имени объекта", + "feedback.validation.gcs.object-name-prefix-hint": "Введите префикс имени объекта или оставьте пустым.", "feedback.validation.invalid-times-of-day": "Неверное время суток", + "feedback.validation.local.directory-path": "Путь к каталогу", + "feedback.validation.local.directory-path-hint": "Введите путь к каталогу, в котором вы хотите хранить файлы репозитория.", "feedback.validation.optional.valid-number-or-empty": "Должно быть действительным числом или пустым.", "feedback.validation.passwords-dont-match": "Пароли не совпадают", "feedback.validation.required.directory": "Обязательное поле", "feedback.validation.required.field": "Обязательное поле", + "feedback.validation.required.password-repository": "Пароль репозитория", + "feedback.validation.required.password-repository-help": "Используется для шифрования содержимого репозитория.", + "feedback.validation.required.password-repository-hint": "Введите пароль репозитория", + "feedback.validation.required.repository-password-confirm": "Подтвердите пароль репозитория", + "feedback.validation.required.repository-password-confirm-again": "введите пароль хранилища еще раз", "feedback.validation.required.valid-number-or-empty": "Должно быть действительным числом или пустым.", "policies.feedback.find.count_one": "Найдено {{count}} политики, соответствующей критериям.", "policies.feedback.find.count_other": "Найдено {{count}} политик, соответствующих критериям.", diff --git a/src/components/SetupRepository.jsx b/src/components/SetupRepository.jsx index 860af13..dbfc7f2 100644 --- a/src/components/SetupRepository.jsx +++ b/src/components/SetupRepository.jsx @@ -39,7 +39,7 @@ const supportedProviders = [ { provider: "webdav", description: 'feedback.provider.webdav-server', component: SetupRepositoryWebDAV }, { provider: "_server", description: 'feedback.provider.kopia-repository-server', component: SetupRepositoryServer }, { provider: "_token", description: 'feedback.provider.use-repository-token', component: SetupRepositoryToken }, - ]; +]; export class SetupRepository extends Component { constructor() { @@ -333,8 +333,7 @@ export class SetupRepository extends Component { variant="primary" aria-controls="advanced-options-div" aria-expanded={this.state.showAdvanced} - size="sm" - > + size="sm"> {text} ; @@ -342,11 +341,11 @@ export class SetupRepository extends Component { renderConfirmCreate() { return
-

Create New Repository

-

Enter a strong password to create Kopia repository in the provided storage.

+

{i18n.t('feedback.repository.create-repository-new')}

+

{i18n.t('feedback.repository.create-repository-new-help')}

- {RequiredField(this, "Repository Password", "password", { autoFocus: true, type: "password", placeholder: "enter repository password" }, "Used to encrypt the repository's contents")} - {RequiredField(this, "Confirm Repository Password", "confirmPassword", { type: "password", placeholder: "enter repository password again" })} + {RequiredField(this, i18n.t('feedback.validation.required.password-repository'), "password", { autoFocus: true, type: "password", placeholder: i18n.t('feedback.validation.required.password-repository-hint') }, i18n.t('feedback.validation.required.password-repository-help'))} + {RequiredField(this, i18n.t('feedback.validation.required.repository-password-confirm'), "confirmPassword", { type: "password", placeholder: i18n.t('feedback.validation.required.repository-password-confirm-again')})}
{this.toggleAdvancedButton()} @@ -355,7 +354,7 @@ export class SetupRepository extends Component {
- Encryption + {i18n.t('feedback.repository.encryption')} Hash Algorithm + name="hash" + onChange={this.handleChange} + data-testid="control-hash" + value={this.state.hash}> {this.state.algorithms.hash.map(x => toAlgorithmOption(x, this.state.defaultHash))} Splitter + name="splitter" + onChange={this.handleChange} + data-testid="control-splitter" + value={this.state.splitter}> {this.state.algorithms.splitter.map(x => toAlgorithmOption(x, this.state.defaultSplitter))} @@ -389,10 +388,10 @@ export class SetupRepository extends Component { Repository Format + name="formatVersion" + onChange={this.handleChange} + data-testid="control-formatVersion" + value={this.state.formatVersion}> @@ -400,10 +399,10 @@ export class SetupRepository extends Component { Error Correction Overhead + name="eccOverheadPercent" + onChange={this.handleChange} + data-testid="control-eccOverheadPercent" + value={this.state.eccOverheadPercent}> @@ -431,7 +430,7 @@ export class SetupRepository extends Component { [EXPERIMENTAL] Error correction can help protect from certain kinds of data corruption due to spontaneous bit flips in the storage media. Click here to - learn more. + learn more. {this.overrideUsernameHostnameRow()} diff --git a/src/components/SetupRepositoryAzure.jsx b/src/components/SetupRepositoryAzure.jsx index b32e22c..492df68 100644 --- a/src/components/SetupRepositoryAzure.jsx +++ b/src/components/SetupRepositoryAzure.jsx @@ -3,6 +3,7 @@ import Row from 'react-bootstrap/Row'; import { handleChange, validateRequiredFields } from '../forms'; import { OptionalField } from '../forms/OptionalField'; import { RequiredField } from '../forms/RequiredField'; +import i18n from '../utils/i18n'; export class SetupRepositoryAzure extends Component { constructor(props) { @@ -21,16 +22,16 @@ export class SetupRepositoryAzure extends Component { render() { return <> - {RequiredField(this, "Container", "container", { autoFocus: true, placeholder: "enter container name" })} - {OptionalField(this, "Object Name Prefix", "prefix", { placeholder: "enter object name prefix or leave empty" })} + {RequiredField(this, i18n.t('feedback.validation.azure.container'), "container", { autoFocus: true, placeholder: i18n.t('feedback.validation.azure.container-hint') })} + {OptionalField(this, i18n.t('feedback.validation.azure.object-name-prefix'), "prefix", { placeholder: i18n.t('feedback.validation.azure.object-name-prefix-hint') })} - {RequiredField(this, "Storage Account", "storageAccount", { placeholder: "enter storage account name" })} - {OptionalField(this, "Access Key", "storageKey", { placeholder: "enter secret access key", type: "password" })} + {RequiredField(this, i18n.t('feedback.validation.azure.storage-account'), "storageAccount", { placeholder: i18n.t('feedback.validation.azure.storage-account-hint') })} + {OptionalField(this, i18n.t('feedback.validation.azure.access-key'), "storageKey", { placeholder: i18n.t('feedback.validation.azure.access-key-hint'), type: "password" })} - {OptionalField(this, "Azure Storage Domain", "storageDomain", { placeholder: "enter storage domain or leave empty for default 'blob.core.windows.net'" })} - {OptionalField(this, "SAS Token", "sasToken", { placeholder: "enter secret SAS Token", type: "password" })} + {OptionalField(this, i18n.t('feedback.validation.azure.azure-storage-domain'), "storageDomain", { placeholder: i18n.t('feedback.validation.azure.azure-storage-domain-hint') })} + {OptionalField(this, i18n.t('feedback.validation.azure.sas-token'), "sasToken", { placeholder: i18n.t('feedback.validation.azure.sas-token-hint'), type: "password" })} ; } diff --git a/src/components/SetupRepositoryB2.jsx b/src/components/SetupRepositoryB2.jsx index 73fffd1..b442bdb 100644 --- a/src/components/SetupRepositoryB2.jsx +++ b/src/components/SetupRepositoryB2.jsx @@ -3,6 +3,7 @@ import Row from 'react-bootstrap/Row'; import { handleChange, validateRequiredFields } from '../forms'; import { RequiredField } from '../forms/RequiredField'; import { OptionalField } from '../forms/OptionalField'; +import i18n from '../utils/i18n'; export class SetupRepositoryB2 extends Component { constructor(props) { @@ -21,14 +22,14 @@ export class SetupRepositoryB2 extends Component { render() { return <> - {RequiredField(this, "B2 Bucket", "bucket", { autoFocus: true, placeholder: "enter bucket name" })} + {RequiredField(this, i18n.t('feedback.validation.b2.bucket-name'), "bucket", { autoFocus: true, placeholder: i18n.t('feedback.validation.b2.bucket-name-hint') })} - {RequiredField(this, "Key ID", "keyId", { placeholder: "enter application or account key ID" })} - {RequiredField(this, "Key", "key", { placeholder: "enter secret application or account key", type: "password" })} + {RequiredField(this, i18n.t('feedback.validation.b2.key-id'), "keyId", { placeholder: i18n.t('feedback.validation.b2.key-id-hint') })} + {RequiredField(this, i18n.t('feedback.validation.b2.key'), "key", { placeholder: i18n.t('feedback.validation.b2.key-hint'), type: "password" })} - {OptionalField(this, "Object Name Prefix", "prefix", { placeholder: "enter object name prefix or leave empty" })} + {OptionalField(this, i18n.t('feedback.validation.b2.object-name-prefix'), "prefix", { placeholder: i18n.t('feedback.validation.b2.object-name-prefix-hint') })} ; } diff --git a/src/components/SetupRepositoryFilesystem.jsx b/src/components/SetupRepositoryFilesystem.jsx index 6f3dbcd..5b14fa2 100644 --- a/src/components/SetupRepositoryFilesystem.jsx +++ b/src/components/SetupRepositoryFilesystem.jsx @@ -1,6 +1,7 @@ import React, { Component } from 'react'; import { handleChange, validateRequiredFields } from '../forms'; import { RequiredDirectory } from '../forms/RequiredDirectory'; +import i18n from '../utils/i18n'; export class SetupRepositoryFilesystem extends Component { constructor(props) { @@ -18,7 +19,7 @@ export class SetupRepositoryFilesystem extends Component { render() { return <> - {RequiredDirectory(this, "Directory Path", "path", { autoFocus: true, placeholder: "enter directory path where you want to store repository files"})} + {RequiredDirectory(this, i18n.t('feedback.validation.local.directory-path'), "path", { autoFocus: true, placeholder: i18n.t('feedback.validation.local.directory-path-hint')})} ; } } diff --git a/src/components/SetupRepositoryGCS.jsx b/src/components/SetupRepositoryGCS.jsx index cb303e9..b57b2fb 100644 --- a/src/components/SetupRepositoryGCS.jsx +++ b/src/components/SetupRepositoryGCS.jsx @@ -3,6 +3,7 @@ import Row from 'react-bootstrap/Row'; import { handleChange, validateRequiredFields } from '../forms'; import { OptionalField } from '../forms/OptionalField'; import { RequiredField } from '../forms/RequiredField'; +import i18n from '../utils/i18n'; export class SetupRepositoryGCS extends Component { constructor(props) { @@ -21,14 +22,14 @@ export class SetupRepositoryGCS extends Component { render() { return <> - {RequiredField(this, "GCS Bucket", "bucket", { autoFocus: true, placeholder: "enter bucket name" })} - {OptionalField(this, "Object Name Prefix", "prefix", { placeholder: "enter object name prefix or leave empty", type: "password" })} + {RequiredField(this, i18n.t('feedback.validation.gcs.bucket-name'), "bucket", { autoFocus: true, placeholder: i18n.t('feedback.validation.gcs.bucket-name-hint') })} + {OptionalField(this, i18n.t('feedback.validation.gcs.object-name-prefix'), "prefix", { placeholder: i18n.t('feedback.validation.gcs.object-name-prefix-hint'), type: "password" })} - {OptionalField(this, "Credentials File", "credentialsFile", { placeholder: "enter name of credentials JSON file" })} + {OptionalField(this, i18n.t('feedback.validation.gcs.credentials-file'), "credentialsFile", { placeholder: i18n.t('feedback.validation.gcs.credentials-file-hint') })} - {OptionalField(this, "Credentials JSON", "credentials", { placeholder: "paste JSON credentials here", as: "textarea", rows: 5 })} + {OptionalField(this, i18n.t('feedback.validation.gcs.credentials-json'), "credentials", { placeholder: i18n.t('feedback.validation.gcs.credentials-json-paste'), as: "textarea", rows: 5 })} ; } diff --git a/src/pages/SnapshotDirectory.jsx b/src/pages/SnapshotDirectory.jsx index 7f051a3..79645ba 100644 --- a/src/pages/SnapshotDirectory.jsx +++ b/src/pages/SnapshotDirectory.jsx @@ -70,7 +70,7 @@ export class SnapshotDirectory extends Component { } mount() { - axios.post('/api/v1/mounts', { "root": this.state.oid} ).then(result => { + axios.post('/api/v1/mounts', { "root": this.state.oid }).then(result => { this.setState({ mountInfo: result.data, }); @@ -111,6 +111,10 @@ export class SnapshotDirectory extends Component { document.execCommand("copy"); } + navigateTo(path) { + this.props.history.push(path); + } + render() { let { items, isLoading, error } = this.state; if (error) { @@ -132,18 +136,15 @@ export class SnapshotDirectory extends Component { : <> - + } -   - -   + {i18n.t('snapshot.feedback.directory.mount.restore')} -   - +
diff --git a/src/tests/Language.test.jsx b/src/tests/Language.test.jsx index 2e9f29e..bd68277 100644 --- a/src/tests/Language.test.jsx +++ b/src/tests/Language.test.jsx @@ -1,28 +1,62 @@ -import { render, screen } from '@testing-library/react' import { expect, test } from '@jest/globals'; +const { sync: globSync } = require('glob'); + +const localesPaths = globSync('./public/locales/*/*.json', { realpath: true }); +const srcPaths = globSync('./src/**/*.+(tsx|ts|jsx)', { realpath: true }); -jest.mock('react-i18next', () => ({ - // this mock makes sure any components using the translate hook can use it without a warning being shown - useTranslation: () => { - return { - t: (str) => str, - i18n: { - changeLanguage: () => new Promise(() => {}), - }, - }; - }, - initReactI18next: { - type: '3rdParty', - init: () => {}, - } - })); + +function computeIntersection(dataA, dataB) { + return dataA.filter(element => dataB.includes(element)); +} /** * */ -describe('Check tranlations', () => { - test('Translations should not have unused keys', () => { - }) +describe('Check completeness of tranlations', () => { + test('Translations should not have unused keys', () => { + }) }) +/** + * This test checks for empty strings within each translation file. + * If an empty string exists, the test will fail. + */ +describe('Check for empty translations', () => { + test('Translations should not be emtpy', async () => { + for (const localeFile in localesPaths) { + let locale = localesPaths[localeFile] + let data = require(locale); + for (const key in data) { + expect(data[key]).toBeTruthy(); + } + } + }) +}) + +/** + * The test checks whether the intersection of two json sets is equal + * to the length of the primary json key set. + * + * Each file is checked against the others. + */ +describe('Check that translations are in sync', () => { + test('All translations should be in sync with each other', () => { + for (const localeF1 in localesPaths) { + let l1 = localesPaths[localeF1] + for (const localeF2 in localesPaths) { + let l2 = localesPaths[localeF2] + // We do not have to check the files with itself + if (l1 == l2) { + break; + } + let dataA = require(l1) + let dataB = require(l2) + let keysA = Object.keys(dataA) + let keysB = Object.keys(dataB) + let intersection = computeIntersection(keysA, keysB) + expect(intersection.length).toEqual(keysA.length) + } + } + }) +})