2016-12-12 11:31:26 +00:00
|
|
|
|
from bs4 import BeautifulSoup, element
|
2016-12-12 11:25:43 +00:00
|
|
|
|
from functools import partial
|
2016-04-26 10:32:26 +01:00
|
|
|
|
import pytest
|
2016-05-18 15:03:23 +01:00
|
|
|
|
from flask import url_for
|
2016-04-26 10:32:26 +01:00
|
|
|
|
from werkzeug.exceptions import InternalServerError
|
|
|
|
|
|
from unittest.mock import Mock, ANY
|
2016-12-12 11:44:11 +00:00
|
|
|
|
from freezegun import freeze_time
|
|
|
|
|
|
from tests.conftest import (
|
|
|
|
|
|
mock_get_services,
|
|
|
|
|
|
mock_get_services_with_no_services,
|
|
|
|
|
|
mock_get_services_with_one_service
|
|
|
|
|
|
)
|
|
|
|
|
|
from app.main.views.feedback import has_live_services, in_business_hours
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def no_redirect():
|
|
|
|
|
|
return lambda _external=True: None
|
2016-04-26 10:32:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-06-07 12:03:47 +01:00
|
|
|
|
@pytest.mark.parametrize('endpoint', [
|
|
|
|
|
|
'main.old_feedback',
|
|
|
|
|
|
'main.support',
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_get_support_index_page(
|
|
|
|
|
|
client,
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
):
|
|
|
|
|
|
response = client.get(url_for('main.support'), follow_redirects=True)
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
|
|
|
|
|
assert page.h1.string.strip() == 'Support'
|
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', [
|
|
|
|
|
|
('problem', 'Report a problem'),
|
|
|
|
|
|
('question', 'Ask a question or give feedback'),
|
|
|
|
|
|
])
|
2016-12-12 11:31:26 +00:00
|
|
|
|
@pytest.mark.parametrize('logged_in, expected_form_field, expected_contact_details', [
|
|
|
|
|
|
(True, type(None), 'We’ll reply to test@user.gov.uk'),
|
2016-12-21 14:55:49 +00:00
|
|
|
|
(False, element.Tag, None),
|
2016-12-12 11:31:26 +00:00
|
|
|
|
])
|
|
|
|
|
|
def test_choose_support_type(
|
|
|
|
|
|
client,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
mock_get_user,
|
|
|
|
|
|
mock_get_services,
|
|
|
|
|
|
logged_in,
|
|
|
|
|
|
expected_form_field,
|
|
|
|
|
|
expected_contact_details,
|
|
|
|
|
|
support_type,
|
|
|
|
|
|
expected_h1
|
|
|
|
|
|
):
|
|
|
|
|
|
if logged_in:
|
|
|
|
|
|
client.login(api_user_active)
|
2016-12-12 11:25:43 +00:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
url_for('main.support'),
|
|
|
|
|
|
data={'support_type': support_type}, follow_redirects=True
|
|
|
|
|
|
)
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
|
|
|
|
|
assert page.h1.string.strip() == expected_h1
|
2016-12-12 11:31:26 +00:00
|
|
|
|
assert isinstance(page.find('input', {'name': 'name'}), expected_form_field)
|
|
|
|
|
|
assert isinstance(page.find('input', {'name': 'email_address'}), expected_form_field)
|
2016-12-21 14:55:49 +00:00
|
|
|
|
if expected_contact_details:
|
|
|
|
|
|
assert page.find('form').find('p').text.strip() == expected_contact_details
|
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', [
|
|
|
|
|
|
('problem', 200),
|
|
|
|
|
|
('question', 200),
|
|
|
|
|
|
('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')
|
|
|
|
|
|
@pytest.mark.parametrize('ticket_type', ['problem', 'question'])
|
|
|
|
|
|
def test_passed_non_logged_in_user_details_through_flow(client, mocker, ticket_type):
|
|
|
|
|
|
mock_post = mocker.patch(
|
|
|
|
|
|
'app.main.views.feedback.requests.post',
|
|
|
|
|
|
return_value=Mock(status_code=201)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
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
|
|
|
|
|
|
assert resp.location == url_for('main.thanks', urgent=True, anonymous=False, _external=True)
|
|
|
|
|
|
mock_post.assert_called_with(
|
|
|
|
|
|
ANY,
|
|
|
|
|
|
data={
|
|
|
|
|
|
'department_id': ANY,
|
|
|
|
|
|
'agent_team_id': ANY,
|
2017-02-07 14:30:57 +00:00
|
|
|
|
'subject': 'Notify feedback {}'.format(data['name']),
|
2017-01-30 14:18:19 +00:00
|
|
|
|
'message': 'Environment: http://localhost/\n\nblah',
|
|
|
|
|
|
'person_email': 'rip@gmail.com',
|
|
|
|
|
|
'person_name': 'Steve Irwin',
|
|
|
|
|
|
'label': ticket_type,
|
|
|
|
|
|
'urgency': ANY,
|
|
|
|
|
|
},
|
|
|
|
|
|
headers=ANY
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
])
|
|
|
|
|
|
@pytest.mark.parametrize('ticket_type', ['problem', 'question'])
|
2016-12-21 14:55:49 +00:00
|
|
|
|
def test_passes_user_details_through_flow(
|
2017-01-30 14:18:19 +00:00
|
|
|
|
logged_in_client,
|
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
|
|
|
|
):
|
2016-04-26 10:32:26 +01:00
|
|
|
|
mock_post = mocker.patch(
|
|
|
|
|
|
'app.main.views.feedback.requests.post',
|
2016-12-12 11:25:43 +00:00
|
|
|
|
return_value=Mock(status_code=201)
|
|
|
|
|
|
)
|
2017-01-30 14:18:19 +00:00
|
|
|
|
|
|
|
|
|
|
resp = logged_in_client.post(
|
2016-12-12 11:25:43 +00:00
|
|
|
|
url_for('main.feedback', ticket_type=ticket_type),
|
|
|
|
|
|
data=data,
|
|
|
|
|
|
)
|
2017-01-30 14:18:19 +00:00
|
|
|
|
|
2016-12-12 11:25:43 +00:00
|
|
|
|
assert resp.status_code == 302
|
2017-01-30 14:18:19 +00:00
|
|
|
|
assert resp.location == url_for('main.thanks', urgent=True, anonymous=False, _external=True)
|
2016-12-12 11:25:43 +00:00
|
|
|
|
mock_post.assert_called_with(
|
|
|
|
|
|
ANY,
|
|
|
|
|
|
data={
|
|
|
|
|
|
'department_id': ANY,
|
|
|
|
|
|
'agent_team_id': ANY,
|
2017-02-07 16:14:58 +00:00
|
|
|
|
'subject': 'Notify feedback Test User',
|
2017-01-30 14:18:19 +00:00
|
|
|
|
'message': ANY,
|
|
|
|
|
|
'person_email': 'test@user.gov.uk',
|
|
|
|
|
|
'person_name': 'Test User',
|
2016-12-12 11:25:43 +00:00
|
|
|
|
'label': ticket_type,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
'urgency': ANY,
|
2016-12-12 11:25:43 +00:00
|
|
|
|
},
|
|
|
|
|
|
headers=ANY
|
|
|
|
|
|
)
|
2017-01-30 14:18:19 +00:00
|
|
|
|
assert mock_post.call_args[1]['data']['message'] == '\n'.join([
|
|
|
|
|
|
'Environment: http://localhost/',
|
|
|
|
|
|
'Service "service one": {}'.format(url_for(
|
|
|
|
|
|
'main.service_dashboard',
|
|
|
|
|
|
service_id='596364a0-858e-42c8-9062-a8fe822260eb',
|
|
|
|
|
|
_external=True
|
|
|
|
|
|
)),
|
|
|
|
|
|
'',
|
|
|
|
|
|
'blah',
|
|
|
|
|
|
])
|
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'},
|
|
|
|
|
|
])
|
2017-02-02 15:31:03 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type, expected_response, things_expected_in_url, expected_error', [
|
|
|
|
|
|
('problem', 200, [], element.Tag),
|
|
|
|
|
|
('question', 302, ['thanks', 'anonymous=True', 'urgent=True'], type(None)),
|
2016-12-21 14:55:49 +00:00
|
|
|
|
])
|
|
|
|
|
|
def test_email_address_required_for_problems(
|
|
|
|
|
|
client,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
data,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
expected_response,
|
2017-02-02 15:31:03 +00:00
|
|
|
|
things_expected_in_url,
|
2016-12-21 14:55:49 +00:00
|
|
|
|
expected_error
|
|
|
|
|
|
):
|
2017-01-30 14:18:19 +00:00
|
|
|
|
mocker.patch(
|
2016-12-21 14:55:49 +00:00
|
|
|
|
'app.main.views.feedback.requests.post',
|
|
|
|
|
|
return_value=Mock(status_code=201)
|
|
|
|
|
|
)
|
|
|
|
|
|
response = client.post(
|
|
|
|
|
|
url_for('main.feedback', ticket_type=ticket_type),
|
|
|
|
|
|
data=data,
|
|
|
|
|
|
)
|
|
|
|
|
|
assert response.status_code == expected_response
|
2017-02-02 15:31:03 +00:00
|
|
|
|
# This is to work around non-deterministic query ordering in Flask url_for
|
|
|
|
|
|
for thing in things_expected_in_url:
|
|
|
|
|
|
assert thing in response.location
|
2016-12-21 14:55:49 +00:00
|
|
|
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
|
|
|
|
|
assert isinstance(page.find('span', {'class': 'error-message'}), expected_error)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 12:29:29 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type, severe, is_in_business_hours, numeric_urgency, is_urgent', [
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
# business hours, always urgent
|
2017-02-02 10:42:17 +00:00
|
|
|
|
('problem', 'yes', True, 10, True),
|
|
|
|
|
|
('question', 'yes', True, 10, True),
|
|
|
|
|
|
('problem', 'no', True, 10, True),
|
|
|
|
|
|
('question', 'no', True, 10, True),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
# out of hours, non emergency, never urgent
|
2017-02-02 10:42:17 +00:00
|
|
|
|
('problem', 'no', False, 1, False),
|
|
|
|
|
|
('question', 'no', False, 1, False),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
# out of hours, emergency problems are urgent
|
2017-02-02 10:42:17 +00:00
|
|
|
|
('problem', 'yes', False, 10, True),
|
|
|
|
|
|
('question', 'yes', False, 1, False),
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_urgency(
|
|
|
|
|
|
logged_in_client,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
ticket_type,
|
|
|
|
|
|
severe,
|
|
|
|
|
|
is_in_business_hours,
|
2016-12-12 12:29:29 +00:00
|
|
|
|
numeric_urgency,
|
|
|
|
|
|
is_urgent,
|
2016-12-12 11:44:11 +00:00
|
|
|
|
):
|
|
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=is_in_business_hours)
|
|
|
|
|
|
mock_post = mocker.patch('app.main.views.feedback.requests.post', return_value=Mock(status_code=201))
|
|
|
|
|
|
response = logged_in_client.post(
|
|
|
|
|
|
url_for('main.feedback', ticket_type=ticket_type, severe=severe),
|
2016-12-21 14:55:49 +00:00
|
|
|
|
data={'feedback': 'blah', 'email_address': 'test@example.com'},
|
2016-12-12 11:44:11 +00:00
|
|
|
|
)
|
|
|
|
|
|
assert response.status_code == 302
|
2016-12-12 12:29:29 +00:00
|
|
|
|
assert response.location == url_for('main.thanks', urgent=is_urgent, anonymous=False, _external=True)
|
|
|
|
|
|
assert mock_post.call_args[1]['data']['urgency'] == numeric_urgency
|
2016-12-12 11:44:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ids, params = zip(*[
|
|
|
|
|
|
('non-logged in users always have to triage', (
|
|
|
|
|
|
'problem', False, False, True,
|
|
|
|
|
|
302, partial(url_for, 'main.triage')
|
|
|
|
|
|
)),
|
|
|
|
|
|
('trial services are never high priority', (
|
|
|
|
|
|
'problem', False, True, False,
|
|
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
)),
|
|
|
|
|
|
('we can triage in hours', (
|
|
|
|
|
|
'problem', True, True, True,
|
|
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
)),
|
|
|
|
|
|
('only problems are high priority', (
|
|
|
|
|
|
'question', False, True, True,
|
|
|
|
|
|
200, no_redirect()
|
|
|
|
|
|
)),
|
|
|
|
|
|
('should triage out of hours', (
|
|
|
|
|
|
'problem', False, True, True,
|
|
|
|
|
|
302, partial(url_for, 'main.triage')
|
|
|
|
|
|
))
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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,
|
|
|
|
|
|
):
|
|
|
|
|
|
mocker.patch('app.main.views.feedback.has_live_services', return_value=has_live_services)
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 14:11:34 +00:00
|
|
|
|
def test_doesnt_lose_message_if_post_across_closing(
|
|
|
|
|
|
logged_in_client,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
):
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.main.views.feedback.has_live_services', return_value=True)
|
|
|
|
|
|
mocker.patch('app.main.views.feedback.in_business_hours', return_value=False)
|
|
|
|
|
|
|
|
|
|
|
|
response = logged_in_client.post(
|
|
|
|
|
|
url_for('main.feedback', ticket_type='problem'),
|
|
|
|
|
|
data={'feedback': 'foo'},
|
|
|
|
|
|
)
|
|
|
|
|
|
with logged_in_client.session_transaction() as session:
|
|
|
|
|
|
assert session['feedback_message'] == 'foo'
|
|
|
|
|
|
assert response.status_code == 302
|
|
|
|
|
|
assert response.location == url_for('.triage', _external=True)
|
|
|
|
|
|
|
|
|
|
|
|
response = logged_in_client.get(
|
2017-02-02 10:42:17 +00:00
|
|
|
|
url_for('main.feedback', ticket_type='problem', severe='yes')
|
2016-12-12 14:11:34 +00:00
|
|
|
|
)
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
|
|
|
|
|
with logged_in_client.session_transaction() as session:
|
|
|
|
|
|
assert page.find('textarea', {'name': 'feedback'}).text == 'foo'
|
|
|
|
|
|
assert 'feedback_message' not in session
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 11:44:11 +00:00
|
|
|
|
@pytest.mark.parametrize('get_services_mock, expected_return_value', [
|
|
|
|
|
|
(mock_get_services, True),
|
|
|
|
|
|
(mock_get_services_with_no_services, False),
|
|
|
|
|
|
(mock_get_services_with_one_service, False),
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_has_live_services(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
fake_uuid,
|
|
|
|
|
|
get_services_mock,
|
|
|
|
|
|
expected_return_value
|
|
|
|
|
|
):
|
|
|
|
|
|
get_services_mock(mocker, fake_uuid)
|
|
|
|
|
|
assert has_live_services(12345) == expected_return_value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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
|
|
|
|
])
|
2017-01-30 14:18:19 +00:00
|
|
|
|
def test_triage_redirects_to_correct_url(client, choice, expected_redirect_param):
|
2016-12-12 11:44:11 +00:00
|
|
|
|
response = client.post(url_for('main.triage'), data={'severe': choice})
|
|
|
|
|
|
assert response.status_code == 302
|
|
|
|
|
|
assert response.location == url_for(
|
|
|
|
|
|
'main.feedback',
|
|
|
|
|
|
ticket_type='problem',
|
|
|
|
|
|
severe=expected_redirect_param,
|
|
|
|
|
|
_external=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
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, '',
|
|
|
|
|
|
302, partial(url_for, 'main.triage'),
|
|
|
|
|
|
302, partial(url_for, 'main.triage'),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
# User hasn’t answered the triage question
|
|
|
|
|
|
(
|
|
|
|
|
|
False, None,
|
|
|
|
|
|
302, partial(url_for, 'main.triage'),
|
|
|
|
|
|
302, partial(url_for, 'main.triage'),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
# 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,
|
|
|
|
|
|
mock_get_services,
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
|
feedback_page = url_for('main.feedback', ticket_type='problem', 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)
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
client.login(active_user_with_permissions, mocker, service_one)
|
|
|
|
|
|
logged_in_response = client.get(bat_phone_page)
|
|
|
|
|
|
assert logged_in_response.status_code == 302
|
|
|
|
|
|
assert logged_in_response.location == url_for('main.feedback', ticket_type='problem', _external=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time('2016-12-12 12:00:00.000000')
|
2016-12-12 11:25:43 +00:00
|
|
|
|
@pytest.mark.parametrize('ticket_type', ['problem', 'question'])
|
|
|
|
|
|
def test_log_error_on_post(app_, mocker, ticket_type):
|
2016-04-26 10:32:26 +01:00
|
|
|
|
mock_post = mocker.patch(
|
|
|
|
|
|
'app.main.views.feedback.requests.post',
|
|
|
|
|
|
return_value=Mock(
|
|
|
|
|
|
status_code=401,
|
|
|
|
|
|
json=lambda: {
|
|
|
|
|
|
'error_code': 'invalid_auth',
|
|
|
|
|
|
'error_message': 'Please provide a valid API key or token'}))
|
|
|
|
|
|
with app_.test_request_context():
|
|
|
|
|
|
mock_logger = mocker.patch.object(app_.logger, 'error')
|
|
|
|
|
|
with app_.test_client() as client:
|
|
|
|
|
|
with pytest.raises(InternalServerError):
|
2017-01-30 14:18:19 +00:00
|
|
|
|
client.post(
|
2016-12-12 11:25:43 +00:00
|
|
|
|
url_for('main.feedback', ticket_type=ticket_type),
|
2016-04-26 10:32:26 +01:00
|
|
|
|
data={'feedback': "blah", 'name': "Steve Irwin", 'email_address': 'rip@gmail.com'})
|
2016-08-04 18:01:08 +01:00
|
|
|
|
assert mock_post.called
|
2016-04-26 10:32:26 +01:00
|
|
|
|
mock_logger.assert_called_with(
|
|
|
|
|
|
"Deskpro create ticket request failed with {} '{}'".format(mock_post().status_code, mock_post().json()))
|
2016-12-12 12:29:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('logged_in', [True, False])
|
|
|
|
|
|
@pytest.mark.parametrize('urgent, anonymous, message', [
|
|
|
|
|
|
|
|
|
|
|
|
(True, False, 'We’ll get back to you within 30 minutes.'),
|
|
|
|
|
|
(False, False, 'We’ll get back to you by the next working day.'),
|
|
|
|
|
|
|
|
|
|
|
|
(True, True, 'We’ll look into it within 30 minutes.'),
|
|
|
|
|
|
(False, True, 'We’ll look into it by the next working day.'),
|
|
|
|
|
|
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_thanks(
|
|
|
|
|
|
client,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
mock_get_user,
|
|
|
|
|
|
urgent,
|
|
|
|
|
|
anonymous,
|
|
|
|
|
|
message,
|
|
|
|
|
|
logged_in,
|
|
|
|
|
|
):
|
|
|
|
|
|
if logged_in:
|
|
|
|
|
|
client.login(api_user_active)
|
|
|
|
|
|
response = client.get(url_for('main.thanks', urgent=urgent, anonymous=anonymous))
|
|
|
|
|
|
assert response.status_code == 200
|
|
|
|
|
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
|
|
|
|
|
assert ' '.join(page.find('main').find('p').text.split()) == message
|