Skip to content

Commit a172921

Browse files
authored
Merge pull request #165 from alphagov/GOVSI-281/checkbox-validation
GOVSI-281: updated content for 'share-info' page
2 parents 06c5493 + 8ab5f5e commit a172921

5 files changed

Lines changed: 184 additions & 16 deletions

File tree

src/components/share-info/index.njk

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,19 @@
5252
},
5353
items: [
5454
{
55-
checked: "false",
5655
text: 'pages.shareInfo.radios.radioText.agree' | translate,
5756
id: "share-info-accepted",
5857
value: "true"
5958
},
6059
{
61-
checked: "true",
6260
text: 'pages.shareInfo.radios.radioText.doNotAgree' | translate,
6361
id: "share-info-rejected",
6462
value: "false"
6563
}
66-
]
64+
],
65+
errorMessage: {
66+
text: errors['consentValue'].text
67+
} if (errors['consentValue'])
6768
}) }}
6869

6970
{{ govukButton({

src/components/share-info/share-info-routes.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ import * as express from "express";
44
import { shareInfoGet, shareInfoPost } from "./share-info-controller";
55
import { validateSessionMiddleware } from "../../middleware/session-middleware";
66
import { asyncHandler } from "../../utils/async";
7+
import { validateShareInfoRequest } from "./share-info-validation";
78

89
const router = express.Router();
910

10-
router.get(PATH_NAMES.SHARE_INFO, asyncHandler(shareInfoGet()));
11+
router.get(
12+
PATH_NAMES.SHARE_INFO,
13+
validateSessionMiddleware,
14+
asyncHandler(shareInfoGet())
15+
);
1116

1217
router.post(
1318
PATH_NAMES.SHARE_INFO,
1419
validateSessionMiddleware,
20+
validateShareInfoRequest(),
1521
asyncHandler(shareInfoPost())
1622
);
1723

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { body } from "express-validator";
2+
import { validateBodyMiddleware } from "../../middleware/form-validation-middleware";
3+
import { ValidationChainFunc } from "../../types";
4+
5+
export function validateShareInfoRequest(): ValidationChainFunc {
6+
return [
7+
body("consentValue")
8+
.notEmpty()
9+
.withMessage((value, { req }) => {
10+
return req.t("pages.shareInfo.radios.radioText.errorMessage", {
11+
value,
12+
});
13+
}),
14+
validateBodyMiddleware("share-info/index.njk"),
15+
];
16+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import request from "supertest";
2+
import { describe } from "mocha";
3+
import { expect, sinon } from "../../../../test/utils/test-utils";
4+
import nock = require("nock");
5+
import * as cheerio from "cheerio";
6+
import decache from "decache";
7+
8+
describe("Integration::share info", () => {
9+
let sandbox: sinon.SinonSandbox;
10+
let token: string | string[];
11+
let cookies: string;
12+
let app: any;
13+
let baseApi: string;
14+
15+
before(() => {
16+
decache("../../../app");
17+
decache("../../../middleware/session-middleware");
18+
const sessionMiddleware = require("../../../middleware/session-middleware");
19+
sandbox = sinon.createSandbox();
20+
sandbox
21+
.stub(sessionMiddleware, "validateSessionMiddleware")
22+
.callsFake(function (req: any, res: any, next: any): void {
23+
res.locals.sessionId = "tDy103saszhcxbQq0-mjdzU854";
24+
res.locals.clientSessionId = "csy103saszhcxbQq0-mjdzU854";
25+
req.session.user = {
26+
email: "test@test.com",
27+
};
28+
next();
29+
});
30+
31+
app = require("../../../app").createApp();
32+
baseApi = process.env.API_BASE_URL;
33+
34+
nock(baseApi)
35+
.get("/client-info")
36+
.once()
37+
.reply(200, {
38+
clientId: "client_test",
39+
clientName: "client_test_name",
40+
scopes: ["email", "phone"],
41+
});
42+
43+
request(app)
44+
.get("/share-info")
45+
.end((err, res) => {
46+
const $ = cheerio.load(res.text);
47+
token = $("[name=_csrf]").val();
48+
cookies = res.headers["set-cookie"];
49+
});
50+
});
51+
52+
beforeEach(() => {
53+
nock.cleanAll();
54+
});
55+
56+
after(() => {
57+
sandbox.restore();
58+
app = undefined;
59+
});
60+
61+
it("should return share info page", (done) => {
62+
nock(baseApi)
63+
.get("/client-info")
64+
.once()
65+
.reply(200, {
66+
clientId: "client_test",
67+
clientName: "client_test_name",
68+
scopes: ["email", "phone"],
69+
});
70+
request(app).get("/share-info").expect(200, done);
71+
});
72+
73+
it("should return error when csrf not present", (done) => {
74+
request(app)
75+
.post("/share-info")
76+
.type("form")
77+
.send({
78+
consentValue: "true",
79+
})
80+
.expect(500, done);
81+
});
82+
83+
it("should return validation error when consentValue not selected", (done) => {
84+
request(app)
85+
.post("/share-info")
86+
.type("form")
87+
.set("Cookie", cookies)
88+
.send({
89+
_csrf: token,
90+
consentValue: undefined,
91+
})
92+
.expect(function (res) {
93+
const $ = cheerio.load(res.text);
94+
expect($("#share-info-error").text()).to.contains(
95+
"Select if you want to share your email address and phone number or not"
96+
);
97+
})
98+
.expect(400, done);
99+
});
100+
101+
it("should redirect to /auth-code page when consentValue valid", (done) => {
102+
nock(baseApi)
103+
.post("/update-profile")
104+
.once()
105+
.reply(200, {
106+
sessionState: "ADDED_CONSENT",
107+
});
108+
109+
request(app)
110+
.post("/share-info")
111+
.type("form")
112+
.set("Cookie", cookies)
113+
.send({
114+
_csrf: token,
115+
consentValue: "true",
116+
})
117+
.expect("Location", "/auth-code")
118+
.expect(302, done);
119+
});
120+
121+
it("should return internal server error when /update-profile API call response is 500", (done) => {
122+
nock(baseApi)
123+
.post("/update-profile")
124+
.once()
125+
.reply(500, {});
126+
127+
request(app)
128+
.post("/share-info")
129+
.type("form")
130+
.set("Cookie", cookies)
131+
.send({
132+
_csrf: token,
133+
consentValue: "true",
134+
})
135+
.expect(500, done);
136+
});
137+
138+
it("should return internal server error when /client-info API call response is 500", (done) => {
139+
nock(baseApi)
140+
.get("/client-info")
141+
.once()
142+
.reply(500, {});
143+
request(app).get("/share-info").expect(500, done);
144+
});
145+
});

src/locales/en/translation.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -291,18 +291,18 @@
291291
"shareInfo": {
292292
"title": "Share information from your GOV.UK account",
293293
"header": "Share information from your GOV.UK account",
294-
"continue": "Continue",
295-
"bulletPointSectionHeader": "This service needs to use your:",
296-
"paragraph1": "You added this information to your GOV.UK Account when you created the account. You can choose to share it with the service instead of entering it when you use the service.",
297-
"paragraph2": "The service will only use this information to contact you about the service. It won't share your information with anyone else. It will keep your information for as long as it needs to or the law requires it to.",
298-
"paragraph3": "If you choose not to share information from your GOV.UK Account, you may still be asked for that information as you use the service. For example if you choose not to share your email address or phone number and the service needs a way to contact you.",
299-
"essentialHeader": "Do you want to share information from your GOV.UK account?",
300-
"radios": {
301-
"shareMy": "Do you consent to sharing your email address and phone number:",
302-
"radioText": {
303-
"agree": "I agree",
304-
"doNotAgree": "I do not agree",
305-
"error": "You must select an option"
294+
"continue" : "Continue",
295+
"bulletPointSectionHeader" : "This service needs to use your:",
296+
"paragraph1" : "You added this information to your GOV.UK account when you created the account. You can choose to share it with the service instead of entering it when you use the service.",
297+
"paragraph2" : "The service will only use this information to contact you about the service. It won't share your information with anyone else. It will keep your information for as long as it needs to or the law requires it to.",
298+
"paragraph3" : "If you choose not to share information from your GOV.UK account, you may still be asked for that information as you use the service. For example if you choose not to share your email address and phone number and the service needs a way to contact you.",
299+
"essentialHeader" : "Do you want to share information from your GOV.UK account?",
300+
"radios" : {
301+
"shareMy" : "Do you want to share information from your GOV.UK account?",
302+
"radioText" : {
303+
"agree" : "Share my email address and phone number",
304+
"doNotAgree" : "Do not share my email address and phone number",
305+
"errorMessage" : "Select if you want to share your email address and phone number or not"
306306
}
307307
}
308308
},

0 commit comments

Comments
 (0)