diff --git a/README.md b/README.md index 40b7def795d246cc5ffb1f5f9eb558cb7f8ec7b0..e10d366f18e78c35ee1a6c0003a8771e0c12854e 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ execution of the following command in MacOS or Ubuntu: In case of Windows, you need to execute the following command: -```> .\.venv\scripts\activate.bat ``` +```> .\venv\Scripts\activate.bat ``` Now, you can launch the tests with the following command in MacOS or Linux: diff --git a/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_01.robot b/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_01.robot new file mode 100644 index 0000000000000000000000000000000000000000..39acd703339d4ceed1ce161604168ef5142122eb --- /dev/null +++ b/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_01.robot @@ -0,0 +1,67 @@ +*** Settings *** +Documentation Check that you can merge a batch of entities + +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationConsumption.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource +Resource ${EXECDIR}/resources/JsonUtils.resource + +Test Setup Setup Initial Entities +Test Teardown Delete Initial Entities +Test Template Batch Merge Entity Scenarios + + +*** Variables *** +${building_id_prefix}= urn:ngsi-ld:Building: +${entity_payload_filename}= merge/building-merge-data.jsonld + + +*** Test Cases *** FILENAME MERGE_FRAGMENT_FILENAME +057_01_01 MergeAnEmptyEntity + [Tags] be-merge 5_6_17 since_v1.6.1 + building-minimal.jsonld batch-merge/two-buildings-non-edited.jsonld +057_01_02 MergeSimpleProperties + [Tags] be-merge 5_6_17 since_v1.6.1 + building-simple-attributes-second.jsonld batch-merge/two-buildings-attributes-edited.jsonld +057_01_03 MergeSimpleRelationship + [Tags] be-merge 5_6_17 since_v1.6.1 + building-relationship.jsonld batch-merge/two-buildings-with-relationship.jsonld +057_01_04 MergePropertyWithPartialData + [Tags] be-merge 5_6_17 since_v1.6.1 + merge/building-only-airQualityLevel-value.jsonld batch-merge/two-buildings-with-changed-airQualityLevel.jsonld + + +*** Keywords *** +Batch Merge Entity Scenarios + [Documentation] Check that you can merge a batch of entities + [Arguments] ${filename} ${expectation_filename} + ${first_entity}= Load Entity ${filename} ${first_entity_id} + ${second_entity}= Load Entity ${filename} ${second_entity_id} + @{entities_ids_to_be_merged}= Create List ${first_entity_id} ${second_entity_id} + @{entities_to_be_merged}= Create List ${first_entity} ${second_entity} + ${response}= Batch Merge Entities @{entities_to_be_merged} + Check Response Status Code 204 ${response.status_code} + + ${expected_entities_ids}= Catenate SEPARATOR=, @{entities_ids_to_be_merged} + ${response1}= Query Entities + ... entity_ids=${expected_entities_ids} + ... entity_types=Building + ... context=${ngsild_test_suite_context} + ... accept=${CONTENT_TYPE_LD_JSON} + Check Response Body Containing List Containing Entity Elements With Different Types + ... filename=${expectation_filename} + ... entities_representation_ids=${entities_ids_to_be_merged} + ... response_body=${response1.json()} + ... ignore_core_context_version=${True} + +Setup Initial Entities + ${first_entity_id}= Generate Random Entity Id ${building_id_prefix} + ${second_entity_id}= Generate Random Entity Id ${building_id_prefix} + Create Entity ${entity_payload_filename} ${first_entity_id} + Create Entity ${entity_payload_filename} ${second_entity_id} + Set Test Variable ${first_entity_id} + Set Test Variable ${second_entity_id} + +Delete Initial Entities + @{entities_ids_to_be_deleted}= Create List ${first_entity_id} ${second_entity_id} + Batch Delete Entities entities_ids_to_be_deleted=@{entities_ids_to_be_deleted} diff --git a/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_02.robot b/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_02.robot new file mode 100644 index 0000000000000000000000000000000000000000..8461c53942fda8807dc5ffb6f37895176b144430 --- /dev/null +++ b/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_02.robot @@ -0,0 +1,72 @@ +*** Settings *** +Documentation Check that you can merge a batch of entities where some will succeed and others will fail + +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationConsumption.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource +Resource ${EXECDIR}/resources/JsonUtils.resource + +Suite Setup Setup Initial Entities +Suite Teardown Delete Initial Entities + + +*** Variables *** +${building_id_prefix}= urn:ngsi-ld:Building: +${entity_payload_filename}= building-simple-attributes.jsonld +${merge_fragment_filename}= fragmentEntities/simple-attributes-relationship-of-property-fragment.json +${entity_filename}= building-relationship-of-property.jsonld + + +*** Test Cases *** +057_02_01 Merge a batch should succeed for existing entities and fail for non existing one by returning 207 status + [Documentation] Check that you can merge a batch of non-existing and existing entities + [Tags] be-merge 5_6_17 since_v1.6.1 + ${first_existing_entity}= Load Entity + ... ${entity_filename} + ... ${first_existing_entity_id} + ${second_existing_entity}= Load Entity + ... ${entity_filename} + ... ${second_existing_entity_id} + ${new_entity_id}= Generate Random Entity Id ${building_id_prefix} + ${new_entity}= Load Entity ${entity_filename} ${new_entity_id} + @{entities_to_be_merged}= Create List ${first_existing_entity} ${second_existing_entity} ${new_entity} + + ${response}= Batch Merge Entities @{entities_to_be_merged} + @{expected_successful_entities_ids}= Create List ${first_existing_entity_id} ${second_existing_entity_id} + Set Suite Variable @{expected_successful_entities_ids} + @{expected_failed_entities_ids}= Create List ${new_entity_id} + &{expected_batch_operation_result}= Create Batch Operation Result + ... ${expected_successful_entities_ids} + ... ${expected_failed_entities_ids} + Check Response Status Code 207 ${response.status_code} + Check Response Body Containing Batch Operation Result ${expected_batch_operation_result} ${response.json()} + + ${first_created_entity}= Load Test Sample entities/${entity_payload_filename} ${first_existing_entity_id} + ${second_created_entity}= Load Test Sample + ... entities/${entity_payload_filename} + ... ${second_existing_entity_id} + ${merge_fragment}= Load Test Sample entities/${merge_fragment_filename} + ${first_merged_entity}= Upsert Element In Entity ${first_created_entity} ${merge_fragment} + ${second_merged_entity}= Upsert Element In Entity ${second_created_entity} ${merge_fragment} + @{merged_entities}= Create List ${first_merged_entity} ${second_merged_entity} + ${expected_entities_ids}= Catenate SEPARATOR=, @{expected_successful_entities_ids} + + ${response1}= Query Entities + ... entity_ids=${expected_entities_ids} + ... entity_types=Building + ... context=${ngsild_test_suite_context} + ... accept=${CONTENT_TYPE_LD_JSON} + Check Updated Resources Set To ${merged_entities} ${response1.json()} + + +*** Keywords *** +Setup Initial Entities + ${first_existing_entity_id}= Generate Random Entity Id ${building_id_prefix} + ${second_existing_entity_id}= Generate Random Entity Id ${building_id_prefix} + Create Entity ${entity_payload_filename} ${first_existing_entity_id} + Create Entity ${entity_payload_filename} ${second_existing_entity_id} + Set Suite Variable ${first_existing_entity_id} + Set Suite Variable ${second_existing_entity_id} + +Delete Initial Entities + Batch Delete Entities entities_ids_to_be_deleted=@{expected_successful_entities_ids} diff --git a/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_03.robot b/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_03.robot new file mode 100644 index 0000000000000000000000000000000000000000..cc968040edec74660a78eb26acd652b9ebe3cb79 --- /dev/null +++ b/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/MergeBatchOfEntities/057_03.robot @@ -0,0 +1,26 @@ +*** Settings *** +Documentation Check that you cannot merge a batch of entities with an invalid request + +Resource ${EXECDIR}/resources/ApiUtils/ContextInformationProvision.resource +Resource ${EXECDIR}/resources/AssertionUtils.resource + +Test Template Batch Merge Entity With Invalid Request Scenarios + + +*** Test Cases *** FILENAME PROBLEM_TYPE +057_03_01 InvalidJson [Tags] be-merge 5_6_17 since_v1.6.1 + batch/invalid-json.jsonld ${ERROR_TYPE_INVALID_REQUEST} +057_03_02 InvalidJsonLd [Tags] be-merge 5_6_17 since_v1.6.1 + batch/invalid-json-ld.jsonld ${ERROR_TYPE_BAD_REQUEST_DATA} + + +*** Keywords *** +Batch Merge Entity With Invalid Request Scenarios + [Documentation] Check that you cannot merge a batch of entities with an invalid request + [Arguments] ${filename} ${problem_type} + ${response}= Batch Request Entities From File merge filename=${filename} + Check Response Status Code 400 ${response.status_code} + Check RL Response Body Containing ProblemDetails Element Containing Type Element set to + ... ${response.json()} + ... ${problem_type} + Check RL Response Body Containing ProblemDetails Element Containing Title Element ${response.json()} diff --git a/data/entities/expectations/batch-merge/two-buildings-attributes-edited.jsonld b/data/entities/expectations/batch-merge/two-buildings-attributes-edited.jsonld new file mode 100644 index 0000000000000000000000000000000000000000..1c38983bdfe9f8c9a818f7c3f1cf5f706cc16996 --- /dev/null +++ b/data/entities/expectations/batch-merge/two-buildings-attributes-edited.jsonld @@ -0,0 +1,48 @@ +[{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Pisa Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "value": 6, + "unitCode": "C62", + "observedAt": "2020-10-10T16:40:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": true + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + } +,{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Pisa Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "value": 6, + "unitCode": "C62", + "observedAt": "2020-10-10T16:40:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": true + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + } + +] diff --git a/data/entities/expectations/batch-merge/two-buildings-non-edited.jsonld b/data/entities/expectations/batch-merge/two-buildings-non-edited.jsonld new file mode 100644 index 0000000000000000000000000000000000000000..3e357424366e9860df9848c48294c3d170c9b9f3 --- /dev/null +++ b/data/entities/expectations/batch-merge/two-buildings-non-edited.jsonld @@ -0,0 +1,48 @@ +[{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Eiffel Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "value": 4, + "unitCode": "C62", + "observedAt": "2020-09-09T16:40:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": false + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + } +,{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Eiffel Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "value": 4, + "unitCode": "C62", + "observedAt": "2020-09-09T16:40:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": false + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + } + +] diff --git a/data/entities/expectations/batch-merge/two-buildings-with-changed-airQualityLevel.jsonld b/data/entities/expectations/batch-merge/two-buildings-with-changed-airQualityLevel.jsonld new file mode 100644 index 0000000000000000000000000000000000000000..ecdc7b964860ea51ed3f786a4e4152cb97c786e6 --- /dev/null +++ b/data/entities/expectations/batch-merge/two-buildings-with-changed-airQualityLevel.jsonld @@ -0,0 +1,46 @@ +[{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Eiffel Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "unitCode": "C62", + "value": 1, + "observedAt": "2024-01-01T00:00:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": false + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" +},{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Eiffel Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "unitCode": "C62", + "value": 1, + "observedAt": "2024-01-01T00:00:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": false + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" +} +] diff --git a/data/entities/expectations/batch-merge/two-buildings-with-relationship.jsonld b/data/entities/expectations/batch-merge/two-buildings-with-relationship.jsonld new file mode 100644 index 0000000000000000000000000000000000000000..9bf9b9d800a54b1b244592464561501cbe1e5c81 --- /dev/null +++ b/data/entities/expectations/batch-merge/two-buildings-with-relationship.jsonld @@ -0,0 +1,56 @@ +[{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Eiffel Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "value": 4, + "unitCode": "C62", + "observedAt": "2020-09-09T16:40:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": false + }, + "locatedAt": { + "type": "Relationship", + "object": "urn:ngsi-ld:City:Paris" + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + } +,{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Eiffel Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "value": 4, + "unitCode": "C62", + "observedAt": "2020-09-09T16:40:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": false + }, + "locatedAt": { + "type": "Relationship", + "object": "urn:ngsi-ld:City:Paris" + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" + } + +] diff --git a/data/entities/merge/building-merge-data.jsonld b/data/entities/merge/building-merge-data.jsonld new file mode 100644 index 0000000000000000000000000000000000000000..32109af26aadf08ea9e79d61c26015f79c1548ae --- /dev/null +++ b/data/entities/merge/building-merge-data.jsonld @@ -0,0 +1,23 @@ +{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "name": { + "type": "Property", + "value": "Eiffel Tower" + }, + "subCategory": { + "type": "Property", + "value": "tourism" + }, + "airQualityLevel": { + "type": "Property", + "value": 4, + "unitCode": "C62", + "observedAt": "2020-09-09T16:40:00.000Z" + }, + "almostFull": { + "type": "Property", + "value": false + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" +} diff --git a/data/entities/merge/building-only-airQualityLevel-value.jsonld b/data/entities/merge/building-only-airQualityLevel-value.jsonld new file mode 100644 index 0000000000000000000000000000000000000000..f961f389605193fc56e06fc59a3855dbdd99f542 --- /dev/null +++ b/data/entities/merge/building-only-airQualityLevel-value.jsonld @@ -0,0 +1,10 @@ +{ + "id": "urn:ngsi-ld:Building:randomUUID", + "type": "Building", + "airQualityLevel": { + "type": "Property", + "value": 1, + "observedAt": "2024-01-01T00:00:00.000Z" + }, + "@context": "https://forge.etsi.org/rep/cim/ngsi-ld-test-suite/-/raw/develop/resources/jsonld-contexts/ngsi-ld-test-suite-compound.jsonld" +} diff --git a/doc/analysis/generaterobotdata.py b/doc/analysis/generaterobotdata.py index 9b2b7a918134f220671843d57823e097ff44c432..79100d7f45530959efec4bf79eb774b236bd801e 100644 --- a/doc/analysis/generaterobotdata.py +++ b/doc/analysis/generaterobotdata.py @@ -52,6 +52,7 @@ class GenerateRobotData: 'BatchEntities/CreateBatchOfEntities': 'BE', 'BatchEntities/UpsertBatchOfEntities': 'BE', 'BatchEntities/UpdateBatchOfEntities': 'BE', + 'BatchEntities/MergeBatchOfEntities': 'BE', 'BatchEntities/DeleteBatchOfEntities': 'BE', 'TemporalEntity/QueryTemporalEvolutionOfEntities': 'TE', 'TemporalEntity/DeleteTemporalRepresentationOfEntity': 'TE', diff --git a/doc/analysis/requests.py b/doc/analysis/requests.py index 3899e01e9b87867bff9effe4d78ee36d16b9e18b..5e809dbca48184b9c047b513bf77c8df62de45ad 100644 --- a/doc/analysis/requests.py +++ b/doc/analysis/requests.py @@ -205,6 +205,10 @@ class Requests: 'positions': [], 'params': ['entities_to_be_upserted', 'update_option'] }, + 'Batch Merge Entities': { + 'positions': [], + 'params': ['entities'] + }, 'Request Entity From File': { 'positions': [0], 'params': ['filename'] @@ -356,6 +360,8 @@ class Requests: Requests.batch_update_entities, 'Batch Upsert Entities': Requests.batch_upsert_entities, + 'Batch Merge Entities': + Requests.batch_merge_entities, 'Request Entity From File': Requests.request_entity_from_file, 'Delete Entity Attributes': @@ -623,6 +629,19 @@ class Requests: else: raise Exception(f"ERROR, expected filename attribute, but received {kwargs}") + @staticmethod + def batch_merge_entities(kwargs) -> str: + if 'overwrite_option' not in kwargs: + kwargs['overwrite_option'] = '${EMPTY}' + + if 'entities' in kwargs: + result = (f"Request batch merge operation over entity from filename '{kwargs['entities']}' " + f"with Content-Type set to 'application/ld+json'") + return result + else: + raise Exception(f"ERROR, expected filename attribute, but received {kwargs}") + + @staticmethod def list_contexts(kwargs) -> str: expected_parameters = ['details', 'kind'] diff --git a/doc/files/ContextInformation/Provision/057_01.json b/doc/files/ContextInformation/Provision/057_01.json new file mode 100644 index 0000000000000000000000000000000000000000..2d5504c6b125490bebcf0cfa39618462397a7433 --- /dev/null +++ b/doc/files/ContextInformation/Provision/057_01.json @@ -0,0 +1,91 @@ +{ + "tp_id": "TP/NGSI-LD/CI/Prov/BE/057_01", + "test_objective": "Check that you can merge a batch of entities", + "reference": "ETSI GS CIM 009 V1.6.1 [], clause 5.6.17", + "config_id": "", + "parent_release": "v1.6.1", + "clauses": [ + "5.6.17" + ], + "pics_selection": "", + "keywords": [ + "Batch Merge Entity Scenarios", + "Setup Initial Entities", + "Delete Initial Entities" + ], + "teardown": "None", + "initial_condition": "with {\n the SUT being in the \"initial state\" and\n and containing a list of entities\n}", + "test_cases": [ + { + "name": "057_01_01 MergeAnEmptyEntity", + "permutation_tp_id": "TP/NGSI-LD/CI/Prov/BE/057_01_01", + "doc": "Check that you can merge a batch of entities", + "tags": [ + "5_6_17", + "be-merge", + "since_v1.6.1" + ], + "setup": "Setup Initial Entities", + "teardown": "Delete Initial Entities", + "template": "Batch Merge Entity Scenarios", + "then": "then {\n the SUT sends a valid Response for the operations:\n Batch Merge Entities with Response Status Code set to 204 and\n Query Entities with Response body containing a list containing entity elements with different types and\n Query Parameter: filename set to 'expectation_filename' and\n Query Parameter: entities_representation_ids set to 'entities_ids_to_be_merged' and\n Query Parameter: response_body set to 'response1.json()' and\n Query Parameter: ignore_core_context_version set to 'True'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entityOperations/merge'\n method set to 'POST'\n Request batch merge operation over entity from filename '@{entities_to_be_merged}' with Content-Type set to 'application/ld+json'\n}", + "http_verb": "POST", + "endpoint": "entityOperations/merge" + }, + { + "name": "057_01_02 MergeSimpleProperties", + "permutation_tp_id": "TP/NGSI-LD/CI/Prov/BE/057_01_02", + "doc": "Check that you can merge a batch of entities", + "tags": [ + "5_6_17", + "be-merge", + "since_v1.6.1" + ], + "setup": "Setup Initial Entities", + "teardown": "Delete Initial Entities", + "template": "Batch Merge Entity Scenarios", + "then": "then {\n the SUT sends a valid Response for the operations:\n Batch Merge Entities with Response Status Code set to 204 and\n Query Entities with Response body containing a list containing entity elements with different types and\n Query Parameter: filename set to 'expectation_filename' and\n Query Parameter: entities_representation_ids set to 'entities_ids_to_be_merged' and\n Query Parameter: response_body set to 'response1.json()' and\n Query Parameter: ignore_core_context_version set to 'True'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entityOperations/merge'\n method set to 'POST'\n Request batch merge operation over entity from filename '@{entities_to_be_merged}' with Content-Type set to 'application/ld+json'\n}", + "http_verb": "POST", + "endpoint": "entityOperations/merge" + }, + { + "name": "057_01_03 MergeSimpleRelationship", + "permutation_tp_id": "TP/NGSI-LD/CI/Prov/BE/057_01_03", + "doc": "Check that you can merge a batch of entities", + "tags": [ + "5_6_17", + "be-merge", + "since_v1.6.1" + ], + "setup": "Setup Initial Entities", + "teardown": "Delete Initial Entities", + "template": "Batch Merge Entity Scenarios", + "then": "then {\n the SUT sends a valid Response for the operations:\n Batch Merge Entities with Response Status Code set to 204 and\n Query Entities with Response body containing a list containing entity elements with different types and\n Query Parameter: filename set to 'expectation_filename' and\n Query Parameter: entities_representation_ids set to 'entities_ids_to_be_merged' and\n Query Parameter: response_body set to 'response1.json()' and\n Query Parameter: ignore_core_context_version set to 'True'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entityOperations/merge'\n method set to 'POST'\n Request batch merge operation over entity from filename '@{entities_to_be_merged}' with Content-Type set to 'application/ld+json'\n}", + "http_verb": "POST", + "endpoint": "entityOperations/merge" + }, + { + "name": "057_01_04 MergePropertyWithPartialData", + "permutation_tp_id": "TP/NGSI-LD/CI/Prov/BE/057_01_04", + "doc": "Check that you can merge a batch of entities", + "tags": [ + "5_6_17", + "be-merge", + "since_v1.6.1" + ], + "setup": "Setup Initial Entities", + "teardown": "Delete Initial Entities", + "template": "Batch Merge Entity Scenarios", + "then": "then {\n the SUT sends a valid Response for the operations:\n Batch Merge Entities with Response Status Code set to 204 and\n Query Entities with Response body containing a list containing entity elements with different types and\n Query Parameter: filename set to 'expectation_filename' and\n Query Parameter: entities_representation_ids set to 'entities_ids_to_be_merged' and\n Query Parameter: response_body set to 'response1.json()' and\n Query Parameter: ignore_core_context_version set to 'True'\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entityOperations/merge'\n method set to 'POST'\n Request batch merge operation over entity from filename '@{entities_to_be_merged}' with Content-Type set to 'application/ld+json'\n}", + "http_verb": "POST", + "endpoint": "entityOperations/merge" + } + ], + "permutations": [], + "robotpath": "ContextInformation/Provision/BatchEntities/MergeBatchOfEntities", + "robotfile": "057_01" +} \ No newline at end of file diff --git a/doc/files/ContextInformation/Provision/057_02.json b/doc/files/ContextInformation/Provision/057_02.json new file mode 100644 index 0000000000000000000000000000000000000000..5b2b533c7b2b3fa92bd31113c71a90f2b960f207 --- /dev/null +++ b/doc/files/ContextInformation/Provision/057_02.json @@ -0,0 +1,38 @@ +{ + "tp_id": "TP/NGSI-LD/CI/Prov/BE/057_02", + "test_objective": "Check that you can merge a batch of entities where some will succeed and others will fail", + "reference": "ETSI GS CIM 009 V1.3.1 [], clause 5.6.17 since.v1.6.1", + "config_id": "", + "parent_release": "v1.3.1", + "clauses": [ + "5.6.17 since.v1.6.1" + ], + "pics_selection": "", + "keywords": [ + "Setup Initial Entities", + "Delete Initial Entities" + ], + "teardown": "Delete Initial Entities", + "initial_condition": "with {\n the SUT containing an initial state\n}", + "test_cases": [ + { + "name": "057_02_01 Merge a batch should succeed for existing entities and fail for non existing one by returning 207 status", + "permutation_tp_id": "TP/NGSI-LD/CI/Prov/BE/057_02_01", + "doc": "Check that you can merge a batch of non-existing and existing entities", + "tags": [ + "5_6_17 since_v1.6.1", + "be-merge" + ], + "setup": null, + "teardown": null, + "template": null, + "then": "then {\n the SUT sends a valid Response for the operations:\n Batch Merge Entities with Response Status Code set to 207 and\n Batch Merge Entities with Response body containing batch operation result set to '${expected_batch_operation_result}' and\n Query Entities with Updated Entities set to '${merged_entities}' valid entities\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entityOperations/merge'\n method set to 'POST'\n Request batch merge operation over entity from filename '@{entities_to_be_merged}' with Content-Type set to 'application/ld+json'\n}", + "http_verb": "POST", + "endpoint": "entityOperations/merge" + } + ], + "permutations": [], + "robotpath": "ContextInformation/Provision/BatchEntities/MergeBatchOfEntities", + "robotfile": "057_02" +} \ No newline at end of file diff --git a/doc/files/ContextInformation/Provision/057_03.json b/doc/files/ContextInformation/Provision/057_03.json new file mode 100644 index 0000000000000000000000000000000000000000..a035ec4f7d01e829daa8453a15969573f18d4a35 --- /dev/null +++ b/doc/files/ContextInformation/Provision/057_03.json @@ -0,0 +1,55 @@ +{ + "tp_id": "TP/NGSI-LD/CI/Prov/BE/057_03", + "test_objective": "Check that you cannot merge a batch of entities with an invalid request", + "reference": "ETSI GS CIM 009 V1.6.1 [], clause 5.6.17", + "config_id": "", + "parent_release": "v1.6.1", + "clauses": [ + "5.6.17" + ], + "pics_selection": "", + "keywords": [ + "Batch Merge Entity With Invalid Request Scenarios" + ], + "teardown": "None", + "initial_condition": "with {\n the SUT containing an initial state\n}", + "test_cases": [ + { + "name": "057_03_01 InvalidJson", + "permutation_tp_id": "TP/NGSI-LD/CI/Prov/BE/057_03_01", + "doc": "Check that you cannot merge a batch of entities with an invalid request", + "tags": [ + "5_6_17", + "be-merge", + "since_v1.6.1" + ], + "setup": null, + "teardown": null, + "template": "Batch Merge Entity With Invalid Request Scenarios", + "then": "then {\n the SUT sends a valid Response for the operations:\n Batch Request Entities From File with Response Status Code set to 400 and\n Batch Request Entities From File with Response Body containing the type '${problem_type}' and\n Batch Request Entities From File with Response body containing 'title' element\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entityOperations/merge'\n method set to 'POST'\n Batch Entity Delete Request with operation set to 'merge', Content-Type set to 'application/ld+json', and body set to '${filename}\n}", + "http_verb": "POST", + "endpoint": "entityOperations/merge" + }, + { + "name": "057_03_02 InvalidJsonLd", + "permutation_tp_id": "TP/NGSI-LD/CI/Prov/BE/057_03_02", + "doc": "Check that you cannot merge a batch of entities with an invalid request", + "tags": [ + "5_6_17", + "be-merge", + "since_v1.6.1" + ], + "setup": null, + "teardown": null, + "template": "Batch Merge Entity With Invalid Request Scenarios", + "then": "then {\n the SUT sends a valid Response for the operations:\n Batch Request Entities From File with Response Status Code set to 400 and\n Batch Request Entities From File with Response Body containing the type '${problem_type}' and\n Batch Request Entities From File with Response body containing 'title' element\n}", + "when": "when {\n the SUT receives a Request from the client containing:\n URL set to '/ngsi-ld/v1/entityOperations/merge'\n method set to 'POST'\n Batch Entity Delete Request with operation set to 'merge', Content-Type set to 'application/ld+json', and body set to '${filename}\n}", + "http_verb": "POST", + "endpoint": "entityOperations/merge" + } + ], + "permutations": [], + "robotpath": "ContextInformation/Provision/BatchEntities/MergeBatchOfEntities", + "robotfile": "057_03" +} \ No newline at end of file diff --git a/doc/tests/test_ContextInformation_Provision.py b/doc/tests/test_ContextInformation_Provision.py index 338d13e637511ba4999522fd9dbb4903743ad695..4be8e70c1bb8803c65227cc2692e39956253e523 100644 --- a/doc/tests/test_ContextInformation_Provision.py +++ b/doc/tests/test_ContextInformation_Provision.py @@ -657,3 +657,24 @@ class TestCIProvision(TestCase): difference_file = f'{self.folder_test_suites}/doc/results/out_016_03.json' self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + + def test_057_01(self): + robot_file = f'{self.folder_test_suites}/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/UpdateBatchOfEntities/005_01.robot' + expected_value = f'{self.folder_test_suites}/doc/files/ContextInformation/Provision/057_01.json' + difference_file = f'{self.folder_test_suites}/doc/results/out_057_01.json' + + self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + + def test_057_02(self): + robot_file = f'{self.folder_test_suites}/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/UpdateBatchOfEntities/057_02.robot' + expected_value = f'{self.folder_test_suites}/doc/files/ContextInformation/Provision/057_02.json' + difference_file = f'{self.folder_test_suites}/doc/results/out_057_02.json' + + self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) + + def test_057_03(self): + robot_file = f'{self.folder_test_suites}/TP/NGSI-LD/ContextInformation/Provision/BatchEntities/UpdateBatchOfEntities/057_03.robot' + expected_value = f'{self.folder_test_suites}/doc/files/ContextInformation/Provision/057_03.json' + difference_file = f'{self.folder_test_suites}/doc/results/out_057_03.json' + + self.common_function(robot_file=robot_file, expected_value=expected_value, difference_file=difference_file) diff --git a/resources/ApiUtils/ContextInformationProvision.resource b/resources/ApiUtils/ContextInformationProvision.resource index 8a32ca2e8278d86184f25110ba44d0ec31b01f67..e809538299684a0ae5ad03cfa297b44dd0c18751 100755 --- a/resources/ApiUtils/ContextInformationProvision.resource +++ b/resources/ApiUtils/ContextInformationProvision.resource @@ -12,11 +12,13 @@ ${BATCH_CREATE_ENDPOINT_PATH} entityOperations/create ${BATCH_DELETE_ENDPOINT_PATH} entityOperations/delete ${BATCH_UPDATE_ENDPOINT_PATH} entityOperations/update ${BATCH_UPSERT_ENDPOINT_PATH} entityOperations/upsert +${BATCH_MERGE_ENDPOINT_PATH} entityOperations/merge &{BATCH_OPERATION_ENDPOINT_MAPPING} &{EMPTY} ... create=${BATCH_CREATE_ENDPOINT_PATH} ... delete=${BATCH_DELETE_ENDPOINT_PATH} ... update=${BATCH_UPDATE_ENDPOINT_PATH} ... upsert=${BATCH_UPSERT_ENDPOINT_PATH} + ... merge=${BATCH_MERGE_ENDPOINT_PATH} ${ENTITIES_ENDPOINT_PATH} entities/ @@ -122,6 +124,17 @@ Batch Update Entities Output ${response} Batch Update Entities RETURN ${response} +Batch Merge Entities + [Arguments] @{entities_to_be_merged} + &{headers}= Create Dictionary Content-Type=application/ld+json + ${response}= POST + ... url=${url}/${BATCH_MERGE_ENDPOINT_PATH} + ... json=@{entities_to_be_merged} + ... headers=${headers} + ... expected_status=any + Output ${response} Batch Merge Entities + RETURN ${response} + Batch Upsert Entities [Arguments] @{entities_to_be_upserted} ${update_option}=replace &{headers}= Create Dictionary Content-Type=application/ld+json