2016-12-12 11:25:43 +00:00
|
|
|
|
from functools import partial
|
2020-12-09 10:54:07 +00:00
|
|
|
|
from unittest.mock import ANY, PropertyMock
|
2018-02-20 11:22:17 +00:00
|
|
|
|
|
2016-04-26 10:32:26 +01:00
|
|
|
|
import pytest
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from bs4 import BeautifulSoup, element
|
2016-05-18 15:03:23 +01:00
|
|
|
|
from flask import url_for
|
2016-12-12 11:44:11 +00:00
|
|
|
|
from freezegun import freeze_time
|
2018-02-20 11:22:17 +00:00
|
|
|
|
|
2020-12-09 10:54:07 +00:00
|
|
|
|
from app.main.views.feedback import in_business_hours
|
2020-03-24 15:45:13 +00:00
|
|
|
|
from app.models.feedback import (
|
|
|
|
|
|
GENERAL_TICKET_TYPE,
|
|
|
|
|
|
PROBLEM_TICKET_TYPE,
|
|
|
|
|
|
QUESTION_TICKET_TYPE,
|
|
|
|
|
|
)
|
2019-12-19 10:22:45 +00:00
|
|
|
|
from tests.conftest import normalize_spaces
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def no_redirect():
|
|
|
|
|
|
return lambda _external=True: None
|
2016-04-26 10:32:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-06-07 12:03:47 +01:00
|
|
|
|
def test_get_support_index_page(
|
2020-03-24 15:01:42 +00:00
|
|
|
|
client_request,
|
2017-06-07 12:03:47 +01:00
|
|
|
|
):
|
2020-03-24 15:01:42 +00:00
|
|
|
|
page = client_request.get('.support')
|
|
|
|
|
|
assert page.select_one('form')['method'] == 'post'
|
|
|
|
|
|
assert 'action' not in page.select_one('form')
|
|
|
|
|
|
assert normalize_spaces(page.select_one('h1').text) == 'Support'
|
|
|
|
|
|
assert normalize_spaces(
|
|
|
|
|
|
page.select_one('form label[for=support_type-0]').text
|
|
|
|
|
|
) == 'Report a problem'
|
|
|
|
|
|
assert page.select_one('form input#support_type-0')['value'] == 'report-problem'
|
|
|
|
|
|
assert normalize_spaces(
|
|
|
|
|
|
page.select_one('form label[for=support_type-1]').text
|
|
|
|
|
|
) == 'Ask a question or give feedback'
|
|
|
|
|
|
assert page.select_one('form input#support_type-1')['value'] == 'ask-question-give-feedback'
|
|
|
|
|
|
assert normalize_spaces(
|
|
|
|
|
|
page.select_one('form button[type=submit]').text
|
|
|
|
|
|
) == 'Continue'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_support_index_page_when_signed_out(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.logout()
|
|
|
|
|
|
page = client_request.get('.support')
|
|
|
|
|
|
assert page.select_one('form')['method'] == 'post'
|
|
|
|
|
|
assert 'action' not in page.select_one('form')
|
|
|
|
|
|
assert normalize_spaces(
|
|
|
|
|
|
page.select_one('form label[for=who-0]').text
|
|
|
|
|
|
) == (
|
|
|
|
|
|
'I work in the public sector and need to send emails, text messages or letters'
|
|
|
|
|
|
)
|
|
|
|
|
|
assert page.select_one('form input#who-0')['value'] == 'public-sector'
|
|
|
|
|
|
assert normalize_spaces(
|
|
|
|
|
|
page.select_one('form label[for=who-1]').text
|
|
|
|
|
|
) == (
|
|
|
|
|
|
'I’m a member of the public with a question for the government'
|
|
|
|
|
|
)
|
|
|
|
|
|
assert page.select_one('form input#who-1')['value'] == 'public'
|
|
|
|
|
|
assert normalize_spaces(
|
|
|
|
|
|
page.select_one('form button[type=submit]').text
|
|
|
|
|
|
) == 'Continue'
|
2016-12-12 11:18:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
@freeze_time('2016-12-12 12:00:00.000000')
|
2016-12-12 11:25:43 +00:00
|
|
|
|
@pytest.mark.parametrize('support_type, expected_h1', [
|
2017-11-28 11:59:11 +00:00
|
|
|
|
(PROBLEM_TICKET_TYPE, 'Report a problem'),
|
|
|
|
|
|
(QUESTION_TICKET_TYPE, 'Ask a question or give feedback'),
|
2016-12-12 11:25:43 +00:00
|
|
|
|
])
|
2016-12-12 11:31:26 +00:00
|
|
|
|
def test_choose_support_type(
|
2020-03-24 15:01:42 +00:00
|
|
|
|
client_request,
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mock_get_non_empty_organisations_and_services_for_user,
|
2016-12-12 11:31:26 +00:00
|
|
|
|
support_type,
|
|
|
|
|
|
expected_h1
|
|
|
|
|
|
):
|
2020-03-24 15:01:42 +00:00
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'main.support',
|
|
|
|
|
|
_data={'support_type': support_type},
|
|
|
|
|
|
_follow_redirects=True,
|
2016-12-12 11:25:43 +00:00
|
|
|
|
)
|
|
|
|
|
|
assert page.h1.string.strip() == expected_h1
|
2020-03-24 15:01:42 +00:00
|
|
|
|
assert not page.select_one('input[name=name]')
|
|
|
|
|
|
assert not page.select_one('input[name=email_address]')
|
|
|
|
|
|
assert page.find('form').find('p').text.strip() == (
|
|
|
|
|
|
'We’ll reply to test@user.gov.uk'
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-24 15:45:13 +00:00
|
|
|
|
@freeze_time('2016-12-12 12:00:00.000000')
|
2020-03-24 15:01:42 +00:00
|
|
|
|
def test_get_support_as_someone_in_the_public_sector(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.logout()
|
|
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'main.support',
|
|
|
|
|
|
_data={'who': 'public-sector'},
|
|
|
|
|
|
_follow_redirects=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
assert normalize_spaces(page.select('h1')) == (
|
2020-03-24 15:45:13 +00:00
|
|
|
|
'Contact GOV.UK Notify support'
|
2020-03-24 15:01:42 +00:00
|
|
|
|
)
|
|
|
|
|
|
assert page.select_one('form textarea[name=feedback]')
|
|
|
|
|
|
assert page.select_one('form input[name=name]')
|
|
|
|
|
|
assert page.select_one('form input[name=email_address]')
|
|
|
|
|
|
assert page.select_one('form button[type=submit]')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_support_as_member_of_public(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.logout()
|
|
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'main.support',
|
|
|
|
|
|
_data={'who': 'public'},
|
|
|
|
|
|
_follow_redirects=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
assert normalize_spaces(page.select('h1')) == (
|
|
|
|
|
|
'The GOV.UK Notify service is for people who work in the government'
|
|
|
|
|
|
)
|
|
|
|
|
|
assert len(page.select('h2 a')) == 3
|
|
|
|
|
|
assert not page.select('form')
|
|
|
|
|
|
assert not page.select('input')
|
|
|
|
|
|
assert not page.select('form [type=submit]')
|
2016-04-26 10:32:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
@freeze_time('2016-12-12 12:00:00.000000')
|
2016-12-12 11:25:43 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type, expected_status_code', [
|
2017-11-28 11:59:11 +00:00
|
|
|
|
(PROBLEM_TICKET_TYPE, 200),
|
|
|
|
|
|
(QUESTION_TICKET_TYPE, 200),
|
2016-12-12 11:25:43 +00:00
|
|
|
|
('gripe', 404)
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_get_feedback_page(client, ticket_type, expected_status_code):
|
|
|
|
|
|
response = client.get(url_for('main.feedback', ticket_type=ticket_type))
|
|
|
|
|
|
assert response.status_code == expected_status_code
|
2016-04-26 10:32:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-30 14:18:19 +00:00
|
|
|
|
@freeze_time('2016-12-12 12:00:00.000000')
|
2017-11-28 11:59:11 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type', [PROBLEM_TICKET_TYPE, QUESTION_TICKET_TYPE])
|
2017-01-30 14:18:19 +00:00
|
|
|
|
def test_passed_non_logged_in_user_details_through_flow(client, mocker, ticket_type):
|
2018-04-24 17:37:15 +01:00
|
|
|
|
mock_post = mocker.patch('app.main.views.feedback.zendesk_client.create_ticket')
|
2017-01-30 14:18:19 +00:00
|
|
|
|
|
2017-02-07 16:14:58 +00:00
|
|
|
|
data = {'feedback': 'blah', 'name': 'Steve Irwin', 'email_address': 'rip@gmail.com'}
|
|
|
|
|
|
|
2017-01-30 14:18:19 +00:00
|
|
|
|
resp = client.post(
|
|
|
|
|
|
url_for('main.feedback', ticket_type=ticket_type),
|
2017-02-07 16:14:58 +00:00
|
|
|
|
data=data
|
2017-01-30 14:18:19 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert resp.status_code == 302
|
2019-07-12 10:35:49 +01:00
|
|
|
|
assert resp.location == url_for(
|
|
|
|
|
|
'main.thanks',
|
|
|
|
|
|
out_of_hours_emergency=False,
|
|
|
|
|
|
email_address_provided=True,
|
|
|
|
|
|
_external=True,
|
|
|
|
|
|
)
|
2017-01-30 14:18:19 +00:00
|
|
|
|
mock_post.assert_called_with(
|
2018-04-26 10:52:28 +01:00
|
|
|
|
subject='Notify feedback',
|
2018-06-15 16:27:17 +01:00
|
|
|
|
message='blah\n',
|
2018-01-16 11:50:29 +00:00
|
|
|
|
user_email='rip@gmail.com',
|
|
|
|
|
|
user_name='Steve Irwin',
|
|
|
|
|
|
ticket_type=ticket_type,
|
2018-04-24 17:37:15 +01:00
|
|
|
|
p1=ANY
|
2017-01-30 14:18:19 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
@freeze_time("2016-12-12 12:00:00.000000")
|
2017-01-30 14:18:19 +00:00
|
|
|
|
@pytest.mark.parametrize('data', [
|
|
|
|
|
|
{'feedback': 'blah'},
|
|
|
|
|
|
{'feedback': 'blah', 'name': 'Ignored', 'email_address': 'ignored@email.com'}
|
2016-12-12 11:25:43 +00:00
|
|
|
|
])
|
2017-11-28 11:59:11 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type', [PROBLEM_TICKET_TYPE, QUESTION_TICKET_TYPE])
|
2016-12-21 14:55:49 +00:00
|
|
|
|
def test_passes_user_details_through_flow(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mock_get_non_empty_organisations_and_services_for_user,
|
2016-12-12 11:25:43 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
ticket_type,
|
2017-01-30 14:18:19 +00:00
|
|
|
|
data
|
2016-12-12 11:25:43 +00:00
|
|
|
|
):
|
2018-04-24 17:37:15 +01:00
|
|
|
|
mock_post = mocker.patch('app.main.views.feedback.zendesk_client.create_ticket')
|
2017-01-30 14:18:19 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type=ticket_type,
|
|
|
|
|
|
_data=data,
|
|
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.thanks',
|
2019-07-12 10:35:49 +01:00
|
|
|
|
email_address_provided=True,
|
|
|
|
|
|
out_of_hours_emergency=False,
|
2019-03-26 12:35:32 +00:00
|
|
|
|
_external=True,
|
|
|
|
|
|
),
|
2016-12-12 11:25:43 +00:00
|
|
|
|
)
|
2017-01-30 14:18:19 +00:00
|
|
|
|
|
2016-12-12 11:25:43 +00:00
|
|
|
|
mock_post.assert_called_with(
|
2018-04-26 10:52:28 +01:00
|
|
|
|
subject='Notify feedback',
|
2018-01-16 11:50:29 +00:00
|
|
|
|
message=ANY,
|
|
|
|
|
|
user_email='test@user.gov.uk',
|
|
|
|
|
|
user_name='Test User',
|
|
|
|
|
|
ticket_type=ticket_type,
|
2018-04-24 17:37:15 +01:00
|
|
|
|
p1=ANY
|
2016-12-12 11:25:43 +00:00
|
|
|
|
)
|
2018-01-16 11:50:29 +00:00
|
|
|
|
assert mock_post.call_args[1]['message'] == '\n'.join([
|
2018-06-15 16:27:17 +01:00
|
|
|
|
'blah',
|
|
|
|
|
|
'Service: "service one"',
|
|
|
|
|
|
url_for(
|
2017-01-30 14:18:19 +00:00
|
|
|
|
'main.service_dashboard',
|
|
|
|
|
|
service_id='596364a0-858e-42c8-9062-a8fe822260eb',
|
|
|
|
|
|
_external=True
|
2018-06-15 16:27:17 +01:00
|
|
|
|
),
|
|
|
|
|
|
''
|
2017-01-30 14:18:19 +00:00
|
|
|
|
])
|
2016-04-26 10:32:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-12-21 14:55:49 +00:00
|
|
|
|
@freeze_time('2016-12-12 12:00:00.000000')
|
|
|
|
|
|
@pytest.mark.parametrize('data', [
|
|
|
|
|
|
{'feedback': 'blah', 'name': 'Fred'},
|
|
|
|
|
|
{'feedback': 'blah'},
|
|
|
|
|
|
])
|
2020-03-23 11:04:03 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type', [
|
|
|
|
|
|
PROBLEM_TICKET_TYPE,
|
|
|
|
|
|
QUESTION_TICKET_TYPE,
|
2016-12-21 14:55:49 +00:00
|
|
|
|
])
|
2020-03-23 11:04:03 +00:00
|
|
|
|
def test_email_address_required_for_problems_and_questions(
|
2019-07-15 13:52:42 +01:00
|
|
|
|
client_request,
|
2016-12-21 14:55:49 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
data,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
):
|
2018-04-24 17:37:15 +01:00
|
|
|
|
mocker.patch('app.main.views.feedback.zendesk_client')
|
2019-07-15 13:52:42 +01:00
|
|
|
|
client_request.logout()
|
|
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type=ticket_type,
|
|
|
|
|
|
_data=data,
|
2020-03-23 11:04:03 +00:00
|
|
|
|
_expected_status=200
|
2016-12-21 14:55:49 +00:00
|
|
|
|
)
|
2020-08-07 15:16:04 +01:00
|
|
|
|
assert isinstance(page.find('span', {'class': 'govuk-error-message'}), element.Tag)
|
2016-12-21 14:55:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
2018-12-07 12:23:12 +00:00
|
|
|
|
@freeze_time('2016-12-12 12:00:00.000000')
|
|
|
|
|
|
@pytest.mark.parametrize('ticket_type', (
|
|
|
|
|
|
PROBLEM_TICKET_TYPE, QUESTION_TICKET_TYPE
|
|
|
|
|
|
))
|
|
|
|
|
|
def test_email_address_must_be_valid_if_provided_to_support_form(
|
|
|
|
|
|
client,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
):
|
|
|
|
|
|
response = client.post(
|
|
|
|
|
|
url_for('main.feedback', ticket_type=ticket_type),
|
|
|
|
|
|
data={
|
|
|
|
|
|
'feedback': 'blah',
|
|
|
|
|
|
'email_address': 'not valid',
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
|
|
|
|
|
|
2020-08-07 15:16:04 +01:00
|
|
|
|
assert normalize_spaces(page.select_one('span.govuk-error-message').text) == (
|
|
|
|
|
|
'Error: Enter a valid email address'
|
2018-12-07 12:23:12 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
@pytest.mark.parametrize('ticket_type, severe, is_in_business_hours, is_out_of_hours_emergency', [
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
# business hours, never an emergency
|
|
|
|
|
|
(PROBLEM_TICKET_TYPE, 'yes', True, False),
|
|
|
|
|
|
(QUESTION_TICKET_TYPE, 'yes', True, False),
|
|
|
|
|
|
(PROBLEM_TICKET_TYPE, 'no', True, False),
|
|
|
|
|
|
(QUESTION_TICKET_TYPE, 'no', True, False),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
# out of hours, if the user says it’s not an emergency
|
|
|
|
|
|
(PROBLEM_TICKET_TYPE, 'no', False, False),
|
|
|
|
|
|
(QUESTION_TICKET_TYPE, 'no', False, False),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
# out of hours, only problems can be emergencies
|
|
|
|
|
|
(PROBLEM_TICKET_TYPE, 'yes', False, True),
|
|
|
|
|
|
(QUESTION_TICKET_TYPE, 'yes', False, False),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_urgency(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mock_get_non_empty_organisations_and_services_for_user,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
severe,
|
|
|
|
|
|
is_in_business_hours,
|
2019-07-12 10:35:49 +01:00
|
|
|
|
is_out_of_hours_emergency,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
):
|
|
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=is_in_business_hours)
|
2018-04-24 17:37:15 +01:00
|
|
|
|
mock_post = mocker.patch('app.main.views.feedback.zendesk_client.create_ticket')
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type=ticket_type,
|
|
|
|
|
|
severe=severe,
|
|
|
|
|
|
_data={'feedback': 'blah', 'email_address': 'test@example.com'},
|
|
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.thanks',
|
2019-07-12 10:35:49 +01:00
|
|
|
|
out_of_hours_emergency=is_out_of_hours_emergency,
|
|
|
|
|
|
email_address_provided=True,
|
2019-03-26 12:35:32 +00:00
|
|
|
|
_external=True,
|
|
|
|
|
|
),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
)
|
2019-07-12 10:35:49 +01:00
|
|
|
|
assert mock_post.call_args[1]['p1'] == is_out_of_hours_emergency
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ids, params = zip(*[
|
|
|
|
|
|
('non-logged in users always have to triage', (
|
2020-03-24 15:45:13 +00:00
|
|
|
|
GENERAL_TICKET_TYPE, False, False, True,
|
|
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=GENERAL_TICKET_TYPE)
|
2016-12-12 11:44:11 +00:00
|
|
|
|
)),
|
|
|
|
|
|
('trial services are never high priority', (
|
2017-11-28 11:59:11 +00:00
|
|
|
|
PROBLEM_TICKET_TYPE, False, True, False,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
)),
|
|
|
|
|
|
('we can triage in hours', (
|
2017-11-28 11:59:11 +00:00
|
|
|
|
PROBLEM_TICKET_TYPE, True, True, True,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
)),
|
|
|
|
|
|
('only problems are high priority', (
|
2017-11-28 11:59:11 +00:00
|
|
|
|
QUESTION_TICKET_TYPE, False, True, True,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
)),
|
|
|
|
|
|
('should triage out of hours', (
|
2017-11-28 11:59:11 +00:00
|
|
|
|
PROBLEM_TICKET_TYPE, False, True, True,
|
2020-03-24 15:45:13 +00:00
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=PROBLEM_TICKET_TYPE)
|
2016-12-12 11:44:11 +00:00
|
|
|
|
))
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
(
|
|
|
|
|
|
'ticket_type, is_in_business_hours, logged_in, has_live_services,'
|
|
|
|
|
|
'expected_status, expected_redirect'
|
|
|
|
|
|
),
|
|
|
|
|
|
params, ids=ids
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_redirects_to_triage(
|
|
|
|
|
|
client,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_user,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
is_in_business_hours,
|
|
|
|
|
|
logged_in,
|
|
|
|
|
|
has_live_services,
|
|
|
|
|
|
expected_status,
|
|
|
|
|
|
expected_redirect,
|
|
|
|
|
|
):
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
'app.models.user.User.live_services',
|
|
|
|
|
|
new_callable=PropertyMock,
|
|
|
|
|
|
return_value=[{}, {}] if has_live_services else [],
|
|
|
|
|
|
)
|
2016-12-12 11:44:11 +00:00
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=is_in_business_hours)
|
|
|
|
|
|
if logged_in:
|
|
|
|
|
|
client.login(api_user_active)
|
|
|
|
|
|
|
|
|
|
|
|
response = client.get(url_for('main.feedback', ticket_type=ticket_type))
|
|
|
|
|
|
assert response.status_code == expected_status
|
|
|
|
|
|
assert response.location == expected_redirect(_external=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-24 15:45:13 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type, expected_h1', (
|
|
|
|
|
|
(PROBLEM_TICKET_TYPE, 'Report a problem'),
|
|
|
|
|
|
(GENERAL_TICKET_TYPE, 'Contact GOV.UK Notify support'),
|
|
|
|
|
|
))
|
|
|
|
|
|
def test_options_on_triage_page(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
expected_h1,
|
|
|
|
|
|
):
|
|
|
|
|
|
page = client_request.get('main.triage', ticket_type=ticket_type)
|
|
|
|
|
|
assert normalize_spaces(page.select_one('h1').text) == expected_h1
|
|
|
|
|
|
assert page.select('form input[type=radio]')[0]['value'] == 'yes'
|
|
|
|
|
|
assert page.select('form input[type=radio]')[1]['value'] == 'no'
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 14:11:34 +00:00
|
|
|
|
def test_doesnt_lose_message_if_post_across_closing(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2016-12-12 14:11:34 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
):
|
|
|
|
|
|
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mocker.patch('app.models.user.User.live_services', return_value=True)
|
2016-12-12 14:11:34 +00:00
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=False)
|
|
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.post(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type=PROBLEM_TICKET_TYPE,
|
|
|
|
|
|
_data={'feedback': 'foo'},
|
|
|
|
|
|
_expected_status=302,
|
2020-03-24 15:45:13 +00:00
|
|
|
|
_expected_redirect=url_for('.triage', ticket_type=PROBLEM_TICKET_TYPE, _external=True),
|
2016-12-12 14:11:34 +00:00
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
with client_request.session_transaction() as session:
|
2016-12-12 14:11:34 +00:00
|
|
|
|
assert session['feedback_message'] == 'foo'
|
|
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type=PROBLEM_TICKET_TYPE,
|
|
|
|
|
|
severe='yes',
|
2016-12-12 14:11:34 +00:00
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
|
|
|
|
|
|
with client_request.session_transaction() as session:
|
2020-04-22 17:49:03 +01:00
|
|
|
|
assert page.find('textarea', {'name': 'feedback'}).text == '\r\nfoo'
|
2016-12-12 14:11:34 +00:00
|
|
|
|
assert 'feedback_message' not in session
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
@pytest.mark.parametrize('when, is_in_business_hours', [
|
|
|
|
|
|
|
2017-02-02 09:35:18 +00:00
|
|
|
|
('2016-06-06 09:29:59+0100', False), # opening time, summer and winter
|
|
|
|
|
|
('2016-12-12 09:29:59+0000', False),
|
|
|
|
|
|
('2016-06-06 09:30:00+0100', True),
|
|
|
|
|
|
('2016-12-12 09:30:00+0000', True),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
2017-02-02 09:35:18 +00:00
|
|
|
|
('2016-12-12 12:00:00+0000', True), # middle of the day
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
2017-02-02 09:35:18 +00:00
|
|
|
|
('2016-12-12 17:29:59+0000', True), # closing time
|
|
|
|
|
|
('2016-12-12 17:30:00+0000', False),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
2017-02-02 09:35:18 +00:00
|
|
|
|
('2016-12-10 12:00:00+0000', False), # Saturday
|
|
|
|
|
|
('2016-12-11 12:00:00+0000', False), # Sunday
|
|
|
|
|
|
('2016-01-01 12:00:00+0000', False), # Bank holiday
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_in_business_hours(when, is_in_business_hours):
|
|
|
|
|
|
with freeze_time(when):
|
|
|
|
|
|
assert in_business_hours() == is_in_business_hours
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-24 15:45:13 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type', (
|
|
|
|
|
|
GENERAL_TICKET_TYPE,
|
|
|
|
|
|
PROBLEM_TICKET_TYPE,
|
|
|
|
|
|
))
|
2016-12-12 11:44:11 +00:00
|
|
|
|
@pytest.mark.parametrize('choice, expected_redirect_param', [
|
2017-03-07 09:44:21 +00:00
|
|
|
|
('yes', 'yes'),
|
|
|
|
|
|
('no', 'no'),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
])
|
2020-03-24 15:45:13 +00:00
|
|
|
|
def test_triage_redirects_to_correct_url(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
choice,
|
|
|
|
|
|
expected_redirect_param,
|
|
|
|
|
|
):
|
|
|
|
|
|
client_request.post(
|
|
|
|
|
|
'main.triage',
|
|
|
|
|
|
ticket_type=ticket_type,
|
|
|
|
|
|
_data={'severe': choice},
|
|
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type=ticket_type,
|
|
|
|
|
|
severe=expected_redirect_param,
|
|
|
|
|
|
_external=True,
|
|
|
|
|
|
),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-25 12:17:39 +00:00
|
|
|
|
@pytest.mark.parametrize('extra_args, expected_back_link', [
|
|
|
|
|
|
(
|
|
|
|
|
|
{'severe': 'yes'},
|
|
|
|
|
|
partial(url_for, 'main.triage', ticket_type=PROBLEM_TICKET_TYPE)
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
{'severe': 'no'},
|
|
|
|
|
|
partial(url_for, 'main.triage', ticket_type=PROBLEM_TICKET_TYPE)
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
{'severe': 'foo'}, # hacking the URL
|
|
|
|
|
|
partial(url_for, 'main.support')
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
{},
|
|
|
|
|
|
partial(url_for, 'main.support')
|
|
|
|
|
|
),
|
|
|
|
|
|
])
|
2020-12-30 09:50:11 +00:00
|
|
|
|
@freeze_time('2012-12-12 12:12')
|
2020-03-25 12:17:39 +00:00
|
|
|
|
def test_back_link_from_form(
|
|
|
|
|
|
client_request,
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mock_get_non_empty_organisations_and_services_for_user,
|
2020-03-25 12:17:39 +00:00
|
|
|
|
extra_args,
|
|
|
|
|
|
expected_back_link,
|
|
|
|
|
|
):
|
|
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type=PROBLEM_TICKET_TYPE,
|
|
|
|
|
|
**extra_args
|
|
|
|
|
|
)
|
|
|
|
|
|
assert page.select_one('.govuk-back-link')['href'] == expected_back_link()
|
|
|
|
|
|
assert normalize_spaces(page.select_one('h1').text) == 'Report a problem'
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-02 10:42:17 +00:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
(
|
|
|
|
|
|
'is_in_business_hours, severe,'
|
|
|
|
|
|
'expected_status_code, expected_redirect,'
|
|
|
|
|
|
'expected_status_code_when_logged_in, expected_redirect_when_logged_in'
|
|
|
|
|
|
),
|
|
|
|
|
|
[
|
|
|
|
|
|
(
|
|
|
|
|
|
True, 'yes',
|
|
|
|
|
|
200, no_redirect(),
|
|
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
True, 'no',
|
|
|
|
|
|
200, no_redirect(),
|
|
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
False, 'no',
|
|
|
|
|
|
200, no_redirect(),
|
|
|
|
|
|
200, no_redirect(),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
# Treat empty query param as mangled URL – ask question again
|
|
|
|
|
|
(
|
|
|
|
|
|
False, '',
|
2020-03-24 15:45:13 +00:00
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=PROBLEM_TICKET_TYPE),
|
|
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=PROBLEM_TICKET_TYPE),
|
2017-02-02 10:42:17 +00:00
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
# User hasn’t answered the triage question
|
|
|
|
|
|
(
|
|
|
|
|
|
False, None,
|
2020-03-24 15:45:13 +00:00
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=PROBLEM_TICKET_TYPE),
|
|
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=PROBLEM_TICKET_TYPE),
|
2017-02-02 10:42:17 +00:00
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
# Escalation is needed for non-logged-in users
|
|
|
|
|
|
(
|
|
|
|
|
|
False, 'yes',
|
|
|
|
|
|
302, partial(url_for, 'main.bat_phone'),
|
|
|
|
|
|
200, no_redirect(),
|
|
|
|
|
|
),
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
2016-12-12 11:44:11 +00:00
|
|
|
|
def test_should_be_shown_the_bat_email(
|
|
|
|
|
|
client,
|
|
|
|
|
|
active_user_with_permissions,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
service_one,
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mock_get_non_empty_organisations_and_services_for_user,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
is_in_business_hours,
|
|
|
|
|
|
severe,
|
|
|
|
|
|
expected_status_code,
|
|
|
|
|
|
expected_redirect,
|
2017-02-02 10:42:17 +00:00
|
|
|
|
expected_status_code_when_logged_in,
|
|
|
|
|
|
expected_redirect_when_logged_in,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
):
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=is_in_business_hours)
|
|
|
|
|
|
|
2017-11-28 11:59:11 +00:00
|
|
|
|
feedback_page = url_for('main.feedback', ticket_type=PROBLEM_TICKET_TYPE, severe=severe)
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
response = client.get(feedback_page)
|
|
|
|
|
|
|
|
|
|
|
|
assert response.status_code == expected_status_code
|
|
|
|
|
|
assert response.location == expected_redirect(_external=True)
|
|
|
|
|
|
|
|
|
|
|
|
# logged in users should never be redirected to the bat email page
|
|
|
|
|
|
client.login(active_user_with_permissions, mocker, service_one)
|
|
|
|
|
|
logged_in_response = client.get(feedback_page)
|
2017-02-02 10:42:17 +00:00
|
|
|
|
assert logged_in_response.status_code == expected_status_code_when_logged_in
|
|
|
|
|
|
assert logged_in_response.location == expected_redirect_when_logged_in(_external=True)
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2020-03-24 15:45:13 +00:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
(
|
|
|
|
|
|
'severe,'
|
|
|
|
|
|
'expected_status_code, expected_redirect,'
|
|
|
|
|
|
'expected_status_code_when_logged_in, expected_redirect_when_logged_in'
|
|
|
|
|
|
),
|
|
|
|
|
|
[
|
|
|
|
|
|
# User hasn’t answered the triage question
|
|
|
|
|
|
(
|
|
|
|
|
|
None,
|
|
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=GENERAL_TICKET_TYPE),
|
|
|
|
|
|
302, partial(url_for, 'main.triage', ticket_type=GENERAL_TICKET_TYPE),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
# Escalation is needed for non-logged-in users
|
|
|
|
|
|
(
|
|
|
|
|
|
'yes',
|
|
|
|
|
|
302, partial(url_for, 'main.bat_phone'),
|
|
|
|
|
|
200, no_redirect(),
|
|
|
|
|
|
),
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_should_be_shown_the_bat_email_for_general_questions(
|
|
|
|
|
|
client,
|
|
|
|
|
|
active_user_with_permissions,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
service_one,
|
2020-12-09 10:54:07 +00:00
|
|
|
|
mock_get_non_empty_organisations_and_services_for_user,
|
2020-03-24 15:45:13 +00:00
|
|
|
|
severe,
|
|
|
|
|
|
expected_status_code,
|
|
|
|
|
|
expected_redirect,
|
|
|
|
|
|
expected_status_code_when_logged_in,
|
|
|
|
|
|
expected_redirect_when_logged_in,
|
|
|
|
|
|
):
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=False)
|
|
|
|
|
|
|
|
|
|
|
|
feedback_page = url_for('main.feedback', ticket_type=GENERAL_TICKET_TYPE, severe=severe)
|
|
|
|
|
|
|
|
|
|
|
|
response = client.get(feedback_page)
|
|
|
|
|
|
|
|
|
|
|
|
assert response.status_code == expected_status_code
|
|
|
|
|
|
assert response.location == expected_redirect(_external=True)
|
|
|
|
|
|
|
|
|
|
|
|
# logged in users should never be redirected to the bat email page
|
|
|
|
|
|
client.login(active_user_with_permissions, mocker, service_one)
|
|
|
|
|
|
logged_in_response = client.get(feedback_page)
|
|
|
|
|
|
assert logged_in_response.status_code == expected_status_code_when_logged_in
|
|
|
|
|
|
assert logged_in_response.location == expected_redirect_when_logged_in(_external=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
def test_bat_email_page(
|
|
|
|
|
|
client,
|
|
|
|
|
|
active_user_with_permissions,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
):
|
|
|
|
|
|
bat_phone_page = url_for('main.bat_phone')
|
|
|
|
|
|
|
|
|
|
|
|
response = client.get(bat_phone_page)
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
|
|
2017-07-15 07:23:22 +01:00
|
|
|
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
2021-07-30 18:23:12 +01:00
|
|
|
|
assert page.select_one('.govuk-back-link').text == 'Back'
|
|
|
|
|
|
assert page.select_one('.govuk-back-link')['href'] == url_for('main.support')
|
|
|
|
|
|
assert page.select('main a')[1].text == 'Fill in this form'
|
|
|
|
|
|
assert page.select('main a')[1]['href'] == url_for('main.feedback', ticket_type=PROBLEM_TICKET_TYPE, severe='no')
|
|
|
|
|
|
next_page_response = client.get(page.select('main a')[1]['href'])
|
2017-07-15 07:23:22 +01:00
|
|
|
|
next_page = BeautifulSoup(next_page_response.data.decode('utf-8'), 'html.parser')
|
|
|
|
|
|
assert next_page.h1.text.strip() == 'Report a problem'
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
client.login(active_user_with_permissions, mocker, service_one)
|
|
|
|
|
|
logged_in_response = client.get(bat_phone_page)
|
|
|
|
|
|
assert logged_in_response.status_code == 302
|
2017-11-28 11:59:11 +00:00
|
|
|
|
assert logged_in_response.location == url_for('main.feedback', ticket_type=PROBLEM_TICKET_TYPE, _external=True)
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
@pytest.mark.parametrize('out_of_hours_emergency, email_address_provided, out_of_hours, message', (
|
2016-12-12 12:29:29 +00:00
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
# Out of hours emergencies trump everything else
|
|
|
|
|
|
(
|
|
|
|
|
|
True, True, True,
|
|
|
|
|
|
'We’ll reply in the next 30 minutes.',
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
True, False, False, # Not a real scenario
|
|
|
|
|
|
'We’ll reply in the next 30 minutes.',
|
|
|
|
|
|
),
|
2016-12-12 12:29:29 +00:00
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
# Anonymous tickets don’t promise a reply
|
|
|
|
|
|
(
|
|
|
|
|
|
False, False, False,
|
2021-08-06 13:10:31 +01:00
|
|
|
|
'We’ll aim to read your message in the next 30 minutes.',
|
2019-07-12 10:35:49 +01:00
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
False, False, True,
|
2019-07-12 11:23:54 +01:00
|
|
|
|
'We’ll read your message when we’re back in the office.',
|
2019-07-12 10:35:49 +01:00
|
|
|
|
),
|
2016-12-12 12:29:29 +00:00
|
|
|
|
|
2019-07-12 10:35:49 +01:00
|
|
|
|
# When we look at your ticket depends on whether we’re in normal
|
|
|
|
|
|
# business hours
|
|
|
|
|
|
(
|
|
|
|
|
|
False, True, False,
|
2021-08-06 13:10:31 +01:00
|
|
|
|
'We’ll aim to read your message in the next 30 minutes and we’ll reply within one working day.',
|
2019-07-12 10:35:49 +01:00
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
False, True, True,
|
|
|
|
|
|
'We’ll reply within one working day.'
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
))
|
2016-12-12 12:29:29 +00:00
|
|
|
|
def test_thanks(
|
2019-07-12 10:35:49 +01:00
|
|
|
|
client_request,
|
2016-12-12 12:29:29 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
mock_get_user,
|
2019-07-12 10:35:49 +01:00
|
|
|
|
out_of_hours_emergency,
|
|
|
|
|
|
email_address_provided,
|
|
|
|
|
|
out_of_hours,
|
2016-12-12 12:29:29 +00:00
|
|
|
|
message,
|
|
|
|
|
|
):
|
2019-07-12 10:35:49 +01:00
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=(not out_of_hours))
|
|
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
'main.thanks',
|
|
|
|
|
|
out_of_hours_emergency=out_of_hours_emergency,
|
|
|
|
|
|
email_address_provided=email_address_provided,
|
|
|
|
|
|
)
|
|
|
|
|
|
assert normalize_spaces(page.find('main').find('p').text) == message
|