Skip to content

Commit b33fe45

Browse files
authored
Handle questionnaire submission failure (#349)
1 parent 3210cb8 commit b33fe45

8 files changed

+186
-48
lines changed

app/routes/errors.py

+5
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ def too_many_individual_response_requests(error=None):
8282

8383

8484
@errors_blueprint.app_errorhandler(SubmissionFailedException)
85+
def submission_failed(error=None):
86+
log_error(error, 500)
87+
return _render_error_page(500, template="submission-failed")
88+
89+
8590
@errors_blueprint.app_errorhandler(Exception)
8691
def internal_server_error(error=None):
8792
try:

app/translations/messages.pot

+16-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ msgid ""
88
msgstr ""
99
"Project-Id-Version: PROJECT VERSION\n"
1010
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
11-
"POT-Creation-Date: 2020-10-13 13:50+0100\n"
11+
"POT-Creation-Date: 2020-10-15 13:52+0100\n"
1212
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1313
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1414
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -309,7 +309,7 @@ msgstr ""
309309
msgid "Continue"
310310
msgstr ""
311311

312-
#: app/views/contexts/list_context.py:94
312+
#: app/views/contexts/list_context.py:103
313313
msgid " (You)"
314314
msgstr ""
315315

@@ -331,7 +331,7 @@ msgid "Confirmation email"
331331
msgstr ""
332332

333333
#: app/views/handlers/confirmation_email.py:31
334-
#: app/views/handlers/question.py:152
334+
#: app/views/handlers/question.py:149
335335
msgid "Error: {page_title}"
336336
msgstr ""
337337

@@ -677,6 +677,8 @@ msgid "For more information on how we use this data."
677677
msgstr ""
678678

679679
#: templates/errors/403.html:3 templates/errors/403.html:6
680+
#: templates/errors/submission-failed.html:5
681+
#: templates/errors/submission-failed.html:8
680682
msgid "Sorry, there is a problem"
681683
msgstr ""
682684

@@ -799,6 +801,16 @@ msgstr ""
799801
msgid "Your census has been submitted"
800802
msgstr ""
801803

804+
#: templates/errors/submission-failed.html:9
805+
msgid "You can try to <a href='{url}'>submit your census again</a>"
806+
msgstr ""
807+
808+
#: templates/errors/submission-failed.html:10
809+
msgid ""
810+
"If this problem keeps happening, please <a href='{url}'>contact us</a> "
811+
"for help."
812+
msgstr ""
813+
802814
#: templates/individual_response/confirmation-post.html:15
803815
msgid ""
804816
"The letter with an individual access code should arrive soon for them to "
@@ -836,7 +848,7 @@ msgstr ""
836848
msgid "Request separate census"
837849
msgstr ""
838850

839-
#: templates/layouts/_base.html:39
851+
#: templates/layouts/_base.html:40
840852
msgid "We use cookies to improve your experience of census.gov.uk"
841853
msgstr ""
842854

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% extends 'layouts/_base.html' %}
2+
3+
{% set hide_signout_button = True %}
4+
5+
{% set page_title = _("Sorry, there is a problem") %}
6+
7+
{% block main %}
8+
<h1>{{ _("Sorry, there is a problem") }}</h1>
9+
<p data-qa="retry">{{ _("You can try to <a href='{url}'>submit your census again</a>").format(url=url_for('questionnaire.get_questionnaire')) }}</p>
10+
<p>{{ _("If this problem keeps happening, please <a href='{url}'>contact us</a> for help.").format(url=contact_us_url) }}</p>
11+
{% endblock %}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
from unittest.mock import Mock
2+
3+
from tests.integration.integration_test_case import IntegrationTestCase
4+
from tests.integration.questionnaire import HUB_URL_PATH, THANK_YOU_URL_PATH
5+
6+
FINAL_SUMMARY_PATH = "/questionnaire/summary/"
7+
FINAL_CONFIRMATION_PATH = "/questionnaire/confirmation/"
8+
9+
10+
class SubmissionTestCase(IntegrationTestCase):
11+
@property
12+
def retry_url(self):
13+
return (
14+
self.getHtmlSoup().find("p", {"data-qa": "retry"}).find("a").attrs["href"]
15+
)
16+
17+
def _mock_submission_failure(self):
18+
submitter = self._application.eq["submitter"]
19+
submitter.send_message = Mock(return_value=False)
20+
21+
22+
class TestQuestionnaireSubmissionFinalConfirmation(SubmissionTestCase):
23+
def _launch_and_submit_questionnaire(self):
24+
# Launch questionnaire
25+
self.launchSurvey("test_final_confirmation")
26+
27+
# Answer questions and submit survey
28+
self.post(action="start_questionnaire")
29+
self.post()
30+
self.post()
31+
32+
def test_successful_submission(self):
33+
# Given I launch and answer a questionnaire, When I submit and the submissions succeeds
34+
self._launch_and_submit_questionnaire()
35+
36+
# Then I should see the thank you page
37+
self.assertInBody(
38+
"Your answers were submitted for <span>Integration Testing</span>"
39+
)
40+
self.assertInUrl(THANK_YOU_URL_PATH)
41+
42+
def test_unsuccessful_submission(self):
43+
self._mock_submission_failure()
44+
45+
# Given I launch and answer a questionnaire, When I submit but the submissions fails
46+
self._launch_and_submit_questionnaire()
47+
48+
# Then I should see an error page
49+
self.assertStatusCode(500)
50+
self.assertEqualPageTitle("Sorry, there is a problem - Census 2021")
51+
52+
self.get(self.retry_url)
53+
self.assertInUrl(FINAL_CONFIRMATION_PATH)
54+
55+
56+
class TestQuestionnaireSubmissionHub(SubmissionTestCase):
57+
def _launch_and_submit_questionnaire(self):
58+
# Launch questionnaire
59+
self.launchSurvey("test_hub_and_spoke")
60+
61+
# Answer questions and submit questionnaire
62+
self.post()
63+
self.post({"employment-status-answer": "Working as an employee"})
64+
self.post()
65+
self.post()
66+
self.post()
67+
self.post()
68+
self.post({"does-anyone-live-here-answer": "No"})
69+
self.post()
70+
self.post()
71+
self.post({"relationships-answer": "No"})
72+
self.post()
73+
self.post()
74+
75+
def test_successful_submission(self):
76+
# Given I launch and answer a questionnaire, When I submit and the submissions succeeds
77+
self._launch_and_submit_questionnaire()
78+
79+
# Then I should see the thank you page
80+
self.assertInBody(
81+
"Your answers were submitted for <span>Integration Testing</span>"
82+
)
83+
self.assertEqualUrl(THANK_YOU_URL_PATH)
84+
85+
def test_unsuccessful_submission(self):
86+
self._mock_submission_failure()
87+
88+
# Given I launch and answer a questionnaire, When I submit but the submissions fails
89+
self._launch_and_submit_questionnaire()
90+
91+
# Then I should see an error page
92+
self.assertStatusCode(500)
93+
self.assertEqualPageTitle("Sorry, there is a problem - Census 2021")
94+
95+
self.get(self.retry_url)
96+
self.assertInUrl(HUB_URL_PATH)
97+
98+
99+
class TestQuestionnaireSubmissionFinalSummary(SubmissionTestCase):
100+
def _launch_and_submit_questionnaire(self):
101+
# Launch questionnaire
102+
self.launchSurvey("test_summary")
103+
104+
# Answer questions and submit survey
105+
self.post()
106+
self.post()
107+
self.post()
108+
self.post()
109+
110+
def test_successful_submission(self):
111+
# Given I launch and answer a questionnaire, When I submit and the submissions succeeds
112+
self._launch_and_submit_questionnaire()
113+
114+
# Then I should see the thank you page
115+
self.assertInBody(
116+
"Your answers were submitted for <span>Integration Testing</span>"
117+
)
118+
self.assertInUrl(THANK_YOU_URL_PATH)
119+
120+
def test_unsuccessful_submission(self):
121+
self._mock_submission_failure()
122+
123+
# Given I launch and answer a questionnaire, When I submit but the submissions fails
124+
self.launchSurvey("test_summary")
125+
self.post()
126+
self.post()
127+
self.post()
128+
self.post()
129+
130+
# Then I should see an error page
131+
self.assertStatusCode(500)
132+
self.assertEqualPageTitle("Sorry, there is a problem - Census 2021")
133+
134+
self.get(self.retry_url)
135+
self.assertInUrl(FINAL_SUMMARY_PATH)

tests/integration/questionnaire/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
from tests.integration.integration_test_case import IntegrationTestCase
22

3+
HUB_URL_PATH = "/questionnaire/"
4+
THANK_YOU_URL_PATH = "/submitted/thank-you/"
5+
36

47
class QuestionnaireTestCase(IntegrationTestCase):
58
def add_person(self, first_name: str, last_name: str):

tests/integration/questionnaire/test_questionnaire_final_confirmation.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from tests.integration.integration_test_case import IntegrationTestCase
22

3+
FINAL_CONFIRMATION = "/questionnaire/confirmation/"
4+
35

46
class TestQuestionnaireFinalConfirmation(IntegrationTestCase):
57
def test_final_confirmation_asked_at_end_of_questionnaire(self):
@@ -12,7 +14,7 @@ def test_final_confirmation_asked_at_end_of_questionnaire(self):
1214
self.post({"breakfast-answer": "Bacon"})
1315

1416
# Then we are presented with a confirmation page
15-
self.assertInUrl("confirmation")
17+
self.assertInUrl(FINAL_CONFIRMATION)
1618
self.assertInBody("Thank you for your answers, do you wish to submit")
1719
self.assertInBody("Submit answers")
1820

@@ -25,7 +27,7 @@ def test_requesting_final_confirmation_before_finished_raises_404(self):
2527
self.assertInBody("What is your favourite breakfast food")
2628

2729
# And try posting straight to the confirmation screen
28-
self.post(url="/questionnaire/confirmation")
30+
self.post(url=FINAL_CONFIRMATION)
2931

3032
# Then we are shown a 404 page
3133
self.assertStatusNotFound()

tests/integration/questionnaire/test_questionnaire_hub.py

+12-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from tests.integration.integration_test_case import IntegrationTestCase
2-
3-
HUB_URL = "/questionnaire/"
2+
from tests.integration.questionnaire import HUB_URL_PATH, THANK_YOU_URL_PATH
43

54

65
class TestQuestionnaireHub(IntegrationTestCase):
@@ -9,7 +8,7 @@ def test_navigation_to_hub_route_when_hub_not_enabled(self):
98
self.launchSurvey("test_checkbox")
109

1110
# When I navigate to the hub url
12-
self.get(HUB_URL)
11+
self.get(HUB_URL_PATH)
1312

1413
# Then I should be redirected to the first incomplete question
1514
self.assertInBody("Which pizza toppings would you like?")
@@ -24,28 +23,7 @@ def test_redirect_to_hub_when_section_complete(self):
2423
self.post({"employment-status-answer": "Working as an employee"})
2524

2625
# Then I should be redirected to the hub
27-
self.assertEqualUrl(HUB_URL)
28-
29-
def test_survey_submission_from_hub(self):
30-
# Given the hub is enabled
31-
self.launchSurvey("test_hub_and_spoke")
32-
33-
# When I submit the survey
34-
self.post()
35-
self.post({"employment-status-answer": "Working as an employee"})
36-
self.post()
37-
self.post()
38-
self.post()
39-
self.post()
40-
self.post({"does-anyone-live-here-answer": "No"})
41-
self.post()
42-
self.post()
43-
self.post({"relationships-answer": "No"})
44-
self.post()
45-
self.post()
46-
47-
# Then I should see the thank you page
48-
self.assertEqualUrl("/submitted/thank-you/")
26+
self.assertEqualUrl(HUB_URL_PATH)
4927

5028
def test_hub_section_url_when_hub_not_enabled(self):
5129
# Given the hub is not enabled
@@ -72,9 +50,9 @@ def test_hub_section_url_when_hub_enabled_and_section_in_progress(self):
7250
self.launchSurvey("test_hub_and_spoke")
7351
self.post()
7452
self.post({"employment-status-answer-exclusive": "None of these apply"})
75-
self.get(HUB_URL)
53+
self.get(HUB_URL_PATH)
7654
self.assertInBody("Partially completed")
77-
self.assertEqualUrl(HUB_URL)
55+
self.assertEqualUrl(HUB_URL_PATH)
7856

7957
# When I navigate to the url for a hub's section that is in-progress
8058
self.get("/questionnaire/employment-type/?resume=True")
@@ -89,7 +67,7 @@ def test_hub_section_url_when_hub_enabled_and_section_complete(self):
8967
self.post()
9068
self.post()
9169
self.assertInBody("View answers")
92-
self.assertEqualUrl(HUB_URL)
70+
self.assertEqualUrl(HUB_URL_PATH)
9371

9472
# When I navigate to the url for a hub's section that is complete
9573
self.get("/questionnaire/sections/accommodation-section/")
@@ -100,7 +78,7 @@ def test_hub_section_url_when_hub_enabled_and_section_complete(self):
10078
def test_hub_inaccessible_if_sections_required_and_incomplete(self):
10179
self.launchSurvey("test_hub_complete_sections")
10280

103-
self.get("/questionnaire/")
81+
self.get(HUB_URL_PATH)
10482

10583
# Redirected to first question to complete
10684
self.assertEqualUrl("/questionnaire/employment-status/")
@@ -111,9 +89,9 @@ def test_hub_accessible_if_sections_required_and_complete(self):
11189
self.post({"employment-status-answer": "Working as an employee"})
11290
self.post()
11391

114-
self.get("/questionnaire/")
92+
self.get(HUB_URL_PATH)
11593

116-
self.assertEqualUrl("/questionnaire/")
94+
self.assertEqualUrl(HUB_URL_PATH)
11795

11896
def test_hub_displays_repeating_sections_with_valid_urls(self):
11997
# Given the hub is enabled and a section is complete
@@ -163,7 +141,7 @@ def test_hub_displays_repeating_sections_with_valid_urls(self):
163141

164142
self.assertInBody("What is <em>John Doe’s</em> date of birth?")
165143

166-
self.get(HUB_URL)
144+
self.get(HUB_URL_PATH)
167145

168146
# Go to second section
169147
second_repeating_section_url = section_urls[2].attrs["href"]
@@ -185,9 +163,9 @@ def test_hub_section_required_but_enabled_false(self):
185163
self.post({"household-relationships-answer": "No"})
186164

187165
# Then I should be redirected to the hub and can submit my answers without completing the other section
188-
self.assertEqualUrl(HUB_URL)
166+
self.assertEqualUrl(HUB_URL_PATH)
189167
self.post()
190-
self.assertEqualUrl("/submitted/thank-you/")
168+
self.assertEqualUrl(THANK_YOU_URL_PATH)
191169

192170
def test_hub_section_required_but_enabled_true(self):
193171
# Given the hub is enabled and there are two required sections

tests/integration/questionnaire/test_questionnaire_schema_theme_thank_you.py

-8
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,3 @@ def test_census_theme_schema_name_not_mapped_to_census_type(self):
4343
self.post({"schema-confirmation-answer": "Yes"})
4444
self.post()
4545
self.assertInBody("Thank you for completing the survey")
46-
47-
def test_default(self):
48-
self.launchSurvey("test_textfield")
49-
self.post({"name-answer": "John Smith"})
50-
self.post()
51-
self.assertInBody(
52-
"Your answers were submitted for <span>Integration Testing</span>"
53-
)

0 commit comments

Comments
 (0)