Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LGA-2803 - Add maintenance page #27

Merged
merged 9 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on: workflow_call

env:
SECRET_KEY: "TEST_KEY"
ENVIRONMENT: CI


jobs:
Expand All @@ -23,12 +24,17 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements/generated/requirements-development.txt
- name: Unit test with pytest
run: |
# Remove this after we move from build assets in-app to esbuild
npm install
pip install pytest pytest-cov
# This is required because at the moment the assets are being built in the app
# When the app tries to access sass files in node_modules it will fail unless this is included
npm install
coverage run -m pytest tests/unit_tests
coverage xml
Expand Down
1 change: 1 addition & 0 deletions app/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ class Config(object):
SESSION_COOKIE_HTTPONLY = True
SENTRY_DSN = os.environ.get("SENTRY_DSN")
LANGUAGES = {"en": "English", "cy": "Welsh"}
SERVICE_UNAVAILABLE = os.environ.get("MAINTENANCE_MODE", "False").lower() == "true"
32 changes: 32 additions & 0 deletions app/main/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
render_template,
request,
current_app,
url_for,
abort,
)
from flask_wtf.csrf import CSRFError
Expand Down Expand Up @@ -46,6 +47,18 @@ def set_locale(locale):
return response


@bp.route("/status", methods=["GET"])
def status():
return "OK"


@bp.route("/service-unavailable", methods=["GET"])
def service_unavailable_page():
if not current_app.config["SERVICE_UNAVAILABLE"]:
return redirect(url_for("main.index"))
abort(503)


@bp.route("/accessibility", methods=["GET"])
def accessibility():
return render_template("accessibility.html")
Expand Down Expand Up @@ -100,3 +113,22 @@ def http_exception(error):
def csrf_error(error):
flash("The form you were submitting has expired. Please try again.")
return redirect(request.full_path)


@bp.before_request
def service_unavailable_middleware():
if not current_app.config["SERVICE_UNAVAILABLE"]:
return

service_unavailable_url = url_for("main.service_unavailable_page")
exempt_urls = [
service_unavailable_url,
url_for("main.status"),
url_for("main.cookies"),
url_for("main.accessibility"),
url_for("main.privacy"),
url_for("main.set_locale", locale="en"),
url_for("main.set_locale", locale="cy"),
]
if request.path not in exempt_urls:
return redirect(service_unavailable_url)
28 changes: 24 additions & 4 deletions app/templates/main/503.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
{% extends "base.html" %}

{% block pageTitle %}Sorry, the service is unavailable – {{config['SERVICE_NAME']}} – GOV.UK{% endblock %}
{% block pageTitle %}{% trans %}Sorry, the service is unavailable{% endtrans %} – {{ config.SERVICE_NAME }} – GOV.UK{% endblock %}

{% set mainClasses = "govuk-main-wrapper--l" %}

{% block content %}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-l">Sorry, the service is unavailable</h1>
<p class="govuk-body">You will be able to use the service from 9am on Monday 19&nbsp;November&nbsp;2018.</p>
<h1 class="govuk-heading-l">{% trans %}Sorry, the service is unavailable{% endtrans%}</h1>
<p class="govuk-body">{% trans %}The service will be available again soon - try in the next hour.{% endtrans%}</p>

<p class="govuk-body">{% trans %}If you already started using the service, your answers will not be saved.{% endtrans%}</p>
<h2 class="govuk-heading-m">{% trans %}If you need urgent help{% endtrans%}</h2>
<p class="govuk-body">{% trans %}Contact the Civil Legal Advice (CLA) helpline.{% endtrans%}</p>
<p class="govuk-body">
{% trans %}Telephone{% endtrans%}: 0345 345 4345 <br />
<a class="govuk-link--no-underline" href="https://www.relayuk.bt.com/">{% trans %}Relay UK{% endtrans%}</a> {% trans %}(textphone and app): 18001 then 0345 345 4345{% endtrans%}
</p>
<p class="govuk-body">
{% trans %}Monday to Friday, 9am to 8pm{% endtrans%} <br />
{% trans %}Saturday, 9am to 12:30pm{% endtrans%} <br />
<a class="govuk-link--no-underline" href="https://www.gov.uk/call-charges">{% trans %}Find out about call charges{% endtrans%}</a>
</p>
<p class="govuk-body">
{% trans %}If you’re worried about the cost of a call{% endtrans%}:
<ul class="govuk-list govuk-list--bullet">
<li>{% trans %}ask the helpline to call you back, or{% endtrans%}</li>
<li>{% trans %}text ‘legalaid’ and your name to 80010 for a call back within 24 hours{% endtrans %}</li>
</ul>
</p>
</div>
</div>
{% endblock %}
{% endblock %}
1 change: 1 addition & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ services:
restart: always
environment:
- SECRET_KEY=CHANGE_ME
- MAINTENANCE_MODE=FALSE
- FLASK_RUN_PORT=8020
- SENTRY_DSN=${SENTRY_DSN:-}
ports:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ spec:
protocol: TCP
livenessProbe:
httpGet:
path: /
path: /status
port: http
readinessProbe:
httpGet:
path: /
path: /status
port: http
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ metadata:
labels:
{{- include "laa-access-civil-legal-aid.labels" . | nindent 4 }}
annotations:
nginx.ingress.kubernetes.io/custom-http-errors: "413,502,504"
{{- if .Values.ingress.cluster.name }}
external-dns.alpha.kubernetes.io/set-identifier: "{{ $fullName }}-{{ .Release.Namespace }}-{{- .Values.ingress.cluster.name -}}"
external-dns.alpha.kubernetes.io/aws-weight: "{{- .Values.ingress.cluster.weight -}}"
Expand Down
7 changes: 6 additions & 1 deletion helm_deploy/laa-access-civil-legal-aid/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,9 @@ envVars:
SENTRY_DSN:
secret:
name: sentry
key: dsn
key: dsn
MAINTENANCE_MODE:
configmap:
name: maintenance-mode
key: enabled
optional: true
5 changes: 4 additions & 1 deletion tests/functional_tests/test_accessibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from axe_core_python.sync_playwright import Axe
import json
import os
import shutil


ACCESSIBILITY_STANDARDS = ["wcag2a", "wcag2aa"]

Expand Down Expand Up @@ -45,7 +47,8 @@ def check_accessibility(page: Page):

@pytest.mark.usefixtures("live_server")
def test_all_page_accessibility(app, page: Page):
ignored_routes = ["static", "/", "main.set_locale"]
ignored_routes = ["static", "/", "main.status", "main.set_locale"]
shutil.rmtree("tests/functional_tests/accessibility_output", ignore_errors=True)
routes = app.view_functions
for route in routes:
if route not in ignored_routes:
Expand Down
4 changes: 0 additions & 4 deletions tests/unit_tests/test_example.py

This file was deleted.

17 changes: 17 additions & 0 deletions tests/unit_tests/test_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,20 @@ def test_set_locale(app, client):
def test_set_locale_invalid(app, client):
response = client.get("/locale/de", headers={"referer": "http://localhost/privacy"})
assert response.status_code == 404, f"Expecting 404 got {response.status_code}"


def test_service_unavailable_on(app, client):
app.config["SERVICE_UNAVAILABLE"] = True
response = client.get("/")
assert response.status_code == 302
assert response.headers["location"] == "/service-unavailable"
response = client.get("/", follow_redirects=True)
assert response.status_code == 503
assert response.request.path == "/service-unavailable"


def test_service_unavailable_off(app, client):
app.config["SERVICE_UNAVAILABLE"] = False
response = client.get("/service-unavailable", follow_redirects=True)
assert response.status_code == 200
assert response.request.path == "/"
Loading