generated from nhs-england-tools/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> This adds in user tool support, so users can be managed from a JSON file rather than the code directly. ## Context <!-- Why is this change required? What problem does it solve? --> Allows for tidy user management, in an easy to maintain format rather than in code. ## Type of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. --> - [ ] Refactoring (non-breaking change) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would change existing functionality) - [ ] Bug fix (non-breaking change which fixes an issue) ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I am familiar with the [contributing guidelines](https://github.com/nhs-england-tools/playwright-python-blueprint/blob/main/CONTRIBUTING.md) - [x] I have followed the code style of the project - [x] I have added tests to cover my changes (where appropriate) - [x] I have updated the documentation accordingly - [ ] This PR is a result of pair or mob programming --- ## Sensitive Information Declaration To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including [PII (Personal Identifiable Information) / PID (Personal Identifiable Data)](https://digital.nhs.uk/data-and-information/keeping-data-safe-and-benefitting-the-public) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter. - [x] I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.
- Loading branch information
1 parent
4692285
commit 7e0a8fc
Showing
13 changed files
with
290 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Utility Guide: NHS Number Tools | ||
|
||
The NHS Number Tools utility provided by this blueprint allows for the easy management of NHS numbers, and provides | ||
common functionality that may apply to many services in relation to NHS Number management. | ||
|
||
## Table of Contents | ||
|
||
- [Utility Guide: NHS Number Tools](#utility-guide-nhs-number-tools) | ||
- [Table of Contents](#table-of-contents) | ||
- [Using the NHS Number Tools class](#using-the-nhs-number-tools-class) | ||
- [`spaced_nhs_number()`: Return Spaced NHS Number](#spaced_nhs_number-return-spaced-nhs-number) | ||
- [Required Arguments](#required-arguments) | ||
- [Returns](#returns) | ||
|
||
## Using the NHS Number Tools class | ||
|
||
You can initialise the NHS Number Tools class by using the following code in your test file: | ||
|
||
from utils.nhs_number_tools import NHSNumberTools | ||
|
||
## `spaced_nhs_number()`: Return Spaced NHS Number | ||
|
||
The `spaced_nhs_number()` method is designed to take the provided NHS number and return it in a formatted | ||
string of the format `nnn nnn nnnn`. It's a static method so can be used in the following way: | ||
|
||
# Return formatted NHS number | ||
spaced_nhs_number = NHSNumberTools.spaced_nhs_number("1234567890") | ||
|
||
### Required Arguments | ||
|
||
The following are required for `NHSNumberTools.spaced_nhs_number()`: | ||
|
||
| Argument | Format | Description | | ||
| ---------- | -------------- | ------------------------- | | ||
| nhs_number | `str` or `int` | The NHS number to format. | | ||
|
||
### Returns | ||
|
||
A `str` with the provided NHS number in `nnn nnn nnnn` format. For example, `NHSNumberTools.spaced_nhs_number(1234567890)` would return `123 456 7890`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
# Utility Guide: User Tools | ||
|
||
The User Tools utility provided by this blueprint allows for the easy management of test users via a json file included | ||
at the base of the repository. | ||
|
||
## Table of Contents | ||
|
||
- [Utility Guide: User Tools](#utility-guide-user-tools) | ||
- [Table of Contents](#table-of-contents) | ||
- [Using the User Tools class](#using-the-user-tools-class) | ||
- [Managing Users](#managing-users) | ||
- [Considering Security](#considering-security) | ||
- [`retrieve_user()`: Retrieve User Details](#retrieve_user-retrieve-user-details) | ||
- [Required Arguments](#required-arguments) | ||
- [Returns](#returns) | ||
- [Example Usage](#example-usage) | ||
|
||
## Using the User Tools class | ||
|
||
You can initialise the User Tools class by using the following code in your test file: | ||
|
||
from utils.user_tools import UserTools | ||
|
||
This module has been designed as a static class, so you do not need to instantiate it when you want to retrieve any user information. | ||
|
||
## Managing Users | ||
|
||
For this class, users are managed via the [users.json](../../users.json) file provided with this repository. For any new users you need to | ||
add, the idea is to just add a new record, with any appropriate metadata you need for the user whilst they interact with your application. | ||
|
||
For example, adding a record like so (this example shows the entire `users.json` file): | ||
|
||
{ | ||
"Documentation User": { | ||
"username": "DOC_USER", | ||
"roles": ["Example Role A"], | ||
"unique_id": 42 | ||
} | ||
} | ||
|
||
The data you require for these users can be completely customised for what information you need, so whilst the example shows `username`, `roles` | ||
and `unique_id` as possible values we may want to use, this is not an exhaustive list. The key that is used (so in this example, `"Documentation User"`) | ||
is also customisable and should be how you want to easily reference retrieving this user in your tests. | ||
|
||
### Considering Security | ||
|
||
An important note on managing users in this way is that passwords or security credentials should **never** be stored in the `users.json` file. These | ||
are considered secrets, and whilst it may be convenient to store them in this file, it goes against the | ||
[security principles outlined in the Software Engineering Quality Framework](https://github.com/NHSDigital/software-engineering-quality-framework/blob/main/practices/security.md#application-level-security). | ||
|
||
With this in mind, it's recommended to do the following when it comes to managing these types of credentials: | ||
|
||
- When running locally, store any secret values in a local configuration file and set this file in `.gitignore` so it is not committed to the codebase. | ||
- When running via a CI/CD process, store any secret values in an appropriate secret store and pass the values into pytest at runtime. | ||
|
||
## `retrieve_user()`: Retrieve User Details | ||
|
||
The `retrieve_user()` method is designed to easily retrieve the data for a specific user entry from the `users.json` file. This is a static method, | ||
so can be called using the following logic: | ||
|
||
# Retrieving documentation user details from example | ||
user_details = UserTools.retrieve_user("Documentation User") | ||
|
||
### Required Arguments | ||
|
||
The following are required for `UserTools.retrieve_user()`: | ||
|
||
| Argument | Format | Description | | ||
| -------- | ------ | ------------------------------------------------------- | | ||
| user | `str` | The key from `users.json` for the user details required | | ||
|
||
### Returns | ||
|
||
A Python `dict` object that contains the values associated with the provided user argument. | ||
|
||
### Example Usage | ||
|
||
When using a `users.json` file as set up in the example above: | ||
|
||
from utils.user_tools import UserTools | ||
from playwright.sync_api import Page | ||
|
||
def test_login(page: Page) -> None: | ||
# Retrieving documentation user details from example | ||
user_details = UserTools.retrieve_user("Documentation User") | ||
|
||
# Use values to populate a form | ||
page.get_by_role("textbox", name="Username").fill(user_details["username"]) | ||
page.get_by_role("textbox", name="ID").fill(user_details["unique_id"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"Test User": { | ||
"username": "TEST_USER1", | ||
"test_key": "TEST A" | ||
}, | ||
"Test User 2": { | ||
"username": "TEST_USER2", | ||
"test_key": "TEST B" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import pytest | ||
from utils.nhs_number_tools import NHSNumberTools, NHSNumberToolsException | ||
|
||
|
||
pytestmark = [pytest.mark.utils] | ||
|
||
def test_nhs_number_checks() -> None: | ||
assert NHSNumberTools._nhs_number_checks("1234567890") == None | ||
|
||
with pytest.raises(Exception, match=r'The NHS number provided \(A234567890\) is not numeric.'): | ||
NHSNumberTools._nhs_number_checks("A234567890") | ||
|
||
with pytest.raises(NHSNumberToolsException, match=r'The NHS number provided \(123\) is not 10 digits'): | ||
NHSNumberTools._nhs_number_checks("123") | ||
|
||
def test_spaced_nhs_number() -> None: | ||
assert NHSNumberTools.spaced_nhs_number("1234567890") == "123 456 7890" | ||
assert NHSNumberTools.spaced_nhs_number(3216549870) == "321 654 9870" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import pytest | ||
import utils.user_tools | ||
from utils.user_tools import UserTools, UserToolsException | ||
from pathlib import Path | ||
|
||
|
||
pytestmark = [pytest.mark.utils] | ||
|
||
def test_retrieve_user(monkeypatch: object) -> None: | ||
monkeypatch.setattr(utils.user_tools, "USERS_FILE", Path(__file__).parent / "resources" / "test_users.json") | ||
|
||
test_user = UserTools.retrieve_user("Test User") | ||
assert test_user["username"] == "TEST_USER1" | ||
assert test_user["test_key"] == "TEST A" | ||
|
||
test_user2 = UserTools.retrieve_user("Test User 2") | ||
assert test_user2["username"] == "TEST_USER2" | ||
assert test_user2["test_key"] == "TEST B" | ||
|
||
with pytest.raises(UserToolsException, match=r'User \[Invalid User\] is not present in users.json'): | ||
UserTools.retrieve_user("Invalid User") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"_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.", | ||
"Example User 1": { | ||
"username": "EXAMPLE_USER1", | ||
"roles": ["Example Role A"] | ||
}, | ||
"Example User 2": { | ||
"username": "EXAMPLE_USER2", | ||
"roles": ["Example Role B", "Example Role C"] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.