diff --git a/apps/postgres/prisma/migrations/20260608155746_remove_channel_sensitivity_from_legacy_third_party_subscription/migration.sql b/apps/postgres/prisma/migrations/20260608155746_remove_channel_sensitivity_from_legacy_third_party_subscription/migration.sql new file mode 100644 index 000000000..edc30aef6 --- /dev/null +++ b/apps/postgres/prisma/migrations/20260608155746_remove_channel_sensitivity_from_legacy_third_party_subscription/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `channel` on the `legacy_third_party_subscription` table. All the data in the column will be lost. + - You are about to drop the column `sensitivity` on the `legacy_third_party_subscription` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE "legacy_third_party_subscription" DROP COLUMN "channel", +DROP COLUMN "sensitivity"; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/cy.ts b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/cy.ts index 1cdba190f..4cc447272 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/cy.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/cy.ts @@ -1,14 +1,7 @@ export const cy = { pageTitle: "Rheoli tanysgrifiadau trydydd parti", - channelLabel: "Dewiswch Sianel os gwelwch yn dda", - channelApiOption: "API", - sensitivityLabel: "Dewiswch sensitifrwydd os gwelwch yn dda", - sensitivityPublicOption: "Cyhoeddus", - sensitivityPrivateOption: "Preifat", - sensitivityClassifiedOption: "Cyfrinachol", listTypesLabel: "Dewiswch fathau rhestr os gwelwch yn dda", saveButtonText: "Cadarnhau tanysgrifiadau", errorSummaryTitle: "Mae yna broblem", - sensitivityRequired: "Dewiswch lefel sensitifrwydd", userNotFound: "Ni chanfuwyd defnyddiwr" }; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/en.ts b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/en.ts index a7920b07a..c6f1011a0 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/en.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/en.ts @@ -1,14 +1,7 @@ export const en = { pageTitle: "Manage third party subscriptions", - channelLabel: "Please select a Channel", - channelApiOption: "API", - sensitivityLabel: "Please select sensitivity", - sensitivityPublicOption: "Public", - sensitivityPrivateOption: "Private", - sensitivityClassifiedOption: "Classified", listTypesLabel: "Please select list types", saveButtonText: "Save subscriptions", errorSummaryTitle: "There is a problem", - sensitivityRequired: "Select a sensitivity level", userNotFound: "User not found" }; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.njk b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.njk index 38f6b3319..c5e4d10dc 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.njk +++ b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.njk @@ -1,17 +1,8 @@ {% extends "layouts/base-template.njk" %} {% from "govuk/components/button/macro.njk" import govukButton %} -{% from "govuk/components/radios/macro.njk" import govukRadios %} {% from "govuk/components/checkboxes/macro.njk" import govukCheckboxes %} {% from "govuk/components/error-summary/macro.njk" import govukErrorSummary %} -{% macro getError(errors, fieldId) -%} - {%- if errors -%} - {%- for error in errors -%} - {%- if error.href == fieldId -%}{{ error.text }}{%- endif -%} - {%- endfor -%} - {%- endif -%} -{%- endmacro %} - {% block content %}
@@ -27,52 +18,6 @@
- {{ govukRadios({ - name: "channel", - fieldset: { - legend: { - text: channelLabel, - classes: "govuk-fieldset__legend--m" - } - }, - items: [ - { - value: "API", - text: channelApiOption, - checked: currentChannel == "API" - } - ] - }) }} - - {% set sensitivityErrorText = getError(errors, "#sensitivity") %} - {{ govukRadios({ - name: "sensitivity", - fieldset: { - legend: { - text: sensitivityLabel, - classes: "govuk-fieldset__legend--m" - } - }, - errorMessage: { text: sensitivityErrorText } if sensitivityErrorText and sensitivityErrorText | length > 0 else undefined, - items: [ - { - value: "PUBLIC", - text: sensitivityPublicOption, - checked: currentSensitivity == "PUBLIC" - }, - { - value: "PRIVATE", - text: sensitivityPrivateOption, - checked: currentSensitivity == "PRIVATE" - }, - { - value: "CLASSIFIED", - text: sensitivityClassifiedOption, - checked: currentSensitivity == "CLASSIFIED" - } - ] - }) }} - {% if listTypes and listTypes.length > 0 %} {% set checkboxItems = [] %} {% for listType in listTypes %} diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.test.ts b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.test.ts index 4588d4c23..24f091922 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.test.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.test.ts @@ -11,12 +11,11 @@ vi.mock("@hmcts/system-admin-pages", async (importOriginal) => { }, findAllListTypes: vi.fn(), findThirdPartyUserById: vi.fn(), - updateThirdPartySubscriptions: vi.fn(), - validateSensitivity: vi.fn() + updateThirdPartySubscriptions: vi.fn() }; }); -import { findAllListTypes, findThirdPartyUserById, updateThirdPartySubscriptions, validateSensitivity } from "@hmcts/system-admin-pages"; +import { findAllListTypes, findThirdPartyUserById, updateThirdPartySubscriptions } from "@hmcts/system-admin-pages"; describe("manage-third-party-subscriptions page", () => { let req: Partial; @@ -40,7 +39,8 @@ describe("manage-third-party-subscriptions page", () => { res = { render: vi.fn(), - redirect: vi.fn() + redirect: vi.fn(), + locals: {} }; }); @@ -53,7 +53,7 @@ describe("manage-third-party-subscriptions page", () => { }); it("should redirect to manage users page with Welsh locale when no id", async () => { - req.query = { lng: "cy" }; + (res as any).locals = { locale: "cy" }; const handler = GET[GET.length - 1]; await handler(req as Request, res as Response, vi.fn()); @@ -80,7 +80,7 @@ describe("manage-third-party-subscriptions page", () => { const mockUser = { id: "user-123", name: "Test User", - subscriptions: [{ listTypeId: 1, sensitivity: "PUBLIC" }] + subscriptions: [{ listTypeId: 1 }] }; (findThirdPartyUserById as any).mockResolvedValue(mockUser); @@ -91,8 +91,6 @@ describe("manage-third-party-subscriptions page", () => { expect(res.render).toHaveBeenCalledWith( "manage-third-party-subscriptions/index", expect.objectContaining({ - currentChannel: "API", - currentSensitivity: "PUBLIC", currentListTypeIds: [1], errors: undefined }) @@ -133,7 +131,6 @@ describe("manage-third-party-subscriptions page", () => { expect(res.render).toHaveBeenCalledWith( "manage-third-party-subscriptions/index", expect.objectContaining({ - currentSensitivity: "", currentListTypeIds: [] }) ); @@ -149,62 +146,37 @@ describe("manage-third-party-subscriptions page", () => { }); it("should redirect with Welsh locale when no session data", async () => { - req.query = { lng: "cy" }; + (res as any).locals = { locale: "cy" }; const handler = POST[POST.length - 1]; await handler(req as Request, res as Response, vi.fn()); expect(res.redirect).toHaveBeenCalledWith("/manage-third-party-users?lng=cy"); }); - it("should show validation error when sensitivity not selected", async () => { - (req.session as any).manageThirdPartyUser = { - userId: "user-123", - userName: "Test User", - originalSubscriptions: [] - }; - req.body = { channel: "API", listTypes: ["1"] }; - (validateSensitivity as any).mockReturnValue({ href: "#sensitivity" }); - - const handler = POST[POST.length - 1]; - await handler(req as Request, res as Response, vi.fn()); - - expect(res.render).toHaveBeenCalledWith( - "manage-third-party-subscriptions/index", - expect.objectContaining({ - errors: expect.arrayContaining([expect.objectContaining({ href: "#sensitivity" })]) - }) - ); - }); - it("should update subscriptions and redirect to success page", async () => { (req.session as any).manageThirdPartyUser = { userId: "user-123", userName: "Test User", originalSubscriptions: [1] }; - req.body = { channel: "API", sensitivity: "PUBLIC", listTypes: ["1", "2"] }; - (validateSensitivity as any).mockReturnValue(null); + req.body = { listTypes: ["1", "2"] }; (updateThirdPartySubscriptions as any).mockResolvedValue(undefined); const handler = POST[POST.length - 1]; await handler(req as Request, res as Response, vi.fn()); - expect(updateThirdPartySubscriptions).toHaveBeenCalledWith("user-123", [ - { listTypeId: 1, channel: "API", sensitivity: "PUBLIC" }, - { listTypeId: 2, channel: "API", sensitivity: "PUBLIC" } - ]); + expect(updateThirdPartySubscriptions).toHaveBeenCalledWith("user-123", [{ listTypeId: 1 }, { listTypeId: 2 }]); expect(res.redirect).toHaveBeenCalledWith("/third-party-subscriptions-updated"); }); it("should redirect with Welsh locale on success", async () => { - req.query = { lng: "cy" }; + (res as any).locals = { locale: "cy" }; (req.session as any).manageThirdPartyUser = { userId: "user-123", userName: "Test User", originalSubscriptions: [] }; - req.body = { channel: "API", sensitivity: "PUBLIC", listTypes: "1" }; - (validateSensitivity as any).mockReturnValue(null); + req.body = { listTypes: "1" }; (updateThirdPartySubscriptions as any).mockResolvedValue(undefined); const handler = POST[POST.length - 1]; @@ -219,14 +191,13 @@ describe("manage-third-party-subscriptions page", () => { userName: "Test User", originalSubscriptions: [] }; - req.body = { channel: "API", sensitivity: "PUBLIC", listTypes: "1" }; - (validateSensitivity as any).mockReturnValue(null); + req.body = { listTypes: "1" }; (updateThirdPartySubscriptions as any).mockResolvedValue(undefined); const handler = POST[POST.length - 1]; await handler(req as Request, res as Response, vi.fn()); - expect(updateThirdPartySubscriptions).toHaveBeenCalledWith("user-123", [{ listTypeId: 1, channel: "API", sensitivity: "PUBLIC" }]); + expect(updateThirdPartySubscriptions).toHaveBeenCalledWith("user-123", [{ listTypeId: 1 }]); }); it("should handle no listTypes selected", async () => { @@ -235,8 +206,7 @@ describe("manage-third-party-subscriptions page", () => { userName: "Test User", originalSubscriptions: [1] }; - req.body = { channel: "API", sensitivity: "PUBLIC" }; - (validateSensitivity as any).mockReturnValue(null); + req.body = {}; (updateThirdPartySubscriptions as any).mockResolvedValue(undefined); const handler = POST[POST.length - 1]; @@ -251,8 +221,7 @@ describe("manage-third-party-subscriptions page", () => { userName: "Test User", originalSubscriptions: [1] }; - req.body = { channel: "API", sensitivity: "PUBLIC", listTypes: ["2"] }; - (validateSensitivity as any).mockReturnValue(null); + req.body = { listTypes: ["2"] }; (updateThirdPartySubscriptions as any).mockResolvedValue(undefined); const handler = POST[POST.length - 1]; @@ -261,7 +230,7 @@ describe("manage-third-party-subscriptions page", () => { expect(req.auditMetadata).toEqual({ shouldLog: true, action: "Update third party subscriptions", - entityInfo: expect.stringMatching(/ID: user-123, Name: Test User, Sensitivity: PUBLIC, Previous List Types: \[.*\], Current List Types: \[.*\]/) + entityInfo: expect.stringMatching(/ID: user-123, Name: Test User, Previous List Types: \[.*\], Current List Types: \[.*\]/) }); }); @@ -271,8 +240,7 @@ describe("manage-third-party-subscriptions page", () => { userName: "Test User", originalSubscriptions: [] }; - req.body = { channel: "API", sensitivity: "PUBLIC", listTypes: [] }; - (validateSensitivity as any).mockReturnValue(null); + req.body = { listTypes: [] }; (updateThirdPartySubscriptions as any).mockResolvedValue(undefined); const handler = POST[POST.length - 1]; @@ -280,21 +248,5 @@ describe("manage-third-party-subscriptions page", () => { expect((req.session as any).manageThirdPartyUser).toBeUndefined(); }); - - it("should default channel to API if not provided", async () => { - (req.session as any).manageThirdPartyUser = { - userId: "user-123", - userName: "Test User", - originalSubscriptions: [] - }; - req.body = { sensitivity: "PUBLIC", listTypes: ["1"] }; - (validateSensitivity as any).mockReturnValue(null); - (updateThirdPartySubscriptions as any).mockResolvedValue(undefined); - - const handler = POST[POST.length - 1]; - await handler(req as Request, res as Response, vi.fn()); - - expect(updateThirdPartySubscriptions).toHaveBeenCalledWith("user-123", [{ listTypeId: 1, channel: "API", sensitivity: "PUBLIC" }]); - }); }); }); diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.ts b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.ts index 19d46ce2b..025b9f742 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-subscriptions/index.ts @@ -1,5 +1,5 @@ import { requireRole, USER_ROLES } from "@hmcts/auth"; -import { AuditLogAction, findAllListTypes, findThirdPartyUserById, updateThirdPartySubscriptions, validateSensitivity } from "@hmcts/system-admin-pages"; +import { AuditLogAction, findAllListTypes, findThirdPartyUserById, updateThirdPartySubscriptions } from "@hmcts/system-admin-pages"; import type { Request, RequestHandler, Response } from "express"; import { cy } from "./cy.js"; import { en } from "./en.js"; @@ -13,20 +13,20 @@ interface ManageThirdPartyUserSession { } const getHandler = async (req: Request, res: Response) => { - const language = req.query.lng === "cy" ? "cy" : "en"; - const content = language === "cy" ? cy : en; + const locale = res.locals.locale || "en"; + const t = locale === "cy" ? cy : en; const userId = req.query.id as string | undefined; if (!userId) { - return res.redirect(`/manage-third-party-users${language === "cy" ? "?lng=cy" : ""}`); + return res.redirect(`/manage-third-party-users${locale === "cy" ? "?lng=cy" : ""}`); } const user = await findThirdPartyUserById(userId); if (!user) { return res.render("manage-third-party-subscriptions/index", { - ...content, - errors: [{ text: content.userNotFound }] + ...t, + errors: [{ text: t.userNotFound }] }); } @@ -37,51 +37,29 @@ const getHandler = async (req: Request, res: Response) => { originalSubscriptions: user.subscriptions.map((s) => s.listTypeId) }; - const currentSensitivity = user.subscriptions.length > 0 ? user.subscriptions[0].sensitivity : ""; const currentListTypeIds = user.subscriptions.map((s) => s.listTypeId); const listTypes = await findAllListTypes(); res.render("manage-third-party-subscriptions/index", { - ...content, + ...t, listTypes, - currentChannel: "API", - currentSensitivity, currentListTypeIds, errors: undefined }); }; const postHandler = async (req: Request, res: Response) => { - const language = req.query.lng === "cy" ? "cy" : "en"; - const content = language === "cy" ? cy : en; + const locale = res.locals.locale || "en"; const session = req.session as ManageThirdPartyUserSession; if (!session.manageThirdPartyUser) { - return res.redirect(`/manage-third-party-users${language === "cy" ? "?lng=cy" : ""}`); + return res.redirect(`/manage-third-party-users${locale === "cy" ? "?lng=cy" : ""}`); } - const channel = req.body.channel as string; - const sensitivity = req.body.sensitivity as string | undefined; const listTypeIds = Array.isArray(req.body.listTypes) ? req.body.listTypes.map(Number) : req.body.listTypes ? [Number(req.body.listTypes)] : []; const listTypes = await findAllListTypes(); - const validationError = validateSensitivity(sensitivity); - if (validationError) { - return res.render("manage-third-party-subscriptions/index", { - ...content, - listTypes, - currentChannel: channel || "API", - currentSensitivity: sensitivity || "", - currentListTypeIds: listTypeIds, - errors: [{ ...validationError, text: content.sensitivityRequired }] - }); - } - - const subscriptions = listTypeIds.map((listTypeId: number) => ({ - listTypeId, - channel: channel || "API", - sensitivity: sensitivity! - })); + const subscriptions = listTypeIds.map((listTypeId: number) => ({ listTypeId })); await updateThirdPartySubscriptions(session.manageThirdPartyUser.userId, subscriptions); @@ -100,12 +78,12 @@ const postHandler = async (req: Request, res: Response) => { req.auditMetadata = { shouldLog: true, action: AuditLogAction.UPDATE_THIRD_PARTY_SUBSCRIPTIONS, - entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Name: ${session.manageThirdPartyUser.userName}, Sensitivity: ${sensitivity}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]` + entityInfo: `ID: ${session.manageThirdPartyUser.userId}, Name: ${session.manageThirdPartyUser.userName}, Previous List Types: [${previousListTypes}], Current List Types: [${currentListTypes}]` }; delete session.manageThirdPartyUser; - res.redirect(`/third-party-subscriptions-updated${language === "cy" ? "?lng=cy" : ""}`); + res.redirect(`/third-party-subscriptions-updated${locale === "cy" ? "?lng=cy" : ""}`); }; export const GET: RequestHandler[] = [requireRole([USER_ROLES.SYSTEM_ADMIN]), getHandler]; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-user/cy.ts b/apps/web/src/pages/(system-admin)/manage-third-party-user/cy.ts index 1a7c1fbbf..f45ba1b1a 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-user/cy.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-user/cy.ts @@ -3,12 +3,7 @@ export const cy = { nameLabel: "enw'r", createdDateLabel: "Crëwyd Dyddiad", numberOfSubscriptionsLabel: "Nifer y tanysgrifiadau", - sensitivityLabel: "Sensitifrwydd", manageSubscriptionsButton: "Rheoli tanysgrifiadau", deleteUserButton: "Dileu Defnyddiwr", - userNotFound: "Ni chanfuwyd defnyddiwr", - classified: "Cyfrinachol", - private: "Preifat", - public: "Cyhoeddus", - unselected: "Heb ei ddewis" + userNotFound: "Ni chanfuwyd defnyddiwr" }; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-user/en.ts b/apps/web/src/pages/(system-admin)/manage-third-party-user/en.ts index a61abd6f4..fc030d4f0 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-user/en.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-user/en.ts @@ -3,12 +3,7 @@ export const en = { nameLabel: "Name", createdDateLabel: "Created date", numberOfSubscriptionsLabel: "Number of subscriptions", - sensitivityLabel: "Sensitivity", manageSubscriptionsButton: "Manage subscriptions", deleteUserButton: "Delete user", - userNotFound: "User not found", - classified: "Classified", - private: "Private", - public: "Public", - unselected: "Unselected" + userNotFound: "User not found" }; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-user/index.njk b/apps/web/src/pages/(system-admin)/manage-third-party-user/index.njk index 41536e217..7de7cd664 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-user/index.njk +++ b/apps/web/src/pages/(system-admin)/manage-third-party-user/index.njk @@ -4,13 +4,11 @@ {% block content %}
-
+

{{ pageTitle }}

{% if user %} - {% set sensitivityText = classified if highestSensitivity == 'CLASSIFIED' else (private if highestSensitivity == 'PRIVATE' else (public if highestSensitivity == 'PUBLIC' else unselected)) %} - {{ govukSummaryList({ rows: [ { @@ -36,14 +34,6 @@ value: { text: user.subscriptions.length } - }, - { - key: { - text: sensitivityLabel - }, - value: { - text: sensitivityText - } } ] }) }} diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-user/index.test.ts b/apps/web/src/pages/(system-admin)/manage-third-party-user/index.test.ts index db20684b7..402706ddb 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-user/index.test.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-user/index.test.ts @@ -6,12 +6,11 @@ vi.mock("@hmcts/system-admin-pages", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, - findThirdPartyUserById: vi.fn(), - getHighestSensitivity: vi.fn() + findThirdPartyUserById: vi.fn() }; }); -import { findThirdPartyUserById, getHighestSensitivity } from "@hmcts/system-admin-pages"; +import { findThirdPartyUserById } from "@hmcts/system-admin-pages"; describe("manage-third-party-user page", () => { let req: Partial; @@ -26,7 +25,8 @@ describe("manage-third-party-user page", () => { res = { render: vi.fn(), - redirect: vi.fn() + redirect: vi.fn(), + locals: {} }; }); @@ -39,7 +39,7 @@ describe("manage-third-party-user page", () => { }); it("should redirect to manage users page with Welsh locale when no id", async () => { - req.query = { lng: "cy" }; + (res as any).locals = { locale: "cy" }; const handler = GET[GET.length - 1]; await handler(req as Request, res as Response, vi.fn()); @@ -66,10 +66,9 @@ describe("manage-third-party-user page", () => { const mockUser = { id: "user-123", name: "Test User", - subscriptions: [{ listTypeId: 1, sensitivity: "PUBLIC" }] + subscriptions: [{ listTypeId: 1 }] }; (findThirdPartyUserById as any).mockResolvedValue(mockUser); - (getHighestSensitivity as any).mockResolvedValue("PUBLIC"); const handler = GET[GET.length - 1]; await handler(req as Request, res as Response, vi.fn()); @@ -78,21 +77,20 @@ describe("manage-third-party-user page", () => { expect(res.render).toHaveBeenCalledWith( "manage-third-party-user/index", expect.objectContaining({ - user: mockUser, - highestSensitivity: "PUBLIC" + user: mockUser }) ); }); it("should render user details in Welsh", async () => { - req.query = { id: "user-123", lng: "cy" }; + req.query = { id: "user-123" }; + (res as any).locals = { locale: "cy" }; const mockUser = { id: "user-123", name: "Test User", subscriptions: [] }; (findThirdPartyUserById as any).mockResolvedValue(mockUser); - (getHighestSensitivity as any).mockResolvedValue(null); const handler = GET[GET.length - 1]; await handler(req as Request, res as Response, vi.fn()); @@ -104,27 +102,5 @@ describe("manage-third-party-user page", () => { }) ); }); - - it("should calculate highest sensitivity for user subscriptions", async () => { - req.query = { id: "user-123" }; - const mockUser = { - id: "user-123", - name: "Test User", - subscriptions: [{ listTypeId: 1, sensitivity: "CLASSIFIED" }] - }; - (findThirdPartyUserById as any).mockResolvedValue(mockUser); - (getHighestSensitivity as any).mockResolvedValue("CLASSIFIED"); - - const handler = GET[GET.length - 1]; - await handler(req as Request, res as Response, vi.fn()); - - expect(getHighestSensitivity).toHaveBeenCalledWith(mockUser.subscriptions); - expect(res.render).toHaveBeenCalledWith( - "manage-third-party-user/index", - expect.objectContaining({ - highestSensitivity: "CLASSIFIED" - }) - ); - }); }); }); diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-user/index.ts b/apps/web/src/pages/(system-admin)/manage-third-party-user/index.ts index f1a5e3bd1..8dcbb6623 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-user/index.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-user/index.ts @@ -1,33 +1,30 @@ import { requireRole, USER_ROLES } from "@hmcts/auth"; -import { findThirdPartyUserById, getHighestSensitivity } from "@hmcts/system-admin-pages"; +import { findThirdPartyUserById } from "@hmcts/system-admin-pages"; import type { Request, RequestHandler, Response } from "express"; import { cy } from "./cy.js"; import { en } from "./en.js"; const getHandler = async (req: Request, res: Response) => { - const language = req.query.lng === "cy" ? "cy" : "en"; - const content = language === "cy" ? cy : en; + const locale = res.locals.locale || "en"; + const t = locale === "cy" ? cy : en; const userId = req.query.id as string | undefined; if (!userId) { - return res.redirect(`/manage-third-party-users${language === "cy" ? "?lng=cy" : ""}`); + return res.redirect(`/manage-third-party-users${locale === "cy" ? "?lng=cy" : ""}`); } const user = await findThirdPartyUserById(userId); if (!user) { return res.render("manage-third-party-user/index", { - ...content, - errors: [{ text: content.userNotFound }] + ...t, + errors: [{ text: t.userNotFound }] }); } - const highestSensitivity = await getHighestSensitivity(user.subscriptions); - res.render("manage-third-party-user/index", { - ...content, - user, - highestSensitivity + ...t, + user }); }; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-users/cy.ts b/apps/web/src/pages/(system-admin)/manage-third-party-users/cy.ts index c3e6f5379..36c7238d4 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-users/cy.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-users/cy.ts @@ -4,12 +4,7 @@ export const cy = { nameColumnHeader: "enw'r", createdDateColumnHeader: "Crëwyd Dyddiad", numberOfSubscriptionsColumnHeader: "Nifer y tanysgrifiadau", - sensitivityColumnHeader: "Sensitifrwydd", actionsColumnHeader: "Camau gweithredu", manageLink: "Rheoli", - noUsersMessage: "Ni chanfuwyd defnyddwyr trydydd parti", - classified: "Cyfrinachol", - private: "Preifat", - public: "Cyhoeddus", - unselected: "Heb ei ddewis" + noUsersMessage: "Ni chanfuwyd defnyddwyr trydydd parti" }; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-users/en.ts b/apps/web/src/pages/(system-admin)/manage-third-party-users/en.ts index db129c152..ff07f3aa9 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-users/en.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-users/en.ts @@ -4,12 +4,7 @@ export const en = { nameColumnHeader: "Name", createdDateColumnHeader: "Created date", numberOfSubscriptionsColumnHeader: "Number of subscriptions", - sensitivityColumnHeader: "Sensitivity", actionsColumnHeader: "Actions", manageLink: "Manage", - noUsersMessage: "No third party users found", - classified: "Classified", - private: "Private", - public: "Public", - unselected: "Unselected" + noUsersMessage: "No third party users found" }; diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-users/index.njk b/apps/web/src/pages/(system-admin)/manage-third-party-users/index.njk index 528706f2c..d96101c77 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-users/index.njk +++ b/apps/web/src/pages/(system-admin)/manage-third-party-users/index.njk @@ -15,12 +15,10 @@ {% if users and users.length > 0 %} {% set tableRows = [] %} {% for user in users %} - {% set sensitivityText = classified if user.highestSensitivity == 'CLASSIFIED' else (private if user.highestSensitivity == 'PRIVATE' else (public if user.highestSensitivity == 'PUBLIC' else unselected)) %} {% set tableRows = (tableRows.push([ { text: user.name }, { text: user.createdDate | date('DD/MM/YYYY') }, { text: user.subscriptions.length }, - { text: sensitivityText }, { html: '' + manageLink + '' } ]), tableRows) %} {% endfor %} @@ -30,7 +28,6 @@ { text: nameColumnHeader }, { text: createdDateColumnHeader }, { text: numberOfSubscriptionsColumnHeader }, - { text: sensitivityColumnHeader }, { text: actionsColumnHeader } ], rows: tableRows diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-users/index.test.ts b/apps/web/src/pages/(system-admin)/manage-third-party-users/index.test.ts index ba0c6a65a..297226505 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-users/index.test.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-users/index.test.ts @@ -6,12 +6,11 @@ vi.mock("@hmcts/system-admin-pages", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, - findAllThirdPartyUsers: vi.fn(), - getHighestSensitivity: vi.fn() + findAllThirdPartyUsers: vi.fn() }; }); -import { findAllThirdPartyUsers, getHighestSensitivity } from "@hmcts/system-admin-pages"; +import { findAllThirdPartyUsers } from "@hmcts/system-admin-pages"; describe("manage-third-party-users page", () => { let req: Partial; @@ -36,7 +35,6 @@ describe("manage-third-party-users page", () => { { id: "2", name: "User Two", subscriptions: [{ listTypeId: 1 }] } ]; (findAllThirdPartyUsers as any).mockResolvedValue(mockUsers); - (getHighestSensitivity as any).mockReturnValue("PUBLIC"); const handler = GET[GET.length - 1]; await handler(req as Request, res as Response, vi.fn()); @@ -47,10 +45,7 @@ describe("manage-third-party-users page", () => { expect.objectContaining({ en: expect.objectContaining({ pageTitle: "Manage third party users" }), cy: expect.objectContaining({ pageTitle: "Rheoli defnyddiwr trydydd parti" }), - users: expect.arrayContaining([ - expect.objectContaining({ id: "1", name: "User One", highestSensitivity: "PUBLIC" }), - expect.objectContaining({ id: "2", name: "User Two", highestSensitivity: "PUBLIC" }) - ]) + users: mockUsers }) ); }); @@ -70,22 +65,5 @@ describe("manage-third-party-users page", () => { }) ); }); - - it("should calculate highest sensitivity for each user", async () => { - const mockUsers = [{ id: "1", name: "User One", subscriptions: [{ listTypeId: 1, sensitivity: "CLASSIFIED" }] }]; - (findAllThirdPartyUsers as any).mockResolvedValue(mockUsers); - (getHighestSensitivity as any).mockReturnValue("CLASSIFIED"); - - const handler = GET[GET.length - 1]; - await handler(req as Request, res as Response, vi.fn()); - - expect(getHighestSensitivity).toHaveBeenCalledWith([{ listTypeId: 1, sensitivity: "CLASSIFIED" }]); - expect(res.render).toHaveBeenCalledWith( - "manage-third-party-users/index", - expect.objectContaining({ - users: expect.arrayContaining([expect.objectContaining({ highestSensitivity: "CLASSIFIED" })]) - }) - ); - }); }); }); diff --git a/apps/web/src/pages/(system-admin)/manage-third-party-users/index.ts b/apps/web/src/pages/(system-admin)/manage-third-party-users/index.ts index 453df86df..0a0a840fa 100644 --- a/apps/web/src/pages/(system-admin)/manage-third-party-users/index.ts +++ b/apps/web/src/pages/(system-admin)/manage-third-party-users/index.ts @@ -1,5 +1,5 @@ import { requireRole, USER_ROLES } from "@hmcts/auth"; -import { findAllThirdPartyUsers, getHighestSensitivity } from "@hmcts/system-admin-pages"; +import { findAllThirdPartyUsers } from "@hmcts/system-admin-pages"; import type { Request, RequestHandler, Response } from "express"; import { cy } from "./cy.js"; import { en } from "./en.js"; @@ -7,15 +7,10 @@ import { en } from "./en.js"; const getHandler = async (_req: Request, res: Response) => { const users = await findAllThirdPartyUsers(); - const usersWithSensitivity = users.map((user) => ({ - ...user, - highestSensitivity: getHighestSensitivity(user.subscriptions) - })); - res.render("manage-third-party-users/index", { en, cy, - users: usersWithSensitivity + users }); }; diff --git a/libs/legacy-third-party-fulfilment/src/queries.test.ts b/libs/legacy-third-party-fulfilment/src/queries.test.ts index 5e8fc6459..4afdd052e 100644 --- a/libs/legacy-third-party-fulfilment/src/queries.test.ts +++ b/libs/legacy-third-party-fulfilment/src/queries.test.ts @@ -17,38 +17,11 @@ describe("findSubscribersByListType", () => { mockFindMany.mockResolvedValue([]); }); - it("filters PUBLIC publications to all sensitivity levels", async () => { - await findSubscribersByListType(42, "PUBLIC"); + it("returns all subscribers for the given listTypeId regardless of sensitivity", async () => { + await findSubscribersByListType(42); expect(mockFindMany).toHaveBeenCalledWith({ - where: { listTypeId: 42, sensitivity: { in: ["PUBLIC", "PRIVATE", "CLASSIFIED"] } }, - include: { user: true } - }); - }); - - it("filters PRIVATE publications to PRIVATE and CLASSIFIED subscribers only", async () => { - await findSubscribersByListType(42, "PRIVATE"); - - expect(mockFindMany).toHaveBeenCalledWith({ - where: { listTypeId: 42, sensitivity: { in: ["PRIVATE", "CLASSIFIED"] } }, - include: { user: true } - }); - }); - - it("filters CLASSIFIED publications to CLASSIFIED subscribers only", async () => { - await findSubscribersByListType(42, "CLASSIFIED"); - - expect(mockFindMany).toHaveBeenCalledWith({ - where: { listTypeId: 42, sensitivity: { in: ["CLASSIFIED"] } }, - include: { user: true } - }); - }); - - it("treats unknown sensitivity as PUBLIC and includes all levels", async () => { - await findSubscribersByListType(42, "UNKNOWN"); - - expect(mockFindMany).toHaveBeenCalledWith({ - where: { listTypeId: 42, sensitivity: { in: ["PUBLIC", "PRIVATE", "CLASSIFIED"] } }, + where: { listTypeId: 42 }, include: { user: true } }); }); @@ -58,14 +31,12 @@ describe("findSubscribersByListType", () => { id: "sub-1", userId: "user-1", listTypeId: 42, - channel: "API", - sensitivity: "PRIVATE", createdDate: new Date(), user: { id: "user-1", name: "Courtel", createdDate: new Date() } }; mockFindMany.mockResolvedValue([row]); - const result = await findSubscribersByListType(42, "PRIVATE"); + const result = await findSubscribersByListType(42); expect(result).toEqual([row]); }); diff --git a/libs/legacy-third-party-fulfilment/src/queries.ts b/libs/legacy-third-party-fulfilment/src/queries.ts index 6db425fc7..201cb22d2 100644 --- a/libs/legacy-third-party-fulfilment/src/queries.ts +++ b/libs/legacy-third-party-fulfilment/src/queries.ts @@ -1,17 +1,8 @@ import { prisma } from "@hmcts/postgres-prisma"; -const SENSITIVITY_ORDER = ["PUBLIC", "PRIVATE", "CLASSIFIED"] as const; -type SensitivityLevel = (typeof SENSITIVITY_ORDER)[number]; - -function eligibleSensitivities(publicationSensitivity: string): SensitivityLevel[] { - const rank = SENSITIVITY_ORDER.indexOf(publicationSensitivity as SensitivityLevel); - const minRank = rank === -1 ? 0 : rank; - return SENSITIVITY_ORDER.filter((_, i) => i >= minRank); -} - -export async function findSubscribersByListType(listTypeId: number, sensitivity: string) { +export async function findSubscribersByListType(listTypeId: number) { return prisma.legacyThirdPartySubscription.findMany({ - where: { listTypeId, sensitivity: { in: eligibleSensitivities(sensitivity) } }, + where: { listTypeId }, include: { user: true } }); } diff --git a/libs/legacy-third-party-fulfilment/src/service.ts b/libs/legacy-third-party-fulfilment/src/service.ts index 15390ea16..229d51d4e 100644 --- a/libs/legacy-third-party-fulfilment/src/service.ts +++ b/libs/legacy-third-party-fulfilment/src/service.ts @@ -65,7 +65,7 @@ export async function sendThirdPartyPublications(params: ThirdPartyPushParams): const secrets = resolveCourtelSecrets(logPrefix); if (!secrets) return; - const subscribers = await findSubscribersByListType(listTypeId, sensitivity); + const subscribers = await findSubscribersByListType(listTypeId); if (subscribers.length === 0) { console.info(`${logPrefix} Third-party push skipped: no subscribers for listTypeId ${listTypeId}`); return; @@ -88,7 +88,7 @@ export async function sendThirdPartyDeletion(params: ThirdPartyDeletionParams): const secrets = resolveCourtelSecrets(logPrefix); if (!secrets) return; - const subscribers = await findSubscribersByListType(listTypeId, sensitivity); + const subscribers = await findSubscribersByListType(listTypeId); if (subscribers.length === 0) { console.info(`${logPrefix} Third-party deletion push skipped: no subscribers for listTypeId ${listTypeId}`); return; diff --git a/libs/list-types/common/src/validation/list-type-validator.test.ts b/libs/list-types/common/src/validation/list-type-validator.test.ts index eeed2cd68..307c78cf8 100644 --- a/libs/list-types/common/src/validation/list-type-validator.test.ts +++ b/libs/list-types/common/src/validation/list-type-validator.test.ts @@ -10,6 +10,9 @@ const testListTypes: ListTypeInfo[] = [ { id: 27, name: "SJP_DELTA_PUBLIC_LIST", friendlyName: "Single Justice Procedure Public List (New cases)" } ]; +// Mock @hmcts/civil-daily-cause-list as empty - simulates a list type with no validation function +vi.mock("@hmcts/civil-daily-cause-list", () => ({})); + // Mock the dynamic import for @hmcts/civil-and-family-daily-cause-list vi.mock("@hmcts/civil-and-family-daily-cause-list", () => ({ validateCivilFamilyCauseList: vi.fn().mockReturnValue({ @@ -70,12 +73,12 @@ describe("list-type-validator", () => { }); it("should return error for list type without JSON schema", async () => { - // Using list type ID 1 (CIVIL_DAILY_CAUSE_LIST) which doesn't have a schema package + // Using list type ID 1 (CROWN_DAILY_LIST) which doesn't have a schema package const result = await validateListTypeJson("1", { test: "data" }, testListTypes); expect(result.isValid).toBe(false); expect(result.errors).toHaveLength(1); - expect(result.errors[0].message).toContain("No JSON schema available"); + expect(result.errors[0].message).toContain("does not support JSON uploads"); }); it("should validate Civil and Family Daily Cause List with valid data", async () => { diff --git a/libs/postgres-prisma/prisma/schema/base.prisma b/libs/postgres-prisma/prisma/schema/base.prisma index 2bd7c3180..579c0d8d2 100644 --- a/libs/postgres-prisma/prisma/schema/base.prisma +++ b/libs/postgres-prisma/prisma/schema/base.prisma @@ -107,8 +107,6 @@ model LegacyThirdPartySubscription { id String @id @default(uuid()) @map("id") @db.Uuid userId String @map("user_id") @db.Uuid listTypeId Int @map("list_type_id") - channel String @default("API") @db.VarChar(20) - sensitivity String @db.VarChar(20) createdDate DateTime @default(now()) @map("created_date") user LegacyThirdPartyUser @relation(fields: [userId], references: [id], onDelete: Cascade) diff --git a/libs/system-admin-pages/src/index.ts b/libs/system-admin-pages/src/index.ts index 1dad6c99e..76d51ba18 100644 --- a/libs/system-admin-pages/src/index.ts +++ b/libs/system-admin-pages/src/index.ts @@ -45,7 +45,6 @@ export * from "./third-party-user/queries.js"; export { type ErrorItem as ThirdPartyUserErrorItem, validateRadioSelection as validateThirdPartyUserRadioSelection, - validateSensitivity, validateThirdPartyUserName } from "./third-party-user/validation.js"; diff --git a/libs/system-admin-pages/src/third-party-user/queries.test.ts b/libs/system-admin-pages/src/third-party-user/queries.test.ts index f9b41a64d..93a9d3c86 100644 --- a/libs/system-admin-pages/src/third-party-user/queries.test.ts +++ b/libs/system-admin-pages/src/third-party-user/queries.test.ts @@ -1,12 +1,5 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { - createThirdPartyUser, - deleteThirdPartyUser, - findAllThirdPartyUsers, - findThirdPartyUserById, - getHighestSensitivity, - updateThirdPartySubscriptions -} from "./queries.js"; +import { createThirdPartyUser, deleteThirdPartyUser, findAllThirdPartyUsers, findThirdPartyUserById, updateThirdPartySubscriptions } from "./queries.js"; vi.mock("@hmcts/postgres-prisma", () => ({ prisma: { @@ -52,8 +45,6 @@ describe("findAllThirdPartyUsers", () => { id: true, userId: true, listTypeId: true, - channel: true, - sensitivity: true, createdDate: true } } @@ -85,8 +76,6 @@ describe("findThirdPartyUserById", () => { id: true, userId: true, listTypeId: true, - channel: true, - sensitivity: true, createdDate: true } } @@ -147,10 +136,7 @@ describe("updateThirdPartySubscriptions", () => { }); vi.mocked(prisma.$transaction).mockImplementation(mockTransaction); - const subscriptions = [ - { listTypeId: 1, channel: "API", sensitivity: "PUBLIC" }, - { listTypeId: 2, channel: "API", sensitivity: "PRIVATE" } - ]; + const subscriptions = [{ listTypeId: 1 }, { listTypeId: 2 }]; await updateThirdPartySubscriptions("user-1", subscriptions); @@ -173,28 +159,3 @@ describe("updateThirdPartySubscriptions", () => { expect(prisma.$transaction).toHaveBeenCalled(); }); }); - -describe("getHighestSensitivity", () => { - it("should return unselected for empty array", async () => { - const result = await getHighestSensitivity([]); - expect(result).toBe("unselected"); - }); - - it("should return CLASSIFIED when present", async () => { - const subscriptions = [{ sensitivity: "PUBLIC" }, { sensitivity: "CLASSIFIED" }, { sensitivity: "PRIVATE" }]; - const result = await getHighestSensitivity(subscriptions); - expect(result).toBe("CLASSIFIED"); - }); - - it("should return PRIVATE when CLASSIFIED is not present", async () => { - const subscriptions = [{ sensitivity: "PUBLIC" }, { sensitivity: "PRIVATE" }]; - const result = await getHighestSensitivity(subscriptions); - expect(result).toBe("PRIVATE"); - }); - - it("should return PUBLIC when only PUBLIC is present", async () => { - const subscriptions = [{ sensitivity: "PUBLIC" }]; - const result = await getHighestSensitivity(subscriptions); - expect(result).toBe("PUBLIC"); - }); -}); diff --git a/libs/system-admin-pages/src/third-party-user/queries.ts b/libs/system-admin-pages/src/third-party-user/queries.ts index 2e06c848f..cc5225610 100644 --- a/libs/system-admin-pages/src/third-party-user/queries.ts +++ b/libs/system-admin-pages/src/third-party-user/queries.ts @@ -14,8 +14,6 @@ export async function findAllThirdPartyUsers() { id: true, userId: true, listTypeId: true, - channel: true, - sensitivity: true, createdDate: true } } @@ -35,8 +33,6 @@ export async function findThirdPartyUserById(id: string) { id: true, userId: true, listTypeId: true, - channel: true, - sensitivity: true, createdDate: true } } @@ -58,7 +54,7 @@ export async function deleteThirdPartyUser(id: string) { }); } -export async function updateThirdPartySubscriptions(userId: string, subscriptions: Array<{ listTypeId: number; channel: string; sensitivity: string }>) { +export async function updateThirdPartySubscriptions(userId: string, subscriptions: Array<{ listTypeId: number }>) { return prisma.$transaction(async (tx) => { await tx.legacyThirdPartySubscription.deleteMany({ where: { userId } @@ -66,28 +62,8 @@ export async function updateThirdPartySubscriptions(userId: string, subscription if (subscriptions.length > 0) { await tx.legacyThirdPartySubscription.createMany({ - data: subscriptions.map((sub) => ({ - userId, - listTypeId: sub.listTypeId, - channel: sub.channel, - sensitivity: sub.sensitivity - })) + data: subscriptions.map((sub) => ({ userId, listTypeId: sub.listTypeId })) }); } }); } - -export function getHighestSensitivity(subscriptions: Array<{ sensitivity: string }>): string { - if (subscriptions.length === 0) { - return "unselected"; - } - - const priorities = { CLASSIFIED: 3, PRIVATE: 2, PUBLIC: 1 }; - const highest = subscriptions.reduce((max, sub) => { - const priority = priorities[sub.sensitivity as keyof typeof priorities] || 0; - const maxPriority = priorities[max as keyof typeof priorities] || 0; - return priority > maxPriority ? sub.sensitivity : max; - }, subscriptions[0].sensitivity); - - return highest; -} diff --git a/libs/system-admin-pages/src/third-party-user/validation.test.ts b/libs/system-admin-pages/src/third-party-user/validation.test.ts index 052fe253c..00f0606a8 100644 --- a/libs/system-admin-pages/src/third-party-user/validation.test.ts +++ b/libs/system-admin-pages/src/third-party-user/validation.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { validateRadioSelection, validateSensitivity, validateThirdPartyUserName } from "./validation.js"; +import { validateRadioSelection, validateThirdPartyUserName } from "./validation.js"; describe("validateThirdPartyUserName", () => { it("should return error when name is undefined", () => { @@ -61,35 +61,3 @@ describe("validateRadioSelection", () => { expect(result).toBeNull(); }); }); - -describe("validateSensitivity", () => { - it("should return error when value is undefined", () => { - const result = validateSensitivity(undefined); - expect(result).toEqual({ href: "#sensitivity" }); - }); - - it("should return error when value is empty string", () => { - const result = validateSensitivity(""); - expect(result).toEqual({ href: "#sensitivity" }); - }); - - it("should return error for invalid sensitivity value", () => { - const result = validateSensitivity("INVALID"); - expect(result).toEqual({ href: "#sensitivity" }); - }); - - it("should return null for PUBLIC", () => { - const result = validateSensitivity("PUBLIC"); - expect(result).toBeNull(); - }); - - it("should return null for PRIVATE", () => { - const result = validateSensitivity("PRIVATE"); - expect(result).toBeNull(); - }); - - it("should return null for CLASSIFIED", () => { - const result = validateSensitivity("CLASSIFIED"); - expect(result).toBeNull(); - }); -}); diff --git a/libs/system-admin-pages/src/third-party-user/validation.ts b/libs/system-admin-pages/src/third-party-user/validation.ts index d4889d5d7..3adf3a830 100644 --- a/libs/system-admin-pages/src/third-party-user/validation.ts +++ b/libs/system-admin-pages/src/third-party-user/validation.ts @@ -27,20 +27,3 @@ export function validateRadioSelection(value: string | undefined): ErrorItem | n return null; } - -export function validateSensitivity(value: string | undefined): ErrorItem | null { - if (!value) { - return { - href: "#sensitivity" - }; - } - - const validValues = ["PUBLIC", "PRIVATE", "CLASSIFIED"]; - if (!validValues.includes(value)) { - return { - href: "#sensitivity" - }; - } - - return null; -}