Skip to content

CCM-24432: release v4.77.0 - #1106

Merged
chris-elliott-nhsd merged 4 commits into
masterfrom
release
Oct 8, 2026
Merged

chris-elliott-nhsd merged 4 commits into
masterfrom
release

Merge pull request #1105 from NHSDigital/v4.77.0

56c05c0
Select commit
Loading
Failed to load commit list.
Azure Pipelines / Communications-Manager-Nightly-Internal-QA failed Oct 12, 2026 in 3m 19s

Build #release+582348 had test failures

Details

Tests

  • Failed: 36 (3.25%, 0 new, 36 recurring)
  • Passed: 1,072 (96.75%)
  • Other: 0 (0.00%)
  • Total: 1,108

Annotations

Check failure on line 18 in Build log

See this annotation in the file changed.

@azure-pipelines azure-pipelines / Communications-Manager-Nightly-Internal-QA

Build log #L18

There are one or more test failures detected in result files. Detailed summary of published test results can be viewed in the Tests tab.

Check failure on line 6886 in Build log

See this annotation in the file changed.

@azure-pipelines azure-pipelines / Communications-Manager-Nightly-Internal-QA

Build log #L6886

Bash exited with code '2'.

Check failure on line 1 in test_user_token_get[/v1/message-batches-get]

See this annotation in the file changed.

@azure-pipelines azure-pipelines / Communications-Manager-Nightly-Internal-QA

test_user_token_get[/v1/message-batches-get]

failed on setup with "RuntimeError: 400: 
        {
          "error" : "unsupported_grant_type",
          "error_description" :"grant_type is invalid",
          "message_id": "rrt-6391643429530192354-a-geu2-2520464-13345178-1"
        }"
Raw output
nhsd_apim_authorization = {'access': 'healthcare_worker', 'api_name': 'communications-manager', 'authentication': 'separate', 'force_new_token': False, ...}
_test_app_credentials = {'apiProducts': [{'apiproduct': 'communications-manager-internal-qa', 'status': 'approved'}], 'attributes': [], 'consumerKey': 'lIJ8DzitfEGDgNqz8lQDqoytnWoHDluk', 'consumerSecret': 'NGA1n1eowGvEtG6Z', ...}
_test_app_callback_url = 'https://google.com/callback'
_keycloak_client_credentials = {'cis2': {'client_id': 'pytest-nhsd-apim', 'client_secret': '48d2a935-a67d-4252-98bb-f9e982427a20', 'redirect_uri': 'h...': 'pytest-nhsd-apim', 'client_secret': '60dd5f3f-2a5e-45cb-9cfc-c6c1ba7971ef', 'redirect_uri': 'https://example.org'}}
identity_service_base_url = 'https://internal-qa.api.service.nhs.uk/oauth2-mock'
jwt_private_key_pem = '-----BEGIN RSA PRIVATE KEY-----\nMIIJKQIBAAKCAgEAr68oZ3Ckzjoj1NBPqd1bBhU+Q4/I/We7tM1Qy1Y+o0Vh5Mhi\nO6EgaRRnLb7r447rIS...Z7U1NgqFfeifAJfS3vkmF8fGs\nXKoTIeMwMWsHvXQFCP5yhtW2Z7viHAYgayD+BkU0QZ8gjAopsTTtk5FYqb29\n-----END RSA PRIVATE KEY-----'
jwt_public_key_id = 'test-1', apigee_environment = 'internal-qa'

    @pytest.fixture()
    def _nhsd_apim_auth_token_data(
        nhsd_apim_authorization,
        _test_app_credentials,
        _test_app_callback_url,
        _keycloak_client_credentials,
        identity_service_base_url,
        jwt_private_key_pem,
        jwt_public_key_id,
        apigee_environment,
    ):
        """
        Main entrypoint to pytest_nhsd_apim.
    
        This fixture will examine the @pytest.mark.nhsd_apim_authorization
        on your test and do the rest.
        """
    
        if nhsd_apim_authorization is None:
            return {}
    
        access = nhsd_apim_authorization["access"]
        level = nhsd_apim_authorization["level"]
        if access == "application":
            if level == "level0":
                return {"apikey": _test_app_credentials["consumerKey"]}
            elif level == "level3":
                token_data = get_access_token_via_signed_jwt_flow(
                    identity_service_base_url,
                    _test_app_credentials["consumerKey"],
                    jwt_private_key_pem,
                    jwt_public_key_id,
                    apigee_environment,
                    force_new_token=nhsd_apim_authorization["force_new_token"],
                )
                return token_data
            else:
                # Should have been pre-validated.
                raise ValueError(f"Invalid level '{level}' for access 'application'.")
    
        # User restricted auth flows...
        authentication = nhsd_apim_authorization.get("authentication")
        login_form = nhsd_apim_authorization.get("login_form")
    
        backend_provider_names = {"healthcare_worker": "nhs-cis2", "patient": "nhs-login"}
    
        if authentication == "combined":
            token_data = get_access_token_via_user_restricted_flow_combined_auth(
                identity_service_base_url,
                _test_app_credentials["consumerKey"],
                _test_app_credentials["consumerSecret"],
                _test_app_callback_url,
                backend_provider_names[access],
                login_form,
                apigee_environment,
                force_new_token=nhsd_apim_authorization["force_new_token"],
            )
    
        elif authentication == "separate":
>           token_data = get_access_token_via_user_restricted_flow_separate_auth(
                identity_service_base_url,
                _keycloak_client_credentials,
                login_form,
                _test_app_credentials["consumerKey"],
                jwt_private_key_pem,
                jwt_public_key_id,
                backend_provider_names[access],
                apigee_environment,
           
... [The stack trace has been truncated as it exceeded the maximum allowed size. Please refer to the complete log available in the Test Run attachments for full details.]

Check failure on line 1 in test_user_token_get[/v1/message-batches-post]

See this annotation in the file changed.

@azure-pipelines azure-pipelines / Communications-Manager-Nightly-Internal-QA

test_user_token_get[/v1/message-batches-post]

failed on setup with "RuntimeError: 400: 
        {
          "error" : "unsupported_grant_type",
          "error_description" :"grant_type is invalid",
          "message_id": "rrt-1012722874460096993-c-geu2-3928124-13399012-1"
        }"
Raw output
nhsd_apim_authorization = {'access': 'healthcare_worker', 'api_name': 'communications-manager', 'authentication': 'separate', 'force_new_token': False, ...}
_test_app_credentials = {'apiProducts': [{'apiproduct': 'communications-manager-internal-qa', 'status': 'approved'}], 'attributes': [], 'consumerKey': 'lIJ8DzitfEGDgNqz8lQDqoytnWoHDluk', 'consumerSecret': 'NGA1n1eowGvEtG6Z', ...}
_test_app_callback_url = 'https://google.com/callback'
_keycloak_client_credentials = {'cis2': {'client_id': 'pytest-nhsd-apim', 'client_secret': '48d2a935-a67d-4252-98bb-f9e982427a20', 'redirect_uri': 'h...': 'pytest-nhsd-apim', 'client_secret': '60dd5f3f-2a5e-45cb-9cfc-c6c1ba7971ef', 'redirect_uri': 'https://example.org'}}
identity_service_base_url = 'https://internal-qa.api.service.nhs.uk/oauth2-mock'
jwt_private_key_pem = '-----BEGIN RSA PRIVATE KEY-----\nMIIJKQIBAAKCAgEAr68oZ3Ckzjoj1NBPqd1bBhU+Q4/I/We7tM1Qy1Y+o0Vh5Mhi\nO6EgaRRnLb7r447rIS...Z7U1NgqFfeifAJfS3vkmF8fGs\nXKoTIeMwMWsHvXQFCP5yhtW2Z7viHAYgayD+BkU0QZ8gjAopsTTtk5FYqb29\n-----END RSA PRIVATE KEY-----'
jwt_public_key_id = 'test-1', apigee_environment = 'internal-qa'

    @pytest.fixture()
    def _nhsd_apim_auth_token_data(
        nhsd_apim_authorization,
        _test_app_credentials,
        _test_app_callback_url,
        _keycloak_client_credentials,
        identity_service_base_url,
        jwt_private_key_pem,
        jwt_public_key_id,
        apigee_environment,
    ):
        """
        Main entrypoint to pytest_nhsd_apim.
    
        This fixture will examine the @pytest.mark.nhsd_apim_authorization
        on your test and do the rest.
        """
    
        if nhsd_apim_authorization is None:
            return {}
    
        access = nhsd_apim_authorization["access"]
        level = nhsd_apim_authorization["level"]
        if access == "application":
            if level == "level0":
                return {"apikey": _test_app_credentials["consumerKey"]}
            elif level == "level3":
                token_data = get_access_token_via_signed_jwt_flow(
                    identity_service_base_url,
                    _test_app_credentials["consumerKey"],
                    jwt_private_key_pem,
                    jwt_public_key_id,
                    apigee_environment,
                    force_new_token=nhsd_apim_authorization["force_new_token"],
                )
                return token_data
            else:
                # Should have been pre-validated.
                raise ValueError(f"Invalid level '{level}' for access 'application'.")
    
        # User restricted auth flows...
        authentication = nhsd_apim_authorization.get("authentication")
        login_form = nhsd_apim_authorization.get("login_form")
    
        backend_provider_names = {"healthcare_worker": "nhs-cis2", "patient": "nhs-login"}
    
        if authentication == "combined":
            token_data = get_access_token_via_user_restricted_flow_combined_auth(
                identity_service_base_url,
                _test_app_credentials["consumerKey"],
                _test_app_credentials["consumerSecret"],
                _test_app_callback_url,
                backend_provider_names[access],
                login_form,
                apigee_environment,
                force_new_token=nhsd_apim_authorization["force_new_token"],
            )
    
        elif authentication == "separate":
>           token_data = get_access_token_via_user_restricted_flow_separate_auth(
                identity_service_base_url,
                _keycloak_client_credentials,
                login_form,
                _test_app_credentials["consumerKey"],
                jwt_private_key_pem,
                jwt_public_key_id,
                backend_provider_names[access],
                apigee_environment,
           
... [The stack trace has been truncated as it exceeded the maximum allowed size. Please refer to the complete log available in the Test Run attachments for full details.]

Check failure on line 1 in test_user_token_get[/v1/message-batches-patch]

See this annotation in the file changed.

@azure-pipelines azure-pipelines / Communications-Manager-Nightly-Internal-QA

test_user_token_get[/v1/message-batches-patch]

failed on setup with "RuntimeError: 400: 
        {
          "error" : "unsupported_grant_type",
          "error_description" :"grant_type is invalid",
          "message_id": "rrt-3096047368984528154-a-geu2-3720575-13856117-1"
        }"
Raw output
nhsd_apim_authorization = {'access': 'healthcare_worker', 'api_name': 'communications-manager', 'authentication': 'separate', 'force_new_token': False, ...}
_test_app_credentials = {'apiProducts': [{'apiproduct': 'communications-manager-internal-qa', 'status': 'approved'}], 'attributes': [], 'consumerKey': 'lIJ8DzitfEGDgNqz8lQDqoytnWoHDluk', 'consumerSecret': 'NGA1n1eowGvEtG6Z', ...}
_test_app_callback_url = 'https://google.com/callback'
_keycloak_client_credentials = {'cis2': {'client_id': 'pytest-nhsd-apim', 'client_secret': '48d2a935-a67d-4252-98bb-f9e982427a20', 'redirect_uri': 'h...': 'pytest-nhsd-apim', 'client_secret': '60dd5f3f-2a5e-45cb-9cfc-c6c1ba7971ef', 'redirect_uri': 'https://example.org'}}
identity_service_base_url = 'https://internal-qa.api.service.nhs.uk/oauth2-mock'
jwt_private_key_pem = '-----BEGIN RSA PRIVATE KEY-----\nMIIJKQIBAAKCAgEAr68oZ3Ckzjoj1NBPqd1bBhU+Q4/I/We7tM1Qy1Y+o0Vh5Mhi\nO6EgaRRnLb7r447rIS...Z7U1NgqFfeifAJfS3vkmF8fGs\nXKoTIeMwMWsHvXQFCP5yhtW2Z7viHAYgayD+BkU0QZ8gjAopsTTtk5FYqb29\n-----END RSA PRIVATE KEY-----'
jwt_public_key_id = 'test-1', apigee_environment = 'internal-qa'

    @pytest.fixture()
    def _nhsd_apim_auth_token_data(
        nhsd_apim_authorization,
        _test_app_credentials,
        _test_app_callback_url,
        _keycloak_client_credentials,
        identity_service_base_url,
        jwt_private_key_pem,
        jwt_public_key_id,
        apigee_environment,
    ):
        """
        Main entrypoint to pytest_nhsd_apim.
    
        This fixture will examine the @pytest.mark.nhsd_apim_authorization
        on your test and do the rest.
        """
    
        if nhsd_apim_authorization is None:
            return {}
    
        access = nhsd_apim_authorization["access"]
        level = nhsd_apim_authorization["level"]
        if access == "application":
            if level == "level0":
                return {"apikey": _test_app_credentials["consumerKey"]}
            elif level == "level3":
                token_data = get_access_token_via_signed_jwt_flow(
                    identity_service_base_url,
                    _test_app_credentials["consumerKey"],
                    jwt_private_key_pem,
                    jwt_public_key_id,
                    apigee_environment,
                    force_new_token=nhsd_apim_authorization["force_new_token"],
                )
                return token_data
            else:
                # Should have been pre-validated.
                raise ValueError(f"Invalid level '{level}' for access 'application'.")
    
        # User restricted auth flows...
        authentication = nhsd_apim_authorization.get("authentication")
        login_form = nhsd_apim_authorization.get("login_form")
    
        backend_provider_names = {"healthcare_worker": "nhs-cis2", "patient": "nhs-login"}
    
        if authentication == "combined":
            token_data = get_access_token_via_user_restricted_flow_combined_auth(
                identity_service_base_url,
                _test_app_credentials["consumerKey"],
                _test_app_credentials["consumerSecret"],
                _test_app_callback_url,
                backend_provider_names[access],
                login_form,
                apigee_environment,
                force_new_token=nhsd_apim_authorization["force_new_token"],
            )
    
        elif authentication == "separate":
>           token_data = get_access_token_via_user_restricted_flow_separate_auth(
                identity_service_base_url,
                _keycloak_client_credentials,
                login_form,
                _test_app_credentials["consumerKey"],
                jwt_private_key_pem,
                jwt_public_key_id,
                backend_provider_names[access],
                apigee_environment,
           
... [The stack trace has been truncated as it exceeded the maximum allowed size. Please refer to the complete log available in the Test Run attachments for full details.]

Check failure on line 1 in test_user_token_get[/v1/message-batches-put]

See this annotation in the file changed.

@azure-pipelines azure-pipelines / Communications-Manager-Nightly-Internal-QA

test_user_token_get[/v1/message-batches-put]

failed on setup with "RuntimeError: 400: 
        {
          "error" : "unsupported_grant_type",
          "error_description" :"grant_type is invalid",
          "message_id": "rrt-8844612381714374509-c-geu2-3682175-13237970-1"
        }"
Raw output
nhsd_apim_authorization = {'access': 'healthcare_worker', 'api_name': 'communications-manager', 'authentication': 'separate', 'force_new_token': False, ...}
_test_app_credentials = {'apiProducts': [{'apiproduct': 'communications-manager-internal-qa', 'status': 'approved'}], 'attributes': [], 'consumerKey': 'lIJ8DzitfEGDgNqz8lQDqoytnWoHDluk', 'consumerSecret': 'NGA1n1eowGvEtG6Z', ...}
_test_app_callback_url = 'https://google.com/callback'
_keycloak_client_credentials = {'cis2': {'client_id': 'pytest-nhsd-apim', 'client_secret': '48d2a935-a67d-4252-98bb-f9e982427a20', 'redirect_uri': 'h...': 'pytest-nhsd-apim', 'client_secret': '60dd5f3f-2a5e-45cb-9cfc-c6c1ba7971ef', 'redirect_uri': 'https://example.org'}}
identity_service_base_url = 'https://internal-qa.api.service.nhs.uk/oauth2-mock'
jwt_private_key_pem = '-----BEGIN RSA PRIVATE KEY-----\nMIIJKQIBAAKCAgEAr68oZ3Ckzjoj1NBPqd1bBhU+Q4/I/We7tM1Qy1Y+o0Vh5Mhi\nO6EgaRRnLb7r447rIS...Z7U1NgqFfeifAJfS3vkmF8fGs\nXKoTIeMwMWsHvXQFCP5yhtW2Z7viHAYgayD+BkU0QZ8gjAopsTTtk5FYqb29\n-----END RSA PRIVATE KEY-----'
jwt_public_key_id = 'test-1', apigee_environment = 'internal-qa'

    @pytest.fixture()
    def _nhsd_apim_auth_token_data(
        nhsd_apim_authorization,
        _test_app_credentials,
        _test_app_callback_url,
        _keycloak_client_credentials,
        identity_service_base_url,
        jwt_private_key_pem,
        jwt_public_key_id,
        apigee_environment,
    ):
        """
        Main entrypoint to pytest_nhsd_apim.
    
        This fixture will examine the @pytest.mark.nhsd_apim_authorization
        on your test and do the rest.
        """
    
        if nhsd_apim_authorization is None:
            return {}
    
        access = nhsd_apim_authorization["access"]
        level = nhsd_apim_authorization["level"]
        if access == "application":
            if level == "level0":
                return {"apikey": _test_app_credentials["consumerKey"]}
            elif level == "level3":
                token_data = get_access_token_via_signed_jwt_flow(
                    identity_service_base_url,
                    _test_app_credentials["consumerKey"],
                    jwt_private_key_pem,
                    jwt_public_key_id,
                    apigee_environment,
                    force_new_token=nhsd_apim_authorization["force_new_token"],
                )
                return token_data
            else:
                # Should have been pre-validated.
                raise ValueError(f"Invalid level '{level}' for access 'application'.")
    
        # User restricted auth flows...
        authentication = nhsd_apim_authorization.get("authentication")
        login_form = nhsd_apim_authorization.get("login_form")
    
        backend_provider_names = {"healthcare_worker": "nhs-cis2", "patient": "nhs-login"}
    
        if authentication == "combined":
            token_data = get_access_token_via_user_restricted_flow_combined_auth(
                identity_service_base_url,
                _test_app_credentials["consumerKey"],
                _test_app_credentials["consumerSecret"],
                _test_app_callback_url,
                backend_provider_names[access],
                login_form,
                apigee_environment,
                force_new_token=nhsd_apim_authorization["force_new_token"],
            )
    
        elif authentication == "separate":
>           token_data = get_access_token_via_user_restricted_flow_separate_auth(
                identity_service_base_url,
                _keycloak_client_credentials,
                login_form,
                _test_app_credentials["consumerKey"],
                jwt_private_key_pem,
                jwt_public_key_id,
                backend_provider_names[access],
                apigee_environment,
           
... [The stack trace has been truncated as it exceeded the maximum allowed size. Please refer to the complete log available in the Test Run attachments for full details.]