Skip to content
Open
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
24 changes: 13 additions & 11 deletions infrastructure/terraform/components/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ No requirements.
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes |
| <a name="input_ca_pem_filename"></a> [ca\_pem\_filename](#input\_ca\_pem\_filename) | Filename for the CA truststore file within the s3 bucket | `string` | `null` | no |
| <a name="input_component"></a> [component](#input\_component) | The variable encapsulating the name of this component | `string` | `"supapi"` | no |
| <a name="input_core_account_id"></a> [core\_account\_id](#input\_core\_account\_id) | AWS Account ID for Core | `string` | `"000000000000"` | no |
| <a name="input_core_environment"></a> [core\_environment](#input\_core\_environment) | Environment of Core | `string` | `"prod"` | no |
| <a name="input_default_tags"></a> [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no |
| <a name="input_enable_backups"></a> [enable\_backups](#input\_enable\_backups) | Enable backups | `bool` | `false` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
Expand All @@ -34,26 +36,26 @@ No requirements.

| Name | Source | Version |
|------|--------|---------|
| <a name="module_authorizer_lambda"></a> [authorizer\_lambda](#module\_authorizer\_lambda) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_authorizer_lambda"></a> [authorizer\_lambda](#module\_authorizer\_lambda) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_domain_truststore"></a> [domain\_truststore](#module\_domain\_truststore) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-s3bucket.zip | n/a |
| <a name="module_eventpub"></a> [eventpub](#module\_eventpub) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-eventpub.zip | n/a |
| <a name="module_eventsub"></a> [eventsub](#module\_eventsub) | ../../modules/eventsub | n/a |
| <a name="module_get_letter"></a> [get\_letter](#module\_get\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_get_letter_data"></a> [get\_letter\_data](#module\_get\_letter\_data) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_get_letters"></a> [get\_letters](#module\_get\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_get_status"></a> [get\_status](#module\_get\_status) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
| <a name="module_get_letter"></a> [get\_letter](#module\_get\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_get_letter_data"></a> [get\_letter\_data](#module\_get\_letter\_data) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_get_letters"></a> [get\_letters](#module\_get\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_get_status"></a> [get\_status](#module\_get\_status) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_kms"></a> [kms](#module\_kms) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-kms.zip | n/a |
| <a name="module_letter_status_update"></a> [letter\_status\_update](#module\_letter\_status\_update) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
| <a name="module_letter_status_update"></a> [letter\_status\_update](#module\_letter\_status\_update) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_letter_status_updates_queue"></a> [letter\_status\_updates\_queue](#module\_letter\_status\_updates\_queue) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-sqs.zip | n/a |
| <a name="module_letter_updates_transformer"></a> [letter\_updates\_transformer](#module\_letter\_updates\_transformer) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_letter_updates_transformer"></a> [letter\_updates\_transformer](#module\_letter\_updates\_transformer) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_logging_bucket"></a> [logging\_bucket](#module\_logging\_bucket) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-s3bucket.zip | n/a |
| <a name="module_patch_letter"></a> [patch\_letter](#module\_patch\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_post_letters"></a> [post\_letters](#module\_post\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.24/terraform-lambda.zip | n/a |
| <a name="module_post_mi"></a> [post\_mi](#module\_post\_mi) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_patch_letter"></a> [patch\_letter](#module\_patch\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_post_letters"></a> [post\_letters](#module\_post\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_post_mi"></a> [post\_mi](#module\_post\_mi) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
| <a name="module_s3bucket_test_letters"></a> [s3bucket\_test\_letters](#module\_s3bucket\_test\_letters) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-s3bucket.zip | n/a |
| <a name="module_sqs_letter_updates"></a> [sqs\_letter\_updates](#module\_sqs\_letter\_updates) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-sqs.zip | n/a |
| <a name="module_supplier_ssl"></a> [supplier\_ssl](#module\_supplier\_ssl) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-ssl.zip | n/a |
| <a name="module_upsert_letter"></a> [upsert\_letter](#module\_upsert\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.26/terraform-lambda.zip | n/a |
| <a name="module_upsert_letter"></a> [upsert\_letter](#module\_upsert\_letter) | https://github.com/NHSDigital/nhs-notify-shared-modules/releases/download/v2.0.29/terraform-lambda.zip | n/a |
## Outputs

| Name | Description |
Expand Down
16 changes: 16 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[pytest]
pythonpath =
tests/e2e-tests
python_files = *_tests.py test-*.py
addopts = --strict-markers
markers =
smoketest: suitable to run against all environments even production
mtlstest: suitable to run against periodically against environments
sandboxtest: suitable to run against sandbox environment
devtest: suitable to run against dev like environments
devtestonly: suitable to run against internal-dev only
devperftest: rate limiting tests suitable to run against dev like environments
inttest: suitable to run against integration environment
prodtest: suitable to run against production environment
uattest: suitable to run against uat environment
test: suitable to run against all environments
1 change: 1 addition & 0 deletions scripts/init.mk
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ _install-dependency: # Install asdf dependency - mandatory: name=[listed in the
_install-dependencies: # Install all the dependencies listed in .tool-versions
for plugin in $$(grep '^[a-z]' .tool-versions | cut -f1 -d' '); do \
echo "Installing $${plugin}..."; \
$(MAKE) _install-dependency name=$${plugin}; \
done

clean:: # Remove all generated and temporary files (common) @Operations
Expand Down
7 changes: 7 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ node_modules/
/target
/playwright/.auth/
/allure-report
*/__pycache__/
**/__pycache__/
__pycache__/
*/__pycache__/
**/__pycache__/
*.pyc
tests/e2e-tests/lib/internal-dev-test-1.pem
33 changes: 33 additions & 0 deletions tests/e2e-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# E2E Tests

## Generate An Apigee Access Token

To generate authentication using Apigee, you must have access to an Apigee account and use `get_token` via the command line and generate an Apigee access token.

**Tokens expire once per day and require refreshing.**

* Install [`get_token`](https://docs.apigee.com/api-platform/system-administration/auth-tools#install)
* Run the following command and log in with your Apigee credentials when prompted:

```shell
export APIGEE_ACCESS_TOKEN=$(SSO_LOGIN_URL=https://login.apigee.com get_token)
```

* If your token does not refresh, try clearing the cache:

```shell
export APIGEE_ACCESS_TOKEN=$(SSO_LOGIN_URL=https://login.apigee.com get_token --clear-sso-cache)
```

### Set Proxy Name

Set the `PROXY_NAME` environment variable to specify the environment for test execution. You can find the proxy name by logging into [Apigee](https://apigee.com/edge), navigating to 'API Proxies' and searching for 'supplier-api'.

```shell
export PROXY_NAME=nhs-notify-supplier--internal-dev--nhs-notify-supplier
```

Available values for `PROXY_NAME` include:

* `nhs-notify-supplier--internal-dev--nhs-notify-supplier`
* `nhs-notify-supplier--internal-dev--nhs-notify-supplier-pr<num>`
Empty file.
33 changes: 33 additions & 0 deletions tests/e2e-tests/api/authentication/test-401-errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import requests
import pytest
from lib.constants import METHODS, VALID_ENDPOINTS
from lib.fixtures import *

@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
@pytest.mark.parametrize("method", METHODS)
@pytest.mark.parametrize("endpoints", VALID_ENDPOINTS)
def test_401_invalid(url, method, endpoints):

resp = getattr(requests, method)(f"{url}{endpoints}", headers={
"Authorization": "invalid",
})

assert(resp.status_code == 401)

@pytest.mark.test
@pytest.mark.nhsd_apim_authorization({"access": "application", "level": "level0"})
@pytest.mark.parametrize("method", METHODS)
@pytest.mark.parametrize("endpoints", VALID_ENDPOINTS)
def test_401_invalid_level(nhsd_apim_proxy_url, nhsd_apim_auth_headers, method, endpoints):
print(nhsd_apim_proxy_url)

resp = getattr(requests, method)(f"{nhsd_apim_proxy_url}{endpoints}", headers={
**nhsd_apim_auth_headers
})

print("Status:", resp.status_code)

assert(resp.status_code == 401)
60 changes: 60 additions & 0 deletions tests/e2e-tests/api/data/test-get-letter_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import uuid
import requests
import pytest
from lib.fixtures import * # NOSONAR
from lib.constants import LETTERS_ENDPOINT
from lib.generators import Generators

@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest

def test_200_get_letter_status(url, bearer_token):

headers = Generators.generate_valid_headers(bearer_token.value)
get_letter_id = requests.get(f"{url}/{LETTERS_ENDPOINT}/", headers=headers)

letter_id = get_letter_id.json().get("data")[0].get("id")
get_letter_data = requests.get(f"{url}/{LETTERS_ENDPOINT}/{letter_id}/data", headers=headers)

assert get_letter_data.status_code == 200
assert get_letter_data.headers.get("Content-Type") == "application/pdf"


@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
def test_404_letter_does_not_exist(url, bearer_token):

headers = Generators.generate_valid_headers(bearer_token.value)
get_message_response = requests.get(f"{url}/{LETTERS_ENDPOINT}/xx", headers=headers)

assert get_message_response.status_code == 404
assert get_message_response.json().get("errors")[0].get("detail") == "No resource found with that ID"

@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
def test_404_letter_does_not_exist(url, bearer_token):

letter_id = uuid.uuid4().hex
headers = Generators.generate_valid_headers(bearer_token.value)
get_message_response = requests.get(f"{url}/{LETTERS_ENDPOINT}/{letter_id}/data", headers=headers)

assert get_message_response.status_code == 404
assert get_message_response.json().get("errors")[0].get("detail") == "No resource found with that ID"

@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
def test_500_letter_does_not_exist(url, bearer_token):

letter_id = "00000000-0000-0000-0000-000000000000"
headers = Generators.generate_valid_headers(bearer_token.value)
get_message_response = requests.get(f"{url}/{LETTERS_ENDPOINT}/{letter_id}/data", headers=headers)

assert get_message_response.status_code == 500
43 changes: 43 additions & 0 deletions tests/e2e-tests/api/endpoint_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pytest
import requests
from os import getenv

def _get(url, headers=None, timeout=10):
return requests.get(url, headers=headers or {}, timeout=timeout)

@pytest.mark.smoketest
def test_ping(nhsd_apim_proxy_url):
resp = requests.get(nhsd_apim_proxy_url + "/_ping")
assert resp.status_code == 200

@pytest.mark.smoketest
@pytest.mark.sandboxtest
@pytest.mark.devtest
def test_status(nhsd_apim_proxy_url, status_endpoint_auth_headers):
resp = requests.get(
f"{nhsd_apim_proxy_url}/_status", headers=status_endpoint_auth_headers
)

assert resp.status_code == 200

@pytest.mark.smoketest
@pytest.mark.sandboxtest
@pytest.mark.devtest
def test_401_status_without_api_key(nhsd_apim_proxy_url):
resp = requests.get(
f"{nhsd_apim_proxy_url}/_status"
)
assert resp.status_code == 401


# @pytest.mark.smoketest
# @pytest.mark.nhsd_apim_authorization(access="application", level="level3")
# def test_invalid_jwt_rejected(nhsd_apim_proxy_url, nhsd_apim_auth_headers):
# """
# Best-effort: if gateway validates JWTs, an invalid token should be rejected.
# If JWT not used in this env, test is skipped.
# """
# headers = {
# **nhsd_apim_auth_headers,
# "x-request-id": "123456"
# }
44 changes: 44 additions & 0 deletions tests/e2e-tests/api/headers/test-x-request-id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from re import M
import requests
import pytest
from lib.fixtures import * # NOSONAR
from lib.constants import VALID_ENDPOINT_LETTERS, MI_ENDPOINT
from lib.generators import Generators

METHODS = ["get", "post"]


@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
@pytest.mark.parametrize("method", METHODS)
@pytest.mark.parametrize("endpoints", VALID_ENDPOINT_LETTERS)
def test_header_letters_endpoint(
url,
method,
endpoints,
bearer_token
):
resp = getattr(requests, method)(f"{url}/{endpoints}", headers={
"Authorization": bearer_token.value,
"X-Request-ID": None
})

assert resp.status_code == 500


@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
def test_header_mi_endpoint(
url,
bearer_token
):
resp = getattr(requests, "post")(f"{url}/{MI_ENDPOINT}", headers={
"Authorization": bearer_token.value,
"X-Request-ID": ""
})

assert resp.status_code == 500
33 changes: 33 additions & 0 deletions tests/e2e-tests/api/letters/test-get-letter-status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import requests
import pytest
from lib.fixtures import * # NOSONAR
from lib.constants import LETTERS_ENDPOINT
from lib.generators import Generators

@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest

def test_200_get_letter_status(url, bearer_token):

headers = Generators.generate_valid_headers(bearer_token.value)
get_letters = requests.get(f"{url}/{LETTERS_ENDPOINT}/", headers=headers)

letter_id = get_letters.json().get("data")[0].get("id")
get_message_response = requests.get(f"{url}/{LETTERS_ENDPOINT}/{letter_id}", headers=headers)

assert get_message_response.status_code == 200


@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
def test_404_letter_does_not_exist(url, bearer_token):

headers = Generators.generate_valid_headers(bearer_token.value)
get_message_response = requests.get(f"{url}/{LETTERS_ENDPOINT}/xx", headers=headers)

assert get_message_response.status_code == 404
assert get_message_response.json().get("errors")[0].get("detail") == "No resource found with that ID"
18 changes: 18 additions & 0 deletions tests/e2e-tests/api/letters/test-get-list-of-letters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import requests
import pytest
from lib.fixtures import * # NOSONAR
from lib.constants import LETTERS_ENDPOINT
from lib.generators import Generators

@pytest.mark.test
@pytest.mark.devtest
@pytest.mark.inttest
@pytest.mark.prodtest
def test_200_get_letters(url, bearer_token):

headers = Generators.generate_valid_headers(bearer_token.value)

get_message_response = requests.get(f"{url}/letters?limit=1", headers=headers)

assert get_message_response.status_code == 200
assert get_message_response.json().get("data")[0].get("attributes").get("status") == "PENDING"
Loading
Loading