Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idva6 2030 validate locales v2 #161

Merged
merged 4 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions locales/cy/dashboard.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@
"remove_users": "[CY] remove users",
"suspended_warning_text": " [CY] has been suspended. You will not be able to file or tell us you have verified someone's identity.",
"tell_companies_house_id": "[CY] Tell Companies House you have verified someone's identity",
"tell_us_about_any_changes": "Tell us about changes to the:",
"tell_us_about_any_changes": "[CY] Tell us about changes to the:",
"tell_us_about_any_changes_within": "[CY] You must tell us about any changes within 14 days.",
"tell_us_if": "[CY] Tell us if ",
"update_authorised_agent": "[CY] Update authorised agent's details",
"view_users": "[CY] View users",
"view_users_who_have_been_added": "[CY] view users who have been added",
"warning": "[CY] Warning",
"you_can": "[CY] You can",
"you_can_view_all_users_who": "[CY] You can view all users who have been added to this account.",
"you_cannot_file_as": "[CY] You cannot file as an authorised agent because ",
"you_cannot_tell_us": "[CY] You cannot tell us you've verified someone's identity because ",
Expand Down
3 changes: 1 addition & 2 deletions locales/cy/manage-users.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
"account_owners": "[CY] Account owners",
"add_a_user": "[CY] Add a user",
"administrators": "[CY] Administrators",
"back_link": "[CY] Return to authorised agent services",
"back_link_to_authorised_agent_services": "[CY] Return to authorised agent services",
"cancel_search": "[CY] Cancel search",
"change_role": "[CY] Change role",
"change_users_role": "[CY] Change user’s role",
"email_address": "[CY] Email address",
"enter_the_users_full_email_address": "[CY] Enter the user’s full email address",
"errors_enter_an_email_address_in_the_correct_format": "[CY] Enter an email address in the correct format, like name@example.com",
"for": "[CY] for",
Expand Down
1 change: 0 additions & 1 deletion locales/en/dashboard.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"view_users": "View users",
"view_users_who_have_been_added": "view users who have been added",
"warning": "Warning",
"you_can": "You can",
"you_can_view_all_users_who": "You can view all users who have been added to this account.",
"you_cannot_file_as": "You cannot file as an authorised agent because ",
"you_cannot_tell_us": "You cannot tell us you've verified someone's identity because ",
Expand Down
3 changes: 1 addition & 2 deletions locales/en/manage-users.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
"account_owners": "Account owners",
"add_a_user": "Add a user",
"administrators": "Administrators",
"back_link": "Return to authorised agent services",
"back_link_to_authorised_agent_services": "Return to authorised agent services",
"cancel_search": "Cancel search",
"change_role": "Change role",
"change_users_role": "Change user’s role",
"email_address": "Email address",
"enter_the_users_full_email_address": "Enter the user’s full email address",
"errors_enter_an_email_address_in_the_correct_format": "Enter an email address in the correct format, like name@example.com",
"for": "for",
Expand Down
10 changes: 9 additions & 1 deletion src/views/manage-users.njk
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
{% from "govuk/components/tabs/macro.njk" import govukTabs %}
{% from "govuk/components/error-message/macro.njk" import govukErrorMessage %}
{% from "govuk/components/pagination/macro.njk" import govukPagination %}
{% from "govuk/components/back-link/macro.njk" import govukBackLink %}

{% extends "layouts/default.njk" %}

{% block back_link %}
{% include "partials/back_link.njk" %}
{{ govukBackLink({
text: lang.back_link_to_authorised_agent_services,
href: backLinkUrl,
attributes: {
id: "back-link-to-previous-page"
}
})
}}
{% endblock %}

{% block main_content %}
Expand Down
130 changes: 130 additions & 0 deletions test/src/locales/locales.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import fs from "fs";
import path from "path";
import * as enCommon from "../../../locales/en/common.json";
import * as cyCommon from "../../../locales/cy/common.json";

const englishDirectory = "../../../locales/en/";
const welshDirectory = "../../../locales/cy/";

const englishTranslationFiles = fs.readdirSync(path.resolve(__dirname, englishDirectory));
const englishTranslationFilesExcludeCommon = englishTranslationFiles.filter(str => str !== "common.json");
const welshTranslationFiles = fs.readdirSync(path.resolve(__dirname, welshDirectory));
const welshTranslationFilesExcludeCommon = welshTranslationFiles.filter(str => str !== "common.json");

const findMissingKeys = function (
original: Record<string, unknown>,
toCheck: Record<string, unknown>,
previousPath = "",
output: string[] = []
) {
for (const key in original) {
const currentPath = previousPath ? `${previousPath} -> ${key}` : key;

if (typeof original[key] === "object") {
if (toCheck !== undefined) {
findMissingKeys(
original[key] as Record<string, unknown>,
toCheck[key] as Record<string, unknown>,
currentPath,
output
);
} else {
findMissingKeys(original[key] as Record<string, unknown>, {}, currentPath, output);
}
} else {
if (toCheck === undefined || toCheck[key] === undefined) {
output.push(`No match for: ${currentPath}`);
}
}
}
return output;
};

function haveAnyMatchingKeys (obj1:Record<string, unknown>, obj2:Record<string, unknown>) {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
const matchingKeys = keys1.filter(key => keys2.includes(key));
if (matchingKeys.length > 0) {
console.log("Matching keys with common found:", matchingKeys);
return true;
}
return false;
}

function haveSameValueForAnyKey (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
obj1: Record<string, any>, obj2: Record<string, any>, path = ""): boolean {
for (const key in obj1) {
// eslint-disable-next-line no-prototype-builtins
if (obj1.hasOwnProperty(key)) {
const newPath = path ? `${path}.${key}` : key; // Track the key path

// eslint-disable-next-line no-prototype-builtins
if (obj2.hasOwnProperty(key)) {
if (
typeof obj1[key] === "object" &&
obj1[key] !== null &&
typeof obj2[key] === "object" &&
obj2[key] !== null
) {
if (haveSameValueForAnyKey(obj1[key], obj2[key], newPath)) {
return true;
}
} else if (obj1[key] === obj2[key]) {
console.log(`Matching key with same value found: "${newPath}" -> ${obj1[key]}`);
return true;
}
}
}
}

return false;
}

describe("Check translation json files", () => {
it("There should not be any missing translation files for welsh translations", () => {
const missingFiles = englishTranslationFiles.filter(x => !welshTranslationFiles.includes(x));
expect(missingFiles).toEqual([]);
});

it("There should not be any missing translation files for english translations", () => {
const missingFiles = welshTranslationFiles.filter(x => !englishTranslationFiles.includes(x));
expect(missingFiles).toEqual([]);
});

test.each(welshTranslationFiles)("Check english translation file %s has no missing keys", file => {
const englishFile = fs.readFileSync(path.resolve(__dirname, englishDirectory + file), "utf-8");
const welshFile = fs.readFileSync(path.resolve(__dirname, welshDirectory + file), "utf-8");
const englishContents = JSON.parse(englishFile) as Record<string, unknown>;
const welshContents = JSON.parse(welshFile) as Record<string, unknown>;
expect(findMissingKeys(welshContents, englishContents)).toEqual([]);
});

test.each(englishTranslationFiles)("Check welsh translation file %s has no missing keys", file => {
const englishFile = fs.readFileSync(path.resolve(__dirname, englishDirectory + file), "utf-8");
const welshFile = fs.readFileSync(path.resolve(__dirname, welshDirectory + file), "utf-8");
const englishContents = JSON.parse(englishFile);
const welshContents = JSON.parse(welshFile);
expect(findMissingKeys(englishContents, welshContents)).toEqual([]);
});

test.each(welshTranslationFiles)("Check english, welsh translation file %s has no values the same", file => {
const englishFile = fs.readFileSync(path.resolve(__dirname, englishDirectory + file), "utf-8");
const welshFile = fs.readFileSync(path.resolve(__dirname, welshDirectory + file), "utf-8");
const englishContents = JSON.parse(englishFile) as Record<string, unknown>;
const welshContents = JSON.parse(welshFile) as Record<string, unknown>;
expect(haveSameValueForAnyKey(welshContents, englishContents)).toEqual(false);
});

test.each(englishTranslationFilesExcludeCommon)("Check english translation file %s has no shared keys with common", file => {
const englishFile = fs.readFileSync(path.resolve(__dirname, englishDirectory + file), "utf-8");
const englishContents = JSON.parse(englishFile);
expect(haveAnyMatchingKeys(englishContents, enCommon)).toBe(false);
});

test.each(welshTranslationFilesExcludeCommon)("Check welsh translation file %s has no shared keys with common", file => {
const welshFile = fs.readFileSync(path.resolve(__dirname, welshDirectory + file), "utf-8");
const welshContents = JSON.parse(welshFile);
expect(haveAnyMatchingKeys(welshContents, cyCommon)).toBe(false);
});
});
5 changes: 3 additions & 2 deletions test/src/routers/controllers/dashboardController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import mocks from "../../../mocks/all.middleware.mock";
import supertest from "supertest";
import app from "../../../../src/app";
import * as en from "../../../../locales/en/dashboard.json";
import * as enCommon from "../../../../locales/en/common.json";
import * as cy from "../../../../locales/cy/dashboard.json";
import * as sessionUtils from "../../../../src/lib/utils/sessionUtils";
import {
Expand Down Expand Up @@ -54,7 +55,7 @@ describe(`GET ${url}`, () => {
expect(decodedResponse).toContain(en.update_authorised_agent);
expect(decodedResponse).toContain(en.view_users_who_have_been_added);
expect(decodedResponse).toContain(en.warning);
expect(decodedResponse).toContain(en.you_can);
expect(decodedResponse).toContain(enCommon.you_can);
expect(decodedResponse).toContain(en.your_role);
expect(decodedResponse).toContain(en.close_the_authorised_agent);
expect(decodedResponse).toContain(en.tell_us_if);
Expand Down Expand Up @@ -83,7 +84,7 @@ describe(`GET ${url}`, () => {
expect(decodedResponse).toContain(en.remove_users);
expect(decodedResponse).toContain(en.tell_companies_house_id);
expect(decodedResponse).toContain(en.view_users_who_have_been_added);
expect(decodedResponse).toContain(en.you_can);
expect(decodedResponse).toContain(enCommon.you_can);
expect(decodedResponse).toContain(en.your_role);
});

Expand Down
4 changes: 2 additions & 2 deletions test/src/routers/controllers/manageUsersController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe("GET /authorised-agent/manage-users", () => {
expect(result.text).toContain(companyNumber);
expect(result.text).toContain(en.page_header);
expect(result.text).toContain(en.administrators);
expect(result.text).toContain(en.back_link);
expect(result.text).toContain(en.back_link_to_authorised_agent_services);
expect(result.text).toContain(en.standard_users);
expect(result.text).toContain(enCommon.email_address);
expect(result.text).toContain(en.name);
Expand All @@ -83,7 +83,7 @@ describe("GET /authorised-agent/manage-users", () => {
expect(result.status).toEqual(200);
expect(result.text).toContain(en.page_header_standard);
expect(result.text).toContain(en.administrators);
expect(result.text).toContain(en.back_link);
expect(result.text).toContain(en.back_link_to_authorised_agent_services);
expect(result.text).toContain(en.standard_users);
expect(result.text).toContain(enCommon.email_address);
expect(result.text).toContain(en.name);
Expand Down