Skip to content

Commit f72a9a9

Browse files
Align environment banner with Mavis
The Environment helper now matches Mavis's HostingEnvironment module by moving the warning sentence to the template and returning just the environment name from title_in_sentence. Also use the newly added SENTRY_ENVIRONMENT.
1 parent c996dd6 commit f72a9a9

File tree

8 files changed

+141
-89
lines changed

8 files changed

+141
-89
lines changed

mavis/reporting/__init__.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from werkzeug.exceptions import Unauthorized
77

88
from mavis.reporting.helpers import mavis_helper, url_helper
9-
from mavis.reporting.helpers.environment_helper import EnvType
109
from mavis.reporting.jinja2_config import configure_jinja2
1110

1211
if dsn := os.environ.get("SENTRY_DSN"):
@@ -43,7 +42,6 @@ def create_app(config_name=None):
4342
app.config["SECRET_KEY"] = os.environ["SECRET_KEY"]
4443

4544
app.config["DEBUG"] = False
46-
app.config["ENVIRONMENT"] = EnvType.PROD
4745
app.config["LOG_LEVEL"] = "INFO"
4846
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 31536000
4947
app.config["SESSION_TTL_SECONDS"] = 600
@@ -52,16 +50,12 @@ def create_app(config_name=None):
5250

5351
if config_name == "development":
5452
app.config["DEBUG"] = True
55-
app.config["ENVIRONMENT"] = EnvType.DEV
5653
app.config["LOG_LEVEL"] = "DEBUG"
5754
app.config["MAVIS_BACKEND_URL"] = os.environ["MAVIS_BACKEND_URL"]
5855
elif config_name == "test":
5956
app.config["DEBUG"] = True
60-
app.config["ENVIRONMENT"] = EnvType.TEST
6157
app.config["LOG_LEVEL"] = "DEBUG"
6258
app.config["TESTING"] = True
63-
elif config_name == "staging":
64-
app.config["ENVIRONMENT"] = EnvType.STAGING
6559

6660
configure_jinja2(app)
6761

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,49 @@
1-
from enum import Enum
2-
3-
4-
class EnvType(Enum):
5-
PROD = "production"
6-
DEV = "development"
7-
REVIEW = "review"
8-
STAGING = "staging"
9-
TEST = "test"
10-
QA = "qa"
11-
PREVIEW = "preview"
12-
13-
def __str__(self):
14-
return str(self.value)
15-
16-
17-
ENV_COLOUR = {
18-
EnvType.PROD: "blue",
19-
EnvType.DEV: "white",
20-
EnvType.REVIEW: "purple",
21-
EnvType.STAGING: "purple",
22-
EnvType.TEST: "red",
23-
EnvType.QA: "orange",
24-
EnvType.PREVIEW: "yellow",
1+
import os
2+
3+
ENVIRONMENT_COLOUR = {
4+
"production": "blue",
5+
"development": "white",
6+
"review": "purple",
7+
"test": "red",
8+
"qa": "orange",
9+
"preview": "yellow",
2510
}
2611

12+
ENVIRONMENT_THEME_COLOUR = {
13+
"production": "#005eb8",
14+
"development": "#fff",
15+
"review": "#d6cce3",
16+
"test": "#f7d4d1",
17+
"qa": "#ffdc8e",
18+
"preview": "#fff59d",
19+
}
20+
21+
22+
class HostingEnvironment:
23+
@classmethod
24+
def name(cls) -> str:
25+
return os.environ["SENTRY_ENVIRONMENT"]
2726

28-
class Environment:
29-
def __init__(self, type: EnvType):
30-
self.type = type
27+
@classmethod
28+
def colour(cls) -> str:
29+
return ENVIRONMENT_COLOUR.get(cls.name(), "white")
3130

32-
def is_production(self):
33-
return self.type == EnvType.PROD
31+
@classmethod
32+
def theme_colour(cls) -> str:
33+
return ENVIRONMENT_THEME_COLOUR.get(cls.name(), "#fff")
3434

35-
@property
36-
def colour(self):
37-
return ENV_COLOUR[self.type]
35+
@classmethod
36+
def title(cls) -> str:
37+
if cls.name() == "qa":
38+
return "QA"
39+
return cls.name().capitalize()
3840

39-
@property
40-
def title(self):
41-
return str(self.type).capitalize()
41+
@classmethod
42+
def title_in_sentence(cls) -> str:
43+
if cls.name() == "qa":
44+
return "QA"
45+
return cls.name()
4246

43-
@property
44-
def title_in_sentence(self):
45-
return (
46-
f"This is a {self.type} environment."
47-
+ " Do not use it to make clinical decisions."
48-
)
47+
@classmethod
48+
def is_production(cls) -> bool:
49+
return cls.name() == "production"

mavis/reporting/templates/components/environment.jinja

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"classes": "nhsuk-tag--" + params.colour,
88
"text": params.title,
99
}) }}
10-
<span>{{ params.title_in_sentence | safe }}</span>
10+
<span>This is a {{ params.title_in_sentence }} environment. Do not use it to make clinical decisions.</span>
1111
</div>
1212
</div>
1313
{% endmacro %}

mavis/reporting/templates/layouts/base.jinja

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717

1818
{% block header %}
1919
{{ environment({
20-
"colour": app_environment.colour,
21-
"title": app_environment.title,
22-
"title_in_sentence": app_environment.title_in_sentence,
20+
"colour": app_environment.colour(),
21+
"title": app_environment.title(),
22+
"title_in_sentence": app_environment.title_in_sentence(),
2323
}) if not app_environment.is_production() }}
2424

2525
{{ header({

mavis/reporting/views.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
get_current_academic_year_range,
2424
get_last_updated_time,
2525
)
26-
from mavis.reporting.helpers.environment_helper import Environment
26+
from mavis.reporting.helpers.environment_helper import HostingEnvironment
2727
from mavis.reporting.helpers.navigation_helper import build_navigation_items
2828
from mavis.reporting.helpers.secondary_nav_helper import generate_secondary_nav_items
2929
from mavis.reporting.models.team import Team
@@ -41,11 +41,9 @@ def stub_mavis_data():
4141
@main.context_processor
4242
def inject_mavis_data():
4343
"""Inject common data into the template context."""
44-
env = Environment(current_app.config["ENVIRONMENT"])
45-
4644
return {
4745
"app_title": "Manage vaccinations in schools",
48-
"app_environment": env,
46+
"app_environment": HostingEnvironment,
4947
"navigation_items": build_navigation_items(request),
5048
"service_guide_url": "https://guide.manage-vaccinations-in-schools.nhs.uk",
5149
}

mise.development.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ SOPS_AGE_KEY_FILE = "{{vars.secret_file}}"
1111
_.file = "{{vars.credentials_file}}"
1212

1313
FLASK_ENV = "development"
14+
SENTRY_ENVIRONMENT = "development"
1415
MAVIS_BACKEND_URL = "http://localhost:4000"
1516
MAVIS_ROOT_URL = "http://localhost:4001/"
1617
ROOT_URL = "http://localhost:{{vars.port}}/"

mise.staging.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ SOPS_AGE_KEY_FILE = "{{vars.secret_file}}"
1111
_.file = "{{vars.credentials_file}}"
1212

1313
FLASK_ENV = "staging"
14+
# SENTRY_ENVIRONMENT = "configured by terraform/app/variables.tf in the mavis repo"
1415
MAVIS_ROOT_URL = "http://web:4000/"
1516
# ROOT_URL = "configured by terraform/app/variables.tf in the mavis repo"
Lines changed: 91 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,94 @@
1-
from mavis.reporting.helpers.environment_helper import (
2-
Environment,
3-
EnvType,
4-
)
1+
import pytest
52

3+
from mavis.reporting.helpers.environment_helper import HostingEnvironment
64

7-
def test_environment_is_production_behaviour():
5+
6+
def test_name_reads_from_sentry_environment(monkeypatch):
7+
"""Test that name reads from SENTRY_ENVIRONMENT env var."""
8+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "qa")
9+
assert HostingEnvironment.name() == "qa"
10+
11+
12+
def test_name_raises_when_sentry_environment_not_set(monkeypatch):
13+
"""Test that name raises KeyError when SENTRY_ENVIRONMENT is not set."""
14+
monkeypatch.delenv("SENTRY_ENVIRONMENT", raising=False)
15+
with pytest.raises(KeyError):
16+
HostingEnvironment.name()
17+
18+
19+
def test_is_production_behaviour(monkeypatch):
820
"""Test that is_production behaves correctly for different environments."""
9-
assert Environment(EnvType.PROD).is_production() is True
10-
assert Environment(EnvType.DEV).is_production() is False
11-
assert Environment(EnvType.STAGING).is_production() is False
12-
assert Environment(EnvType.TEST).is_production() is False
13-
14-
15-
def test_environment_colour_property():
16-
"""Test that colour property returns correct color for each environment."""
17-
assert Environment(EnvType.PROD).colour == "blue"
18-
assert Environment(EnvType.DEV).colour == "white"
19-
assert Environment(EnvType.STAGING).colour == "purple"
20-
assert Environment(EnvType.TEST).colour == "red"
21-
22-
23-
def test_environment_title_property():
24-
"""Test that title property returns capitalized environment type."""
25-
assert Environment(EnvType.PROD).title == "Production"
26-
assert Environment(EnvType.DEV).title == "Development"
27-
assert Environment(EnvType.STAGING).title == "Staging"
28-
29-
30-
def test_environment_title_in_sentence_property():
31-
"""Test that title_in_sentence property returns correct warning message."""
32-
title_in_sentence = Environment(EnvType.DEV).title_in_sentence
33-
assert (
34-
title_in_sentence
35-
== "This is a development environment."
36-
+ " Do not use it to make clinical decisions."
37-
)
21+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "production")
22+
assert HostingEnvironment.is_production() is True
23+
24+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "development")
25+
assert HostingEnvironment.is_production() is False
26+
27+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "qa")
28+
assert HostingEnvironment.is_production() is False
29+
30+
31+
def test_colour(monkeypatch):
32+
"""Test that colour returns correct color for each environment."""
33+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "production")
34+
assert HostingEnvironment.colour() == "blue"
35+
36+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "development")
37+
assert HostingEnvironment.colour() == "white"
38+
39+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "qa")
40+
assert HostingEnvironment.colour() == "orange"
41+
42+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "test")
43+
assert HostingEnvironment.colour() == "red"
44+
45+
46+
def test_colour_defaults_to_white_for_unknown(monkeypatch):
47+
"""Test that colour defaults to white for unknown environments."""
48+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "unknown")
49+
assert HostingEnvironment.colour() == "white"
50+
51+
52+
def test_title(monkeypatch):
53+
"""Test that title returns capitalized environment name."""
54+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "production")
55+
assert HostingEnvironment.title() == "Production"
56+
57+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "development")
58+
assert HostingEnvironment.title() == "Development"
59+
60+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "qa")
61+
assert HostingEnvironment.title() == "QA"
62+
63+
64+
def test_title_in_sentence(monkeypatch):
65+
"""Test that title_in_sentence returns the environment name for sentences."""
66+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "development")
67+
assert HostingEnvironment.title_in_sentence() == "development"
68+
69+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "qa")
70+
assert HostingEnvironment.title_in_sentence() == "QA"
71+
72+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "production")
73+
assert HostingEnvironment.title_in_sentence() == "production"
74+
75+
76+
def test_theme_colour(monkeypatch):
77+
"""Test that theme_colour returns correct hex colour for each environment."""
78+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "production")
79+
assert HostingEnvironment.theme_colour() == "#005eb8"
80+
81+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "development")
82+
assert HostingEnvironment.theme_colour() == "#fff"
83+
84+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "qa")
85+
assert HostingEnvironment.theme_colour() == "#ffdc8e"
86+
87+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "test")
88+
assert HostingEnvironment.theme_colour() == "#f7d4d1"
89+
90+
91+
def test_theme_colour_defaults_for_unknown(monkeypatch):
92+
"""Test that theme_colour defaults to white for unknown environments."""
93+
monkeypatch.setenv("SENTRY_ENVIRONMENT", "unknown")
94+
assert HostingEnvironment.theme_colour() == "#fff"

0 commit comments

Comments
 (0)