From 378717571b2da23227abc40e250a4f4e6319f228 Mon Sep 17 00:00:00 2001
From: stvnrlly
Date: Wed, 20 Dec 2023 10:44:38 -0500
Subject: [PATCH] remove unused support forms/pages & unused go-live form
---
app/__init__.py | 7 +-
app/main/forms.py | 51 -
app/main/views/feedback.py | 239 +---
app/main/views/organizations.py | 23 -
app/main/views/service_settings.py | 84 +-
app/models/event.py | 3 -
app/models/feedback.py | 3 -
app/models/organization.py | 2 -
app/models/service.py | 18 -
app/navigation.py | 12 -
.../support-tickets/go-live-request.txt | 31 -
.../support-tickets/support-ticket.txt | 5 -
app/templates/views/get-started.html | 2 +-
.../settings/edit-go-live-notes.html | 30 -
.../organization/settings/index.html | 10 -
app/templates/views/service-settings.html | 2 +-
.../service-settings/estimate-usage.html | 42 -
.../service-settings/request-to-go-live.html | 75 --
.../service-already-live.html | 28 -
app/templates/views/support/bat-phone.html | 46 -
app/templates/views/support/form.html | 42 -
app/templates/views/support/public.html | 50 -
app/templates/views/support/thanks.html | 38 -
app/templates/views/support/triage.html | 62 -
app/templates/views/trial-mode.html | 4 +-
app/url_converters.py | 9 -
get_zendesk_tickets.py | 152 ---
tests/__init__.py | 2 -
.../views/organizations/test_organizations.py | 43 -
.../service_settings/test_service_settings.py | 1151 +----------------
tests/app/main/views/test_feedback.py | 807 +-----------
tests/app/main/views/test_index.py | 8 -
tests/app/models/test_user.py | 1 -
tests/app/test_navigation.py | 9 -
34 files changed, 17 insertions(+), 3074 deletions(-)
delete mode 100644 app/models/feedback.py
delete mode 100644 app/templates/support-tickets/go-live-request.txt
delete mode 100644 app/templates/support-tickets/support-ticket.txt
delete mode 100644 app/templates/views/organizations/organization/settings/edit-go-live-notes.html
delete mode 100644 app/templates/views/service-settings/estimate-usage.html
delete mode 100644 app/templates/views/service-settings/request-to-go-live.html
delete mode 100644 app/templates/views/service-settings/service-already-live.html
delete mode 100644 app/templates/views/support/bat-phone.html
delete mode 100644 app/templates/views/support/form.html
delete mode 100644 app/templates/views/support/public.html
delete mode 100644 app/templates/views/support/thanks.html
delete mode 100644 app/templates/views/support/triage.html
delete mode 100644 get_zendesk_tickets.py
diff --git a/app/__init__.py b/app/__init__.py
index dd668fee8..4e53bbb76 100644
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -110,11 +110,7 @@ from app.notify_client.template_folder_api_client import template_folder_api_cli
from app.notify_client.template_statistics_api_client import template_statistics_client
from app.notify_client.upload_api_client import upload_api_client
from app.notify_client.user_api_client import user_api_client
-from app.url_converters import (
- SimpleDateTypeConverter,
- TemplateTypeConverter,
- TicketTypeConverter,
-)
+from app.url_converters import SimpleDateTypeConverter, TemplateTypeConverter
login_manager = LoginManager()
csrf = CSRFProtect()
@@ -326,7 +322,6 @@ def init_app(application):
application.url_map.converters["uuid"].to_python = lambda self, value: value
application.url_map.converters["template_type"] = TemplateTypeConverter
- application.url_map.converters["ticket_type"] = TicketTypeConverter
application.url_map.converters["simple_date"] = SimpleDateTypeConverter
diff --git a/app/main/forms.py b/app/main/forms.py
index a3b38f779..2520474fc 100644
--- a/app/main/forms.py
+++ b/app/main/forms.py
@@ -61,7 +61,6 @@ from app.main.validators import (
ValidEmail,
ValidGovEmail,
)
-from app.models.feedback import PROBLEM_TICKET_TYPE, QUESTION_TICKET_TYPE
from app.models.organization import Organization
from app.utils import merge_jsonlike
from app.utils.csv import get_user_preferred_timezone
@@ -1319,49 +1318,6 @@ class CreateKeyForm(StripWhitespaceForm):
raise ValidationError("A key with this name already exists")
-class SupportType(StripWhitespaceForm):
- support_type = GovukRadiosField(
- "How can we help you?",
- choices=[
- (PROBLEM_TICKET_TYPE, "Report a problem"),
- (QUESTION_TICKET_TYPE, "Ask a question or give feedback"),
- ],
- )
-
-
-class SupportRedirect(StripWhitespaceForm):
- who = GovukRadiosField(
- "What do you need help with?",
- choices=[
- (
- "public-sector",
- "I work in the public sector and need to send emails or text messages",
- ),
- ("public", "I’m a member of the public with a question for the government"),
- ],
- param_extensions={"fieldset": {"legend": {"classes": "usa-sr-only"}}},
- )
-
-
-class FeedbackOrProblem(StripWhitespaceForm):
- name = GovukTextInputField("Name (optional)")
- email_address = email_address(label="Email address", gov_user=False, required=True)
- feedback = TextAreaField(
- "Your message", validators=[DataRequired(message="Cannot be empty")]
- )
-
-
-class Triage(StripWhitespaceForm):
- severe = GovukRadiosField(
- "Is it an emergency?",
- choices=[
- ("yes", "Yes"),
- ("no", "No"),
- ],
- thing="yes or no",
- )
-
-
class EstimateUsageForm(StripWhitespaceForm):
volume_email = ForgivingIntegerField(
"How many emails do you expect to send in the next year?",
@@ -1905,13 +1861,6 @@ class AdminClearCacheForm(StripWhitespaceForm):
raise ValidationError("Select at least one option")
-class AdminOrganizationGoLiveNotesForm(StripWhitespaceForm):
- request_to_go_live_notes = TextAreaField(
- "Go live notes",
- filters=[lambda x: x or None],
- )
-
-
class ChangeSecurityKeyNameForm(StripWhitespaceForm):
security_key_name = GovukTextInputField(
"Name of key",
diff --git a/app/main/views/feedback.py b/app/main/views/feedback.py
index a68cc798a..26399f9db 100644
--- a/app/main/views/feedback.py
+++ b/app/main/views/feedback.py
@@ -1,239 +1,10 @@
-from datetime import datetime
+from flask import render_template
-import pytz
-from flask import redirect, render_template, request, session, url_for
-from flask_login import current_user
-from govuk_bank_holidays.bank_holidays import BankHolidays
-from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket
-
-from app import convert_to_boolean, current_service
-from app.extensions import zendesk_client
from app.main import main
-from app.main.forms import FeedbackOrProblem, SupportRedirect, SupportType, Triage
-from app.models.feedback import (
- GENERAL_TICKET_TYPE,
- PROBLEM_TICKET_TYPE,
- QUESTION_TICKET_TYPE,
-)
-from app.utils import hide_from_search_engines
-
-bank_holidays = BankHolidays(use_cached_holidays=True)
+from app.utils.user import user_is_logged_in
-@main.route("/support", methods=["GET", "POST"])
-@hide_from_search_engines
+@main.route("/support", methods=["GET"])
+@user_is_logged_in
def support():
- if current_user.is_authenticated:
- form = SupportType()
- if form.validate_on_submit():
- return redirect(
- url_for(
- ".feedback",
- ticket_type=form.support_type.data,
- )
- )
- else:
- form = SupportRedirect()
- if form.validate_on_submit():
- if form.who.data == "public":
- return redirect(url_for(".support_public"))
- else:
- return redirect(
- url_for(
- ".feedback",
- ticket_type=GENERAL_TICKET_TYPE,
- )
- )
-
- return render_template("views/support/index.html", form=form)
-
-
-@main.route("/support/public")
-@hide_from_search_engines
-def support_public():
- return render_template("views/support/public.html")
-
-
-@main.route("/support/triage", methods=["GET", "POST"])
-@main.route("/support/triage/", methods=["GET", "POST"])
-@hide_from_search_engines
-def triage(ticket_type=PROBLEM_TICKET_TYPE):
- form = Triage()
- if form.validate_on_submit():
- return redirect(
- url_for(".feedback", ticket_type=ticket_type, severe=form.severe.data)
- )
- return render_template(
- "views/support/triage.html",
- form=form,
- page_title={
- PROBLEM_TICKET_TYPE: "Report a problem",
- GENERAL_TICKET_TYPE: "Contact Notify.gov support",
- }.get(ticket_type),
- )
-
-
-@main.route("/support/", methods=["GET", "POST"])
-@hide_from_search_engines
-def feedback(ticket_type):
- form = FeedbackOrProblem()
-
- if not form.feedback.data:
- form.feedback.data = session.pop("feedback_message", "")
-
- if request.args.get("severe") in ["yes", "no"]:
- severe = convert_to_boolean(request.args.get("severe"))
- else:
- severe = None
-
- out_of_hours_emergency = all(
- (
- ticket_type != QUESTION_TICKET_TYPE,
- not in_business_hours(),
- severe,
- )
- )
-
- if needs_triage(ticket_type, severe):
- session["feedback_message"] = form.feedback.data
- return redirect(url_for(".triage", ticket_type=ticket_type))
-
- if needs_escalation(ticket_type, severe):
- return redirect(url_for(".bat_phone"))
-
- if current_user.is_authenticated:
- form.email_address.data = current_user.email_address
- form.name.data = current_user.name
-
- if form.validate_on_submit():
- user_email = form.email_address.data
- user_name = form.name.data or None
-
- feedback_msg = render_template(
- "support-tickets/support-ticket.txt",
- content=form.feedback.data,
- )
-
- ticket = NotifySupportTicket(
- subject="Notify feedback",
- message=feedback_msg,
- ticket_type=get_zendesk_ticket_type(ticket_type),
- p1=out_of_hours_emergency,
- user_name=user_name,
- user_email=user_email,
- org_id=current_service.organization_id if current_service else None,
- org_type=current_service.organization_type if current_service else None,
- service_id=current_service.id if current_service else None,
- )
- zendesk_client.send_ticket_to_zendesk(ticket)
-
- return redirect(
- url_for(
- ".thanks",
- out_of_hours_emergency=out_of_hours_emergency,
- email_address_provided=(
- current_user.is_authenticated or bool(form.email_address.data)
- ),
- )
- )
-
- return render_template(
- "views/support/form.html",
- form=form,
- back_link=(
- url_for(".support")
- if severe is None
- else url_for(".triage", ticket_type=ticket_type)
- ),
- show_status_page_banner=(ticket_type == PROBLEM_TICKET_TYPE),
- page_title={
- GENERAL_TICKET_TYPE: "Contact Notify.gov support",
- PROBLEM_TICKET_TYPE: "Report a problem",
- QUESTION_TICKET_TYPE: "Ask a question or give feedback",
- }.get(ticket_type),
- )
-
-
-@main.route("/support/escalate", methods=["GET", "POST"])
-@hide_from_search_engines
-def bat_phone():
- if current_user.is_authenticated:
- return redirect(url_for("main.feedback", ticket_type=PROBLEM_TICKET_TYPE))
-
- return render_template("views/support/bat-phone.html")
-
-
-@main.route("/support/thanks", methods=["GET", "POST"])
-@hide_from_search_engines
-def thanks():
- return render_template(
- "views/support/thanks.html",
- out_of_hours_emergency=convert_to_boolean(
- request.args.get("out_of_hours_emergency")
- ),
- email_address_provided=convert_to_boolean(
- request.args.get("email_address_provided")
- ),
- out_of_hours=not in_business_hours(),
- )
-
-
-def in_business_hours():
- now = datetime.utcnow().replace(tzinfo=pytz.utc)
-
- if is_weekend(now) or is_bank_holiday(now):
- return False
-
- return london_time_today_as_utc(9, 30) <= now < london_time_today_as_utc(17, 30)
-
-
-def london_time_today_as_utc(hour, minute):
- return (
- pytz.timezone("Europe/London")
- .localize(datetime.now().replace(hour=hour, minute=minute))
- .astimezone(pytz.utc)
- )
-
-
-def is_weekend(time):
- return time.strftime("%A") in {
- "Saturday",
- "Sunday",
- }
-
-
-def is_bank_holiday(time):
- return bank_holidays.is_holiday(time.date())
-
-
-def needs_triage(ticket_type, severe):
- return all(
- (
- ticket_type != QUESTION_TICKET_TYPE,
- severe is None,
- (not current_user.is_authenticated or current_user.live_services),
- not in_business_hours(),
- )
- )
-
-
-def needs_escalation(ticket_type, severe):
- return all(
- (
- ticket_type != QUESTION_TICKET_TYPE,
- severe,
- not current_user.is_authenticated,
- not in_business_hours(),
- )
- )
-
-
-def get_zendesk_ticket_type(ticket_type):
- # Zendesk has 4 ticket types - "problem", "incident", "task" and "question".
- # We don't want to use a Zendesk "problem" ticket type when someone reports a
- # Notify problem because they are designed to group multiple incident tickets together,
- # allowing them to be solved as a group.
- if ticket_type == PROBLEM_TICKET_TYPE:
- return NotifySupportTicket.TYPE_INCIDENT
-
- return NotifySupportTicket.TYPE_QUESTION
+ return render_template("views/support/index.html")
diff --git a/app/main/views/organizations.py b/app/main/views/organizations.py
index ed5c7ca9d..14ccc9de2 100644
--- a/app/main/views/organizations.py
+++ b/app/main/views/organizations.py
@@ -13,7 +13,6 @@ from app.main.forms import (
AdminNewOrganizationForm,
AdminNotesForm,
AdminOrganizationDomainsForm,
- AdminOrganizationGoLiveNotesForm,
InviteOrgUserForm,
OrganizationOrganizationTypeForm,
RenameOrganizationForm,
@@ -313,28 +312,6 @@ def edit_organization_domains(org_id):
)
-@main.route(
- "/organizations//settings/edit-go-live-notes", methods=["GET", "POST"]
-)
-@user_is_platform_admin
-def edit_organization_go_live_notes(org_id):
- form = AdminOrganizationGoLiveNotesForm()
-
- if form.validate_on_submit():
- organizations_client.update_organization(
- org_id, request_to_go_live_notes=form.request_to_go_live_notes.data
- )
- return redirect(url_for(".organization_settings", org_id=org_id))
-
- org = organizations_client.get_organization(org_id)
- form.request_to_go_live_notes.data = org["request_to_go_live_notes"]
-
- return render_template(
- "views/organizations/organization/settings/edit-go-live-notes.html",
- form=form,
- )
-
-
@main.route("/organizations//settings/notes", methods=["GET", "POST"])
@user_is_platform_admin
def edit_organization_notes(org_id):
diff --git a/app/main/views/service_settings.py b/app/main/views/service_settings.py
index 05f219ab6..feb1e4388 100644
--- a/app/main/views/service_settings.py
+++ b/app/main/views/service_settings.py
@@ -13,7 +13,6 @@ from flask import (
)
from flask_login import current_user
from notifications_python_client.errors import HTTPError
-from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket
from app import (
billing_api_client,
@@ -28,7 +27,6 @@ from app.event_handlers import (
create_resume_service_event,
create_suspend_service_event,
)
-from app.extensions import zendesk_client
from app.formatters import email_safe
from app.main import main
from app.main.forms import (
@@ -41,7 +39,6 @@ from app.main.forms import (
AdminServiceRateLimitForm,
AdminServiceSMSAllowanceForm,
AdminSetOrganizationForm,
- EstimateUsageForm,
RenameServiceForm,
SearchByNameForm,
ServiceContactDetailsForm,
@@ -54,11 +51,7 @@ from app.main.forms import (
)
from app.utils import DELIVERED_STATUSES, FAILURE_STATUSES, SENDING_STATUSES
from app.utils.time import parse_naive_dt
-from app.utils.user import (
- user_has_permissions,
- user_is_gov_user,
- user_is_platform_admin,
-)
+from app.utils.user import user_has_permissions, user_is_platform_admin
PLATFORM_ADMIN_SERVICE_PERMISSIONS = OrderedDict(
[
@@ -120,81 +113,6 @@ def service_name_change(service_id):
)
-@main.route(
- "/services//service-settings/request-to-go-live/estimate-usage",
- methods=["GET", "POST"],
-)
-@user_has_permissions("manage_service")
-def estimate_usage(service_id):
- form = EstimateUsageForm(
- volume_email=current_service.volume_email,
- volume_sms=current_service.volume_sms,
- consent_to_research={
- True: "yes",
- False: "no",
- }.get(current_service.consent_to_research),
- )
-
- if form.validate_on_submit():
- current_service.update(
- volume_email=form.volume_email.data,
- volume_sms=form.volume_sms.data,
- consent_to_research=(form.consent_to_research.data == "yes"),
- )
- return redirect(
- url_for(
- "main.request_to_go_live",
- service_id=service_id,
- )
- )
-
- return render_template(
- "views/service-settings/estimate-usage.html",
- form=form,
- )
-
-
-@main.route(
- "/services//service-settings/request-to-go-live", methods=["GET"]
-)
-@user_has_permissions("manage_service")
-def request_to_go_live(service_id):
- if current_service.live:
- return render_template("views/service-settings/service-already-live.html")
-
- return render_template("views/service-settings/request-to-go-live.html")
-
-
-@main.route(
- "/services//service-settings/request-to-go-live", methods=["POST"]
-)
-@user_has_permissions("manage_service")
-@user_is_gov_user
-def submit_request_to_go_live(service_id):
- ticket_message = render_template("support-tickets/go-live-request.txt") + "\n"
-
- ticket = NotifySupportTicket(
- subject=f"Request to go live - {current_service.name}",
- message=ticket_message,
- ticket_type=NotifySupportTicket.TYPE_QUESTION,
- user_name=current_user.name,
- user_email=current_user.email_address,
- requester_sees_message_content=False,
- org_id=current_service.organization_id,
- org_type=current_service.organization_type,
- service_id=current_service.id,
- )
- zendesk_client.send_ticket_to_zendesk(ticket)
-
- current_service.update(go_live_user=current_user.id)
-
- flash(
- "Thanks for your request to go live. We’ll get back to you within one working day.",
- "default",
- )
- return redirect(url_for(".service_settings", service_id=service_id))
-
-
@main.route(
"/services//service-settings/switch-live", methods=["GET", "POST"]
)
diff --git a/app/models/event.py b/app/models/event.py
index b988ba3b4..3af502ea7 100644
--- a/app/models/event.py
+++ b/app/models/event.py
@@ -113,9 +113,6 @@ class ServiceEvent(Event):
def format_service_callback_api(self):
return "Updated the callback for delivery receipts"
- def format_go_live_user(self):
- return "Requested for this service to go live"
-
class APIKeyEvent(Event):
relevant = True
diff --git a/app/models/feedback.py b/app/models/feedback.py
deleted file mode 100644
index 31a669ac2..000000000
--- a/app/models/feedback.py
+++ /dev/null
@@ -1,3 +0,0 @@
-QUESTION_TICKET_TYPE = "ask-question-give-feedback"
-PROBLEM_TICKET_TYPE = "report-problem"
-GENERAL_TICKET_TYPE = "general"
diff --git a/app/models/organization.py b/app/models/organization.py
index 87b0bdff9..e9e30f460 100644
--- a/app/models/organization.py
+++ b/app/models/organization.py
@@ -25,7 +25,6 @@ class Organization(JSONModel, SortByNameMixin):
"active",
"organization_type",
"domains",
- "request_to_go_live_notes",
"count_of_live_services",
"billing_contact_email_addresses",
"billing_contact_names",
@@ -71,7 +70,6 @@ class Organization(JSONModel, SortByNameMixin):
self.name = None
self.domains = []
self.organization_type = None
- self.request_to_go_live_notes = None
@property
def organization_type_label(self):
diff --git a/app/models/service.py b/app/models/service.py
index 81b604f50..2932a3253 100644
--- a/app/models/service.py
+++ b/app/models/service.py
@@ -27,8 +27,6 @@ class Service(JSONModel, SortByNameMixin):
"contact_link",
"count_as_live",
"email_from",
- "go_live_at",
- "go_live_user",
"id",
"inbound_api",
"message_limit",
@@ -370,22 +368,6 @@ class Service(JSONModel, SortByNameMixin):
)
)
- @property
- def go_live_checklist_completed(self):
- return all(
- (
- bool(self.volumes),
- self.has_team_members,
- self.has_templates,
- not self.needs_to_add_email_reply_to_address,
- not self.needs_to_change_sms_sender,
- )
- )
-
- @property
- def go_live_checklist_completed_as_yes_no(self):
- return "Yes" if self.go_live_checklist_completed else "No"
-
@cached_property
def free_sms_fragment_limit(self):
return billing_api_client.get_free_sms_fragment_limit_for_year(self.id) or 0
diff --git a/app/navigation.py b/app/navigation.py
index 931d3caad..e824d6de2 100644
--- a/app/navigation.py
+++ b/app/navigation.py
@@ -38,12 +38,7 @@ class Navigation:
class HeaderNavigation(Navigation):
mapping = {
"support": {
- "bat_phone",
- "feedback",
"support",
- "support_public",
- "thanks",
- "triage",
},
"features": {
"features",
@@ -101,9 +96,7 @@ class HeaderNavigation(Navigation):
"manage_users",
"remove_user_from_service",
"usage",
- "estimate_usage",
"link_service_to_organization",
- "request_to_go_live",
"service_add_email_reply_to",
"service_add_sms_sender",
"service_confirm_delete_email_reply_to",
@@ -127,7 +120,6 @@ class HeaderNavigation(Navigation):
"set_free_sms_allowance",
"set_message_limit",
"set_rate_limit",
- "submit_request_to_go_live",
},
"pricing": {
"how_to_pay",
@@ -245,9 +237,7 @@ class MainNavigation(Navigation):
"usage",
},
"settings": {
- "estimate_usage",
"link_service_to_organization",
- "request_to_go_live",
"service_add_email_reply_to",
"service_add_sms_sender",
"service_confirm_delete_email_reply_to",
@@ -271,7 +261,6 @@ class MainNavigation(Navigation):
"set_free_sms_allowance",
"set_message_limit",
"set_rate_limit",
- "submit_request_to_go_live",
},
"api-integration": {
"api_callbacks",
@@ -316,7 +305,6 @@ class OrgNavigation(Navigation):
"settings": {
"edit_organization_billing_details",
"edit_organization_domains",
- "edit_organization_go_live_notes",
"edit_organization_name",
"edit_organization_notes",
"edit_organization_type",
diff --git a/app/templates/support-tickets/go-live-request.txt b/app/templates/support-tickets/go-live-request.txt
deleted file mode 100644
index 996234f35..000000000
--- a/app/templates/support-tickets/go-live-request.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-{% set service = current_service -%}
-{% set organization = service.organization -%}
-{% set user = current_user -%}
-
-Service: {{ service.name }}
-{{ url_for('main.service_dashboard', service_id=service.id, _external=True) }}
-
----
-Organization type: {{ service.organization_type_label }}
-{%- if organization.name %} (organization is {{ organization.name }})
-{%- else %} (domain is {{ user.email_domain }})
-{%- endif %}.
-{%- if organization.request_to_go_live_notes %} {{ organization.request_to_go_live_notes }}{% endif %}
-{%- if organization.agreement_signed_by %}
-Agreement signed by: {{ organization.agreement_signed_by.email_address }}
-{% endif -%}
-{%- if organization.agreement_signed_on_behalf_of_email_address -%}
-Agreement signed on behalf of: {{ organization.agreement_signed_on_behalf_of_email_address }}
-{%- endif %}
-
-Emails in next year: {{ service.volume_email|format_thousands }}
-Text messages in next year: {{ service.volume_sms|format_thousands }}
-
-Consent to research: {{ service.consent_to_research|format_yes_no }}
-Other live services for that user: {{ user.live_services|format_yes_no }}
-
-Service reply-to address: {{ service.default_email_reply_to_address or "not set" }}
-
----
-Request sent by {{ user.email_address }}
-Requester’s user page: {{ url_for('main.user_information', user_id=user.id, _external=True) }}
diff --git a/app/templates/support-tickets/support-ticket.txt b/app/templates/support-tickets/support-ticket.txt
deleted file mode 100644
index 08fd2629d..000000000
--- a/app/templates/support-tickets/support-ticket.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-{{ content }}
-{% if current_service -%}
-Service: "{{ current_service.name }}"
-{{ url_for('main.service_dashboard', service_id=current_service.id, _external=True) }}
-{% endif %}
diff --git a/app/templates/views/get-started.html b/app/templates/views/get-started.html
index d4ad0ebce..d3c9363f9 100644
--- a/app/templates/views/get-started.html
+++ b/app/templates/views/get-started.html
@@ -53,7 +53,7 @@
{% if not current_user.is_authenticated or not current_service %}
When you’re ready to send messages to people outside your team, go to the Settings page and select Request to go live. We’ll approve your request within one working day.
{% else %}
- You should request to go live when you’re ready to send messages to people outside your team. We’ll approve your request within one working day.
+ You should request to go live when you’re ready to send messages to people outside your team. We’ll approve your request within one working day.
{% endif %}
diff --git a/app/templates/views/organizations/organization/settings/edit-go-live-notes.html b/app/templates/views/organizations/organization/settings/edit-go-live-notes.html
deleted file mode 100644
index c7955f616..000000000
--- a/app/templates/views/organizations/organization/settings/edit-go-live-notes.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends "org_template.html" %}
-{% from "components/form.html" import form_wrapper %}
-{% from "components/page-footer.html" import page_footer %}
-{% from "components/page-header.html" import page_header %}
-{% from "components/textbox.html" import textbox %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block org_page_title %}
- Edit request to go live notes
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": url_for('.organization_settings', org_id=current_org.id) }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
- {{ page_header("Edit request to go live notes") }}
-
-
-
- Text entered here will be displayed in the Zendesk ticket when a service
- belonging to this organization requests to go live.
-
- {% call form_wrapper() %}
- {{ textbox(form.request_to_go_live_notes, width='1-1', rows=3, autosize=True) }}
- {{ page_footer('Save') }}
- {% endcall %}
-
-
-{% endblock %}
diff --git a/app/templates/views/organizations/organization/settings/index.html b/app/templates/views/organizations/organization/settings/index.html
index a9d339bf8..ddd60bc64 100644
--- a/app/templates/views/organizations/organization/settings/index.html
+++ b/app/templates/views/organizations/organization/settings/index.html
@@ -34,16 +34,6 @@
)
}}
{% endcall %}
- {% call row() %}
- {{ text_field('Request to go live notes') }}
- {{ optional_text_field(current_org.request_to_go_live_notes, default='None') }}
- {{ edit_field(
- 'Change',
- url_for('.edit_organization_go_live_notes', org_id=current_org.id),
- suffix='go live notes for the organization'
- )
- }}
- {% endcall %}
{% call row() %}
{{ text_field('Billing details')}}
diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html
index 86ef1a36d..0bb3da6e4 100644
--- a/app/templates/views/service-settings.html
+++ b/app/templates/views/service-settings.html
@@ -206,7 +206,7 @@
Problems or comments?
- Give feedback.
+ Contact us.
{% endif %}
diff --git a/app/templates/views/service-settings/estimate-usage.html b/app/templates/views/service-settings/estimate-usage.html
deleted file mode 100644
index 2b0643cfe..000000000
--- a/app/templates/views/service-settings/estimate-usage.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% extends "withnav_template.html" %}
-{% from "components/banner.html" import banner_wrapper %}
-{% from "components/form.html" import form_wrapper %}
-{% from "components/page-header.html" import page_header %}
-{% from "components/page-footer.html" import page_footer %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block service_page_title %}
- Tell us how many messages you expect to send
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": url_for('main.request_to_go_live', service_id=current_service.id) }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
-
-
- {% if not form.at_least_one_volume_filled %}
- {% call banner_wrapper(type='dangerous') %}
-
- Enter the number of messages you expect to send in the next year
-
- {% endcall %}
- {% else %}
- {{ page_header('Tell us how many messages you expect to send') }}
- {% endif %}
- {% call form_wrapper() %}
-
- {{ form.volume_email(param_extensions={
- "hint": {"text": "For example, 50,000"},
- }) }}
- {{ form.volume_sms(param_extensions={
- "hint": {"text": "For example, 50,000"},
- }) }}
-
- {{ form.consent_to_research }}
- {{ page_footer('Continue') }}
- {% endcall %}
-
-
-{% endblock %}
diff --git a/app/templates/views/service-settings/request-to-go-live.html b/app/templates/views/service-settings/request-to-go-live.html
deleted file mode 100644
index 5a5d89cdc..000000000
--- a/app/templates/views/service-settings/request-to-go-live.html
+++ /dev/null
@@ -1,75 +0,0 @@
-{% extends "withnav_template.html" %}
-{% from "components/form.html" import form_wrapper %}
-{% from "components/page-header.html" import page_header %}
-{% from "components/page-footer.html" import page_footer %}
-{% from "components/task-list.html" import task_list_wrapper, task_list_item %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block service_page_title %}
- Before you request to go live
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": url_for('main.service_settings', service_id=current_service.id) }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
-
-
- {{ page_header('Before you request to go live') }}
- {% call task_list_wrapper() %}
- {{ task_list_item(
- current_service.has_estimated_usage,
- 'Tell us how many messages you expect to send',
- url_for('main.estimate_usage', service_id=current_service.id),
- ) }}
- {{ task_list_item(
- current_service.has_team_members,
- 'Add a team member who can manage settings, team and usage',
- url_for('main.manage_users', service_id=current_service.id),
- ) }}
- {{ task_list_item(
- current_service.has_templates,
- 'Add templates with examples of the content you plan to send',
- url_for('main.choose_template', service_id=current_service.id),
- ) }}
- {% if current_service.intending_to_send_email %}
- {{ task_list_item(
- current_service.has_email_reply_to_address,
- 'Add a reply-to email address',
- url_for('main.service_email_reply_to', service_id=current_service.id),
- ) }}
- {% endif %}
- {% if (
- current_service.intending_to_send_sms
- and current_service.shouldnt_use_govuk_as_sms_sender
- ) %}
- {{ task_list_item(
- not current_service.sms_sender_is_govuk,
- 'Change your text message sender name',
- url_for('main.service_sms_senders', service_id=current_service.id),
- ) }}
- {% endif %}
- {% endcall %}
- {% if not current_user.is_gov_user %}
-
- Only team members with a government email address can request to go live.
-
- {% elif (not current_service.go_live_checklist_completed) %}
-
- You must complete these steps before you can request to go live.
-
- {% else %}
-
- When we receive your request we’ll get back to you within one working day.
-
-
- By requesting to go live you’re agreeing to our terms of use.
-
- {% call form_wrapper() %}
- {{ page_footer('Request to go live') }}
- {% endcall %}
- {% endif %}
-
-
-{% endblock %}
diff --git a/app/templates/views/service-settings/service-already-live.html b/app/templates/views/service-settings/service-already-live.html
deleted file mode 100644
index a42a87618..000000000
--- a/app/templates/views/service-settings/service-already-live.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "withnav_template.html" %}
-{% from "components/page-header.html" import page_header %}
-
-{% block service_page_title %}
- Your service is already live
-{% endblock %}
-
-{% block maincolumn_content %}
-
-
- {{ page_header('Your service is already live') }}
-
-
- {% if current_service.go_live_at %}
- ‘{{ current_service.name }}’ went live on {{ current_service.go_live_at | format_date_normal }}.
- {% else %}
- ‘{{ current_service.name }}’ is already live.
- {% endif %}
-
-
-
- Switch service
- if you want to make a different service live.
-
-
-
-
-{% endblock %}
diff --git a/app/templates/views/support/bat-phone.html b/app/templates/views/support/bat-phone.html
deleted file mode 100644
index 46e947f44..000000000
--- a/app/templates/views/support/bat-phone.html
+++ /dev/null
@@ -1,46 +0,0 @@
-{% extends "withoutnav_template.html" %}
-{% from "components/page-footer.html" import page_footer %}
-{% from "components/page-header.html" import page_header %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block per_page_title %}
- Out of hours emergencies
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": url_for('.support') }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
-
- {{ page_header('Out of hours emergencies')}}
-
-
-
- First, check the
- system status page.
- You do not need to contact us if
- the problem you’re having is listed on that page.
-
-
- Otherwise, contact us using the emergency email address we
- gave you or your service manager when we made your service live.
-
-
- We’ll reply within 30 minutes and give you hourly updates
- until the problem’s fixed.
-
-
- We do not offer out of hours support if your service is in
- trial mode.
-
-
Any other problems
-
- Fill in this form
- and we’ll get back to you by the next working day.
-
-
-
-
-
-{% endblock %}
diff --git a/app/templates/views/support/form.html b/app/templates/views/support/form.html
deleted file mode 100644
index 904bc9485..000000000
--- a/app/templates/views/support/form.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% extends "withoutnav_template.html" %}
-{% from "components/textbox.html" import textbox %}
-{% from "components/page-footer.html" import sticky_page_footer %}
-{% from "components/page-header.html" import page_header %}
-{% from "components/form.html" import form_wrapper %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block per_page_title %}
- {{ page_title }}
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": back_link }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
-
- {{ page_header(page_title) }}
-
-
- {% if show_status_page_banner %}
-
-
- Check our system status
- page to see if there are any known issues with Notify.gov.
-
-
- {% endif %}
- {% call form_wrapper() %}
- {{ textbox(form.feedback, width='1-1', hint='', rows=10, autosize=True) }}
- {% if not current_user.is_authenticated %}
- {{ form.name(param_extensions={"classes": ""}) }}
- {{ form.email_address(param_extensions={"classes": ""}) }}
- {% else %}
-
We’ll reply to {{ current_user.email_address }}
- {% endif %}
- {{ sticky_page_footer('Send') }}
- {% endcall %}
-
-
-
-{% endblock %}
diff --git a/app/templates/views/support/public.html b/app/templates/views/support/public.html
deleted file mode 100644
index 344d0961a..000000000
--- a/app/templates/views/support/public.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% extends "withoutnav_template.html" %}
-
-{% from "components/page-header.html" import page_header %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block per_page_title %}
- The Notify.gov service is for people who work in the government
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": url_for('.support') }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
-
-
-
-
- {{ page_header('The Notify.gov service is for people who work in the government') }}
-
-
- We cannot give advice to the public. We do not have access to information about you held by government departments.
-
-
-
- There are other pages on Notify.gov where you can get help:
-
-
-
-
- Find guidance and support.
-
-
-
- Ask about benefits, driving, transport, tax, and more.
-
-
-
- Advice on suspicious emails and text messages.
-
-
-
-
-{% endblock %}
diff --git a/app/templates/views/support/thanks.html b/app/templates/views/support/thanks.html
deleted file mode 100644
index f695b2d3b..000000000
--- a/app/templates/views/support/thanks.html
+++ /dev/null
@@ -1,38 +0,0 @@
-{% extends "withoutnav_template.html" %}
-{% from "components/page-footer.html" import page_footer %}
-{% from "components/page-header.html" import page_header %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block per_page_title %}
- Thanks for contacting us
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": url_for('.support') }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
-
- {{ page_header('Thanks for contacting us') }}
-
- {% if out_of_hours_emergency %}
- We’ll reply in the next 30 minutes.
- {% else %}
- {% if email_address_provided %}
- {% if out_of_hours %}
- We’ll reply within one working day.
- {% else %}
- We’ll aim to read your message in the next 30 minutes and we’ll reply within one
- working day.
- {% endif %}
- {% else %}
- {% if out_of_hours %}
- We’ll read your message when we’re back in the office.
- {% else %}
- We’ll aim to read your message in the next 30 minutes.
- {% endif %}
- {% endif %}
- {% endif %}
-
-
-{% endblock %}
diff --git a/app/templates/views/support/triage.html b/app/templates/views/support/triage.html
deleted file mode 100644
index 447e1a8e0..000000000
--- a/app/templates/views/support/triage.html
+++ /dev/null
@@ -1,62 +0,0 @@
-{% extends "withoutnav_template.html" %}
-{% from "components/page-footer.html" import page_footer %}
-{% from "components/page-header.html" import page_header %}
-{% from "components/form.html" import form_wrapper %}
-{% from "components/components/back-link/macro.njk" import usaBackLink %}
-
-{% block per_page_title %}
- {{ page_title }}
-{% endblock %}
-
-{% block backLink %}
- {{ usaBackLink({ "href": url_for('.support') }) }}
-{% endblock %}
-
-{% block maincolumn_content %}
-
-
-
- {{ page_header(page_title) }}
- {% call form_wrapper() %}
- {{ form.severe }}
- {{ page_footer('Continue') }}
- {% endcall %}
-
- It’s only an emergency if:
-
-
- -
- no one in your team can log in
-
- -
- you get a ‘technical difficulties’ error message when you try
- to upload a file
-
- -
- you get a 500 response code when you try to send messages
- using the API
-
-
-
- It’s not an emergency if:
-
-
- -
- all your messages stay in ‘sending’ for a few hours
-
- -
- you send the wrong message by accident
-
- -
- a team member uses Notify.gov to send an
- inappropriate message
-
- -
- your system is telling the Notify.gov API to send the wrong
- message
-
-
-
-
-
-{% endblock %}
diff --git a/app/templates/views/trial-mode.html b/app/templates/views/trial-mode.html
index 6c4d9b8db..72b37170d 100644
--- a/app/templates/views/trial-mode.html
+++ b/app/templates/views/trial-mode.html
@@ -17,7 +17,7 @@
{% if current_service and current_service.trial_mode %}
- To remove these restrictions, you can request to go live.
+ To remove these restrictions, you can request to go live.
{% else %}
To remove these restrictions:
@@ -38,6 +38,6 @@
update your settings so you’re ready to send and receive messages
accept our terms of use
-
+
{% endblock %}
diff --git a/app/url_converters.py b/app/url_converters.py
index 15d3f3b73..8c9500d36 100644
--- a/app/url_converters.py
+++ b/app/url_converters.py
@@ -1,10 +1,5 @@
from werkzeug.routing import BaseConverter
-from app.models.feedback import (
- GENERAL_TICKET_TYPE,
- PROBLEM_TICKET_TYPE,
- QUESTION_TICKET_TYPE,
-)
from app.models.service import Service
@@ -12,9 +7,5 @@ class TemplateTypeConverter(BaseConverter):
regex = "(?:{})".format("|".join(Service.TEMPLATE_TYPES))
-class TicketTypeConverter(BaseConverter):
- regex = f"(?:{PROBLEM_TICKET_TYPE}|{QUESTION_TICKET_TYPE}|{GENERAL_TICKET_TYPE})"
-
-
class SimpleDateTypeConverter(BaseConverter):
regex = r"([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))"
diff --git a/get_zendesk_tickets.py b/get_zendesk_tickets.py
deleted file mode 100644
index 6d32d484d..000000000
--- a/get_zendesk_tickets.py
+++ /dev/null
@@ -1,152 +0,0 @@
-"""
-This script can be used to retrieve Zendesk tickets.
-This can be run locally if you set the ZENDESK_API_KEY. Or the script can be run from a flask shell from a ssh session.
-"""
-# flake8: noqa: T001 (print)
-
-import csv
-import os
-import urllib.parse
-
-import requests
-
-# Group: 3rd Line--Notify Support
-NOTIFY_GROUP_ID = 360000036529
-
-# Organization: GDS
-NOTIFY_ORG_ID = 21891972
-
-# the account used to authenticate with. If no requester is provided, the ticket will come from this account.
-NOTIFY_ZENDESK_EMAIL = "zd-api-notify@digital.cabinet-office.gov.uk"
-ZENDESK_API_KEY = os.environ.get("ZENDESK_API_KEY")
-
-
-def get_tickets():
- ZENDESK_TICKET_URL = "https://govuk.zendesk.com/api/v2/search.json?query={}"
- query_params = "type:ticket group:{}".format(NOTIFY_GROUP_ID)
- query_params = urllib.parse.quote(query_params)
-
- next_page = ZENDESK_TICKET_URL.format(query_params)
-
- with open("zendesk_ticket_data.csv", "w") as csvfile:
- fieldnames = [
- "Service id",
- "Ticket id",
- "Subject line",
- "Date ticket created",
- "Tags",
- ]
- writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
- writer.writeheader()
- while next_page:
- print(next_page)
- response = requests.get(
- next_page,
- headers={"Content-type": "application/json"},
- auth=("{}/token".format(NOTIFY_ZENDESK_EMAIL), ZENDESK_API_KEY),
- )
- data = response.json()
- print(data)
- for row in data["results"]:
- service_url = [
- x
- for x in row["description"].split("\n")
- if x.startswith(
- "https://www.notifications.service.gov.uk/services/"
- )
- ]
- service_url = service_url[0][50:] if len(service_url) > 0 else None
- if service_url:
- writer.writerow(
- {
- "Service id": service_url,
- "Ticket id": row["id"],
- "Subject line": row["subject"],
- "Date ticket created": row["created_at"],
- "Tags": row.get("tags", ""),
- }
- )
- next_page = data["next_page"]
-
-
-def get_tickets_without_service_id():
- ZENDESK_TICKET_URL = "https://govuk.zendesk.com/api/v2/search.json?query={}"
- query_params = "type:ticket group:{}".format(NOTIFY_GROUP_ID)
- query_params = urllib.parse.quote(query_params)
-
- next_page = ZENDESK_TICKET_URL.format(query_params)
- with open("zendesk_ticket_data_without_service.csv", "w") as csvfile:
- fieldnames = [
- "Ticket id",
- "Subject line",
- "Date ticket created",
- "Tags",
- ]
- writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
- writer.writeheader()
- while next_page:
- print(next_page)
- response = requests.get(
- next_page,
- headers={"Content-type": "application/json"},
- auth=("{}/token".format(NOTIFY_ZENDESK_EMAIL), ZENDESK_API_KEY),
- )
- data = response.json()
- print(data)
- for row in data["results"]:
- service_url = [
- x
- for x in row["description"].split("\n")
- if x.startswith(
- "https://www.notifications.service.gov.uk/services/"
- )
- ]
- service_url = service_url[0][50:] if len(service_url) > 0 else None
- if not service_url:
- writer.writerow(
- {
- "Ticket id": row["id"],
- "Subject line": row["subject"],
- "Date ticket created": row["created_at"],
- "Tags": row.get("tags", ""),
- }
- )
- next_page = data["next_page"]
-
-
-def get_tickets_with_description():
- ZENDESK_TICKET_URL = "https://govuk.zendesk.com/api/v2/search.json?query={}"
- query_params = "type:ticket group:{}, created>2019-07-01".format(NOTIFY_GROUP_ID)
- query_params = urllib.parse.quote(query_params)
-
- next_page = ZENDESK_TICKET_URL.format(query_params)
- with open("zendesk_ticket.csv", "w") as csvfile:
- fieldnames = [
- "Ticket id",
- "Subject line",
- "Description",
- "Date ticket created",
- "Tags",
- ]
- writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
- writer.writeheader()
- while next_page:
- print(next_page)
- response = requests.get(
- next_page,
- headers={"Content-type": "application/json"},
- auth=("{}/token".format(NOTIFY_ZENDESK_EMAIL), ZENDESK_API_KEY),
- )
- data = response.json()
- print(data)
- for row in data["results"]:
- writer.writerow(
- {
- "Ticket id": row["id"],
- "Subject line": row["subject"],
- "Description": row["description"],
- "Date ticket created": row["created_at"],
- "Tags": row.get("tags", ""),
- }
- )
- next_page = data["next_page"]
diff --git a/tests/__init__.py b/tests/__init__.py
index bf6527147..0f2827511 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -222,7 +222,6 @@ def organization_json(
agreement_signed_on_behalf_of_name=None,
agreement_signed_on_behalf_of_email_address=None,
organization_type="federal",
- request_to_go_live_notes=None,
notes=None,
billing_contact_email_addresses=None,
billing_contact_names=None,
@@ -248,7 +247,6 @@ def organization_json(
"agreement_signed_on_behalf_of_name": agreement_signed_on_behalf_of_name,
"agreement_signed_on_behalf_of_email_address": agreement_signed_on_behalf_of_email_address,
"domains": domains or [],
- "request_to_go_live_notes": request_to_go_live_notes,
"count_of_live_services": len(services),
"notes": notes,
"billing_contact_email_addresses": billing_contact_email_addresses,
diff --git a/tests/app/main/views/organizations/test_organizations.py b/tests/app/main/views/organizations/test_organizations.py
index 440e8252a..7679e1429 100644
--- a/tests/app/main/views/organizations/test_organizations.py
+++ b/tests/app/main/views/organizations/test_organizations.py
@@ -928,7 +928,6 @@ def test_organization_settings_for_platform_admin(
"Label Value Action",
"Name Test organization Change organization name",
"Sector Federal government Change sector for the organization",
- "Request to go live notes None Change go live notes for the organization",
"Billing details None Change billing details for the organization",
"Notes None Change the notes for the organization",
"Known email domains None Change known email domains for the organization",
@@ -1346,48 +1345,6 @@ def test_update_organization_with_non_unique_name(
)
-def test_get_edit_organization_go_live_notes_page(
- client_request,
- platform_admin_user,
- mock_get_organization,
- organization_one,
-):
- client_request.login(platform_admin_user)
- page = client_request.get(
- ".edit_organization_go_live_notes",
- org_id=organization_one["id"],
- )
- assert page.find("textarea", id="request_to_go_live_notes")
-
-
-@pytest.mark.parametrize(
- ("input_note", "saved_note"),
- [("Needs permission", "Needs permission"), (" ", None)],
-)
-def test_post_edit_organization_go_live_notes_updates_go_live_notes(
- client_request,
- platform_admin_user,
- mock_get_organization,
- mock_update_organization,
- organization_one,
- input_note,
- saved_note,
-):
- client_request.login(platform_admin_user)
- client_request.post(
- ".edit_organization_go_live_notes",
- org_id=organization_one["id"],
- _data={"request_to_go_live_notes": input_note},
- _expected_redirect=url_for(
- ".organization_settings",
- org_id=organization_one["id"],
- ),
- )
- mock_update_organization.assert_called_once_with(
- organization_one["id"], request_to_go_live_notes=saved_note
- )
-
-
def test_organization_settings_links_to_edit_organization_notes_page(
mocker,
mock_get_organization,
diff --git a/tests/app/main/views/service_settings/test_service_settings.py b/tests/app/main/views/service_settings/test_service_settings.py
index 906dcc883..a36d2c0ff 100644
--- a/tests/app/main/views/service_settings/test_service_settings.py
+++ b/tests/app/main/views/service_settings/test_service_settings.py
@@ -1,18 +1,15 @@
-from datetime import datetime
from functools import partial
-from unittest.mock import ANY, Mock, PropertyMock, call
+from unittest.mock import Mock, PropertyMock, call
from uuid import uuid4
import pytest
from flask import url_for
from freezegun import freeze_time
from notifications_python_client.errors import HTTPError
-from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket
import app
from tests import (
find_element_by_tag_and_partial_text,
- invite_json,
organization_json,
sample_uuid,
service_json,
@@ -30,7 +27,6 @@ from tests.conftest import (
create_platform_admin_user,
create_reply_to_email_address,
create_sms_sender,
- create_template,
normalize_spaces,
)
@@ -119,39 +115,6 @@ def test_should_show_overview(
app.service_api_client.get_service.assert_called_with(SERVICE_ONE_ID)
-@pytest.mark.usefixtures("_mock_get_service_settings_page_common")
-def test_no_go_live_link_for_service_without_organization(
- client_request,
- mocker,
- no_reply_to_email_addresses,
- single_sms_sender,
- platform_admin_user,
-):
- mocker.patch("app.organizations_client.get_organization", return_value=None)
- client_request.login(platform_admin_user)
- page = client_request.get("main.service_settings", service_id=SERVICE_ONE_ID)
-
- assert page.find("h1").text == "Settings"
-
- is_live = find_element_by_tag_and_partial_text(page, tag="td", string="Live")
- assert (
- normalize_spaces(is_live.find_next_sibling().text)
- == "No (organization must be set first)"
- )
-
- organization = find_element_by_tag_and_partial_text(
- page, tag="td", string="Organization"
- )
- assert (
- normalize_spaces(organization.find_next_siblings()[0].text)
- == "Not set Federal government"
- )
- assert (
- normalize_spaces(organization.find_next_siblings()[1].text)
- == "Change organization for service"
- )
-
-
@pytest.mark.usefixtures("_mock_get_service_settings_page_common")
def test_organization_name_links_to_org_dashboard(
client_request,
@@ -584,1120 +547,12 @@ def test_should_redirect_after_service_name_change(
)
-@pytest.mark.parametrize(
- ("volumes", "consent_to_research", "expected_estimated_volumes_item"),
- [
- ((0, 0), None, "Tell us how many messages you expect to send Not completed"),
- ((1, 0), None, "Tell us how many messages you expect to send Not completed"),
- ((1, 0), False, "Tell us how many messages you expect to send Completed"),
- ((1, 0), True, "Tell us how many messages you expect to send Completed"),
- ((9, 99), True, "Tell us how many messages you expect to send Completed"),
- ],
-)
-def test_should_check_if_estimated_volumes_provided(
- client_request,
- mocker,
- single_sms_sender,
- single_reply_to_email_address,
- mock_get_service_templates,
- mock_get_users_by_service,
- mock_get_organization,
- mock_get_invites_for_service,
- volumes,
- consent_to_research,
- expected_estimated_volumes_item,
-):
- for volume, channel in zip(volumes, ("sms", "email")):
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=volume,
- )
-
- mocker.patch(
- "app.models.service.Service.consent_to_research",
- create=True,
- new_callable=PropertyMock,
- return_value=consent_to_research,
- )
-
- page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
- assert page.h1.text == "Before you request to go live"
-
- assert normalize_spaces(page.select_one(".task-list .task-list-item").text) == (
- expected_estimated_volumes_item
- )
-
-
-@pytest.mark.parametrize(
- (
- "volume_email",
- "count_of_email_templates",
- "reply_to_email_addresses",
- "expected_reply_to_checklist_item",
- ),
- [
- (None, 1, [], "Add a reply-to email address Not completed"),
- (None, 1, [{}], "Add a reply-to email address Completed"),
- (1, 1, [], "Add a reply-to email address Not completed"),
- (1, 1, [{}], "Add a reply-to email address Completed"),
- (1, 0, [], "Add a reply-to email address Not completed"),
- (1, 0, [{}], "Add a reply-to email address Completed"),
- ],
-)
-def test_should_check_for_reply_to_on_go_live(
- client_request,
- mocker,
- service_one,
- fake_uuid,
- single_sms_sender,
- volume_email,
- count_of_email_templates,
- reply_to_email_addresses,
- expected_reply_to_checklist_item,
- mock_get_invites_for_service,
- mock_get_users_by_service,
-):
- mocker.patch(
- "app.service_api_client.get_service_templates",
- return_value={
- "data": [
- create_template(template_type="email")
- for _ in range(0, count_of_email_templates)
- ]
- },
- )
-
- mock_get_reply_to_email_addresses = mocker.patch(
- "app.main.views.service_settings.service_api_client.get_reply_to_email_addresses",
- return_value=reply_to_email_addresses,
- )
-
- for channel, volume in (("email", volume_email), ("sms", 0)):
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=volume,
- )
-
- page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
- assert page.h1.text == "Before you request to go live"
-
- checklist_items = page.select(".task-list .task-list-item")
- assert normalize_spaces(checklist_items[3].text) == expected_reply_to_checklist_item
-
- if count_of_email_templates:
- mock_get_reply_to_email_addresses.assert_called_once_with(SERVICE_ONE_ID)
-
-
-@pytest.mark.parametrize(
- (
- "volume_email",
- "count_of_email_templates",
- "reply_to_email_addresses",
- "expected_reply_to_checklist_item",
- ),
- [
- (None, 0, [], ""),
- (0, 0, [], ""),
- ],
-)
-def test_should_check_for_reply_to_on_go_live_index_error(
- client_request,
- mocker,
- service_one,
- fake_uuid,
- single_sms_sender,
- volume_email,
- count_of_email_templates,
- reply_to_email_addresses,
- expected_reply_to_checklist_item,
- mock_get_invites_for_service,
- mock_get_users_by_service,
-):
- mocker.patch(
- "app.service_api_client.get_service_templates",
- return_value={
- "data": [
- create_template(template_type="email")
- for _ in range(0, count_of_email_templates)
- ]
- },
- )
-
- mocker.patch(
- "app.main.views.service_settings.service_api_client.get_reply_to_email_addresses",
- return_value=reply_to_email_addresses,
- )
-
- for channel, volume in (("email", volume_email), ("sms", 0)):
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=volume,
- )
-
- page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
- assert page.h1.text == "Before you request to go live"
- checklist_items = page.select(".task-list .task-list-item")
-
- with pytest.raises(expected_exception=IndexError):
- assert (
- normalize_spaces(checklist_items[3].text)
- == expected_reply_to_checklist_item
- )
-
-
-@pytest.mark.parametrize(
- (
- "count_of_users_with_manage_service",
- "count_of_invites_with_manage_service",
- "expected_user_checklist_item",
- ),
- [
- (
- 1,
- 0,
- "Add a team member who can manage settings, team and usage Not completed",
- ),
- (2, 0, "Add a team member who can manage settings, team and usage Completed"),
- (1, 1, "Add a team member who can manage settings, team and usage Completed"),
- ],
-)
-@pytest.mark.parametrize(
- ("count_of_templates", "expected_templates_checklist_item"),
- [
- (
- 0,
- "Add templates with examples of the content you plan to send Not completed",
- ),
- (1, "Add templates with examples of the content you plan to send Completed"),
- (2, "Add templates with examples of the content you plan to send Completed"),
- ],
-)
-def test_should_check_for_sending_things_right(
- client_request,
- mocker,
- service_one,
- fake_uuid,
- single_sms_sender,
- count_of_users_with_manage_service,
- count_of_invites_with_manage_service,
- expected_user_checklist_item,
- count_of_templates,
- expected_templates_checklist_item,
- active_user_with_permissions,
- active_user_no_settings_permission,
- single_reply_to_email_address,
-):
- mocker.patch(
- "app.service_api_client.get_service_templates",
- return_value={
- "data": [
- create_template(template_type="sms")
- for _ in range(0, count_of_templates)
- ]
- },
- )
-
- mock_get_users = mocker.patch(
- "app.models.user.Users.client_method",
- return_value=(
- [active_user_with_permissions] * count_of_users_with_manage_service
- + [active_user_no_settings_permission]
- ),
- )
- invite_one = invite_json(
- id_=uuid4(),
- from_user=service_one["users"][0],
- service_id=service_one["id"],
- email_address="invited_user@test.gsa.gov",
- permissions="view_activity,send_messages,manage_service,manage_api_keys",
- created_at=datetime.utcnow(),
- status="pending",
- auth_type="sms_auth",
- folder_permissions=[],
- )
-
- invite_two = invite_one.copy()
- invite_two["permissions"] = "view_activity"
-
- mock_get_invites = mocker.patch(
- "app.models.user.InvitedUsers.client_method",
- return_value=(
- ([invite_one] * count_of_invites_with_manage_service) + [invite_two]
- ),
- )
-
- page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
- assert page.h1.text == "Before you request to go live"
-
- checklist_items = page.select(".task-list .task-list-item")
- assert normalize_spaces(checklist_items[1].text) == expected_user_checklist_item
- assert (
- normalize_spaces(checklist_items[2].text) == expected_templates_checklist_item
- )
-
- mock_get_users.assert_called_once_with(SERVICE_ONE_ID)
- mock_get_invites.assert_called_once_with(SERVICE_ONE_ID)
-
-
-@pytest.mark.parametrize(
- ("checklist_completed", "expected_button"),
- [
- (True, True),
- (False, False),
- ],
-)
-def test_should_not_show_go_live_button_if_checklist_not_complete(
- client_request,
- mocker,
- mock_get_service_templates,
- mock_get_users_by_service,
- mock_get_service_organization,
- mock_get_invites_for_service,
- single_sms_sender,
- checklist_completed,
- expected_button,
-):
- mocker.patch(
- "app.models.service.Service.go_live_checklist_completed",
- new_callable=PropertyMock,
- return_value=checklist_completed,
- )
-
- for channel in ("email", "sms"):
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=0,
- )
-
- page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
- assert page.h1.text == "Before you request to go live"
-
- if expected_button:
- assert page.select_one("form")["method"] == "post"
- assert "action" not in page.select_one("form")
- assert normalize_spaces(page.select("main p")[0].text) == (
- "When we receive your request we’ll get back to you within one working day."
- )
- assert normalize_spaces(page.select("main p")[1].text) == (
- "By requesting to go live you’re agreeing to our terms of use."
- )
- assert page.select_one("main [type=submit]").text.strip() == (
- "Request to go live"
- )
- else:
- assert not page.select("form")
- assert not page.select("main [type=submit]")
- assert len(page.select("main p")) == 1
- assert normalize_spaces(page.select_one("main p").text) == (
- "You must complete these steps before you can request to go live."
- )
-
-
-@pytest.mark.parametrize(
- ("go_live_at", "message"),
- [
- (None, "‘service one’ is already live."),
- ("2020-10-09 13:55:20", "‘service one’ went live on 9 October 2020."),
- ],
-)
-def test_request_to_go_live_redirects_if_service_already_live(
- client_request,
- service_one,
- go_live_at,
- message,
-):
- service_one["restricted"] = False
- service_one["go_live_at"] = go_live_at
-
- page = client_request.get(
- "main.request_to_go_live",
- service_id=SERVICE_ONE_ID,
- )
-
- assert page.h1.text == "Your service is already live"
- assert normalize_spaces(page.select_one("main p").text) == message
-
-
-@pytest.mark.parametrize(
- (
- "estimated_sms_volume",
- "organization_type",
- "count_of_sms_templates",
- "sms_senders",
- "expected_sms_sender_checklist_item",
- ),
- [
- (
- 0,
- "state",
- 0,
- [],
- "",
- ),
- (
- None,
- "state",
- 0,
- [{"is_default": True, "sms_sender": "GOVUK"}],
- "",
- ),
- (
- None,
- "federal",
- 99,
- [{"is_default": True, "sms_sender": "GOVUK"}],
- "",
- ),
- (
- 1,
- "federal",
- 99,
- [{"is_default": True, "sms_sender": "GOVUK"}],
- "",
- ),
- (
- 1,
- "state",
- 1,
- [],
- "Change your text message sender name Not completed",
- ),
- (
- 1,
- "state",
- 1,
- [
- {"is_default": False, "sms_sender": "GOVUK"},
- {"is_default": True, "sms_sender": "KUVOG"},
- ],
- "Change your text message sender name Completed",
- ),
- ],
-)
-def test_should_check_for_sms_sender_on_go_live(
- client_request,
- service_one,
- mocker,
- mock_get_organization,
- mock_get_invites_for_service,
- organization_type,
- count_of_sms_templates,
- sms_senders,
- expected_sms_sender_checklist_item,
- estimated_sms_volume,
-):
- service_one["organization_type"] = organization_type
-
- mocker.patch(
- "app.service_api_client.get_service_templates",
- return_value={
- "data": [
- create_template(template_type="sms")
- for _ in range(0, count_of_sms_templates)
- ]
- },
- )
-
- mocker.patch(
- "app.models.service.Service.has_team_members",
- return_value=True,
- )
-
- mock_get_sms_senders = mocker.patch(
- "app.main.views.service_settings.service_api_client.get_sms_senders",
- return_value=sms_senders,
- )
-
- for channel, volume in (("email", 0), ("sms", estimated_sms_volume)):
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=volume,
- )
-
- with pytest.raises(expected_exception=IndexError):
- simple_statement_for_test_should_check_for_sms_sender_on_go_live(
- client_request, expected_sms_sender_checklist_item, mock_get_sms_senders
- )
-
-
-def simple_statement_for_test_should_check_for_sms_sender_on_go_live(
- client_request, expected_sms_sender_checklist_item, mock_get_sms_senders
-):
- page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
- assert page.h1.text == "Before you request to go live"
- checklist_items = page.select(".task-list .task-list-item")
-
- assert (
- normalize_spaces(checklist_items[3].text) == expected_sms_sender_checklist_item
- )
-
- mock_get_sms_senders.assert_called_once_with(SERVICE_ONE_ID)
-
-
-def test_non_gov_user_is_told_they_cant_go_live(
- client_request,
- api_nongov_user_active,
- mock_get_invites_for_service,
- mocker,
- mock_get_organizations,
- mock_get_organization,
-):
- mocker.patch(
- "app.models.service.Service.has_team_members",
- return_value=False,
- )
- mocker.patch(
- "app.models.service.Service.all_templates",
- new_callable=PropertyMock,
- return_value=[],
- )
- mocker.patch(
- "app.main.views.service_settings.service_api_client.get_sms_senders",
- return_value=[],
- )
- mocker.patch(
- "app.main.views.service_settings.service_api_client.get_reply_to_email_addresses",
- return_value=[],
- )
- client_request.login(api_nongov_user_active)
- page = client_request.get("main.request_to_go_live", service_id=SERVICE_ONE_ID)
- assert normalize_spaces(page.select_one("main p").text) == (
- "Only team members with a government email address can request to go live."
- )
- assert len(page.select("main form")) == 0
- assert len(page.select("main button")) == 0
-
-
-@pytest.mark.parametrize(
- ("consent_to_research", "displayed_consent"),
- [
- (None, None),
- (True, "yes"),
- (False, "no"),
- ],
-)
-@pytest.mark.parametrize(
- ("volumes", "displayed_volumes"),
- [
- (
- (("email", None), ("sms", None)),
- (None, None),
- ),
- (
- (("email", 1234), ("sms", 0)),
- ("1,234", "0"),
- ),
- ],
-)
-def test_should_show_estimate_volumes(
- mocker,
- client_request,
- volumes,
- displayed_volumes,
- consent_to_research,
- displayed_consent,
-):
- for channel, volume in volumes:
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=volume,
- )
- mocker.patch(
- "app.models.service.Service.consent_to_research",
- create=True,
- new_callable=PropertyMock,
- return_value=consent_to_research,
- )
- page = client_request.get("main.estimate_usage", service_id=SERVICE_ONE_ID)
- assert page.h1.text == "Tell us how many messages you expect to send"
- for channel, label, hint, value in (
- (
- "email",
- "How many emails do you expect to send in the next year?",
- "For example, 50,000",
- displayed_volumes[0],
- ),
- (
- "sms",
- "How many text messages do you expect to send in the next year?",
- "For example, 50,000",
- displayed_volumes[1],
- ),
- ):
- assert (
- normalize_spaces(
- page.select_one("label[for=volume_{}]".format(channel)).text
- )
- == label
- )
- assert (
- normalize_spaces(page.select_one("#volume_{}-hint".format(channel)).text)
- == hint
- )
- assert page.select_one("#volume_{}".format(channel)).get("value") == value
-
- assert len(page.select("input[type=radio]")) == 2
-
- if displayed_consent is None:
- assert len(page.select("input[checked]")) == 0
- else:
- assert len(page.select("input[checked]")) == 1
- assert page.select_one("input[checked]")["value"] == displayed_consent
-
-
-@pytest.mark.parametrize(
- ("consent_to_research", "expected_persisted_consent_to_research"),
- [
- ("yes", True),
- ("no", False),
- ],
-)
-def test_should_show_persist_estimated_volumes(
- client_request,
- mock_update_service,
- consent_to_research,
- expected_persisted_consent_to_research,
-):
- client_request.post(
- "main.estimate_usage",
- service_id=SERVICE_ONE_ID,
- _data={
- "volume_email": "1,234,567",
- "volume_sms": "",
- "consent_to_research": consent_to_research,
- },
- _expected_status=302,
- _expected_redirect=url_for(
- "main.request_to_go_live",
- service_id=SERVICE_ONE_ID,
- ),
- )
- mock_update_service.assert_called_once_with(
- SERVICE_ONE_ID,
- volume_email=1234567,
- volume_sms=0,
- consent_to_research=expected_persisted_consent_to_research,
- )
-
-
-@pytest.mark.parametrize(
- ("data", "error_selector", "expected_error_message"),
- [
- (
- {
- "volume_email": "1234",
- "volume_sms": "2000000001",
- "consent_to_research": "yes",
- },
- "#volume_sms-error",
- "Number of text messages must be 2,000,000,000 or less",
- ),
- (
- {
- "volume_email": "1 234",
- "volume_sms": "0",
- "consent_to_research": "",
- },
- '[data-error-label="consent_to_research"]',
- "Select yes or no",
- ),
- ],
-)
-def test_should_error_if_bad_estimations_given(
- client_request,
- mock_update_service,
- data,
- error_selector,
- expected_error_message,
-):
- page = client_request.post(
- "main.estimate_usage",
- service_id=SERVICE_ONE_ID,
- _data=data,
- _expected_status=200,
- )
- assert expected_error_message in page.select_one(error_selector).text
- assert mock_update_service.called is False
-
-
-def test_should_error_if_all_volumes_zero(
- client_request,
- mock_update_service,
-):
- page = client_request.post(
- "main.estimate_usage",
- service_id=SERVICE_ONE_ID,
- _data={
- "volume_email": "",
- "volume_sms": "0",
- "consent_to_research": "yes",
- },
- _expected_status=200,
- )
- assert page.select("input[type=text]")[0].get("value") is None
- assert page.select("input[type=text]")[1]["value"] == "0"
- assert normalize_spaces(page.select_one(".banner-dangerous").text) == (
- "Enter the number of messages you expect to send in the next year"
- )
- assert mock_update_service.called is False
-
-
-def test_should_not_default_to_zero_if_some_fields_dont_validate(
- client_request,
- mock_update_service,
-):
- page = client_request.post(
- "main.estimate_usage",
- service_id=SERVICE_ONE_ID,
- _data={
- "volume_email": "aaaaaaaaaaaaa",
- "volume_sms": "",
- "consent_to_research": "yes",
- },
- _expected_status=200,
- )
- assert page.select("input[type=text]")[0]["value"] == "aaaaaaaaaaaaa"
- assert page.select("input[type=text]")[1].get("value") is None
- assert (
- normalize_spaces(page.select_one("#volume_email-error").text)
- == "Error: Enter the number of emails you expect to send"
- )
- assert mock_update_service.called is False
-
-
-def test_non_gov_users_cant_request_to_go_live(
- client_request,
- api_nongov_user_active,
- mock_get_organizations,
-):
- client_request.login(api_nongov_user_active)
- client_request.post(
- "main.request_to_go_live",
- service_id=SERVICE_ONE_ID,
- _expected_status=403,
- )
-
-
-@pytest.mark.usefixtures("_mock_get_service_settings_page_common")
-@pytest.mark.parametrize(
- ("volumes", "displayed_volumes", "formatted_displayed_volumes"),
- [
- (
- (("email", None), ("sms", None)),
- ", ",
- ("Emails in next year: \n" "Text messages in next year: \n"),
- ),
- (
- (("email", 1234), ("sms", 0)),
- "0, 1234", # This is a different order to match the spreadsheet
- ("Emails in next year: 1,234\n" "Text messages in next year: 0\n"),
- ),
- ],
-)
-@freeze_time("2012-12-21 13:12:12.12354")
-def test_should_redirect_after_request_to_go_live(
- client_request,
- mocker,
- active_user_with_permissions,
- single_reply_to_email_address,
- mock_get_organizations_and_services_for_user,
- single_sms_sender,
- mock_get_service_templates,
- mock_get_users_by_service,
- mock_update_service,
- mock_get_invites_without_manage_permission,
- volumes,
- displayed_volumes,
- formatted_displayed_volumes,
-):
- for channel, volume in volumes:
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=volume,
- )
- mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
- mock_send_ticket_to_zendesk = mocker.patch(
- "app.main.views.service_settings.zendesk_client.send_ticket_to_zendesk",
- autospec=True,
- )
- page = client_request.post(
- "main.request_to_go_live", service_id=SERVICE_ONE_ID, _follow_redirects=True
- )
-
- expected_message = (
- "Service: service one\n"
- "http://localhost/services/{service_id}\n"
- "\n"
- "---\n"
- "Organization type: Federal government (domain is user.gsa.gov).\n"
- "\n"
- "{formatted_displayed_volumes}"
- "\n"
- "Consent to research: Yes\n"
- "Other live services for that user: No\n"
- "\n"
- "Service reply-to address: test@example.com\n"
- "\n"
- "---\n"
- "Request sent by test@user.gsa.gov\n"
- "Requester’s user page: http://localhost/users/{user_id}\n"
- ).format(
- service_id=SERVICE_ONE_ID,
- formatted_displayed_volumes=formatted_displayed_volumes,
- user_id=active_user_with_permissions["id"],
- )
- mock_create_ticket.assert_called_once_with(
- ANY,
- subject="Request to go live - service one",
- message=expected_message,
- ticket_type="question",
- user_name=active_user_with_permissions["name"],
- user_email=active_user_with_permissions["email_address"],
- requester_sees_message_content=False,
- org_id=None,
- org_type="federal",
- service_id=SERVICE_ONE_ID,
- )
- mock_send_ticket_to_zendesk.assert_called_once()
-
- assert normalize_spaces(page.select_one(".banner-default").text) == (
- "Thanks for your request to go live. We’ll get back to you within one working day."
- )
- assert normalize_spaces(page.select_one("h1").text) == ("Settings")
- mock_update_service.assert_called_once_with(
- SERVICE_ONE_ID, go_live_user=active_user_with_permissions["id"]
- )
-
-
-@pytest.mark.usefixtures("_mock_get_service_settings_page_common")
-def test_request_to_go_live_displays_go_live_notes_in_zendesk_ticket(
- client_request,
- mocker,
- active_user_with_permissions,
- single_reply_to_email_address,
- mock_get_organizations_and_services_for_user,
- single_sms_sender,
- mock_get_service_organization,
- mock_get_service_templates,
- mock_get_users_by_service,
- mock_update_service,
- mock_get_invites_without_manage_permission,
-):
- go_live_note = "This service is not allowed to go live"
-
- mocker.patch(
- "app.organizations_client.get_organization",
- side_effect=lambda org_id: organization_json(
- ORGANISATION_ID,
- "Org 1",
- request_to_go_live_notes=go_live_note,
- ),
- )
- mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
- mock_send_ticket_to_zendesk = mocker.patch(
- "app.main.views.service_settings.zendesk_client.send_ticket_to_zendesk",
- autospec=True,
- )
- client_request.post(
- "main.request_to_go_live", service_id=SERVICE_ONE_ID, _follow_redirects=True
- )
-
- expected_message = (
- "Service: service one\n"
- "http://localhost/services/{service_id}\n"
- "\n"
- "---\n"
- "Organization type: Federal government (organization is Org 1). {go_live_note}\n"
- "\n"
- "Emails in next year: 111,111\n"
- "Text messages in next year: 222,222\n"
- "\n"
- "Consent to research: Yes\n"
- "Other live services for that user: No\n"
- "\n"
- "Service reply-to address: test@example.com\n"
- "\n"
- "---\n"
- "Request sent by test@user.gsa.gov\n"
- "Requester’s user page: http://localhost/users/{user_id}\n"
- ).format(
- service_id=SERVICE_ONE_ID,
- go_live_note=go_live_note,
- user_id=active_user_with_permissions["id"],
- )
-
- mock_create_ticket.assert_called_once_with(
- ANY,
- subject="Request to go live - service one",
- message=expected_message,
- ticket_type="question",
- user_name=active_user_with_permissions["name"],
- user_email=active_user_with_permissions["email_address"],
- requester_sees_message_content=False,
- org_id=ORGANISATION_ID,
- org_type="federal",
- service_id=SERVICE_ONE_ID,
- )
- mock_send_ticket_to_zendesk.assert_called_once()
-
-
-@pytest.mark.usefixtures("_mock_get_service_settings_page_common")
-def test_request_to_go_live_displays_mou_signatories(
- client_request,
- mocker,
- fake_uuid,
- active_user_with_permissions,
- single_reply_to_email_address,
- mock_get_organizations_and_services_for_user,
- single_sms_sender,
- mock_get_service_organization,
- mock_get_service_templates,
- mock_get_users_by_service,
- mock_update_service,
- mock_get_invites_without_manage_permission,
-):
- mocker.patch(
- "app.organizations_client.get_organization",
- side_effect=lambda org_id: organization_json(
- ORGANISATION_ID,
- "Org 1",
- agreement_signed=True,
- agreement_signed_by_id=fake_uuid,
- agreement_signed_on_behalf_of_email_address="bigdog@example.gsa.gov",
- ),
- )
- mocker.patch(
- "app.main.views.service_settings.zendesk_client.send_ticket_to_zendesk",
- autospec=True,
- )
- mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
- client_request.post(
- "main.request_to_go_live", service_id=SERVICE_ONE_ID, _follow_redirects=True
- )
-
- assert ("Organization type: Federal government") in mock_create_ticket.call_args[1][
- "message"
- ]
-
- assert ("Emails in next year: 111,111\n") in mock_create_ticket.call_args[1][
- "message"
- ]
-
-
-@pytest.mark.usefixtures("_mock_get_service_settings_page_common")
-def test_should_be_able_to_request_to_go_live_with_no_organization(
- client_request,
- mocker,
- single_reply_to_email_address,
- mock_get_organizations_and_services_for_user,
- single_sms_sender,
- mock_get_service_templates,
- mock_get_users_by_service,
- mock_update_service,
- mock_get_invites_without_manage_permission,
-):
- for channel in {"email", "sms"}:
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=1,
- )
- mock_post = mocker.patch(
- "app.main.views.service_settings.zendesk_client.send_ticket_to_zendesk",
- autospec=True,
- )
-
- client_request.post(
- "main.request_to_go_live", service_id=SERVICE_ONE_ID, _follow_redirects=True
- )
-
- assert mock_post.called is True
-
-
-@pytest.mark.parametrize(
- (
- "has_team_members",
- "has_templates",
- "has_email_templates",
- "has_sms_templates",
- "has_email_reply_to_address",
- "shouldnt_use_govuk_as_sms_sender",
- "sms_sender_is_govuk",
- "volume_email",
- "volume_sms",
- "expected_readyness",
- "agreement_signed",
- ),
- [
- ( # Just sending email
- True,
- True,
- True,
- False,
- True,
- True,
- True,
- 1,
- 0,
- "Yes",
- True,
- ),
- ( # Needs to set reply to address
- True,
- True,
- True,
- False,
- False,
- True,
- True,
- 1,
- 0,
- "No",
- True,
- ),
- ( # Just sending SMS
- True,
- True,
- False,
- True,
- True,
- True,
- False,
- 0,
- 1,
- "Yes",
- True,
- ),
- ( # Needs to change SMS sender
- True,
- True,
- False,
- True,
- True,
- True,
- True,
- 0,
- 1,
- "No",
- True,
- ),
- ( # Needs team members
- False,
- True,
- False,
- True,
- True,
- True,
- False,
- 1,
- 0,
- "No",
- True,
- ),
- ( # Needs templates
- True,
- False,
- False,
- True,
- True,
- True,
- False,
- 0,
- 1,
- "No",
- True,
- ),
- ( # Not done anything yet
- False,
- False,
- False,
- False,
- False,
- False,
- True,
- None,
- None,
- "No",
- False,
- ),
- ],
-)
-def test_ready_to_go_live(
- client_request,
- mocker,
- mock_get_service_organization,
- has_team_members,
- has_templates,
- has_email_templates,
- has_sms_templates,
- has_email_reply_to_address,
- shouldnt_use_govuk_as_sms_sender,
- sms_sender_is_govuk,
- volume_email,
- volume_sms,
- expected_readyness,
- agreement_signed,
-):
- mocker.patch(
- "app.organizations_client.get_organization",
- return_value=organization_json(agreement_signed=agreement_signed),
- )
-
- for prop in {
- "has_team_members",
- "has_templates",
- "has_email_templates",
- "has_sms_templates",
- "has_email_reply_to_address",
- "shouldnt_use_govuk_as_sms_sender",
- "sms_sender_is_govuk",
- }:
- mocker.patch(
- "app.models.service.Service.{}".format(prop), new_callable=PropertyMock
- ).return_value = locals()[prop]
-
- for channel, volume in (
- ("sms", volume_sms),
- ("email", volume_email),
- ):
- mocker.patch(
- "app.models.service.Service.volume_{}".format(channel),
- create=True,
- new_callable=PropertyMock,
- return_value=volume,
- )
-
- assert (
- app.models.service.Service(
- {"id": SERVICE_ONE_ID}
- ).go_live_checklist_completed_as_yes_no
- == expected_readyness
- )
-
-
@pytest.mark.usefixtures("_mock_get_service_settings_page_common")
@pytest.mark.parametrize(
"route",
[
"main.service_settings",
"main.service_name_change",
- "main.request_to_go_live",
- "main.submit_request_to_go_live",
"main.archive_service",
],
)
@@ -1731,8 +586,6 @@ def test_route_permissions(
[
"main.service_settings",
"main.service_name_change",
- "main.request_to_go_live",
- "main.submit_request_to_go_live",
"main.service_switch_live",
"main.archive_service",
],
@@ -1765,8 +618,6 @@ def test_route_invalid_permissions(
[
"main.service_settings",
"main.service_name_change",
- "main.request_to_go_live",
- "main.submit_request_to_go_live",
],
)
def test_route_for_platform_admin(
diff --git a/tests/app/main/views/test_feedback.py b/tests/app/main/views/test_feedback.py
index e3ab37e93..633ad54c4 100644
--- a/tests/app/main/views/test_feedback.py
+++ b/tests/app/main/views/test_feedback.py
@@ -1,812 +1,15 @@
-from functools import partial
-from unittest.mock import ANY, PropertyMock
-
-import pytest
-from flask import url_for
from freezegun import freeze_time
-from notifications_utils.clients.zendesk.zendesk_client import NotifySupportTicket
-from app.main.views.feedback import in_business_hours
-from app.models.feedback import (
- GENERAL_TICKET_TYPE,
- PROBLEM_TICKET_TYPE,
- QUESTION_TICKET_TYPE,
-)
-from tests.conftest import SERVICE_ONE_ID, normalize_spaces
-
-
-def no_redirect():
- return lambda: None
-
-
-@pytest.mark.skip(reason="Not currently using Zendesk")
-def test_get_support_index_page(
- client_request,
-):
- 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"
- )
-
-
-@pytest.mark.skip(reason="Not currently using Zendesk")
-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 or text messages"
- )
- 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"
- )
-
-
-@freeze_time("2016-12-12 12:00:00.000000")
-@pytest.mark.parametrize(
- ("support_type", "expected_h1"),
- [
- (PROBLEM_TICKET_TYPE, "Report a problem"),
- (QUESTION_TICKET_TYPE, "Ask a question or give feedback"),
- ],
-)
-def test_choose_support_type(
- client_request,
- mock_get_non_empty_organizations_and_services_for_user,
- support_type,
- expected_h1,
-):
- page = client_request.post(
- "main.support",
- _data={"support_type": support_type},
- _follow_redirects=True,
- )
- assert page.h1.string.strip() == expected_h1
- 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.gsa.gov"
- )
+from tests.conftest import normalize_spaces
@freeze_time("2016-12-12 12:00:00.000000")
def test_get_support_as_someone_in_the_public_sector(
+ mocker,
+ active_user_with_permissions,
client_request,
):
- client_request.logout()
- page = client_request.post(
+ page = client_request.get(
"main.support",
- _data={"who": "public-sector"},
- _follow_redirects=True,
)
- assert normalize_spaces(page.select("h1")) == ("Contact Notify.gov support")
- 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 Notify.gov 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]")
-
-
-@freeze_time("2016-12-12 12:00:00.000000")
-@pytest.mark.parametrize(
- ("ticket_type", "expected_status_code"),
- [(PROBLEM_TICKET_TYPE, 200), (QUESTION_TICKET_TYPE, 200), ("gripe", 404)],
-)
-def test_get_feedback_page(client_request, ticket_type, expected_status_code):
- client_request.logout()
- client_request.get(
- "main.feedback",
- ticket_type=ticket_type,
- _expected_status=expected_status_code,
- )
-
-
-@freeze_time("2016-12-12 12:00:00.000000")
-@pytest.mark.parametrize(
- ("ticket_type", "zendesk_ticket_type"),
- [
- (PROBLEM_TICKET_TYPE, "incident"),
- (QUESTION_TICKET_TYPE, "question"),
- (GENERAL_TICKET_TYPE, "question"),
- ],
-)
-def test_passed_non_logged_in_user_details_through_flow(
- client_request, mocker, ticket_type, zendesk_ticket_type
-):
- client_request.logout()
- mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
- mock_send_ticket_to_zendesk = mocker.patch(
- "app.main.views.feedback.zendesk_client.send_ticket_to_zendesk",
- autospec=True,
- )
-
- data = {
- "feedback": "blah",
- "name": "Anne Example",
- "email_address": "anne@example.com",
- }
-
- client_request.post(
- "main.feedback",
- ticket_type=ticket_type,
- _data=data,
- _expected_redirect=url_for(
- "main.thanks",
- out_of_hours_emergency=False,
- email_address_provided=True,
- ),
- )
-
- mock_create_ticket.assert_called_once_with(
- ANY,
- subject="Notify feedback",
- message="blah\n",
- ticket_type=zendesk_ticket_type,
- p1=False,
- user_name="Anne Example",
- user_email="anne@example.com",
- org_id=None,
- org_type=None,
- service_id=None,
- )
- mock_send_ticket_to_zendesk.assert_called_once()
-
-
-@freeze_time("2016-12-12 12:00:00.000000")
-@pytest.mark.parametrize(
- "data",
- [
- {"feedback": "blah"},
- {"feedback": "blah", "name": "Ignored", "email_address": "ignored@email.com"},
- ],
-)
-@pytest.mark.parametrize(
- ("ticket_type", "zendesk_ticket_type"),
- [
- (PROBLEM_TICKET_TYPE, "incident"),
- (QUESTION_TICKET_TYPE, "question"),
- (GENERAL_TICKET_TYPE, "question"),
- ],
-)
-def test_passes_user_details_through_flow(
- client_request,
- mock_get_non_empty_organizations_and_services_for_user,
- mocker,
- ticket_type,
- zendesk_ticket_type,
- data,
-):
- mock_create_ticket = mocker.spy(NotifySupportTicket, "__init__")
- mock_send_ticket_to_zendesk = mocker.patch(
- "app.main.views.feedback.zendesk_client.send_ticket_to_zendesk",
- autospec=True,
- )
-
- client_request.post(
- "main.feedback",
- ticket_type=ticket_type,
- _data=data,
- _expected_status=302,
- _expected_redirect=url_for(
- "main.thanks",
- email_address_provided=True,
- out_of_hours_emergency=False,
- ),
- )
- mock_create_ticket.assert_called_once_with(
- ANY,
- subject="Notify feedback",
- message=ANY,
- ticket_type=zendesk_ticket_type,
- p1=False,
- user_name="Test User",
- user_email="test@user.gsa.gov",
- org_id=None,
- org_type="federal",
- service_id=SERVICE_ONE_ID,
- )
-
- assert mock_create_ticket.call_args[1]["message"] == "\n".join(
- [
- "blah",
- 'Service: "service one"',
- url_for(
- "main.service_dashboard",
- service_id=SERVICE_ONE_ID,
- _external=True,
- ),
- "",
- ]
- )
- mock_send_ticket_to_zendesk.assert_called_once()
-
-
-@freeze_time("2016-12-12 12:00:00.000000")
-@pytest.mark.parametrize(
- "data",
- [
- {"feedback": "blah", "name": "Fred"},
- {"feedback": "blah"},
- ],
-)
-@pytest.mark.parametrize(
- "ticket_type",
- [
- PROBLEM_TICKET_TYPE,
- QUESTION_TICKET_TYPE,
- ],
-)
-def test_email_address_required_for_problems_and_questions(
- client_request,
- mocker,
- data,
- ticket_type,
-):
- mocker.patch("app.main.views.feedback.zendesk_client")
- client_request.logout()
- page = client_request.post(
- "main.feedback", ticket_type=ticket_type, _data=data, _expected_status=200
- )
- assert normalize_spaces(page.select_one(".usa-error-message").text) == (
- "Error: Cannot be empty"
- )
-
-
-@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_request,
- mocker,
- ticket_type,
-):
- client_request.logout()
- page = client_request.post(
- "main.feedback",
- ticket_type=ticket_type,
- _data={
- "feedback": "blah",
- "email_address": "not valid",
- },
- _expected_status=200,
- )
-
- assert normalize_spaces(page.select_one("span.usa-error-message").text) == (
- "Error: Enter a valid email address"
- )
-
-
-@pytest.mark.parametrize(
- ("ticket_type", "severe", "is_in_business_hours", "is_out_of_hours_emergency"),
- [
- # 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),
- # out of hours, if the user says it’s not an emergency
- (PROBLEM_TICKET_TYPE, "no", False, False),
- (QUESTION_TICKET_TYPE, "no", False, False),
- # out of hours, only problems can be emergencies
- (PROBLEM_TICKET_TYPE, "yes", False, True),
- (QUESTION_TICKET_TYPE, "yes", False, False),
- ],
-)
-def test_urgency(
- client_request,
- mock_get_non_empty_organizations_and_services_for_user,
- mocker,
- ticket_type,
- severe,
- is_in_business_hours,
- is_out_of_hours_emergency,
-):
- mocker.patch(
- "app.main.views.feedback.in_business_hours", return_value=is_in_business_hours
- )
-
- mock_ticket = mocker.patch("app.main.views.feedback.NotifySupportTicket")
- mocker.patch(
- "app.main.views.feedback.zendesk_client.send_ticket_to_zendesk",
- autospec=True,
- )
-
- 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",
- out_of_hours_emergency=is_out_of_hours_emergency,
- email_address_provided=True,
- ),
- )
- assert mock_ticket.call_args[1]["p1"] == is_out_of_hours_emergency
-
-
-ids, params = zip(
- *[
- (
- "non-logged in users always have to triage",
- (
- GENERAL_TICKET_TYPE,
- False,
- False,
- True,
- 302,
- partial(url_for, "main.triage", ticket_type=GENERAL_TICKET_TYPE),
- ),
- ),
- (
- "trial services are never high priority",
- (PROBLEM_TICKET_TYPE, False, True, False, 200, no_redirect()),
- ),
- (
- "we can triage in hours",
- (PROBLEM_TICKET_TYPE, True, True, True, 200, no_redirect()),
- ),
- (
- "only problems are high priority",
- (QUESTION_TICKET_TYPE, False, True, True, 200, no_redirect()),
- ),
- (
- "should triage out of hours",
- (
- PROBLEM_TICKET_TYPE,
- False,
- True,
- True,
- 302,
- partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
- ),
- ),
- ]
-)
-
-
-@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_request,
- 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.models.user.User.live_services",
- new_callable=PropertyMock,
- return_value=[{}, {}] if has_live_services else [],
- )
- mocker.patch(
- "app.main.views.feedback.in_business_hours", return_value=is_in_business_hours
- )
- if not logged_in:
- client_request.logout()
-
- client_request.get(
- "main.feedback",
- ticket_type=ticket_type,
- _expected_status=expected_status,
- _expected_redirect=expected_redirect(),
- )
-
-
-@pytest.mark.parametrize(
- ("ticket_type", "expected_h1"),
- [
- (PROBLEM_TICKET_TYPE, "Report a problem"),
- (GENERAL_TICKET_TYPE, "Contact Notify.gov 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"
-
-
-def test_doesnt_lose_message_if_post_across_closing(
- client_request,
- mocker,
-):
- mocker.patch("app.models.user.User.live_services", return_value=True)
- mocker.patch("app.main.views.feedback.in_business_hours", return_value=False)
-
- page = client_request.post(
- "main.feedback",
- ticket_type=PROBLEM_TICKET_TYPE,
- _data={"feedback": "foo"},
- _expected_status=302,
- _expected_redirect=url_for(".triage", ticket_type=PROBLEM_TICKET_TYPE),
- )
- with client_request.session_transaction() as session:
- assert session["feedback_message"] == "foo"
-
- page = client_request.get(
- "main.feedback",
- ticket_type=PROBLEM_TICKET_TYPE,
- severe="yes",
- )
-
- with client_request.session_transaction() as session:
- assert page.find("textarea", {"name": "feedback"}).text == "\r\nfoo"
- assert "feedback_message" not in session
-
-
-@pytest.mark.parametrize(
- ("when", "is_in_business_hours"),
- [
- ("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 12:00:00+0000", True), # middle of the day
- ("2016-12-12 17:29:59+0000", True), # closing time
- ("2016-12-12 17:30:00+0000", False),
- ("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
- ],
-)
-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(
- "ticket_type",
- [
- GENERAL_TICKET_TYPE,
- PROBLEM_TICKET_TYPE,
- ],
-)
-@pytest.mark.parametrize(
- ("choice", "expected_redirect_param"),
- [
- ("yes", "yes"),
- ("no", "no"),
- ],
-)
-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,
- ),
- )
-
-
-@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"}, partial(url_for, "main.support")), # hacking the URL
- ({}, partial(url_for, "main.support")),
- ],
-)
-@freeze_time("2012-12-12 12:12")
-def test_back_link_from_form(
- client_request,
- mock_get_non_empty_organizations_and_services_for_user,
- extra_args,
- expected_back_link,
-):
- page = client_request.get(
- "main.feedback", ticket_type=PROBLEM_TICKET_TYPE, **extra_args
- )
- assert page.select_one(".usa-back-link")["href"] == expected_back_link()
- assert normalize_spaces(page.select_one("h1").text) == "Report a problem"
-
-
-@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", ticket_type=PROBLEM_TICKET_TYPE),
- 302,
- partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
- ),
- # User hasn’t answered the triage question
- (
- False,
- None,
- 302,
- partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
- 302,
- partial(url_for, "main.triage", ticket_type=PROBLEM_TICKET_TYPE),
- ),
- # Escalation is needed for non-logged-in users
- (
- False,
- "yes",
- 302,
- partial(url_for, "main.bat_phone"),
- 200,
- no_redirect(),
- ),
- ],
-)
-def test_should_be_shown_the_bat_email(
- client_request,
- active_user_with_permissions,
- mocker,
- service_one,
- mock_get_non_empty_organizations_and_services_for_user,
- is_in_business_hours,
- 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=is_in_business_hours
- )
-
- feedback_page = url_for(
- "main.feedback", ticket_type=PROBLEM_TICKET_TYPE, severe=severe
- )
-
- client_request.logout()
- client_request.get_url(
- feedback_page,
- _expected_status=expected_status_code,
- _expected_redirect=expected_redirect(),
- )
-
- # logged in users should never be redirected to the bat email page
- client_request.login(active_user_with_permissions)
- client_request.get_url(
- feedback_page,
- _expected_status=expected_status_code_when_logged_in,
- _expected_redirect=expected_redirect_when_logged_in(),
- )
-
-
-@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_request,
- active_user_with_permissions,
- mocker,
- service_one,
- mock_get_non_empty_organizations_and_services_for_user,
- 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
- )
-
- client_request.logout()
- client_request.get_url(
- feedback_page,
- _expected_status=expected_status_code,
- _expected_redirect=expected_redirect(),
- )
-
- # logged in users should never be redirected to the bat email page
- client_request.login(active_user_with_permissions)
- client_request.get_url(
- feedback_page,
- _expected_status=expected_status_code_when_logged_in,
- _expected_redirect=expected_redirect_when_logged_in(),
- )
-
-
-def test_bat_email_page(
- client_request,
- active_user_with_permissions,
- mocker,
- service_one,
-):
- bat_phone_page = "main.bat_phone"
-
- client_request.logout()
- page = client_request.get(bat_phone_page)
-
- assert page.select_one(".usa-back-link").text == "Back"
- assert page.select_one(".usa-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 = client_request.get_url(page.select("main a")[1]["href"])
- assert next_page.h1.text.strip() == "Report a problem"
-
- client_request.login(active_user_with_permissions)
- client_request.get(
- bat_phone_page,
- _expected_redirect=url_for("main.feedback", ticket_type=PROBLEM_TICKET_TYPE),
- )
-
-
-@pytest.mark.parametrize(
- ("out_of_hours_emergency", "email_address_provided", "out_of_hours", "message"),
- [
- # 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.",
- ),
- # Anonymous tickets don’t promise a reply
- (
- False,
- False,
- False,
- "We’ll aim to read your message in the next 30 minutes.",
- ),
- (
- False,
- False,
- True,
- "We’ll read your message when we’re back in the office.",
- ),
- # When we look at your ticket depends on whether we’re in normal
- # business hours
- (
- False,
- True,
- False,
- "We’ll aim to read your message in the next 30 minutes and we’ll reply within one working day.",
- ),
- (False, True, True, "We’ll reply within one working day."),
- ],
-)
-def test_thanks(
- client_request,
- mocker,
- api_user_active,
- mock_get_user,
- out_of_hours_emergency,
- email_address_provided,
- out_of_hours,
- message,
-):
- 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
+ assert normalize_spaces(page.select("h1")) == ("Contact us")
diff --git a/tests/app/main/views/test_index.py b/tests/app/main/views/test_index.py
index ac55aed4f..315ef635a 100644
--- a/tests/app/main/views/test_index.py
+++ b/tests/app/main/views/test_index.py
@@ -65,14 +65,6 @@ def test_robots(client_request):
("endpoint", "kwargs"),
[
("sign_in", {}),
- ("support", {}),
- ("support_public", {}),
- ("triage", {}),
- ("feedback", {"ticket_type": "ask-question-give-feedback"}),
- ("feedback", {"ticket_type": "general"}),
- ("feedback", {"ticket_type": "report-problem"}),
- ("bat_phone", {}),
- ("thanks", {}),
("register", {}),
pytest.param("index", {}, marks=pytest.mark.xfail(raises=AssertionError)),
],
diff --git a/tests/app/models/test_user.py b/tests/app/models/test_user.py
index 4611d5ea6..8c4c26907 100644
--- a/tests/app/models/test_user.py
+++ b/tests/app/models/test_user.py
@@ -10,7 +10,6 @@ def test_anonymous_user(notify_admin):
assert AnonymousUser().default_organization.name is None
assert AnonymousUser().default_organization.domains == []
assert AnonymousUser().default_organization.organization_type is None
- assert AnonymousUser().default_organization.request_to_go_live_notes is None
def test_user(notify_admin):
diff --git a/tests/app/test_navigation.py b/tests/app/test_navigation.py
index 2f890d7b3..6005599cf 100644
--- a/tests/app/test_navigation.py
+++ b/tests/app/test_navigation.py
@@ -31,7 +31,6 @@ EXCLUDED_ENDPOINTS = tuple(
"api_keys",
"archive_service",
"archive_user",
- "bat_phone",
"begin_tour",
"billing_details",
"callbacks",
@@ -73,7 +72,6 @@ EXCLUDED_ENDPOINTS = tuple(
"edit_data_retention",
"edit_organization_billing_details",
"edit_organization_domains",
- "edit_organization_go_live_notes",
"edit_organization_name",
"edit_organization_notes",
"edit_organization_type",
@@ -86,10 +84,8 @@ EXCLUDED_ENDPOINTS = tuple(
"edit_user_permissions",
"email_not_received",
"error",
- "estimate_usage",
"features",
"features_sms",
- "feedback",
"find_services_by_name",
"find_users_by_email",
"forgot_password",
@@ -153,7 +149,6 @@ EXCLUDED_ENDPOINTS = tuple(
"registration_continue",
"remove_user_from_organization",
"remove_user_from_service",
- "request_to_go_live",
"resend_email_link",
"resend_email_verification",
"resume_service",
@@ -205,16 +200,12 @@ EXCLUDED_ENDPOINTS = tuple(
"sign_in",
"sign_out",
"start_job",
- "submit_request_to_go_live",
"support",
- "support_public",
"suspend_service",
"template_history",
"template_usage",
"terms",
- "thanks",
"tour_step",
- "triage",
"trial_mode",
"trial_mode_new",
"trial_services",