From 0bffa2b36f5b4a0eb092fa0db916414374f8126b Mon Sep 17 00:00:00 2001 From: Wambere Date: Thu, 15 Feb 2024 20:19:29 +0300 Subject: [PATCH 1/4] Require id for resource updates --- importer/main.py | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/importer/main.py b/importer/main.py index 6fd2fe90..7af092da 100644 --- a/importer/main.py +++ b/importer/main.py @@ -479,13 +479,11 @@ def get_valid_resource_type(resource_type): # This function gets the current resource version from the API -def get_resource_version(resource_id, resource_type): - logging.debug("Getting resource version") - modified_resource_type = get_valid_resource_type(resource_type) - resource_url = "/".join([config.fhir_base_url, modified_resource_type, resource_id]) +def get_resource(resource_id, resource_type): + resource_type = get_valid_resource_type(resource_type) + resource_url = "/".join([config.fhir_base_url, resource_type, resource_id]) response = handle_request("GET", "", resource_url) - json_response = json.loads(response[0]) - return json_response["meta"]["versionId"] + return json.loads(response[0])["meta"]["versionId"] if response[1] == 200 else "0" # This function builds a json payload @@ -501,15 +499,7 @@ def build_payload(resource_type, resources, resource_payload_file): name, status, method, id, *_ = resource try: if method == "create": - if len(id.strip()) > 0: - # use the provided id - unique_uuid = id.strip() - identifier_uuid = id.strip() - else: - # generate a new uuid - unique_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, name)) - identifier_uuid = unique_uuid - elif method == "update": + version = "1" if len(id.strip()) > 0: # use the provided id unique_uuid = id.strip() @@ -522,12 +512,31 @@ def build_payload(resource_type, resources, resource_payload_file): # default if method is not provided unique_uuid = str(uuid.uuid5(uuid.NAMESPACE_DNS, name)) identifier_uuid = unique_uuid + version = "1" + + try: + if method == "update": + if len(id.strip()) > 0: + version = get_resource(id, resource_type) + if version != "0": + # use the provided id + unique_uuid = id.strip() + identifier_uuid = id.strip() + else: + logging.info("Failed to get resource!") + raise ValueError("Trying to update a Non-existent resource") + else: + logging.info("The id is required!") + raise ValueError("The id is required to update a resource") + except IndexError: + raise ValueError("The id is required to update a resource") # ps = payload_string ps = ( payload_string.replace("$name", name) .replace("$unique_uuid", unique_uuid) .replace("$identifier_uuid", identifier_uuid) + .replace("$version", version) ) try: @@ -535,13 +544,6 @@ def build_payload(resource_type, resources, resource_payload_file): except IndexError: ps = ps.replace("$status", "active") - # Get resource versions from API - try: - version = get_resource_version(id, resource_type) - ps = ps.replace("$version", version) - except Exception: - ps = ps.replace("$version", "1") - if resource_type == "organizations": ps = organization_extras(resource, ps) elif resource_type == "locations": From eb5691e06c0862f133fa5fe99ee32e5d701bcbdc Mon Sep 17 00:00:00 2001 From: Wambere Date: Thu, 15 Feb 2024 21:26:39 +0300 Subject: [PATCH 2/4] Fix failing tests --- importer/requirements.txt | 1 + importer/test_main.py | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/importer/requirements.txt b/importer/requirements.txt index c0786cd2..ac3b213f 100644 --- a/importer/requirements.txt +++ b/importer/requirements.txt @@ -6,3 +6,4 @@ urllib3==2.0.3 backoff==2.2.1 pytest==7.4.2 jsonschema==4.21.1 +mock==5.1.0 \ No newline at end of file diff --git a/importer/test_main.py b/importer/test_main.py index d1caa61a..00aa9fa1 100644 --- a/importer/test_main.py +++ b/importer/test_main.py @@ -1,6 +1,7 @@ import json import unittest from jsonschema import validate +from mock import patch from main import read_csv, build_payload, build_org_affiliation, extract_matches, create_user_resources @@ -11,7 +12,10 @@ def test_read_csv(self): self.assertIsInstance(records, list) self.assertEqual(len(records), 3) - def test_build_payload_organizations(self): + @patch('main.get_resource') + def test_build_payload_organizations(self, mock_get_resource): + mock_get_resource.return_value = "1" + csv_file = "csv/organizations/organizations_full.csv" resource_list = read_csv(csv_file) payload = build_payload( @@ -46,7 +50,10 @@ def test_build_payload_organizations(self): } validate(payload_obj["entry"][2]["request"], request_schema) - def test_build_payload_locations(self): + @patch('main.get_resource') + def test_build_payload_locations(self, mock_get_resource): + mock_get_resource.return_value = "1" + csv_file = "csv/locations/locations_full.csv" resource_list = read_csv(csv_file) payload = build_payload( @@ -129,7 +136,10 @@ def test_build_payload_locations(self): } validate(payload_obj["entry"][0]["request"], request_schema) - def test_build_payload_care_teams(self): + @patch('main.get_resource') + def test_build_payload_care_teams(self, mock_get_resource): + mock_get_resource.return_value = "1" + csv_file = "csv/careteams/careteam_full.csv" resource_list = read_csv(csv_file) payload = build_payload( From 9a0fed94ac99a9a145548f264b51959f1f54224e Mon Sep 17 00:00:00 2001 From: Wambere Date: Thu, 15 Feb 2024 22:53:27 +0300 Subject: [PATCH 3/4] add tests --- importer/test_main.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/importer/test_main.py b/importer/test_main.py index 00aa9fa1..92386da4 100644 --- a/importer/test_main.py +++ b/importer/test_main.py @@ -335,6 +335,21 @@ def test_uuid_generated_in_build_org_affiliation_is_unique_and_repeatable(self): self.assertEqual(organization_affiliation1, organization_affiliation3) self.assertEqual(organization_affiliation2, organization_affiliation4) + def test_update_resource_with_no_id_fails(self): + resources = [[ "City1", "active", "update" , "","test location-1","18fcbc2e-4240-4a84-a270-7a444523d7b6", "site", "si", "ward", "wa"]] + with self.assertRaises(ValueError) as raised_error: + build_payload("locations", resources, "json_payloads/locations_payload.json") + self.assertEqual("The id is required to update a resource", str(raised_error.exception)) + + @patch('main.get_resource') + def test_update_resource_with_non_existing_id_fails(self, mock_get_resource): + mock_get_resource.return_value = "0" + non_existing_id = "123" + resources = [[ "City1", "active", "update" , non_existing_id,"test location-1","18fcbc2e-4240-4a84-a270-7a444523d7b6", "site", "si", "ward", "wa"]] + with self.assertRaises(ValueError) as raised_error: + build_payload("locations", resources, "json_payloads/locations_payload.json") + self.assertEqual("Trying to update a Non-existent resource", str(raised_error.exception)) + if __name__ == "__main__": unittest.main() From 4036437d1b017a1e8cc1c5c4714f0dbc8f3b728c Mon Sep 17 00:00:00 2001 From: Wambere Date: Thu, 15 Feb 2024 22:55:19 +0300 Subject: [PATCH 4/4] black formatting --- importer/test_main.py | 62 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/importer/test_main.py b/importer/test_main.py index 92386da4..b108bce2 100644 --- a/importer/test_main.py +++ b/importer/test_main.py @@ -2,7 +2,13 @@ import unittest from jsonschema import validate from mock import patch -from main import read_csv, build_payload, build_org_affiliation, extract_matches, create_user_resources +from main import ( + read_csv, + build_payload, + build_org_affiliation, + extract_matches, + create_user_resources, +) class TestMain(unittest.TestCase): @@ -12,7 +18,7 @@ def test_read_csv(self): self.assertIsInstance(records, list) self.assertEqual(len(records), 3) - @patch('main.get_resource') + @patch("main.get_resource") def test_build_payload_organizations(self, mock_get_resource): mock_get_resource.return_value = "1" @@ -50,7 +56,7 @@ def test_build_payload_organizations(self, mock_get_resource): } validate(payload_obj["entry"][2]["request"], request_schema) - @patch('main.get_resource') + @patch("main.get_resource") def test_build_payload_locations(self, mock_get_resource): mock_get_resource.return_value = "1" @@ -136,7 +142,7 @@ def test_build_payload_locations(self, mock_get_resource): } validate(payload_obj["entry"][0]["request"], request_schema) - @patch('main.get_resource') + @patch("main.get_resource") def test_build_payload_care_teams(self, mock_get_resource): mock_get_resource.return_value = "1" @@ -336,19 +342,53 @@ def test_uuid_generated_in_build_org_affiliation_is_unique_and_repeatable(self): self.assertEqual(organization_affiliation2, organization_affiliation4) def test_update_resource_with_no_id_fails(self): - resources = [[ "City1", "active", "update" , "","test location-1","18fcbc2e-4240-4a84-a270-7a444523d7b6", "site", "si", "ward", "wa"]] + resources = [ + [ + "City1", + "active", + "update", + "", + "test location-1", + "18fcbc2e-4240-4a84-a270-7a444523d7b6", + "site", + "si", + "ward", + "wa", + ] + ] with self.assertRaises(ValueError) as raised_error: - build_payload("locations", resources, "json_payloads/locations_payload.json") - self.assertEqual("The id is required to update a resource", str(raised_error.exception)) + build_payload( + "locations", resources, "json_payloads/locations_payload.json" + ) + self.assertEqual( + "The id is required to update a resource", str(raised_error.exception) + ) - @patch('main.get_resource') + @patch("main.get_resource") def test_update_resource_with_non_existing_id_fails(self, mock_get_resource): mock_get_resource.return_value = "0" non_existing_id = "123" - resources = [[ "City1", "active", "update" , non_existing_id,"test location-1","18fcbc2e-4240-4a84-a270-7a444523d7b6", "site", "si", "ward", "wa"]] + resources = [ + [ + "City1", + "active", + "update", + non_existing_id, + "test location-1", + "18fcbc2e-4240-4a84-a270-7a444523d7b6", + "site", + "si", + "ward", + "wa", + ] + ] with self.assertRaises(ValueError) as raised_error: - build_payload("locations", resources, "json_payloads/locations_payload.json") - self.assertEqual("Trying to update a Non-existent resource", str(raised_error.exception)) + build_payload( + "locations", resources, "json_payloads/locations_payload.json" + ) + self.assertEqual( + "Trying to update a Non-existent resource", str(raised_error.exception) + ) if __name__ == "__main__":