diff --git a/TP/NGSI-LD/CommonBehaviours/CommonResponses/VerifyInvalidParameters/059_01.robot b/TP/NGSI-LD/CommonBehaviours/CommonResponses/VerifyInvalidParameters/059_01.robot new file mode 100644 index 0000000000000000000000000000000000000000..b353751cd5c4d1b4e49aa93c0ef0c5b221e1c8ac --- /dev/null +++ b/TP/NGSI-LD/CommonBehaviours/CommonResponses/VerifyInvalidParameters/059_01.robot @@ -0,0 +1,52 @@ +*** Settings *** +Documentation Check that sending an invalid parameter returns a 400 invalidRequest + +Resource ${EXECDIR}/resources/ApiUtils/Common.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource +Resource ${EXECDIR}/resources/JsonUtils.resource + +Test Template Call endpoint with invalid parameter + + +*** Variables *** +${filename}= building-minimal.json + + +*** Test Cases *** METHOD ENDPOINT FILENAME ADDITIONAL_QUERY_PARAM +059_01_01 CreateEntity + [Tags] e-create 5_6_1 6_3_20 since_v1.7.1 + POST entities entities/building-minimal.json +059_01_02 QueryEntities + [Tags] e-query 5_7_2 6_3_20 since_v1.7.1 + GET entities additionalParam=type=Building +059_01_03 CreateTemporalEntity + [Tags] te-create 5_6_11 6_3_20 since_v1.7.1 + POST ${TEMPORAL_ENTITIES_ENDPOINT_PATH} entities/building-minimal.json +059_01_04 QueryTemporalEntities + [Tags] te-query 5_7_2 6_3_20 since_v1.7.1 + GET ${TEMPORAL_ENTITIES_ENDPOINT_PATH} additionalParam=type=Building +059_01_05 RetrieveEntityTypes + [Tags] ed-types 5_7_5 6_3_20 since_v1.7.1 + GET ${ENTITIES_TYPES_ENDPOINT_PATH} +059_01_06 CreateSubscription + [Tags] sub-create 5_8_1 6_3_20 since_v1.7.1 + POST subscriptions subscriptions/subscription.jsonld +059_01_07 QuerySubscriptions + [Tags] sub-create 5_8_1 6_3_20 since_v1.7.1 + GET subscriptions + + +*** Keywords *** +Call endpoint with invalid parameter + [Documentation] Check that sending an invalid parameter returns a 400 invalidRequest + [Arguments] ${method} ${endpoint} ${filename}=${EMPTY} ${additionalParam}=${EMPTY} + ${response}= Call Api Endpoint With Invalid Parameter + ... ${method} + ... ${endpoint} + ... ${filename} + ... ${additionalParam} + + Check Response Status Code 400 ${response.status_code} + Check Response Body Containing ProblemDetails Element Containing Type Element set to + ... ${response.json()} + ... ${ERROR_TYPE_INVALID_REQUEST} diff --git a/doc/analysis/generaterobotdata.py b/doc/analysis/generaterobotdata.py index 987447d0f1b98a45c7d83558fdc8954fa4a904b2..da646582b95351469e7dc0b4b2d6acee7d1c61e6 100644 --- a/doc/analysis/generaterobotdata.py +++ b/doc/analysis/generaterobotdata.py @@ -91,7 +91,8 @@ class GenerateRobotData: 'CommonResponses/VerifyMergePatchJson': 'HTTP', 'CommonResponses/VerifyGETWithoutAccept': 'HTTP', 'CommonResponses/VerifyUnsupportedMediaType': 'HTTP', - 'CommonResponses/VerifyNotAcceptableMediaType': 'HTTP' + 'CommonResponses/VerifyNotAcceptableMediaType': 'HTTP', + 'CommonResponses/VerifyInvalidParameters': 'HTTP' } self.references = { 'v1.3.1': 'ETSI GS CIM 009 V1.3.1 []' diff --git a/doc/analysis/parserobotfile.py b/doc/analysis/parserobotfile.py index 04b753176f973679956a75bbc26e81833e3881f8..038d884e754303798a252559995f9d226400c674 100644 --- a/doc/analysis/parserobotfile.py +++ b/doc/analysis/parserobotfile.py @@ -369,7 +369,7 @@ class ParseRobotFile: return checks def generate_when_content(self, http_verb, endpoint, when): - if when.find("a subscription with id set to") == -1: + if when.find("a subscription with id set to") == -1 and when.find("Call API Endpoint with") == -1: url = f"URL set to '/ngsi-ld/v1/{endpoint}'" method = f"method set to '{http_verb}'" when = (f"when {{\n the SUT receives a Request from the client containing:\n" @@ -377,6 +377,10 @@ class ParseRobotFile: f" {method}\n" f" {when}\n" f"}}") + elif when.find("Call API Endpoint with") != -1: + when = (f"when {{\n the SUT receives a Request from the client containing:\n" + f" {when}\n" + f"}}") else: # This is a Notification operation when = f"The client at ${{endpoint}} receives a valid Notification containing {when}" diff --git a/doc/analysis/requests.py b/doc/analysis/requests.py index 7283c6d9d332031993d64ed443a2528b17ced06b..d18b0f79838784b174127674629720e0e353cea7 100644 --- a/doc/analysis/requests.py +++ b/doc/analysis/requests.py @@ -20,6 +20,10 @@ class Requests: 'positions': [0], 'params': ['filename'] }, + 'Call Api Endpoint With Invalid Parameter': { + 'positions': [0, 1, 2, 3], + 'params': ['method', 'endpoint', 'filename', 'extraParam'] + }, 'Create Entity From JSON-LD Content': { 'positions': [0], 'params': ['content'] @@ -298,6 +302,8 @@ class Requests: Requests.create_entity_selecting_content_type, 'Create Entity From File': Requests.create_entity_from_file, + 'Call Api Endpoint With Invalid Parameter': + Requests.call_api_endpoint_with_invalid_parameter, 'Create Or Update Temporal Representation Of Entity Selecting Content Type': Requests.create_or_update_temporal_representation_of_entity_selecting_content_type, 'Batch Create Entities': @@ -633,6 +639,27 @@ class Requests: else: raise Exception(f"ERROR: expected filename attribute, but received {kwargs}") + @staticmethod + def call_api_endpoint_with_invalid_parameter(kwargs) -> str: + expected_parameters = ['method', 'endpoint', 'filename', 'extraParam'] + + result = [x for x in kwargs if x not in expected_parameters] + response = "Call API Endpoint with:" + for key, value in kwargs.items(): + match key: + case 'method': + response = f"{response} and\n Method: {key} set to '{value}'" + case 'endpoint': + response = f"{response} and\n Endpoint: {key} set to '{value}'" + case 'filename': + response = f"{response} and\n Filename: {key} set to '{value}'" + case 'extraParam': + response = f"{response} and\n Extra param: {key} set to '{value}'" + case _: + raise Exception(f"ERROR: unexpected attribute(s) {result}, the attributes expected are " + f"{expected_parameters}, but received: {kwargs}") + return response + @staticmethod def batch_update_entities(kwargs) -> str: if 'overwrite_option' not in kwargs: diff --git a/doc/files/CommonBehaviours/059_01.json b/doc/files/CommonBehaviours/059_01.json new file mode 100644 index 0000000000000000000000000000000000000000..9a1cb0a6b1f86f059a113cd130675859fde4fb70 --- /dev/null +++ b/doc/files/CommonBehaviours/059_01.json @@ -0,0 +1,154 @@ +{ + "tp_id": "TP/NGSI-LD/CB/HTTP/059_01", + "test_objective": "Check that sending an invalid parameter returns a 400 invalidRequest", + "reference": "ETSI GS CIM 009 V1.7.1 [], clauses 5.6.1, 5.6.11, 5.7.2, 5.7.5, 5.8.1, 6.3.20", + "config_id": "", + "parent_release": "v1.7.1", + "clauses": [ + "5.6.1", + "5.6.11", + "5.7.2", + "5.7.5", + "5.8.1", + "6.3.20" + ], + "pics_selection": "", + "keywords": [ + "Call endpoint with invalid parameter" + ], + "teardown": "None", + "initial_condition": "with {\n the SUT containing an initial state\n}", + "test_cases": [ + { + "name": "059_01_01 CreateEntity", + "permutation_tp_id": "TP/NGSI-LD/CB/HTTP/059_01_01", + "doc": "Check that sending an invalid parameter returns a 400 invalidRequest", + "tags": [ + "5_6_1", + "6_3_20", + "e-create", + "since_v1.7.1" + ], + "setup": null, + "teardown": null, + "template": "Call endpoint with invalid parameter", + "then": "then {\n the SUT sends a valid Response for the operations:\n Call Api Endpoint With Invalid Parameter with Response Status Code set to 400 and\n Call Api Endpoint With Invalid Parameter with Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/InvalidRequest'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n Call API Endpoint with: and\n Method: method set to 'POST' and\n Endpoint URL: endpoint_url set to 'entities' and\n Filename: filename set to 'building-minimal.json' and\n Extra param: extraParam set to '${additionalParam}'\n}", + "http_verb": "GET", + "endpoint": "{endpoint}/{params}" + }, + { + "name": "059_01_02 QueryEntities", + "permutation_tp_id": "TP/NGSI-LD/CB/HTTP/059_01_02", + "doc": "Check that sending an invalid parameter returns a 400 invalidRequest", + "tags": [ + "5_7_2", + "6_3_20", + "e-query", + "since_v1.7.1" + ], + "setup": null, + "teardown": null, + "template": "Call endpoint with invalid parameter", + "then": "then {\n the SUT sends a valid Response for the operations:\n Call Api Endpoint With Invalid Parameter with Response Status Code set to 400 and\n Call Api Endpoint With Invalid Parameter with Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/InvalidRequest'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n Call API Endpoint with: and\n Method: method set to 'GET' and\n Endpoint URL: endpoint_url set to 'entities' and\n Filename: filename set to 'building-minimal.json' and\n Extra param: extraParam set to '${additionalParam}'\n}", + "http_verb": "GET", + "endpoint": "{endpoint}/{params}" + }, + { + "name": "059_01_03 CreateTemporalEntity", + "permutation_tp_id": "TP/NGSI-LD/CB/HTTP/059_01_03", + "doc": "Check that sending an invalid parameter returns a 400 invalidRequest", + "tags": [ + "5_6_11", + "6_3_20", + "since_v1.7.1", + "te-create" + ], + "setup": null, + "teardown": null, + "template": "Call endpoint with invalid parameter", + "then": "then {\n the SUT sends a valid Response for the operations:\n Call Api Endpoint With Invalid Parameter with Response Status Code set to 400 and\n Call Api Endpoint With Invalid Parameter with Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/InvalidRequest'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n Call API Endpoint with: and\n Method: method set to 'POST' and\n Endpoint URL: endpoint_url set to 'temporal/entities' and\n Filename: filename set to 'building-minimal.json' and\n Extra param: extraParam set to '${additionalParam}'\n}", + "http_verb": "GET", + "endpoint": "{endpoint}/{params}" + }, + { + "name": "059_01_04 QueryTemporalEntities", + "permutation_tp_id": "TP/NGSI-LD/CB/HTTP/059_01_04", + "doc": "Check that sending an invalid parameter returns a 400 invalidRequest", + "tags": [ + "5_7_2", + "6_3_20", + "since_v1.7.1", + "te-query" + ], + "setup": null, + "teardown": null, + "template": "Call endpoint with invalid parameter", + "then": "then {\n the SUT sends a valid Response for the operations:\n Call Api Endpoint With Invalid Parameter with Response Status Code set to 400 and\n Call Api Endpoint With Invalid Parameter with Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/InvalidRequest'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n Call API Endpoint with: and\n Method: method set to 'GET' and\n Endpoint URL: endpoint_url set to 'temporal/entities' and\n Filename: filename set to 'building-minimal.json' and\n Extra param: extraParam set to '${additionalParam}'\n}", + "http_verb": "GET", + "endpoint": "{endpoint}/{params}" + }, + { + "name": "059_01_05 RetrieveEntityTypes", + "permutation_tp_id": "TP/NGSI-LD/CB/HTTP/059_01_05", + "doc": "Check that sending an invalid parameter returns a 400 invalidRequest", + "tags": [ + "5_7_5", + "6_3_20", + "ed-types", + "since_v1.7.1" + ], + "setup": null, + "teardown": null, + "template": "Call endpoint with invalid parameter", + "then": "then {\n the SUT sends a valid Response for the operations:\n Call Api Endpoint With Invalid Parameter with Response Status Code set to 400 and\n Call Api Endpoint With Invalid Parameter with Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/InvalidRequest'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n Call API Endpoint with: and\n Method: method set to 'GET' and\n Endpoint URL: endpoint_url set to 'types' and\n Filename: filename set to 'building-minimal.json' and\n Extra param: extraParam set to '${additionalParam}'\n}", + "http_verb": "GET", + "endpoint": "{endpoint}/{params}" + }, + { + "name": "059_01_06 CreateSubscription", + "permutation_tp_id": "TP/NGSI-LD/CB/HTTP/059_01_06", + "doc": "Check that sending an invalid parameter returns a 400 invalidRequest", + "tags": [ + "5_8_1", + "6_3_20", + "since_v1.7.1", + "sub-create" + ], + "setup": null, + "teardown": null, + "template": "Call endpoint with invalid parameter", + "then": "then {\n the SUT sends a valid Response for the operations:\n Call Api Endpoint With Invalid Parameter with Response Status Code set to 400 and\n Call Api Endpoint With Invalid Parameter with Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/InvalidRequest'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n Call API Endpoint with: and\n Method: method set to 'POST' and\n Endpoint URL: endpoint_url set to 'subscriptions' and\n Filename: filename set to 'building-minimal.json' and\n Extra param: extraParam set to '${additionalParam}'\n}", + "http_verb": "GET", + "endpoint": "{endpoint}/{params}" + }, + { + "name": "059_01_07 QuerySubscriptions", + "permutation_tp_id": "TP/NGSI-LD/CB/HTTP/059_01_07", + "doc": "Check that sending an invalid parameter returns a 400 invalidRequest", + "tags": [ + "5_8_1", + "6_3_20", + "since_v1.7.1", + "sub-create" + ], + "setup": null, + "teardown": null, + "template": "Call endpoint with invalid parameter", + "then": "then {\n the SUT sends a valid Response for the operations:\n Call Api Endpoint With Invalid Parameter with Response Status Code set to 400 and\n Call Api Endpoint With Invalid Parameter with Response Body containing the type 'https://uri.etsi.org/ngsi-ld/errors/InvalidRequest'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n Call API Endpoint with: and\n Method: method set to 'GET' and\n Endpoint URL: endpoint_url set to 'subscriptions' and\n Filename: filename set to 'building-minimal.json' and\n Extra param: extraParam set to '${additionalParam}'\n}", + "http_verb": "GET", + "endpoint": "{endpoint}/{params}" + } + ], + "permutations": [ + "when" + ], + "robotpath": "CommonBehaviours/CommonResponses/VerifyInvalidParameters", + "robotfile": "059_01" +} \ No newline at end of file diff --git a/resources/ApiUtils/Common.resource b/resources/ApiUtils/Common.resource index 85c8ad5b4b4296032a373e2dedd56bc81188e5c9..a199aceb689377a72f7f0b33d1bfc2ac932cf3b3 100644 --- a/resources/ApiUtils/Common.resource +++ b/resources/ApiUtils/Common.resource @@ -1,18 +1,28 @@ *** Settings *** -Library String +Variables ${EXECDIR}/resources/variables.py +Library ${EXECDIR}/libraries/logUtils.py +Library RequestsLibrary +Library OperatingSystem +Library Collections +Library JSONLibrary +Library String *** Variables *** -${BUILDING_ID_PREFIX} urn:ngsi-ld:Building: -${BUS_ID_PREFIX} urn:ngsi-ld:Bus: -${CITY_ID_PREFIX} urn:ngsi-ld:City: -${PARKING_ID_PREFIX} urn:ngsi-ld:OffStreetParking: -${VEHICLE_ID_PREFIX} urn:ngsi-ld:Vehicle: +${BUILDING_ID_PREFIX} urn:ngsi-ld:Building: +${BUS_ID_PREFIX} urn:ngsi-ld:Bus: +${CITY_ID_PREFIX} urn:ngsi-ld:City: +${PARKING_ID_PREFIX} urn:ngsi-ld:OffStreetParking: +${VEHICLE_ID_PREFIX} urn:ngsi-ld:Vehicle: -${SUBSCRIPTION_ID_PREFIX}= urn:ngsi-ld:Subscription: +${SUBSCRIPTION_ID_PREFIX}= urn:ngsi-ld:Subscription: -${CSR_ID_PREFIX}= urn:ngsi-ld:ContextSourceRegistration: +${CSR_ID_PREFIX}= urn:ngsi-ld:ContextSourceRegistration: +${TEMPORAL_ENTITIES_ENDPOINT_PATH} temporal/entities +${ENTITIES_TYPES_ENDPOINT_PATH} types + +${ERROR_TYPE_INVALID_REQUEST} https://uri.etsi.org/ngsi-ld/errors/InvalidRequest *** Keywords *** Build Context Link @@ -51,3 +61,40 @@ Generate Random Subscription Id Generate Random CSR Id ${entity_id}= Generate Random Id ${CSR_ID_PREFIX} RETURN ${entity_id} + +Call Api Endpoint With Invalid Parameter + [Arguments] ${method} ${endpoint} ${filename}=${EMPTY} ${extraParam}=${EMPTY} + IF '${filename}' != "${EMPTY}" + ${file_content}= Get File ${EXECDIR}/data/${filename} + END + + &{headers}= Create Dictionary Content-Type=application/ld+json + + IF '${extraParam}' != "${empty}" + ${params}= Catenate ?invalidParams=invalidValue& ${extraParam} + ELSE + ${params}= Catenate ?invalidParams=invalidValue + END + + # No multi method request function in the robotframework-requests library + IF "${method}"=="GET" + ${response}= GET + ... url=${url}/${endpoint}${params} + ... headers=${headers} + ... expected_status=any + ELSE IF "${method}"=="POST" + ${response}= POST + ... url=${url}/${endpoint}${params} + ... json=${file_content} + ... headers=${headers} + ... expected_status=any + ELSE IF "${method}"=="PUT" + ${response}= PUT + ... url=${url}/${endpoint}${params} + ... json=${file_content} + ... headers=${headers} + ... expected_status=any + END + + Output ${response} Call endpoint With Invalid Parameter + RETURN ${response}