From 58a1c13883f815197c76487b382eddf2eed67207 Mon Sep 17 00:00:00 2001 From: Kiran Date: Tue, 17 Oct 2023 19:32:38 +0530 Subject: changes for update functionality for entities.. Issue-ID: TEST-412 Change-Id: I598c289f87fff80323ef979600df45d4fa4591dd Signed-off-by: Kiran --- src/onapsdk/aai/aai_element.py | 1 + src/onapsdk/aai/business/customer.py | 52 ++++++++++++++++- src/onapsdk/aai/business/owning_entity.py | 26 ++++++++- .../aai/cloud_infrastructure/cloud_region.py | 55 +++++++++++++++++- src/onapsdk/aai/cloud_infrastructure/complex.py | 67 +++++++++++++++++++++- .../aai/templates/aai_owning_entity_create.json.j2 | 4 -- .../aai_owning_entity_create_update.json.j2 | 4 ++ .../aai/templates/cloud_region_create.json.j2 | 16 ------ .../templates/cloud_region_create_update.json.j2 | 16 ++++++ src/onapsdk/aai/templates/complex_create.json.j2 | 23 -------- .../aai/templates/complex_create_update.json.j2 | 23 ++++++++ src/onapsdk/aai/templates/customer_create.json.j2 | 15 ----- .../aai/templates/customer_create_update.json.j2 | 15 +++++ src/onapsdk/onap_service.py | 9 ++- tests/test_aai_cloud_region.py | 26 +++++++++ tests/test_aai_complex.py | 14 +++++ tests/test_aai_customer.py | 17 ++++++ tests/test_aai_owning_entity.py | 16 ++++++ 18 files changed, 336 insertions(+), 63 deletions(-) delete mode 100644 src/onapsdk/aai/templates/aai_owning_entity_create.json.j2 create mode 100644 src/onapsdk/aai/templates/aai_owning_entity_create_update.json.j2 delete mode 100644 src/onapsdk/aai/templates/cloud_region_create.json.j2 create mode 100644 src/onapsdk/aai/templates/cloud_region_create_update.json.j2 delete mode 100644 src/onapsdk/aai/templates/complex_create.json.j2 create mode 100644 src/onapsdk/aai/templates/complex_create_update.json.j2 delete mode 100644 src/onapsdk/aai/templates/customer_create.json.j2 create mode 100644 src/onapsdk/aai/templates/customer_create_update.json.j2 diff --git a/src/onapsdk/aai/aai_element.py b/src/onapsdk/aai/aai_element.py index 5b72f95..69b2c71 100644 --- a/src/onapsdk/aai/aai_element.py +++ b/src/onapsdk/aai/aai_element.py @@ -99,6 +99,7 @@ class AaiElement(OnapService): base_url = settings.AAI_URL api_version = "/aai/" + settings.AAI_API_VERSION headers = headers_aai_creator(OnapService.headers) + patch_headers = headers_aai_creator(OnapService.patch_headers) @classmethod def get_guis(cls) -> GuiItem: diff --git a/src/onapsdk/aai/business/customer.py b/src/onapsdk/aai/business/customer.py index 1df1bc2..6799fac 100644 --- a/src/onapsdk/aai/business/customer.py +++ b/src/onapsdk/aai/business/customer.py @@ -505,7 +505,7 @@ class Customer(AaiResource): "declare customer", url, data=jinja_env() - .get_template("customer_create.json.j2") + .get_template("customer_create_update.json.j2") .render( global_customer_id=global_customer_id, subscriber_name=subscriber_name, @@ -523,6 +523,56 @@ class Customer(AaiResource): resource_version=response["resource-version"], ) + @classmethod + def update(cls, + global_customer_id: str, + subscriber_name: str, + subscriber_type: str, + service_subscriptions: Optional[Iterable[str]] = None) -> "Customer": + """Update customer. + + Args: + global_customer_id (str): Global customer id used across ONAP + to uniquely identify customer. + subscriber_name (str): Subscriber name, an alternate way + to retrieve a customer. + subscriber_type (str): Subscriber type, a way to provide + VID with only the INFRA customers. + service_subscriptions (Optional[Iterable[str]], optional): Iterable + of service subscription names should be created for newly + created customer. Defaults to None. + + Returns: + Customer: Customer object. + + """ + url: str = ( + f"{cls.base_url}{cls.api_version}/business/customers/" + f"customer/{global_customer_id}" + ) + cls.send_message( + "PATCH", + "update customer", + url, + data=jinja_env() + .get_template("customer_create_update.json.j2") + .render( + global_customer_id=global_customer_id, + subscriber_name=subscriber_name, + subscriber_type=subscriber_type, + service_subscriptions=service_subscriptions + ), + ) + response: dict = cls.send_message_json( + "GET", "get updated customer", url + ) # Call API one more time to get Customer's resource version + return Customer( + global_customer_id=response["global-customer-id"], + subscriber_name=response["subscriber-name"], + subscriber_type=response["subscriber-type"], + resource_version=response["resource-version"], + ) + @property def url(self) -> str: """Return customer object url. diff --git a/src/onapsdk/aai/business/owning_entity.py b/src/onapsdk/aai/business/owning_entity.py index ebe9b11..1ef0a39 100644 --- a/src/onapsdk/aai/business/owning_entity.py +++ b/src/onapsdk/aai/business/owning_entity.py @@ -148,7 +148,31 @@ class OwningEntity(AaiResource, AaiResourceLinkToTenantMixin): "Declare A&AI owning entity", (f"{cls.base_url}{cls.api_version}/business/owning-entities/" f"owning-entity/{owning_entity_id}"), - data=jinja_env().get_template("aai_owning_entity_create.json.j2").render( + data=jinja_env().get_template("aai_owning_entity_create_update.json.j2").render( + owning_entity_name=name, + owning_entity_id=owning_entity_id + ) + ) + return cls.get_by_owning_entity_id(owning_entity_id) + + @classmethod + def update(cls, name: str, owning_entity_id: str) -> "OwningEntity": + """Update owning entity A&AI resource. + + Args: + name (str): owning entity name + owning_entity_id (str): owning entity ID. + + Returns: + OwningEntity: Updated OwningEntity object + + """ + cls.send_message( + "PATCH", + "update A&AI owning entity", + (f"{cls.base_url}{cls.api_version}/business/owning-entities/" + f"owning-entity/{owning_entity_id}"), + data=jinja_env().get_template("aai_owning_entity_create_update.json.j2").render( owning_entity_name=name, owning_entity_id=owning_entity_id ) diff --git a/src/onapsdk/aai/cloud_infrastructure/cloud_region.py b/src/onapsdk/aai/cloud_infrastructure/cloud_region.py index 171be34..5f01548 100644 --- a/src/onapsdk/aai/cloud_infrastructure/cloud_region.py +++ b/src/onapsdk/aai/cloud_infrastructure/cloud_region.py @@ -270,7 +270,60 @@ class CloudRegion(AaiResource, AaiResourceLinkToComplexMixin, AaiResourceLinkToP "Create cloud region", url, data=jinja_env() - .get_template("cloud_region_create.json.j2") + .get_template("cloud_region_create_update.json.j2") + .render(cloud_region=cloud_region), + ) + return cloud_region + + @classmethod + def update(cls, # pylint: disable=too-many-locals + cloud_owner: str, + cloud_region_id: str, + orchestration_disabled: bool, + in_maint: bool, + *, # rest of parameters are keyword + cloud_type: str = "", + owner_defined_type: str = "", + cloud_region_version: str = "", + identity_url: str = "", + cloud_zone: str = "", + complex_name: str = "", + sriov_automation: str = "", + cloud_extra_info: str = "", + upgrade_cycle: str = "") -> "CloudRegion": + """Update CloudRegion object. + + Update cloud region with given values. + + Returns: + CloudRegion: Updated cloud region. + + """ + cloud_region: "CloudRegion" = CloudRegion( + cloud_owner=cloud_owner, + cloud_region_id=cloud_region_id, + orchestration_disabled=orchestration_disabled, + in_maint=in_maint, + cloud_type=cloud_type, + owner_defined_type=owner_defined_type, + cloud_region_version=cloud_region_version, + identity_url=identity_url, + cloud_zone=cloud_zone, + complex_name=complex_name, + sriov_automation=sriov_automation, + cloud_extra_info=cloud_extra_info, + upgrade_cycle=upgrade_cycle, + ) + url: str = ( + f"{cls.base_url}{cls.api_version}/cloud-infrastructure/cloud-regions/cloud-region/" + f"{cloud_region.cloud_owner}/{cloud_region.cloud_region_id}" + ) + cls.send_message( + "PATCH", + "Update cloud region", + url, + data=jinja_env() + .get_template("cloud_region_create_update.json.j2") .render(cloud_region=cloud_region), ) return cloud_region diff --git a/src/onapsdk/aai/cloud_infrastructure/complex.py b/src/onapsdk/aai/cloud_infrastructure/complex.py index 167234d..1a1684a 100644 --- a/src/onapsdk/aai/cloud_infrastructure/complex.py +++ b/src/onapsdk/aai/cloud_infrastructure/complex.py @@ -179,7 +179,7 @@ class Complex(AaiResource, AaiResourceLinkToGeoRegionMixin): # pylint: disable= data_source=data_source, data_source_version=data_source_version ) - payload: str = jinja_env().get_template("complex_create.json.j2").render( + payload: str = jinja_env().get_template("complex_create_update.json.j2").render( complex=complex_object) url: str = ( f"{cls.base_url}{cls.api_version}/cloud-infrastructure/complexes/complex/" @@ -188,6 +188,71 @@ class Complex(AaiResource, AaiResourceLinkToGeoRegionMixin): # pylint: disable= cls.send_message("PUT", "create complex", url, data=payload) return complex_object + @classmethod + def update(cls, # pylint: disable=too-many-locals + physical_location_id: str, + *, + name: str = "", + data_center_code: str = "", + identity_url: str = "", + resource_version: str = "", + physical_location_type: str = "", + street1: str = "", + street2: str = "", + city: str = "", + state: str = "", + postal_code: str = "", + country: str = "", + region: str = "", + latitude: str = "", + longitude: str = "", + elevation: str = "", + lata: str = "", + timezone: str = "", + data_owner: str = "", + data_source: str = "", + data_source_version: str = "") -> "Complex": + """Update complex. + + Update complex object by calling A&AI API. + If API request doesn't fail it returns Complex object. + + Returns: + Complex: Updated complex object + + """ + complex_object: Complex = Complex( + name=name, + physical_location_id=physical_location_id, + data_center_code=data_center_code, + identity_url=identity_url, + resource_version=resource_version, + physical_location_type=physical_location_type, + street1=street1, + street2=street2, + city=city, + state=state, + postal_code=postal_code, + country=country, + region=region, + latitude=latitude, + longitude=longitude, + elevation=elevation, + lata=lata, + timezone=timezone, + data_owner=data_owner, + data_source=data_source, + data_source_version=data_source_version + ) + payload: str = jinja_env().get_template("complex_create_update.json.j2").render( + complex=complex_object) + url: str = ( + f"{cls.base_url}{cls.api_version}/cloud-infrastructure/complexes/complex/" + f"{complex_object.physical_location_id}" + ) + cls.send_message("PATCH", "update complex", url, data=payload) + return complex_object + @classmethod def get_all_url(cls) -> str: # pylint: disable=arguments-differ """Return an url to get all complexes. diff --git a/src/onapsdk/aai/templates/aai_owning_entity_create.json.j2 b/src/onapsdk/aai/templates/aai_owning_entity_create.json.j2 deleted file mode 100644 index 2877a3d..0000000 --- a/src/onapsdk/aai/templates/aai_owning_entity_create.json.j2 +++ /dev/null @@ -1,4 +0,0 @@ -{ - "owning-entity-name": "{{ owning_entity_name }}", - "owning-entity-id": "{{ owning_entity_id }}" -} \ No newline at end of file diff --git a/src/onapsdk/aai/templates/aai_owning_entity_create_update.json.j2 b/src/onapsdk/aai/templates/aai_owning_entity_create_update.json.j2 new file mode 100644 index 0000000..2877a3d --- /dev/null +++ b/src/onapsdk/aai/templates/aai_owning_entity_create_update.json.j2 @@ -0,0 +1,4 @@ +{ + "owning-entity-name": "{{ owning_entity_name }}", + "owning-entity-id": "{{ owning_entity_id }}" +} \ No newline at end of file diff --git a/src/onapsdk/aai/templates/cloud_region_create.json.j2 b/src/onapsdk/aai/templates/cloud_region_create.json.j2 deleted file mode 100644 index 65a7057..0000000 --- a/src/onapsdk/aai/templates/cloud_region_create.json.j2 +++ /dev/null @@ -1,16 +0,0 @@ -{ - "cloud-owner": "{{ cloud_region.cloud_owner }}", - "cloud-region-id": "{{ cloud_region.cloud_region_id }}", - "orchestration-disabled": "{{ cloud_region.orchestration_disabled }}", - "in-maint": "{{ cloud_region.in_maint }}", - "cloud-type": "{{ cloud_region.cloud_type }}", - "owner-defined-type": "{{ cloud_region.owner_defined_type }}", - "cloud-region-version": "{{ cloud_region.cloud_region_version }}", - "identity-url": "{{ cloud_region.identity_url }}", - "cloud-zone": "{{ cloud_region.cloud_zone }}", - "complex-name": "{{ cloud_region.complex_name }}", - "sriov-automation": "{{ cloud_region.sriov_automation }}", - "cloud-extra-info": "{{ cloud_region.cloud_extra_info }}", - "upgrade-cycle": "{{ cloud_region.upgrade_cycle }}", - "resource-version": "{{ cloud_region.resource_version }}" -} \ No newline at end of file diff --git a/src/onapsdk/aai/templates/cloud_region_create_update.json.j2 b/src/onapsdk/aai/templates/cloud_region_create_update.json.j2 new file mode 100644 index 0000000..65a7057 --- /dev/null +++ b/src/onapsdk/aai/templates/cloud_region_create_update.json.j2 @@ -0,0 +1,16 @@ +{ + "cloud-owner": "{{ cloud_region.cloud_owner }}", + "cloud-region-id": "{{ cloud_region.cloud_region_id }}", + "orchestration-disabled": "{{ cloud_region.orchestration_disabled }}", + "in-maint": "{{ cloud_region.in_maint }}", + "cloud-type": "{{ cloud_region.cloud_type }}", + "owner-defined-type": "{{ cloud_region.owner_defined_type }}", + "cloud-region-version": "{{ cloud_region.cloud_region_version }}", + "identity-url": "{{ cloud_region.identity_url }}", + "cloud-zone": "{{ cloud_region.cloud_zone }}", + "complex-name": "{{ cloud_region.complex_name }}", + "sriov-automation": "{{ cloud_region.sriov_automation }}", + "cloud-extra-info": "{{ cloud_region.cloud_extra_info }}", + "upgrade-cycle": "{{ cloud_region.upgrade_cycle }}", + "resource-version": "{{ cloud_region.resource_version }}" +} \ No newline at end of file diff --git a/src/onapsdk/aai/templates/complex_create.json.j2 b/src/onapsdk/aai/templates/complex_create.json.j2 deleted file mode 100644 index 681fdad..0000000 --- a/src/onapsdk/aai/templates/complex_create.json.j2 +++ /dev/null @@ -1,23 +0,0 @@ -{ - "physical-location-id": "{{ complex.physical_location_id }}", - "data-center-code": "{{ complex.data_center_code }}", - "complex-name": "{{ complex.name }}", - "identity-url": "{{ complex.identity_url }}", - "resource-version": "{{ complex.resource_version }}", - "physical-location-type": "{{ complex.physical_location_type }}", - "street1": "{{ complex.street1 }}", - "street2": "{{ complex.street2 }}", - "city": "{{ complex.city }}", - "state": "{{ complex.state }}", - "postal-code": "{{ complex.postal_code }}", - "country": "{{ complex.country }}", - "region": "{{ complex.region }}", - "latitude": "{{ complex.latitude }}", - "longitude": "{{ complex.longitude }}", - "elevation": "{{ complex.elevation }}", - "lata": "{{ complex.lata }}", - "time-zone": "{{ complex.timezone }}", - "data-owner": "{{ complex.data_owner }}", - "data-source": "{{ complex.data_source }}", - "data-source-version": "{{ complex.data_source_version }}" -} \ No newline at end of file diff --git a/src/onapsdk/aai/templates/complex_create_update.json.j2 b/src/onapsdk/aai/templates/complex_create_update.json.j2 new file mode 100644 index 0000000..681fdad --- /dev/null +++ b/src/onapsdk/aai/templates/complex_create_update.json.j2 @@ -0,0 +1,23 @@ +{ + "physical-location-id": "{{ complex.physical_location_id }}", + "data-center-code": "{{ complex.data_center_code }}", + "complex-name": "{{ complex.name }}", + "identity-url": "{{ complex.identity_url }}", + "resource-version": "{{ complex.resource_version }}", + "physical-location-type": "{{ complex.physical_location_type }}", + "street1": "{{ complex.street1 }}", + "street2": "{{ complex.street2 }}", + "city": "{{ complex.city }}", + "state": "{{ complex.state }}", + "postal-code": "{{ complex.postal_code }}", + "country": "{{ complex.country }}", + "region": "{{ complex.region }}", + "latitude": "{{ complex.latitude }}", + "longitude": "{{ complex.longitude }}", + "elevation": "{{ complex.elevation }}", + "lata": "{{ complex.lata }}", + "time-zone": "{{ complex.timezone }}", + "data-owner": "{{ complex.data_owner }}", + "data-source": "{{ complex.data_source }}", + "data-source-version": "{{ complex.data_source_version }}" +} \ No newline at end of file diff --git a/src/onapsdk/aai/templates/customer_create.json.j2 b/src/onapsdk/aai/templates/customer_create.json.j2 deleted file mode 100644 index 0eea2ed..0000000 --- a/src/onapsdk/aai/templates/customer_create.json.j2 +++ /dev/null @@ -1,15 +0,0 @@ -{ - "global-customer-id": "{{ global_customer_id }}", - "subscriber-name": "{{ subscriber_name }}", - "subscriber-type": "{{ subscriber_type }}"{% if service_subscriptions %}, - "service-subscriptions": { - "service-subscription": [ - {% for service_subscription in service_subscriptions %} - { - "service-type": "{{ service_subscription }}" - }{% if not loop.last %},{% endif %} - {% endfor %} - ] - } - {% endif %} -} \ No newline at end of file diff --git a/src/onapsdk/aai/templates/customer_create_update.json.j2 b/src/onapsdk/aai/templates/customer_create_update.json.j2 new file mode 100644 index 0000000..0eea2ed --- /dev/null +++ b/src/onapsdk/aai/templates/customer_create_update.json.j2 @@ -0,0 +1,15 @@ +{ + "global-customer-id": "{{ global_customer_id }}", + "subscriber-name": "{{ subscriber_name }}", + "subscriber-type": "{{ subscriber_type }}"{% if service_subscriptions %}, + "service-subscriptions": { + "service-subscription": [ + {% for service_subscription in service_subscriptions %} + { + "service-type": "{{ service_subscription }}" + }{% if not loop.last %},{% endif %} + {% endfor %} + ] + } + {% endif %} +} \ No newline at end of file diff --git a/src/onapsdk/onap_service.py b/src/onapsdk/onap_service.py index 872d384..a054529 100644 --- a/src/onapsdk/onap_service.py +++ b/src/onapsdk/onap_service.py @@ -79,6 +79,10 @@ class OnapService(ABC): "Content-Type": "application/json", "Accept": "application/json", } + patch_headers: Dict[str, str] = { + "Content-Type": "application/merge-patch+json", + "Accept": "application/json", + } proxy: Dict[str, str] = None permanent_headers: PermanentHeadersCollection = PermanentHeadersCollection() @@ -123,7 +127,10 @@ class OnapService(ABC): basic_auth: Dict[str, str] = kwargs.pop('basic_auth', None) exception = kwargs.pop('exception', None) timeout = kwargs.pop('timeout', None) - headers = kwargs.pop('headers', cls.headers).copy() + if method == "PATCH": + headers = kwargs.pop('headers', cls.patch_headers).copy() + else: + headers = kwargs.pop('headers', cls.headers).copy() if OnapService.permanent_headers: for header in OnapService.permanent_headers: headers.update(header) diff --git a/tests/test_aai_cloud_region.py b/tests/test_aai_cloud_region.py index a821090..13ba539 100644 --- a/tests/test_aai_cloud_region.py +++ b/tests/test_aai_cloud_region.py @@ -69,3 +69,29 @@ def test_cloud_region_get_tenants_by_name(mock_tenants): def test_cloud_region_count(mock_send_message_json): mock_send_message_json.return_value = COUNT assert CloudRegion.count() == 2 + +@mock.patch.object(CloudRegion, "send_message") +def test_cloud_region_delete(mock_send_message): + cloud_region = CloudRegion("test_cloud_owner", "test_cloud_region_id", False, False) + cloud_region.delete() + mock_send_message.assert_called_once_with( + "DELETE", + f"Delete cloud region {cloud_region.cloud_region_id}", + f"{cloud_region.url}", + params={'resource-version': cloud_region.resource_version} + ) + + +@mock.patch.object(CloudRegion, "send_message") +def test_cloud_region_update(mock_send_message): + cloud_region = CloudRegion("test_cloud_owner", "test_cloud_region_id", False, False) + cloud_region.update("test_cloud_owner", "test_cloud_region_id", False, False) + mock_send_message.assert_called_once() + assert cloud_region.cloud_owner == "test_cloud_owner" + assert cloud_region.cloud_region_id == "test_cloud_region_id" + assert cloud_region.url == (f"{CloudRegion.base_url}{CloudRegion.api_version}/cloud-infrastructure/cloud-regions/" + f"cloud-region/test_cloud_owner/test_cloud_region_id") + method, _, url = mock_send_message.call_args[0] + assert method == "PATCH" + assert url == (f"{CloudRegion.base_url}{CloudRegion.api_version}/cloud-infrastructure/cloud-regions/" + "cloud-region/test_cloud_owner/test_cloud_region_id") diff --git a/tests/test_aai_complex.py b/tests/test_aai_complex.py index 8368d18..9b36426 100644 --- a/tests/test_aai_complex.py +++ b/tests/test_aai_complex.py @@ -77,6 +77,20 @@ def test_complex(mock_send_message): assert url == (f"{Complex.base_url}{Complex.api_version}/cloud-infrastructure/" "complexes/complex/test_location_id") +@mock.patch.object(Complex, "send_message") +def test_complex_update(mock_send_message): + cmplx1 = Complex.update(name="test_complex_name", + physical_location_id="test_location_id") + mock_send_message.assert_called_once() + assert cmplx1.name == "test_complex_name" + assert cmplx1.physical_location_id == "test_location_id" + assert cmplx1.url == (f"{Complex.base_url}{Complex.api_version}/cloud-infrastructure/" + "complexes/complex/test_location_id") + method, _, url = mock_send_message.call_args[0] + assert method == "PATCH" + assert url == (f"{Complex.base_url}{Complex.api_version}/cloud-infrastructure/" + "complexes/complex/test_location_id") + @mock.patch.object(Complex, "send_message_json") def test_complex_get_all(mock_send_message_json): diff --git a/tests/test_aai_customer.py b/tests/test_aai_customer.py index 260520c..1597ac2 100644 --- a/tests/test_aai_customer.py +++ b/tests/test_aai_customer.py @@ -392,6 +392,23 @@ def test_customer_delete(mock_send): customer.url ) +@mock.patch.object(Customer, "send_message") +@mock.patch.object(Customer, "send_message_json") +def test_customer_update(mock_send_json, mock_send): + """Test Customer's update method.""" + mock_send_json.return_value = SIMPLE_CUSTOMER_2 + customer = Customer.update("generic", "generic", "INFRA") + assert customer.global_customer_id == "generic" + assert customer.subscriber_name == "generic" + assert customer.subscriber_type == "INFRA" + assert customer.resource_version is not None + + customer = Customer.create("generic", "generic", "INFRA", service_subscriptions=["test-service-type"]) + assert customer.global_customer_id == "generic" + assert customer.subscriber_name == "generic" + assert customer.subscriber_type == "INFRA" + assert customer.resource_version is not None + @mock.patch.object(Customer, "send_message") def test_delete_subscribed_service(mock_send): diff --git a/tests/test_aai_owning_entity.py b/tests/test_aai_owning_entity.py index dce8986..49658b1 100644 --- a/tests/test_aai_owning_entity.py +++ b/tests/test_aai_owning_entity.py @@ -96,3 +96,19 @@ def test_owning_entity_delete(mock_send_message): "Delete owning entity", f"{owning_entity.url}?resource-version={owning_entity.resource_version}" ) + +@mock.patch.object(OwningEntity, "send_message") +@mock.patch.object(OwningEntity, "send_message_json") +def test_owning_entity_update(mock_send_json, mock_send): + mock_send_json.return_value = OWNING_ENTITY + OwningEntity.update( + name="OE-generic", + owning_entity_id="OE-generic" + ) + + owning_entity = OwningEntity.update( + name="OE-generic", + owning_entity_id="OE-generic" + ) + assert owning_entity.owning_entity_id == "OE-generic" + assert owning_entity.name == "OE-generic" -- cgit 1.2.3-korg