diff --git a/app/helpers/form_helper.py b/app/helpers/form_helper.py index 1559472ad2..037f21a98e 100644 --- a/app/helpers/form_helper.py +++ b/app/helpers/form_helper.py @@ -10,9 +10,7 @@ logger = get_logger() -def get_form_for_location( - schema, block_json, location, answer_store, metadata, disable_mandatory=False -): # pylint: disable=too-many-locals +def get_form_for_location(schema, block_json, location, answer_store, metadata): """ Returns the form necessary for the location given a get request, plus any template arguments @@ -21,11 +19,8 @@ def get_form_for_location( :param location: The location which this form is for :param answer_store: The current answer store :param metadata: metadata - :param disable_mandatory: Make mandatory answers optional :return: form, template_args A tuple containing the form for this location and any additional template arguments """ - if disable_mandatory: - block_json = disable_mandatory_answers(block_json) mapped_answers = get_mapped_answers(schema, answer_store, location=location) @@ -40,13 +35,7 @@ def get_form_for_location( def post_form_for_block( - schema, - block_json, - answer_store, - metadata, - request_form, - location, - disable_mandatory=False, + schema, block_json, answer_store, metadata, request_form, location ): """ Returns the form necessary for the location given a post request, plus any template arguments @@ -57,10 +46,7 @@ def post_form_for_block( :param metadata: metadata :param request_form: form, template_args A tuple containing the form for this location and any additional template arguments :param location: The location in the survey this post is for - :param disable_mandatory: Make mandatory answers optional """ - if disable_mandatory: - block_json = disable_mandatory_answers(block_json) question = block_json.get("question") @@ -71,19 +57,6 @@ def post_form_for_block( ) -def disable_mandatory_answers(block): - def set_mandatory_to_false(question): - # Here Be Dragons: This loop modifies the input in place. - for answer in question.get("answers", []): - if answer.get("mandatory", True) is True: - answer["mandatory"] = False - - if block.get("question"): - set_mandatory_to_false(block["question"]) - - return block - - def clear_detail_answer_field(data, question): """ Checks the submitted answers and in the case of both checkboxes and radios, diff --git a/app/routes/questionnaire.py b/app/routes/questionnaire.py index 6fee14c16c..6a8c5490be 100644 --- a/app/routes/questionnaire.py +++ b/app/routes/questionnaire.py @@ -3,16 +3,7 @@ import humanize import simplejson as json from dateutil.tz import tzutc -from flask import ( - Blueprint, - g, - redirect, - request, - url_for, - current_app, - jsonify, - session as cookie_session, -) +from flask import Blueprint, g, redirect, request, url_for, current_app, jsonify from flask_login import current_user, login_required from jwcrypto.common import base64url_decode from sdc.crypto.encrypter import encrypt @@ -145,12 +136,6 @@ def get_questionnaire(schema, questionnaire_store): @with_questionnaire_store @with_schema def post_questionnaire(schema, questionnaire_store): - if any( - action in request.form - for action in ("action[save_sign_out]", "action[sign_out]") - ): - return redirect(url_for("session.get_sign_out")) - router = Router( schema, questionnaire_store.answer_store, @@ -226,9 +211,6 @@ def block(schema, questionnaire_store, block_id, list_name=None, list_item_id=No if block_handler.block["type"] == "RelationshipCollector": return redirect(block_handler.get_first_location_url()) - if "action[sign_out]" in request.form: - return redirect(url_for("session.get_sign_out")) - if "action[clear_radios]" in request.form: block_handler.clear_radio_answers() return redirect(request.url) @@ -247,10 +229,6 @@ def block(schema, questionnaire_store, block_id, list_name=None, list_item_id=No page_title=block_handler.page_title, ) - if "action[save_sign_out]" in request.form: - block_handler.save_on_sign_out() - return redirect(url_for("session.get_sign_out")) - if block_handler.block["type"] in END_BLOCKS: return submit_answers( schema, questionnaire_store, block_handler.router.full_routing_path() @@ -298,10 +276,6 @@ def relationship(schema, questionnaire_store, block_id, list_item_id, to_list_it page_title=block_handler.page_title, ) - if "action[save_sign_out]" in request.form: - block_handler.save_on_sign_out() - return redirect(url_for("session.get_sign_out")) - block_handler.handle_post() next_location_url = block_handler.get_next_location_url() return redirect(next_location_url) @@ -327,9 +301,6 @@ def get_thank_you(schema): timedelta(seconds=schema.json["view_submitted_response"]["duration"]) ) - cookie_session.pop("account_service_log_out_url", None) - cookie_session.pop("account_service_url", None) - return render_template( template="thank-you", metadata=metadata_context, @@ -339,18 +310,10 @@ def get_thank_you(schema): ), view_submission_url=view_submission_url, view_submission_duration=view_submission_duration, + hide_signout_button=True, ) -@post_submission_blueprint.route("thank-you/", methods=["POST"]) -@login_required -def post_thank_you(): - if "action[sign_out]" in request.form: - return redirect(url_for("session.get_sign_out")) - - return redirect(url_for("post_submission.get_thank_you")) - - @post_submission_blueprint.route("view-submission/", methods=["GET"]) @login_required @with_schema @@ -411,29 +374,13 @@ def get_view_submission(schema): return redirect(url_for("post_submission.get_thank_you")) -@post_submission_blueprint.route("view-submission/", methods=["POST"]) -@login_required -def post_view_submission(): - if "action[sign_out]" in request.form: - return redirect(url_for("session.get_sign_out")) - - return redirect(url_for("post_submission.get_view_submission")) - - def _generate_wtf_form(block_schema, schema, current_location): answer_store = get_answer_store(current_user) metadata = get_metadata(current_user) if request.method == "POST": - disable_mandatory = "action[save_sign_out]" in request.form return post_form_for_block( - schema, - block_schema, - answer_store, - metadata, - request.form, - current_location, - disable_mandatory, + schema, block_schema, answer_store, metadata, request.form, current_location ) return get_form_for_location( schema, block_schema, current_location, answer_store, metadata diff --git a/app/routes/session.py b/app/routes/session.py index eb9472f862..7b326d5850 100644 --- a/app/routes/session.py +++ b/app/routes/session.py @@ -121,7 +121,7 @@ def get_session_expired(): return render_template("errors/session-expired") -@session_blueprint.route("/signed-out", methods=["GET"]) +@session_blueprint.route("/sign-out", methods=["GET"]) def get_sign_out(): """ Signs the user first out of eq, then the account service by hitting the account services' @@ -133,4 +133,9 @@ def get_sign_out(): if account_service_log_out_url: return redirect(account_service_log_out_url) + return redirect(url_for(".get_signed_out")) + + +@session_blueprint.route("/signed-out", methods=["GET"]) +def get_signed_out(): return render_template(template="signed-out") diff --git a/app/translations/messages.pot b/app/translations/messages.pot index 673f0f6cc7..259ecf77e8 100644 --- a/app/translations/messages.pot +++ b/app/translations/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2020-06-03 09:10+0100\n" +"POT-Creation-Date: 2020-06-09 13:22+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -584,12 +584,12 @@ msgstr "" msgid "Save and sign out" msgstr "" -#: templates/layouts/configs/_save-sign-out-button.html:18 -msgid "Sign out" +#: templates/layouts/configs/_save-sign-out-button.html:7 +msgid "Save and complete later" msgstr "" -#: templates/layouts/configs/_save-sign-out-button.html:32 -msgid "Save and complete later" +#: templates/layouts/configs/_save-sign-out-button.html:24 +msgid "Sign out" msgstr "" #: templates/partials/answer-guidance.html:13 @@ -607,23 +607,23 @@ msgid "" " of the section" msgstr "" -#: templates/partials/question.html:39 +#: templates/partials/question.html:48 msgid "Selecting this will clear your answer" msgstr "" -#: templates/partials/question.html:40 +#: templates/partials/question.html:49 msgid "cleared" msgstr "" -#: templates/partials/question.html:43 +#: templates/partials/question.html:52 msgid "Selecting this will deselect any selected options" msgstr "" -#: templates/partials/question.html:44 templates/partials/question.html:52 +#: templates/partials/question.html:53 templates/partials/question.html:61 msgid "deselected" msgstr "" -#: templates/partials/question.html:48 +#: templates/partials/question.html:57 msgid "Or" msgstr "" diff --git a/templates/layouts/configs/_save-sign-out-button.html b/templates/layouts/configs/_save-sign-out-button.html index b65780cf99..77fb5b6cd1 100644 --- a/templates/layouts/configs/_save-sign-out-button.html +++ b/templates/layouts/configs/_save-sign-out-button.html @@ -1,11 +1,16 @@ -{% if current_user.is_authenticated %} - {% if account_service_log_out_url %} +{% if current_user.is_authenticated and not hide_signout_button %} + {% if save_on_signout %} + {% if account_service_log_out_url %} + {% set button_text = _("Save and sign out") %} + {% else %} + {% set button_text = _("Save and complete later") %} + {% endif %} {% do pageConfig | setAttribute("signoutButton", { - "text": _("Save and sign out"), - "name": "action[save_sign_out]", + "text": button_text, + "name": "btn-save-sign-out", "classes": "js-btn-save", - "url": "/signed-out", + "url": "/sign-out", "attributes": { "data-qa": "btn-save-sign-out", "data-ga": "click", @@ -13,11 +18,12 @@ "data-ga-action": "Save and sign out click" } }) %} + {% else %} {% do pageConfig | setAttribute("signoutButton", { "text": _("Sign out"), - "name": "action[sign_out]", - "url": "/signed-out", + "name": "btn-sign-out", + "url": "/sign-out", "attributes": { "data-qa": "btn-sign-out", "data-ga": "click", @@ -25,21 +31,7 @@ "data-ga-action": "Sign out click" } }) %} + {% endif %} - {% else %} - {% if save_on_signout %} - {% do pageConfig | setAttribute("signoutButton", { - "text": _("Save and complete later"), - "name": "action[save_sign_out]", - "classes": "js-btn-save", - "url": "/signed-out", - "attributes": { - "data-qa": "btn-save-sign-out", - "data-ga": "click", - "data-ga-category": "Navigation", - "data-ga-action": "Save and sign out click" - } - }) %} - {% endif %} - {% endif %} + {% endif %} diff --git a/templates/macros/helpers.html b/templates/macros/helpers.html index ce6d6350ba..7efc06740b 100644 --- a/templates/macros/helpers.html +++ b/templates/macros/helpers.html @@ -27,23 +27,3 @@ } %} {{email}} {%- endmacro -%} - -{%- macro save_signout_button(button_text) -%} - {% set attr = { - "class": "btn btn--ghost print__hidden js-btn-save", - "data-qa": "btn-save-sign-out", - "name": "action[save_sign_out]", - } %} - {% set analytics = track('click', 'Navigation', 'Save and sign out click') %} - -{%- endmacro -%} - -{%- macro signout_button(button_text) -%} - {% set attr = { - "class": "btn btn--ghost print__hidden", - "data-qa": "btn-sign-out", - "name": "action[sign_out]", - } %} - {% set analytics = track('click', 'Navigation', 'Sign out click') %} - -{%- endmacro -%} diff --git a/tests/app/helpers/test_form_helper.py b/tests/app/helpers/test_form_helper.py index e6571dde30..3e7697af26 100644 --- a/tests/app/helpers/test_form_helper.py +++ b/tests/app/helpers/test_form_helper.py @@ -12,7 +12,7 @@ from app.utilities.schema import load_schema_from_name from app.questionnaire.relationship_location import RelationshipLocation from app.data_model.answer_store import AnswerStore -from app.forms.validators import DateRequired, OptionalForm +from app.forms.validators import DateRequired class TestFormHelper(AppContextTestCase): @@ -36,31 +36,6 @@ def test_get_form_for_block_location(self): self.assertIsInstance(period_from_field.year.validators[0], DateRequired) self.assertIsInstance(period_to_field.year.validators[0], DateRequired) - def test_get_form_and_disable_mandatory_answers(self): - with self.app_request_context(): - schema = load_schema_from_name("test_date_range") - - block_json = deepcopy(schema.get_block("date-block")) - location = Location(section_id="default-section", block_id="date-block") - - form = get_form_for_location( - schema, - block_json, - location, - AnswerStore(), - metadata=None, - disable_mandatory=True, - ) - - period_from_field = getattr(form, "date-range-from-answer", None) - period_to_field = getattr(form, "date-range-to-answer", None) - - assert period_from_field - assert period_to_field - - self.assertIsInstance(period_from_field.year.validators[0], OptionalForm) - self.assertIsInstance(period_to_field.year.validators[0], OptionalForm) - def test_post_form_for_block_location(self): with self.app_request_context(): schema = load_schema_from_name("test_date_range") @@ -95,31 +70,6 @@ def test_post_form_for_block_location(self): self.assertEqual(period_from_field.data, "2015-05-01") self.assertEqual(period_to_field.data, "2017-09-01") - def test_post_form_and_disable_mandatory(self): - with self.app_request_context(): - schema = load_schema_from_name("test_date_range") - - block_json = deepcopy(schema.get_block("date-block")) - - form = post_form_for_block( - schema, - block_json, - AnswerStore(), - metadata=None, - request_form={}, - disable_mandatory=True, - location=None, - ) - - self.assertTrue(hasattr(form, "date-range-from-answer")) - self.assertTrue(hasattr(form, "date-range-to-answer")) - - period_from_field = getattr(form, "date-range-from-answer") - period_to_field = getattr(form, "date-range-to-answer") - - self.assertIsInstance(period_from_field.year.validators[0], OptionalForm) - self.assertIsInstance(period_to_field.year.validators[0], OptionalForm) - def test_post_form_for_radio_other_not_selected(self): with self.app_request_context(): schema = load_schema_from_name("test_radio_mandatory_with_mandatory_other") diff --git a/tests/functional/spec/save_sign_out.spec.js b/tests/functional/spec/save_sign_out.spec.js index 724246ab72..1fca72f62c 100644 --- a/tests/functional/spec/save_sign_out.spec.js +++ b/tests/functional/spec/save_sign_out.spec.js @@ -55,7 +55,7 @@ describe("SaveSignOut", () => { it("Given a logout url is not set, when I navigate the questionnaire, then I see the correct sign out buttons", () => { browser.openQuestionnaire("test_introduction.json", { includeLogoutUrl: false }); - expect($(IntroductionPage.signOut()).isExisting()).to.be.false; + expect($(IntroductionPage.signOut()).getText()).to.contain("Sign out"); $(IntroductionPage.getStarted()).click(); expect($(IntroInterstitialPage.saveSignOut()).getText()).to.contain("Save and complete later"); diff --git a/tests/integration/questionnaire/test_questionnaire_csrf.py b/tests/integration/questionnaire/test_questionnaire_csrf.py index 8caa144eb5..01d1404e9c 100644 --- a/tests/integration/questionnaire/test_questionnaire_csrf.py +++ b/tests/integration/questionnaire/test_questionnaire_csrf.py @@ -85,24 +85,6 @@ def test_given_valid_answer_when_answer_with_invalid_csrf_token_then_answer_not_ answers = json.loads(self.getResponseData()) self.assertEqual(2, len(answers["ANSWERS"])) - def test_given_valid_answers_when_save_and_sign_out_with_invalid_csrf_token_then_answers_not_saved( - self - ): - # Given - self.launchSurvey("test_interstitial_page", roles=["dumper"]) - self.post() - post_data = {"favourite-breakfast": "Muesli"} - - # When - self.last_csrf_token = "made-up-token" - self.post(post_data=post_data, action="save_sign_out") - - # Then - self.assertStatusCode(401) - self.get("/dump/debug") - answers = json.loads(self.getResponseData()) - self.assertEqual(0, len(answers["ANSWERS"])) - def test_given_csrf_attack_when_refresh_then_on_question(self): # Given self.launchSurvey("test_interstitial_page", roles=["dumper"]) diff --git a/tests/integration/questionnaire/test_questionnaire_hub.py b/tests/integration/questionnaire/test_questionnaire_hub.py index 443bcfff9d..c6d3241288 100644 --- a/tests/integration/questionnaire/test_questionnaire_hub.py +++ b/tests/integration/questionnaire/test_questionnaire_hub.py @@ -30,39 +30,29 @@ def test_redirect_to_hub_when_section_complete(self): self.launchSurvey("test_hub_and_spoke") # When I complete a section - self.post(action="submit") + self.post() self.post({"employment-status-answer": "Working as an employee"}) # Then I should be redirected to the hub self.assertEqualUrl(HUB_URL) - def test_save_and_sign_out_from_the_hub(self): - # Given the hub is enabled - self.launchSurvey("test_hub_and_spoke") - - # When I click Save and sign out - self.post(action="save_sign_out") - - # Then I should be redirected to the hub - self.assertEqualUrl("/signed-out") - def test_survey_submission_from_hub(self): # Given the hub is enabled self.launchSurvey("test_hub_and_spoke") # When I submit the survey - self.post(action="submit") + self.post() self.post({"employment-status-answer": "Working as an employee"}) - self.post(action="submit") self.post() - self.post(action="submit") - self.post(action="submit") + self.post() + self.post() + self.post() self.post({"does-anyone-live-here-answer": "No"}) - self.post(action="submit") - self.post(action="submit") + self.post() + self.post() self.post({"relationships-answer": "No"}) - self.post(action="submit") - self.post(action="submit") + self.post() + self.post() # Then I should see the thank you page self.assertEqualUrl("/submitted/thank-you/") @@ -100,7 +90,7 @@ def test_section_url_when_hub_enabled_and_section_not_started(self): def test_hub_section_url_when_hub_enabled_and_section_in_progress(self): # Given the hub is enabled and a section is in-progress self.launchSurvey("test_hub_and_spoke") - self.post(action="submit") + self.post() self.post({"employment-status-answer-exclusive": "None of these apply"}) self.get(HUB_URL) self.assertInBody("Partially completed") @@ -117,7 +107,7 @@ def test_hub_section_url_when_hub_enabled_and_section_complete(self): self.launchSurvey("test_hub_and_spoke") self.get("/questionnaire/sections/accommodation-section/") self.post() - self.post(action="submit") + self.post() self.assertInBody("View answers") self.assertEqualUrl(HUB_URL) @@ -139,7 +129,7 @@ def test_hub_accessible_if_sections_required_and_complete(self): self.launchSurvey("test_hub_complete_sections") self.post({"employment-status-answer": "Working as an employee"}) - self.post(action="submit") + self.post() self.get("/questionnaire/") @@ -149,7 +139,7 @@ def test_hub_displays_repeating_sections_with_valid_urls(self): # Given the hub is enabled and a section is complete self.launchSurvey("test_repeating_sections_with_hub_and_spoke") # Go to first section - self.post(action="submit") + self.post() # Add a primary person self.post({"you-live-here": "Yes"}) @@ -164,7 +154,7 @@ def test_hub_displays_repeating_sections_with_valid_urls(self): self.post({"anyone-else": "No"}) # Submit interstitial page - self.post(action="submit") + self.post() # Go to visitors self.post({"another-anyone-else": "No"}) @@ -216,7 +206,7 @@ def test_hub_section_required_but_enabled_false(self): # Then I should be redirected to the hub and can submit my answers without completing the other section self.assertEqualUrl(HUB_URL) - self.post(action="submit") + self.post() self.assertEqualUrl("/submitted/thank-you/") def test_hub_section_required_but_enabled_true(self): diff --git a/tests/integration/questionnaire/test_questionnaire_last_viewed_guidance.py b/tests/integration/questionnaire/test_questionnaire_last_viewed_guidance.py index 647de432fd..2208ba4e36 100644 --- a/tests/integration/questionnaire/test_questionnaire_last_viewed_guidance.py +++ b/tests/integration/questionnaire/test_questionnaire_last_viewed_guidance.py @@ -37,7 +37,7 @@ def test_not_shown_on_section_resume_first_block_in_new_section(self): self._post_address_confirmation_answer() self._post_you_live_here_answer() self._post_list_collector_answers() - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) @@ -52,7 +52,7 @@ def test_not_shown_on_resume_section_not_started(self): ) # When I sign out without starting the section and I resume the survey - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) @@ -69,7 +69,7 @@ def test_shown_on_resume_section_in_progress(self): # When I sign out after I have started the section and I resume the survey self.post() - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) @@ -90,7 +90,7 @@ def test_shown_on_section_in_progress_resume_primary_person_list_collector(self) # When I sign out and resume on a primary person list collector self.post() self._post_address_confirmation_answer() - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) @@ -114,7 +114,7 @@ def test_shown_on_section_in_progress_resume_primary_person_list_collector_add_p self.post() self._post_address_confirmation_answer() self._post_you_live_here_answer() - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) @@ -137,7 +137,7 @@ def test_shown_on_section_in_progress_resume_list_collector(self): self._post_address_confirmation_answer() self._post_you_live_here_answer() self._post_primary_person_answer() - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) @@ -161,7 +161,7 @@ def test_shown_on_section_in_progress_resume_list_collector_add_person(self): self._post_you_live_here_answer() self._post_primary_person_answer() self.post({"anyone-else": "Yes"}) - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) @@ -186,7 +186,7 @@ def test_shown_on_section_in_progress_resume_relationships(self): self._post_list_collector_answers() self.post() self.post() - self.post(action="sign_out") + self.get("/sign-out") self.launchSurvey( "test_last_viewed_question_guidance", reponse_id=self.response_id ) diff --git a/tests/integration/questionnaire/test_questionnaire_relationships.py b/tests/integration/questionnaire/test_questionnaire_relationships.py index 9a5ddb9023..d5d966751e 100644 --- a/tests/integration/questionnaire/test_questionnaire_relationships.py +++ b/tests/integration/questionnaire/test_questionnaire_relationships.py @@ -54,18 +54,6 @@ def test_failed_validation(self): self.post() self.assertInBody("This page has an error") - def test_save_sign_out(self): - self.launchSurvey( - "test_relationships", - account_service_url="https://localhost/my-account", - account_service_log_out_url="https://localhost/logout", - ) - self.add_person("Marie", "Doe") - self.add_person("John", "Doe") - self.post({"anyone-else": "No"}) - self.post(action="save_sign_out") - self.assertInUrl("/logout") - def test_multiple_relationships(self): self.launchSurvey("test_relationships") self.add_person("Marie", "Doe") diff --git a/tests/integration/questionnaire/test_questionnaire_save_sign_out.py b/tests/integration/questionnaire/test_questionnaire_save_sign_out.py deleted file mode 100644 index c3422b09e5..0000000000 --- a/tests/integration/questionnaire/test_questionnaire_save_sign_out.py +++ /dev/null @@ -1,116 +0,0 @@ -from app.forms.error_messages import error_messages -from tests.integration.integration_test_case import IntegrationTestCase - - -class TestSaveSignOut(IntegrationTestCase): - def test_save_sign_out_with_mandatory_question_not_answered(self): - # We can save and go to the sign-out page without having to fill in mandatory answer - - # Given - self.launchSurvey( - "test_radio_mandatory", - account_service_url="https://localhost/my-account", - account_service_log_out_url="https://localhost/logout", - ) - - # When - self.post(action="save_sign_out") - - # Then we are presented with the sign out page - self.assertInUrl("/logout") - - def test_save_sign_out_with_non_mandatory_validation_error(self): - # We can't save if a validation error is caused, this doesn't include missing a mandatory question - - # Given - self.launchSurvey("test_error_messages") - - # When - self.post(post_data={"test-number": "error"}, action="save_sign_out") - - # Then we are presented with an error message - self.assertRegexPage(error_messages["INVALID_NUMBER"]) - - def test_save_sign_out_complete_a_block_then_revisit_it(self): - # If a user completes a block, but then goes back and uses save and come back on that block, that block - # should no longer be considered complete and on re-authenticate it should return to it - - self.launchSurvey("test_textfield") - - block_one_url = self.last_url - - post_data = {"name-answer": "Joe Bloggs"} - - self.post(post_data) - - # We go back to the first page and save and complete later - self.get(block_one_url) - self.post(action="save_sign_out") - - # We re-authenticate and check we are on the first page - self.launchSurvey("test_textfield") - self.assertEqual(block_one_url, self.last_url) - - def test_sign_out_on_introduction_page(self): - - # Given - self.launchSurvey( - "test_introduction", - account_service_url="https://localhost/my-account", - account_service_log_out_url="https://localhost/logout", - ) - - # When - self.post(action="sign_out") - - # Then we are presented with the sign out page - self.assertInUrl("/logout") - - def test_thank_you_without_logout_url(self): - """ - If the signed-out url is hit but there is no account_service_log_out_url, then a sign out page is rendered. - """ - self.launchSurvey("test_textarea") - self.post({"answer": "This is an answer"}) - token = self.last_csrf_token - - self.post() - self.assertInUrl("thank-you") - - self.last_csrf_token = token - self.post(action="sign_out") - self.assertInUrl("/signed-out") - self.assertInBody("Your survey answers have been saved. You are now signed out") - - def test_thank_you_page_post_without_action(self): - """ - If the thank you page is posted to without an action, - it takes you back to the thank you page. - """ - - self.launchSurvey("test_textarea") - self.post({"answer": "This is an answer"}) - token = self.last_csrf_token - - self.post() - self.assertInUrl("thank-you") - - self.last_csrf_token = token - self.post() - self.assertInUrl("/thank-you") - - def test_relaunch_from_section_summary(self): - - # Given - self.launchSurvey("test_section_summary", display_address="test address") - - self.post({"insurance-type-answer": "Both"}) - self.post({"insurance-address-answer": "Address"}) - - # And I sign out - self.assertInUrl("/sections/property-details-section/") - self.post(action="sign_out") - - # When I launch the survey again, I should go to the next incomplete location - self.launchSurvey("test_section_summary", display_address="test address") - self.assertInUrl("/questionnaire/house-type/") diff --git a/tests/integration/questionnaire/test_questionnaire_sign_out.py b/tests/integration/questionnaire/test_questionnaire_sign_out.py new file mode 100644 index 0000000000..3f6b7ff6a1 --- /dev/null +++ b/tests/integration/questionnaire/test_questionnaire_sign_out.py @@ -0,0 +1,48 @@ +from tests.integration.integration_test_case import IntegrationTestCase + + +class TestSignOut(IntegrationTestCase): + def test_sign_out_not_signed_in_redirects_to_signed_out_page(self): + self.get("/sign-out") + self.assertInUrl("/signed-out") + + def test_sign_out_without_log_out_url_redirects_to_signed_out_page(self): + self.launchSurvey("test_textfield") + self.get("/sign-out") + self.assertInUrl("/signed-out") + + def test_sign_out_with_log_out_url_redirects_to_log_out_url(self): + self.launchSurvey( + "test_textfield", + account_service_log_out_url="https://localhost/logout", + ) + self.get("/sign-out") + self.assertInUrl("/logout") + + def test_sign_out_after_navigating_backwards(self): + # If a user completes a block, then goes back and signs out, on re-authentication + # they should resume on the first incomplete location + self.launchSurvey("test_textfield") + self.post({"name-answer": "Joe Bloggs"}) + + # Go back to the first page + self.get("/questionnaire/name-block") + + self.get("/sign-out") + self.launchSurvey("test_textfield") + + # Check we are on the second page + self.assertEqual("/questionnaire/summary", self.last_url) + + def test_sign_out_on_section_summary(self): + # If a user completes a section and signs out on the section summary, + # on re-authentication they should resume at the start of the next section + self.launchSurvey("test_section_summary", display_address="test address") + self.post({"insurance-type-answer": "Both"}) + self.post({"insurance-address-answer": "Address"}) + + self.get("/sign-out") + self.launchSurvey("test_section_summary", display_address="test address") + + # Check we are at the start of the next section + self.assertInUrl("/questionnaire/house-type/") diff --git a/tests/integration/routes/test_session.py b/tests/integration/routes/test_session.py index 0b84ba022e..f8631fb3ca 100644 --- a/tests/integration/routes/test_session.py +++ b/tests/integration/routes/test_session.py @@ -13,7 +13,7 @@ def test_session_signed_out(self): self.launchSurvey(account_service_log_out_url="https://localhost/logout") self.assertInBody("Save and sign out") - self.post(action="save_sign_out") + self.get("/sign-out") self.assertInUrl("/logout") diff --git a/tests/integration/routes/test_view_submission.py b/tests/integration/routes/test_view_submission.py index 455585f5b6..7c13d6b0fa 100644 --- a/tests/integration/routes/test_view_submission.py +++ b/tests/integration/routes/test_view_submission.py @@ -49,7 +49,7 @@ def test_view_submission(self): def test_view_submission_sign_out(self): self.get("submitted/view-submission") - self.post(action="sign_out") + self.get("/sign-out") self.assertEqualUrl("/signed-out") def test_view_submission_post_no_action(self):