Skip to content

Commit b0c2a97

Browse files
authored
Merge pull request #624 from companieshouse/lp-1467-post-update-general-partner-person
LP-1467 post update general partner person with appointment id
2 parents e7b705f + 9cfeda3 commit b0c2a97

File tree

9 files changed

+163
-98
lines changed

9 files changed

+163
-98
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# limited-partnerships-web
22
Web front-end for the Limited Partnerships service
33

4-
Requires >= Node v20
5-
>= npm v10
4+
Requires >= Node v24
5+
>= npm v11
66

77
## Local build instructions
88
1. run 'npm i' to install packages
@@ -52,4 +52,4 @@ $ npm run test
5252
all tests watch mode:
5353
```
5454
$ npm run test:watch
55-
```
55+
```

src/config/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ export const TRANSACTION_DESCRIPTION_REMOVE_GENERAL_PARTNER_PERSON = "Remove a g
5252
export const TRANSACTION_DESCRIPTION_REMOVE_GENERAL_PARTNER_LEGAL_ENTITY = "Remove a general partner (legal entity)";
5353
export const TRANSACTION_DESCRIPTION_REMOVE_LIMITED_PARTNER_PERSON = "Remove a limited partner (person)";
5454
export const TRANSACTION_DESCRIPTION_REMOVE_LIMITED_PARTNER_LEGAL_ENTITY = "Remove a limited partner (legal entity)";
55+
export const TRANSACTION_DESCRIPTION_UPDATE_GENERAL_PARTNER_PERSON = "Update a general partner's details (person)";
56+
export const TRANSACTION_DESCRIPTION_UPDATE_GENERAL_PARTNER_LEGAL_ENTITY = "Update a general partner's details (legal entity)";
5557
export const TRANSACTION_DESCRIPTION_DESIGNATE_AS_PRIVATE_FUND_PARTNERSHIP = "Designate as a private fund limited partnership";
5658

5759
// Templates

src/presentation/controller/postTransition/PostTransitionPartnerController.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ class PostTransitionPartnerController extends PartnerController {
112112
pageType === PostTransitionPageType.addGeneralPartnerLegalEntity ||
113113
pageType === PostTransitionPageType.whenDidTheGeneralPartnerLegalEntityCease ||
114114
pageType === PostTransitionPageType.addLimitedPartnerLegalEntity ||
115-
pageType === PostTransitionPageType.whenDidTheLimitedPartnerLegalEntityCease;
115+
pageType === PostTransitionPageType.whenDidTheLimitedPartnerLegalEntityCease ||
116+
pageType === PostTransitionPageType.updateGeneralPartnerLegalEntity;
116117

117118
const limitedPartnershipData = limitedPartnershipResult?.limitedPartnership?.data;
118119

@@ -210,14 +211,14 @@ class PostTransitionPartnerController extends PartnerController {
210211
const { tokens, ids } = super.extract(request);
211212

212213
const dataToSend = {
213-
...request.body,
214-
215214
forename: resultAppointment?.partner.data?.forename,
216215
surname: resultAppointment?.partner.data?.surname,
217216
legal_entity_name: resultAppointment?.partner.data?.legal_entity_name,
218217
date_of_birth: resultAppointment?.partner.data?.date_of_birth,
219-
appointment_id: ids.appointmentId,
220218

219+
...request.body,
220+
221+
appointment_id: ids.appointmentId,
221222
kind: isLegalEntity ? data?.legalEntity.kind : data?.person.kind
222223
};
223224

src/presentation/controller/postTransition/pageType.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ enum PostTransitionPageType {
4949

5050
redesignateToPflp = "redesignate-to-pflp",
5151

52-
updateGeneralPartnerPerson = "update-general-partner-person"
52+
updateGeneralPartnerPerson = "update-general-partner-person",
53+
updateGeneralPartnerLegalEntity = "update-general-partner-legal-entity",
54+
55+
updateUsualResidentialAddressYesNo = "update-usual-residential-address-yes-no"
5356
}
5457

5558
const CeaseDatePageTypes: string[] = [

src/presentation/controller/postTransition/routing/generalPartner.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const postTransitionRoutingRemoveGeneralPartnerLegalEntityCheckYourAnswers = {
8585
const postTransitionRoutingUpdateGeneralPartnerPerson = {
8686
previousUrl: url.LANDING_PAGE_URL,
8787
currentUrl: url.UPDATE_GENERAL_PARTNER_PERSON_URL,
88-
nextUrl: "/", // not defined yet
88+
nextUrl: url.UPDATE_USUAL_RESIDENTIAL_ADDRESS_YES_NO_URL,
8989
pageType: PostTransitionPageType.updateGeneralPartnerPerson
9090
};
9191

src/presentation/controller/postTransition/template.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ export const REMOVE_LIMITED_PARTNER_LEGAL_ENTITY_CHECK_YOUR_ANSWERS_TEMPLATE =
6060
export const REDESIGNATE_TO_PFLP_TEMPLATE = PostTransitionPageType.redesignateToPflp;
6161

6262
export const UPDATE_GENERAL_PARTNER_PERSON_TEMPLATE = PostTransitionPageType.updateGeneralPartnerPerson;
63+
export const UPDATE_USUAL_RESIDENTIAL_ADDRESS_YES_NO_TEMPLATE = PostTransitionPageType.updateUsualResidentialAddressYesNo;

src/presentation/controller/postTransition/url.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const ADD_GENERAL_PARTNER_LEGAL_ENTITY_WITH_IDS_URL = `${POST_TRANSITION_
2222
export const GENERAL_PARTNER_CHECK_YOUR_ANSWERS_URL = `${POST_TRANSITION_WITH_IDS_URL}${GENERAL_PARTNER_WITH_ID_URL}/${template.GENERAL_PARTNER_CHECK_YOUR_ANSWERS_TEMPLATE}`;
2323
export const UPDATE_GENERAL_PARTNER_PERSON_URL = `${POST_TRANSITION_WITH_ID_URL}${APPOINTMENT_ID_URL}/${template.UPDATE_GENERAL_PARTNER_PERSON_TEMPLATE}`;
2424
export const UPDATE_GENERAL_PARTNER_PERSON_WITH_IDS_URL = `${POST_TRANSITION_WITH_IDS_URL}${GENERAL_PARTNER_WITH_ID_URL}/${template.UPDATE_GENERAL_PARTNER_PERSON_TEMPLATE}`;
25+
export const UPDATE_USUAL_RESIDENTIAL_ADDRESS_YES_NO_URL = `${POST_TRANSITION_WITH_IDS_URL}${GENERAL_PARTNER_WITH_ID_URL}/${template.UPDATE_USUAL_RESIDENTIAL_ADDRESS_YES_NO_TEMPLATE}`;
2526

2627
// limited partner
2728
export const LIMITED_PARTNER_CHOICE_URL = `${POST_TRANSITION_WITH_ID_URL}/${template.LIMITED_PARTNER_CHOICE_TEMPLATE}`;
Lines changed: 128 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1+
import { PartnerKind } from "@companieshouse/api-sdk-node/dist/services/limited-partnerships";
2+
13
import request from "supertest";
24
import enTranslationText from "../../../../../../locales/en/translations.json";
35
import cyTranslationText from "../../../../../../locales/cy/translations.json";
46
import app from "../../app";
57
import {
68
UPDATE_GENERAL_PARTNER_PERSON_URL,
79
UPDATE_GENERAL_PARTNER_PERSON_WITH_IDS_URL,
10+
UPDATE_USUAL_RESIDENTIAL_ADDRESS_YES_NO_URL,
811
} from "../../../../controller/postTransition/url";
912
import { getUrl, setLocalesEnabled, testTranslations } from "../../../utils";
1013
import CompanyProfileBuilder from "../../../builder/CompanyProfileBuilder";
1114
import CompanyAppointmentBuilder from "../../../builder/CompanyAppointmentBuilder";
1215
import { appDevDependencies } from "../../../../../config/dev-dependencies";
1316
import GeneralPartnerBuilder from "../../../../../presentation/test/builder/GeneralPartnerBuilder";
17+
import PostTransitionPageType from "../../../../../presentation/controller/postTransition/pageType";
18+
import { ApiErrors } from "../../../../../domain/entities/UIErrors";
1419

1520
describe("Update General Partner Legal Entity Page", () => {
1621
const URL = getUrl(UPDATE_GENERAL_PARTNER_PERSON_URL);
1722
const URL_WITH_IDS = getUrl(UPDATE_GENERAL_PARTNER_PERSON_WITH_IDS_URL);
23+
const REDIRECT = getUrl(UPDATE_USUAL_RESIDENTIAL_ADDRESS_YES_NO_URL);
1824

1925
let companyProfile;
2026
let companyAppointment;
@@ -32,97 +38,131 @@ describe("Update General Partner Legal Entity Page", () => {
3238
appDevDependencies.companyGateway.feedCompanyAppointments([]);
3339
});
3440

35-
describe("Get update general partner person page", () => {
36-
it("should load the update general partner legal entity page with English text", async () => {
37-
setLocalesEnabled(true);
38-
39-
const res = await request(app).get(URL + "?lang=en");
40-
41-
expect(res.status).toBe(200);
42-
43-
expect(res.text).toContain(
44-
`${companyProfile.data.companyName?.toUpperCase()} (${companyProfile.data.companyNumber?.toUpperCase()})`
45-
);
46-
47-
testTranslations(res.text, enTranslationText.updatePartnerPersonPage, [
48-
"limitedPartner",
49-
"errorMessages",
50-
]);
51-
52-
expect(res.text).not.toContain("WELSH -");
53-
});
54-
55-
it("should load the update general partner person page with Welsh text", async () => {
56-
setLocalesEnabled(true);
57-
58-
const res = await request(app).get(URL + "?lang=cy");
59-
60-
expect(res.status).toBe(200);
61-
62-
expect(res.text).toContain(
63-
`${companyProfile.data.companyName?.toUpperCase()} (${companyProfile.data.companyNumber?.toUpperCase()})`
64-
);
65-
66-
testTranslations(res.text, cyTranslationText.updatePartnerPersonPage, [
67-
"limitedPartner",
68-
"errorMessages",
69-
]);
41+
describe("Update general partner person page", () => {
42+
43+
describe("GET general partner cease date page", () => {
44+
45+
it.each([
46+
["English", "en", enTranslationText],
47+
["Welsh", "cy", cyTranslationText]
48+
])("should load the update general partner legal entity page with %s text", async (_description: string, lang: string, translationText: any) => {
49+
setLocalesEnabled(true);
50+
51+
const res = await request(app).get(`${URL}?lang=${lang}`);
52+
53+
expect(res.status).toBe(200);
54+
55+
expect(res.text).toContain(
56+
`${companyProfile.data.companyName?.toUpperCase()} (${companyProfile.data.companyNumber?.toUpperCase()})`
57+
);
58+
59+
testTranslations(res.text, translationText.updatePartnerPersonPage, [
60+
"limitedPartner",
61+
"errorMessages",
62+
]);
63+
64+
if (lang === "cy") {
65+
expect(res.text).toContain("WELSH - ");
66+
} else {
67+
expect(res.text).not.toContain("WELSH -");
68+
}
69+
});
70+
71+
it("should contain the partnership name", async () => {
72+
const res = await request(app).get(URL);
73+
74+
expect(res.status).toBe(200);
75+
expect(res.text).toContain(
76+
`${companyProfile.data.companyName.toUpperCase()} (${companyProfile.data.companyNumber.toUpperCase()})`
77+
);
78+
});
79+
80+
it.each([
81+
["with appointment id", URL],
82+
["with general partner id", URL_WITH_IDS]
83+
])("should load the update general partner person page and replay saved data %s", async (_description: string, url: string) => {
84+
if (url.includes("/appointment/")) {
85+
companyAppointment = new CompanyAppointmentBuilder()
86+
.withOfficerRole("general-partner-in-a-limited-partnership")
87+
.withName("Doe - GP, Joe - GP")
88+
.withNationality("British,Irish")
89+
.build();
90+
appDevDependencies.companyGateway.feedCompanyAppointments([
91+
companyAppointment,
92+
]);
93+
} else {
94+
const generalPartner = new GeneralPartnerBuilder()
95+
.withId(appDevDependencies.generalPartnerGateway.generalPartnerId)
96+
.isPerson()
97+
.withNotDisqualifiedStatementChecked(true)
98+
.withNationality1("British")
99+
.withNationality2("Irish")
100+
.build();
101+
102+
appDevDependencies.generalPartnerGateway.feedGeneralPartners([
103+
generalPartner,
104+
]);
105+
}
106+
107+
setLocalesEnabled(true);
108+
const res = await request(app).get(url);
109+
110+
expect(res.status).toBe(200);
111+
expect(res.text).toContain("Joe - GP");
112+
expect(res.text).toContain("Doe - GP");
113+
expect(res.text).toContain('<option value="British" selected>British</option>');
114+
expect(res.text).toContain('<option value="Irish" selected>Irish</option>');
115+
});
70116
});
71117

72-
it("should contain the partnership name", async () => {
73-
const res = await request(app).get(URL);
74-
75-
expect(res.status).toBe(200);
76-
expect(res.text).toContain(
77-
`${companyProfile.data.companyName.toUpperCase()} (${companyProfile.data.companyNumber.toUpperCase()})`
78-
);
79-
});
80-
81-
it("should load the update general partner person page and replay saved data from CHS appointment", async () => {
82-
companyAppointment = new CompanyAppointmentBuilder()
83-
.withOfficerRole("general-partner-in-a-limited-partnership")
84-
.withName("Doe - GP, Joe - GP")
85-
.withNationality("British,Irish")
86-
.build();
87-
appDevDependencies.companyGateway.feedCompanyAppointments([
88-
companyAppointment,
89-
]);
90-
91-
setLocalesEnabled(true);
92-
const res = await request(app).get(URL);
93-
94-
expect(res.status).toBe(200);
95-
expect(res.text).toContain("Joe - GP");
96-
expect(res.text).toContain("Doe - GP");
97-
expect(res.text).toContain(
98-
'<option value="British" selected>British</option>'
99-
);
100-
expect(res.text).toContain(
101-
'<option value="Irish" selected>Irish</option>'
102-
);
118+
describe("POST general partner cease date page", () => {
119+
120+
it("should send the general partner person details to API", async () => {
121+
expect(appDevDependencies.generalPartnerGateway.generalPartners).toHaveLength(0);
122+
123+
const res = await request(app).post(URL).send({
124+
pageType: PostTransitionPageType.updateGeneralPartnerPerson,
125+
"forename": "John",
126+
"surname": "Doe",
127+
"nationality1": "British",
128+
"nationality2": "Irish"
129+
});
130+
131+
expect(res.status).toBe(302);
132+
expect(res.text).toContain(`Redirecting to ${REDIRECT}`);
133+
134+
expect(appDevDependencies.generalPartnerGateway.generalPartners).toHaveLength(1);
135+
expect(appDevDependencies.generalPartnerGateway.generalPartners[0].data?.kind).toEqual(
136+
PartnerKind.UPDATE_GENERAL_PARTNER_PERSON
137+
);
138+
expect(appDevDependencies.generalPartnerGateway.generalPartners[0].data?.forename).toEqual("John");
139+
expect(appDevDependencies.generalPartnerGateway.generalPartners[0].data?.surname).toEqual("Doe");
140+
expect(appDevDependencies.generalPartnerGateway.generalPartners[0].data?.nationality1).toEqual("British");
141+
expect(appDevDependencies.generalPartnerGateway.generalPartners[0].data?.nationality2).toEqual("Irish");
142+
});
143+
144+
it("should replay entered data when a validation error occurs", async () => {
145+
const apiErrors: ApiErrors = {
146+
errors: { forename: "forename is invalid" }
147+
};
148+
appDevDependencies.generalPartnerGateway.feedErrors(apiErrors);
149+
150+
const res = await request(app).post(URL).send({
151+
pageType: PostTransitionPageType.updateGeneralPartnerPerson,
152+
"forename": "INVALID-FORENAME",
153+
"surname": "Doe",
154+
"nationality1": "British",
155+
"nationality2": "Irish"
156+
});
157+
158+
expect(res.status).toBe(200);
159+
expect(res.text).toContain("forename is invalid");
160+
expect(res.text).toContain("INVALID-FORENAME");
161+
expect(res.text).toContain("Doe");
162+
expect(res.text).toContain('<option value="British" selected>British</option>');
163+
expect(res.text).toContain('<option value="Irish" selected>Irish</option>');
164+
});
103165
});
104166

105-
it("should load the update general partner person page and replay saved general partner data", async () => {
106-
const generalPartner = new GeneralPartnerBuilder()
107-
.withId(appDevDependencies.generalPartnerGateway.generalPartnerId)
108-
.isPerson()
109-
.withNotDisqualifiedStatementChecked(true)
110-
.withNationality1("British")
111-
.build();
112-
113-
appDevDependencies.generalPartnerGateway.feedGeneralPartners([
114-
generalPartner,
115-
]);
116-
117-
setLocalesEnabled(true);
118-
const res = await request(app).get(URL_WITH_IDS);
119-
120-
expect(res.status).toBe(200);
121-
expect(res.text).toContain("Joe - GP");
122-
expect(res.text).toContain("Doe - GP");
123-
expect(res.text).toContain(
124-
'<option value="British" selected>British</option>'
125-
);
126-
});
127167
});
128168
});

src/routes/postTransition.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ import {
6161
TRANSACTION_DESCRIPTION_REMOVE_GENERAL_PARTNER_LEGAL_ENTITY,
6262
TRANSACTION_DESCRIPTION_REMOVE_GENERAL_PARTNER_PERSON,
6363
TRANSACTION_DESCRIPTION_REMOVE_LIMITED_PARTNER_LEGAL_ENTITY,
64-
TRANSACTION_DESCRIPTION_REMOVE_LIMITED_PARTNER_PERSON
64+
TRANSACTION_DESCRIPTION_REMOVE_LIMITED_PARTNER_PERSON,
65+
TRANSACTION_DESCRIPTION_UPDATE_GENERAL_PARTNER_LEGAL_ENTITY,
66+
TRANSACTION_DESCRIPTION_UPDATE_GENERAL_PARTNER_PERSON
6567
} from "../config/constants";
6668

6769
const postTransitionEndpoints = (router: Router, dependencies: IDependencies): void => {
@@ -621,6 +623,21 @@ const postTransitionEndpoints = (router: Router, dependencies: IDependencies): v
621623
companyAuthentication,
622624
dependencies.generalPartnerPostTransitionController.getUpdatePageRouting()
623625
);
626+
router.post(
627+
UPDATE_GENERAL_PARTNER_PERSON_URL,
628+
companyAuthentication,
629+
dependencies.generalPartnerPostTransitionController.createGeneralPartner({
630+
person: {
631+
description: TRANSACTION_DESCRIPTION_UPDATE_GENERAL_PARTNER_PERSON,
632+
kind: PartnerKind.UPDATE_GENERAL_PARTNER_PERSON
633+
},
634+
legalEntity: {
635+
description: TRANSACTION_DESCRIPTION_UPDATE_GENERAL_PARTNER_LEGAL_ENTITY,
636+
kind: PartnerKind.UPDATE_GENERAL_PARTNER_LEGAL_ENTITY
637+
},
638+
needAppointment: true
639+
})
640+
);
624641

625642
router.get(
626643
UPDATE_GENERAL_PARTNER_PERSON_WITH_IDS_URL,

0 commit comments

Comments
 (0)