Skip to content

Commit b9b9493

Browse files
wip
1 parent 24013cf commit b9b9493

File tree

8 files changed

+98
-35
lines changed

8 files changed

+98
-35
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
"Licence",
1111
"organisation",
1212
"pytest",
13+
"pytestmark",
14+
"retcode",
15+
"ruleset",
1316
"utilise",
1417
"utilised",
1518
"Utilising"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import pytest
2+
from utils.nhs_number_tools import NHSNumberTools, NHSNumberToolsException
3+
4+
5+
pytestmark = [pytest.mark.utils]
6+
7+
def test_nhs_number_checks() -> None:
8+
assert NHSNumberTools._nhs_number_checks("1234567890") == None
9+
10+
with pytest.raises(Exception, match=r'The NHS number provided \(A234567890\) is not numeric.'):
11+
NHSNumberTools._nhs_number_checks("A234567890")
12+
13+
with pytest.raises(NHSNumberToolsException, match=r'The NHS number provided \(123\) is not 10 digits'):
14+
NHSNumberTools._nhs_number_checks("123")
15+
16+
def test_spaced_nhs_number() -> None:
17+
assert NHSNumberTools.spaced_nhs_number("1234567890") == "123 456 7890"
18+
assert NHSNumberTools.spaced_nhs_number(3216549870) == "321 654 9870"
19+
20+
if __name__ == "__main__":
21+
retcode = pytest.main(["-m", "utils"])

tests_utils/test_user_tools.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import pytest
2+
from utils.user_tools import UserTools, UserToolsException
3+
4+
5+
pytestmark = [pytest.mark.utils]
6+
7+
def test_nhs_number_checks() -> None:
8+
assert UserTools().retrieve_user("Example User 1")

users.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
{
2-
"Example User": {
1+
{
2+
"_comment": "This file can be used to store data on users for your application, and then pulled through using the utils.user_tools UserTools utility. The documentation for this utility explains how this file is read.",
3+
"Example User 1": {
34
"username": "EXAMPLE_USER1",
4-
"roles": "Example Role A"
5+
"roles": ["Example Role A"]
56
},
67
"Example User 2": {
78
"username": "EXAMPLE_USER2",
8-
"roles": "Example Role B"
9+
"roles": ["Example Role B", "Example Role C"]
910
}
1011
}

utils/axe.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pathlib import Path
77

88

9+
logger = logging.getLogger(__name__)
910
AXE_PATH = Path(__file__).parent / "resources" / "axe.js"
1011
PATH_FOR_REPORT = Path(__file__).parent.parent / "axe-reports"
1112
DEFAULT_WCAG_RULESET = ['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa', 'wcag22a', 'wcag22aa', 'best-practice']
@@ -36,13 +37,16 @@ def run(page: Page,
3637
strict_mode (bool): [Optional] If true, raise an exception if a violation is detected. If false (default), proceed with test execution.
3738
html_report_generated (bool): [Optional] If true (default), generates a html report for the page scanned. If false, no html report is generated.
3839
json_report_generated (bool): [Optional] If true (default), generates a json report for the page scanned. If false, no json report is generated.
40+
41+
Returns:
42+
dict: A Python dictionary with the axe-core output of the page scanned.
3943
"""
4044

4145
page.evaluate(AXE_PATH.read_text(encoding="UTF-8"))
4246

4347
response = page.evaluate("axe." + Axe._build_run_command(ruleset) + ".then(results => {return results;})")
4448

45-
logging.info(f"""Axe scan summary of [{response["url"]}]: Passes = {len(response["passes"])},
49+
logger.info(f"""Axe scan summary of [{response["url"]}]: Passes = {len(response["passes"])},
4650
Violations = {len(response["violations"])}, Inapplicable = {len(response["inapplicable"])},
4751
Incomplete = {len(response["incomplete"])}""")
4852

@@ -81,6 +85,9 @@ def run_list(page: Page,
8185
strict_mode (bool): [Optional] If true, raise an exception if a violation is detected. If false (default), proceed with test execution.
8286
html_report_generated (bool): [Optional] If true (default), generates a html report for the page scanned. If false, no html report is generated.
8387
json_report_generated (bool): [Optional] If true (default), generates a json report for the page scanned. If false, no json report is generated.
88+
89+
Returns:
90+
dict: A Python dictionary with the axe-core output of all the pages scanned, with the page list used as the key for each report.
8491
"""
8592
results = {}
8693
for selected_page in page_list:
@@ -120,24 +127,24 @@ def _create_path_for_report(filename: str) -> Path:
120127
return PATH_FOR_REPORT / filename
121128

122129
@staticmethod
123-
def _create_json_report(data: dict, filename_overide: str = "") -> None:
124-
filename = f"{Axe._modify_filename_for_report(data["url"])}.json" if filename_overide == "" else f"{filename_overide}.json"
130+
def _create_json_report(data: dict, filename_override: str = "") -> None:
131+
filename = f"{Axe._modify_filename_for_report(data["url"])}.json" if filename_override == "" else f"{filename_override}.json"
125132
full_path = Axe._create_path_for_report(filename)
126133

127134
with open(full_path, 'w') as file:
128135
file.writelines(json.dumps(data))
129136

130-
logging.info(f"JSON report generated: {full_path}")
137+
logger.info(f"JSON report generated: {full_path}")
131138

132139
@staticmethod
133-
def _create_html_report(data: dict, filename_overide: str = "") -> None:
134-
filename = f"{Axe._modify_filename_for_report(data["url"])}.html" if filename_overide == "" else f"{filename_overide}.html"
140+
def _create_html_report(data: dict, filename_override: str = "") -> None:
141+
filename = f"{Axe._modify_filename_for_report(data["url"])}.html" if filename_override == "" else f"{filename_override}.html"
135142
full_path = Axe._create_path_for_report(filename)
136143

137144
with open(full_path, 'w') as file:
138145
file.writelines(Axe._generate_html(data))
139146

140-
logging.info(f"HTML report generated: {full_path}")
147+
logger.info(f"HTML report generated: {full_path}")
141148

142149
@staticmethod
143150
def _generate_html(data: dict) -> str:

utils/date_time_utils.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33

44
class DateTimeUtils:
5+
"""
6+
A utility class for doing common actions with datetimes.
7+
"""
8+
59
def __init__(self):
610
pass
711

@@ -13,8 +17,7 @@ def current_datetime(format_date: str = "%d/%m/%Y %H:%M") -> str:
1317
format_date (str): [Optional] The format to return the current datetime in. Defaults to dd/mm/yyyy hh:mm if not provided.
1418
1519
Returns:
16-
current_date (str): The current datetime in the specified format.
17-
20+
str: The current datetime in the specified format.
1821
"""
1922
return datetime.now().strftime(format_date)
2023

@@ -27,9 +30,8 @@ def format_date(date: datetime, format_date: str = "%d/%m/%Y") -> str:
2730
format_date (str): [Optional] The format to return the datetime in. Defaults to dd/mm/yyyy if not provided.
2831
2932
Returns:
30-
format_date (str): The formatted date in the specified format.
31-
32-
"""
33+
str: The formatted date in the specified format.
34+
"""
3335
return date.strftime(format_date)
3436

3537
@staticmethod
@@ -41,9 +43,8 @@ def add_days(date: datetime, days: float) -> datetime:
4143
days (float): The number of days to add to the specified date.
4244
4345
Returns:
44-
new_date (datetime): The specified date plus the number of specified days (year, month, day, hour, minute, second, microsecond).
45-
46-
"""
46+
datetime: The specified date plus the number of specified days (year, month, day, hour, minute, second, microsecond).
47+
"""
4748
return date + timedelta(days=days)
4849

4950
@staticmethod
@@ -54,9 +55,8 @@ def get_day_of_week_for_today(date: datetime) -> str:
5455
date (datetime): The current date using the now function
5556
5657
Returns:
57-
day_of_week (str): The day of the week relating to the specified date.
58-
59-
"""
58+
str: The day of the week relating to the specified date.
59+
"""
6060
return date.strftime("%A")
6161

6262
@staticmethod
@@ -67,7 +67,6 @@ def get_a_day_of_week(date: datetime) -> str:
6767
date (datetime): The date for which the day of the week will be returned.
6868
6969
Returns:
70-
day_of_week (str): The day of the week relating to the specified date.
71-
72-
"""
70+
str: The day of the week relating to the specified date.
71+
"""
7372
return date.strftime("%A")

utils/nhs_number_tools.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,45 @@
11
import logging
2+
3+
24
logger = logging.getLogger(__name__)
35

6+
47
class NHSNumberTools:
58
"""
69
A utility class providing functionality around NHS numbers.
710
"""
8-
def _nhs_number_checks(self, nhs_number: str) -> None:
11+
def __init__(self) -> None:
12+
pass
13+
14+
@staticmethod
15+
def _nhs_number_checks(nhs_number: str) -> None:
916
"""
10-
This does basic checks on NHS number values provided and outputs information or exceptions if applicable.
17+
This does basic checks on NHS number values provided and raises an exception if the number is not valid.
1118
1219
Args:
1320
nhs_number (str): The NHS number to check.
1421
"""
1522
if not nhs_number.isnumeric():
16-
raise Exception("The NHS number provided ({}) is not numeric.".format(nhs_number))
23+
raise NHSNumberToolsException("The NHS number provided ({}) is not numeric.".format(nhs_number))
24+
if not len(nhs_number) == 10:
25+
raise NHSNumberToolsException("The NHS number provided ({}) is not 10 digits.".format(nhs_number))
1726

18-
19-
def spaced_nhs_number(self, nhs_number: int | str) -> str:
27+
@staticmethod
28+
def spaced_nhs_number(nhs_number: int | str) -> str:
2029
"""
21-
This will space out a provided NHS number in the format nnn nnn nnnn.
30+
This will space out a provided NHS number in the format: nnn nnn nnnn.
2231
2332
Args:
2433
nhs_number (int | str): The NHS number to space out.
2534
2635
Returns:
2736
str: The NHS number in "nnn nnn nnnn" format.
2837
"""
29-
self._nhs_number_checks(str(nhs_number))
30-
return "{} {} {}".format(str(nhs_number)[:3], str(nhs_number)[3:6], str(nhs_number)[6:])
38+
formatted_nhs_number = str(nhs_number).replace(" ", "")
39+
NHSNumberTools._nhs_number_checks(formatted_nhs_number)
40+
41+
return f"{formatted_nhs_number[:3]} {formatted_nhs_number[3:6]} {formatted_nhs_number[6:]}"
42+
43+
44+
class NHSNumberToolsException(Exception):
45+
pass

utils/user_tools.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import json
2-
import os
32
import logging
43
from pathlib import Path
54

5+
6+
logger = logging.getLogger(__name__)
67
USERS_FILE = Path(__file__).parent.parent / "users.json"
78

89

@@ -18,11 +19,19 @@ def retrieve_user(user: str) -> dict:
1819
1920
Args:
2021
user (str): The user details required, using the record key from users.json.
22+
23+
Returns:
24+
dict: A Python dictionary with the details of the user requested, if present.
2125
"""
2226
with open(USERS_FILE, 'r') as file:
2327
user_data = json.loads(file.read())
2428

2529
if not user in user_data:
26-
raise Exception(f"User [{user}] is not present in users.json")
30+
raise UserToolsException(f"User [{user}] is not present in users.json")
2731

32+
logger.debug(f"Returning user: {user_data[user]}")
2833
return user_data[user]
34+
35+
36+
class UserToolsException(Exception):
37+
pass

0 commit comments

Comments
 (0)