Commit 0174e991 authored by kzangeli's avatar kzangeli
Browse files

feat(cb): add TCs for HEAD on every resource that has GET/HEAD (TS 104-176 clause 5)

A HEAD request functions as the GET request would, omits the body, and answers 204 No Content
on success (TS 104-176 clause 5). No Test Case sent a HEAD before.

- 061_01: 19 resources, one permutation each - 204 and no body: /entities/, /entities/{entityId},
  .../attrs/{attrId}, .../attrs/{attrId}/value, /subscriptions/ and by id, /types/ and by type,
  /attributes/ and by id, /temporal/entities/ and by id, /csourceRegistrations/ and by id,
  /csourceSubscriptions/ and by id, /jsonldContexts/ and by id, /info/sourceIdentity.
- 061_02: 18 errors the GET answers - the same 400 or 404, and no body.
- Request With HEAD (Common.resource): HEAD on a path, the other named arguments are URL
  parameters; declared in doc/analysis/requests.py. parseapiutilsfile.py knows the HEAD verb,
  generaterobotdata.py the VerifyHEAD directory.

Not yet: HEAD on /entityMaps/, /temporal/entityMaps, /entityMaps/{entityMapId} and
/snapshots/{snapshotId} - the suite has no Test Case for those resources at all; they come with them.

Co-Authored-By: default avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 7a82c9de
Loading
Loading
Loading
Loading
+270 −0
Changes for TP/NGSI-LD/CommonBehaviours/CommonResponses/VerifyHEAD/061_01.robot: 270 added lines, 0 removed lines.
Original line number Diff line number Diff line
*** Settings ***
Documentation       Verify that a HEAD request on a resource that has GET/HEAD functions in the same manner as a GET request, omits the body in the response and that the response code 204 No Content is used on success

Resource            ${EXECDIR}/resources/ApiUtils/Common.resource
Resource            ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource
Resource            ${EXECDIR}/resources/ApiUtils/ContextInformationSubscription.resource
Resource            ${EXECDIR}/resources/ApiUtils/ContextSourceRegistration.resource
Resource            ${EXECDIR}/resources/ApiUtils/ContextSourceRegistrationSubscription.resource
Resource            ${EXECDIR}/resources/ApiUtils/TemporalContextInformationProvision.resource
Resource            ${EXECDIR}/resources/ApiUtils/jsonldContext.resource
Resource            ${EXECDIR}/resources/AssertionUtils.resource
Resource            ${EXECDIR}/resources/HttpUtils.resource
Resource            ${EXECDIR}/resources/JsonUtils.resource


*** Variables ***
${building_filename}=               building-simple-attributes.jsonld
${subscription_filename}=           subscriptions/subscription.jsonld
${registration_filename}=           csourceRegistrations/context-source-registration-with-expiration.jsonld
${csr_subscription_filename}=       csourceSubscriptions/subscription.jsonld
${tea_filename}=                    vehicle-temporal-representation.jsonld
${context_filename}=                @context-minimal-valid.json


*** Test Cases ***
061_01_01 Endpoint /entities/
    [Documentation]    Verify that a HEAD request on /entities/ is answered with 204 No Content and no body
    [Tags]    e-query    cb-head    http_5    http_7_2_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=entities/
    ...    type=Building
    ...    context=${ngsild_test_suite_context}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_02 Endpoint /entities/{entityId}
    [Documentation]    Verify that a HEAD request on /entities/{entityId} is answered with 204 No Content and no body
    [Tags]    e-retrieve    cb-head    http_5    http_7_3_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=entities/${id}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_03 Endpoint /entities/{entityId}/attrs/{attrId}
    [Documentation]    Verify that a HEAD request on /entities/{entityId}/attrs/{attrId} is answered with 204 No Content and no body
    [Tags]    ea-retrieve    cb-head    http_5    http_7_5_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=entities/${id}/attrs/name
    ...    context=${ngsild_test_suite_context}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_04 Endpoint /entities/{entityId}/attrs/{attrId}/value
    [Documentation]    Verify that a HEAD request on /entities/{entityId}/attrs/{attrId}/value is answered with 204 No Content and no body
    [Tags]    ea-retrieve-value    cb-head    http_5    http_7_6_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=entities/${id}/attrs/name/value
    ...    context=${ngsild_test_suite_context}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_05 Endpoint /subscriptions/
    [Documentation]    Verify that a HEAD request on /subscriptions/ is answered with 204 No Content and no body
    [Tags]    sub-query    cb-head    http_5    http_7_13_3_1
    ${id}=    Generate Random Subscription Id
    ${response}=    Create Subscription    ${id}    ${subscription_filename}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=subscriptions/
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Subscription    ${id}

061_01_06 Endpoint /subscriptions/{subscriptionId}
    [Documentation]    Verify that a HEAD request on /subscriptions/{subscriptionId} is answered with 204 No Content and no body
    [Tags]    sub-retrieve    cb-head    http_5    http_7_14_3_1
    ${id}=    Generate Random Subscription Id
    ${response}=    Create Subscription    ${id}    ${subscription_filename}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=subscriptions/${id}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Subscription    ${id}

061_01_07 Endpoint /types/
    [Documentation]    Verify that a HEAD request on /types/ is answered with 204 No Content and no body
    [Tags]    ed-types    cb-head    http_5    http_7_15_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=types/
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_08 Endpoint /types/{type}
    [Documentation]    Verify that a HEAD request on /types/{type} is answered with 204 No Content and no body
    [Tags]    ed-type    cb-head    http_5    http_7_16_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=types/Building
    ...    context=${ngsild_test_suite_context}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_09 Endpoint /attributes/
    [Documentation]    Verify that a HEAD request on /attributes/ is answered with 204 No Content and no body
    [Tags]    ed-attrs    cb-head    http_5    http_7_17_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=attributes/
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_10 Endpoint /attributes/{attrId}
    [Documentation]    Verify that a HEAD request on /attributes/{attrId} is answered with 204 No Content and no body
    [Tags]    ed-attr    cb-head    http_5    http_7_18_3_1
    ${id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type    ${building_filename}    ${id}    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=attributes/name
    ...    context=${ngsild_test_suite_context}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Entity    ${id}

061_01_11 Endpoint /temporal/entities/
    [Documentation]    Verify that a HEAD request on /temporal/entities/ is answered with 204 No Content and no body
    [Tags]    te-query    cb-head    http_5    http_8_2_3_1
    ${id}=    Generate Random Vehicle Entity Id
    ${response}=    Create Or Update Temporal Representation Of Entity Selecting Content Type
    ...    temporal_entity_representation_id=${id}
    ...    filename=${tea_filename}
    ...    content_type=${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=temporal/entities/
    ...    type=Vehicle
    ...    timerel=after
    ...    timeAt=2020-08-01T12:05:00Z
    ...    context=${ngsild_test_suite_context}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Temporal Representation Of Entity    ${id}

061_01_12 Endpoint /temporal/entities/{entityId}
    [Documentation]    Verify that a HEAD request on /temporal/entities/{entityId} is answered with 204 No Content and no body
    [Tags]    te-retrieve    cb-head    http_5    http_8_3_3_1
    ${id}=    Generate Random Vehicle Entity Id
    ${response}=    Create Or Update Temporal Representation Of Entity Selecting Content Type
    ...    temporal_entity_representation_id=${id}
    ...    filename=${tea_filename}
    ...    content_type=${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=temporal/entities/${id}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Temporal Representation Of Entity    ${id}

061_01_13 Endpoint /csourceRegistrations/
    [Documentation]    Verify that a HEAD request on /csourceRegistrations/ is answered with 204 No Content and no body
    [Tags]    csr-query    cb-head    http_5    http_9_2_3_1
    ${id}=    Generate Random CSR Id
    ${payload}=    Load JSON From File    ${EXECDIR}/data/${registration_filename}
    ${payload}=    Update Value To JSON    ${payload}    $..id    ${id}
    ${response}=    Create Context Source Registration With Return    ${payload}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=csourceRegistrations/
    ...    type=Vehicle
    ...    context=${ngsild_test_suite_context}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Context Source Registration    ${id}

061_01_14 Endpoint /csourceRegistrations/{registrationId}
    [Documentation]    Verify that a HEAD request on /csourceRegistrations/{registrationId} is answered with 204 No Content and no body
    [Tags]    csr-retrieve    cb-head    http_5    http_9_3_3_1
    ${id}=    Generate Random CSR Id
    ${payload}=    Load JSON From File    ${EXECDIR}/data/${registration_filename}
    ${payload}=    Update Value To JSON    ${payload}    $..id    ${id}
    ${response}=    Create Context Source Registration With Return    ${payload}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=csourceRegistrations/${id}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Context Source Registration    ${id}

061_01_15 Endpoint /csourceSubscriptions/
    [Documentation]    Verify that a HEAD request on /csourceSubscriptions/ is answered with 204 No Content and no body
    [Tags]    csrsub-query    cb-head    http_5    http_9_4_3_1
    ${id}=    Generate Random Subscription Id
    ${payload}=    Load Test Sample    ${csr_subscription_filename}    ${id}
    ${response}=    Create Context Source Registration Subscription    ${payload}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=csourceSubscriptions/
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Context Source Registration Subscription    ${id}

061_01_16 Endpoint /csourceSubscriptions/{subscriptionId}
    [Documentation]    Verify that a HEAD request on /csourceSubscriptions/{subscriptionId} is answered with 204 No Content and no body
    [Tags]    csrsub-retrieve    cb-head    http_5    http_9_5_3_1
    ${id}=    Generate Random Subscription Id
    ${payload}=    Load Test Sample    ${csr_subscription_filename}    ${id}
    ${response}=    Create Context Source Registration Subscription    ${payload}
    Check Response Status Code    201    ${response.status_code}
    ${response}=    Request With HEAD
    ...    path=csourceSubscriptions/${id}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete Context Source Registration Subscription    ${id}

061_01_17 Endpoint /jsonldContexts/
    [Documentation]    Verify that a HEAD request on /jsonldContexts/ is answered with 204 No Content and no body
    [Tags]    ctx-list    cb-head    http_5    http_10_2_3_1
    ${response}=    Request With HEAD
    ...    path=jsonldContexts/
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}

061_01_18 Endpoint /jsonldContexts/{contextId}
    [Documentation]    Verify that a HEAD request on /jsonldContexts/{contextId} is answered with 204 No Content and no body
    [Tags]    ctx-serve    cb-head    http_5    http_10_3_3_1
    ${response}=    Add a new @context    ${context_filename}
    Check Response Status Code    201    ${response.status_code}
    ${uri}=    Fetch Id From Response Location Header    ${response.headers}
    ${context_id}=    Replace String    ${uri}    ${NGSI_LD_API_PATH}/jsonldContexts/    ${EMPTY}
    ${context_id}=    Evaluate    urllib.parse.quote($context_id, safe='')    modules=urllib
    ${response}=    Request With HEAD
    ...    path=jsonldContexts/${context_id}
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
    [Teardown]    Delete a @context    ${uri}

061_01_19 Endpoint /info/sourceIdentity
    [Documentation]    Verify that a HEAD request on /info/sourceIdentity is answered with 204 No Content and no body
    [Tags]    csi-retrieve    cb-head    http_5    http_12_2_3_1
    ${response}=    Request With HEAD
    ...    path=info/sourceIdentity
    Check Response Status Code    204    ${response.status_code}
    Check Response Body Is Empty    ${response}
+95 −0
Changes for TP/NGSI-LD/CommonBehaviours/CommonResponses/VerifyHEAD/061_02.robot: 95 added lines, 0 removed lines.
Original line number Diff line number Diff line
*** Settings ***
Documentation       Verify that a HEAD request that the corresponding GET request would answer with an error is answered with the same error status code and no body

Resource            ${EXECDIR}/resources/ApiUtils/Common.resource
Resource            ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource
Resource            ${EXECDIR}/resources/AssertionUtils.resource

Suite Setup         Create Initial Entity
Suite Teardown      Delete Initial Entity
Test Template       Request With HEAD Answered With An Error


*** Variables ***
${building_filename}=       building-simple-attributes.jsonld


*** Test Cases ***    PATH    CONTEXT    EXPECTED_STATUS_CODE
061_02_01 Endpoint /entities/ Without Any Query Parameter
    [Tags]    e-query    cb-head    http_5    http_7_2_3_1
    entities/    ${EMPTY}    400
061_02_02 Endpoint /entities/{entityId} If The Entity Id Is Not A Valid URI
    [Tags]    e-retrieve    cb-head    http_5    http_7_3_3_1
    entities/thisisaninvaliduri    ${EMPTY}    400
061_02_03 Endpoint /entities/{entityId} If The Entity Is Not Known
    [Tags]    e-retrieve    cb-head    http_5    http_7_3_3_1
    entities/urn:ngsi-ld:Building:unknown061    ${EMPTY}    404
061_02_04 Endpoint /entities/{entityId}/attrs/{attrId} If The Attribute Is Not Known
    [Tags]    ea-retrieve    cb-head    http_5    http_7_5_3_1
    entities/${entity_id}/attrs/unknownAttribute    ${ngsild_test_suite_context}    404
061_02_05 Endpoint /entities/{entityId}/attrs/{attrId}/value If The Attribute Is Not Known
    [Tags]    ea-retrieve-value    cb-head    http_5    http_7_6_3_1
    entities/${entity_id}/attrs/unknownAttribute/value    ${ngsild_test_suite_context}    404
061_02_06 Endpoint /subscriptions/{subscriptionId} If The Subscription Id Is Not A Valid URI
    [Tags]    sub-retrieve    cb-head    http_5    http_7_14_3_1
    subscriptions/thisisaninvaliduri    ${EMPTY}    400
061_02_07 Endpoint /subscriptions/{subscriptionId} If The Subscription Is Not Known
    [Tags]    sub-retrieve    cb-head    http_5    http_7_14_3_1
    subscriptions/urn:ngsi-ld:Subscription:unknown061    ${EMPTY}    404
061_02_08 Endpoint /types/{type} If The Type Is Not Known
    [Tags]    ed-type    cb-head    http_5    http_7_16_3_1
    types/UnknownType061    ${ngsild_test_suite_context}    404
061_02_09 Endpoint /attributes/{attrId} If The Attribute Is Not Known
    [Tags]    ed-attr    cb-head    http_5    http_7_18_3_1
    attributes/unknownAttribute061    ${ngsild_test_suite_context}    404
061_02_10 Endpoint /temporal/entities/ Without Any Query Parameter
    [Tags]    te-query    cb-head    http_5    http_8_2_3_1
    temporal/entities/    ${EMPTY}    400
061_02_11 Endpoint /temporal/entities/{entityId} If The Entity Id Is Not A Valid URI
    [Tags]    te-retrieve    cb-head    http_5    http_8_3_3_1
    temporal/entities/thisisaninvaliduri    ${EMPTY}    400
061_02_12 Endpoint /temporal/entities/{entityId} If The Entity Is Not Known
    [Tags]    te-retrieve    cb-head    http_5    http_8_3_3_1
    temporal/entities/urn:ngsi-ld:Vehicle:unknown061    ${EMPTY}    404
061_02_13 Endpoint /csourceRegistrations/ Without Entity Types And Attribute Names
    [Tags]    csr-query    cb-head    http_5    http_9_2_3_1
    csourceRegistrations/    ${ngsild_test_suite_context}    400
061_02_14 Endpoint /csourceRegistrations/{registrationId} If The Registration Id Is Not A Valid URI
    [Tags]    csr-retrieve    cb-head    http_5    http_9_3_3_1
    csourceRegistrations/thisisaninvaliduri    ${EMPTY}    400
061_02_15 Endpoint /csourceRegistrations/{registrationId} If The Registration Is Not Known
    [Tags]    csr-retrieve    cb-head    http_5    http_9_3_3_1
    csourceRegistrations/urn:ngsi-ld:ContextSourceRegistration:unknown061    ${EMPTY}    404
061_02_16 Endpoint /csourceSubscriptions/{subscriptionId} If The Subscription Id Is Not A Valid URI
    [Tags]    csrsub-retrieve    cb-head    http_5    http_9_5_3_1
    csourceSubscriptions/thisisaninvaliduri    ${EMPTY}    400
061_02_17 Endpoint /csourceSubscriptions/{subscriptionId} If The Subscription Is Not Known
    [Tags]    csrsub-retrieve    cb-head    http_5    http_9_5_3_1
    csourceSubscriptions/urn:ngsi-ld:Subscription:unknown061    ${EMPTY}    404
061_02_18 Endpoint /jsonldContexts/{contextId} If The @context Is Not Known
    [Tags]    ctx-serve    cb-head    http_5    http_10_3_3_1
    jsonldContexts/unknownContext061    ${EMPTY}    404


*** Keywords ***
Create Initial Entity
    ${entity_id}=    Generate Random Building Entity Id
    ${response}=    Create Entity Selecting Content Type
    ...    ${building_filename}
    ...    ${entity_id}
    ...    ${CONTENT_TYPE_LD_JSON}
    Check Response Status Code    201    ${response.status_code}
    Set Suite Variable    ${entity_id}

Delete Initial Entity
    Delete Entity    ${entity_id}

Request With HEAD Answered With An Error
    [Documentation]    Verify that a HEAD request that the GET request would answer with an error gets the same status code and no body
    [Arguments]    ${path}    ${context}    ${expected_status_code}

    ${response}=    Request With HEAD
    ...    path=${path}
    ...    context=${context}
    Check Response Status Code    ${expected_status_code}    ${response.status_code}
    Check Response Body Is Empty    ${response}
+1 −0
Changes for doc/analysis/generaterobotdata.py: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ class GenerateRobotData:
            'CommonResponses/VerifyLdContextNotAvailable': 'HTTP',
            'CommonResponses/VerifyMergePatchJson': 'HTTP',
            'CommonResponses/VerifyGETWithoutAccept': 'HTTP',
            'CommonResponses/VerifyHEAD': 'HTTP',
            'CommonResponses/VerifyUnsupportedMediaType': 'HTTP',
            'CommonResponses/VerifyNotAcceptableMediaType': 'HTTP',
            'CommonResponses/VerifyInvalidParameters': 'HTTP'
+1 −1
Changes for doc/analysis/parseapiutilsfile.py: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ class ParseApiUtilsFile:

        for i, item in enumerate(string):
            if 'response' in item:
                regex = r"\s{4}\$\{response\}=\s{4}(POST|GET|PUT|PATCH|DELETE).*"
                regex = r"\s{4}\$\{response\}=\s{4}(POST|GET|PUT|PATCH|DELETE|HEAD).*"
                match = re.match(pattern=regex, string=item)

                if match:
+22 −0
Changes for doc/analysis/requests.py: 22 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -90,6 +90,10 @@ class Requests:
                'positions': [0],
                'params': ['attribute_name']
            },
            'Request With HEAD': {
                'positions': [],
                'params': ['path', 'context']
            },
            'Retrieve Entity Type': {
                'positions': [0, 1],
                'params': ['type', 'context']
@@ -343,6 +347,8 @@ class Requests:
                Requests.append_entity_attributes_with_parameters,
            'Retrieve Attribute':
                Requests.retrieve_attribute,
            'Request With HEAD':
                Requests.request_with_head,
            'Retrieve Entity Type':
                Requests.retrieve_entity_type,
            'Query Entities':
@@ -1347,6 +1353,22 @@ class Requests:

        return response

    @staticmethod
    def request_with_head(kwargs) -> str:
        # Any other named argument is a URL parameter
        response = "Request with HEAD:"
        for key, value in kwargs.items():
            match key:
                case 'path':
                    response = f"{response} and\n    Resource path set to '{value}'"
                case 'context':
                    if value not in ('', '${EMPTY}'):
                        response = f"{response} and\n    Header['Link'] containing '{value}'"
                case _:
                    response = f"{response} and\n    Query Parameter: {key} set to '{value}'"

        return response

    @staticmethod
    def retrieve_attribute(kwargs) -> str:
        if 'attribute_name' in kwargs:
Loading