From 61d62bfec3b5c1c5d21675162fe35c65bfffa94e Mon Sep 17 00:00:00 2001 From: Cecilie Seim <68303562+tilen1976@users.noreply.github.com> Date: Wed, 18 Dec 2024 08:34:19 +0100 Subject: [PATCH] Add methods for variable owner (#81) * add update method * add delete method * add create patch and validity period * add exception handler to get patch * refactor code * test validation error handling * remove validation error handling * add date create patch * test update * Update variable definitions file * update docstrings - update VardefClientException - Constraints violations are now string, not list * correct docstring args * add exception handler to all variable definition methods --- .../variable_definitions/exceptions.py | 3 +- .../variable_definition.py | 112 ++++++++++++++++++ tests/variable_definitions/conftest.py | 34 +++++- .../resources/variable-definitions-0.1.yml | 4 +- tests/variable_definitions/test_vardef.py | 74 ++++++++++++ 5 files changed, 222 insertions(+), 5 deletions(-) diff --git a/src/dapla_metadata/variable_definitions/exceptions.py b/src/dapla_metadata/variable_definitions/exceptions.py index dbbcbd9..3e1422e 100644 --- a/src/dapla_metadata/variable_definitions/exceptions.py +++ b/src/dapla_metadata/variable_definitions/exceptions.py @@ -29,11 +29,10 @@ def __init__(self, response_body: str) -> None: if not available or the response is invalid. detail (str || list): A detailed error message from the response, or "No detail provided" if not provided. If "Constraint violation" - the detail is a list with field and message. + detail contains 'field' and 'message'. response_body (str): The raw response body string, stored for debugging purposes. """ - self.detail: str | list try: data = json.loads(response_body) self.status = data.get("status", "Unknown status") diff --git a/src/dapla_metadata/variable_definitions/variable_definition.py b/src/dapla_metadata/variable_definitions/variable_definition.py index 10f41ff..55ad170 100644 --- a/src/dapla_metadata/variable_definitions/variable_definition.py +++ b/src/dapla_metadata/variable_definitions/variable_definition.py @@ -1,4 +1,11 @@ +from datetime import date + +from dapla_metadata.variable_definitions import config from dapla_metadata.variable_definitions._client import VardefClient +from dapla_metadata.variable_definitions.exceptions import vardef_exception_handler +from dapla_metadata.variable_definitions.generated.vardef_client.api.draft_variable_definitions_api import ( + DraftVariableDefinitionsApi, +) from dapla_metadata.variable_definitions.generated.vardef_client.api.patches_api import ( PatchesApi, ) @@ -8,6 +15,15 @@ from dapla_metadata.variable_definitions.generated.vardef_client.models.complete_response import ( CompleteResponse, ) +from dapla_metadata.variable_definitions.generated.vardef_client.models.patch import ( + Patch, +) +from dapla_metadata.variable_definitions.generated.vardef_client.models.update_draft import ( + UpdateDraft, +) +from dapla_metadata.variable_definitions.generated.vardef_client.models.validity_period import ( + ValidityPeriod, +) class VariableDefinition(CompleteResponse): @@ -28,18 +44,64 @@ def from_complete_response( """Create a VariableDefinition instance from a CompleteResponse.""" return VariableDefinition.model_construct(**complete_response.model_dump()) + @vardef_exception_handler def list_validity_periods(self) -> list[CompleteResponse]: """List all Validity Periods for this Variable Definition.""" return ValidityPeriodsApi(VardefClient.get_client()).list_validity_periods( variable_definition_id=self.id, ) + @vardef_exception_handler def list_patches(self) -> list[CompleteResponse]: """List all Patches for this Variable Definition.""" return PatchesApi(VardefClient.get_client()).list_patches( variable_definition_id=self.id, ) + @vardef_exception_handler + def update_draft( + self, + update_draft: UpdateDraft, + ) -> CompleteResponse: + """Update this Variable definition. + + Variable definition must have status 'DRAFT'. + + Args: + update_draft: The input with updated values. + + Returns: + CompleteResponse: Updated Variable definition with all details. + """ + return DraftVariableDefinitionsApi( + VardefClient.get_client(), + ).update_variable_definition_by_id( + variable_definition_id=self.id, + active_group=config.get_active_group(), + update_draft=update_draft, + ) + + @vardef_exception_handler + def delete_draft( + self, + ) -> str: + """Delete this Variable definition. + + Variable definition must have status 'DRAFT'. + + Returns: + str: A message if the operation was succsessful. + + """ + DraftVariableDefinitionsApi( + VardefClient.get_client(), + ).delete_variable_definition_by_id( + variable_definition_id=self.id, + active_group=config.get_active_group(), + ) + return f"Variable {self.id} safely deleted" + + @vardef_exception_handler def get_patch(self, patch_id: int) -> CompleteResponse: """Get a single Patch by ID. @@ -53,3 +115,53 @@ def get_patch(self, patch_id: int) -> CompleteResponse: variable_definition_id=self.id, patch_id=patch_id, ) + + @vardef_exception_handler + def create_patch( + self, + patch: Patch, + valid_from: date | None = None, + ) -> CompleteResponse: + """Create a new patch for this Variable definition. + + Args: + patch: The input for a new patch. + valid_from: Optional date for selecting validity period to create patch in. + If value is None the patch is created in the last validity period. + + Returns: + CompleteResponse: Variable definition with all details. + + """ + return PatchesApi( + VardefClient.get_client(), + ).create_patch( + variable_definition_id=self.id, + active_group=config.get_active_group(), + patch=patch, + valid_from=valid_from, + ) + + @vardef_exception_handler + def create_validity_period( + self, + validity_period: ValidityPeriod, + ) -> CompleteResponse: + """Create a new validity period for this Variable definition. + + In order to create a new validity period input must contain updated + 'definition' text for all present languages and a new valid from. + + Args: + validity_period: The input for new validity period + + Returns: + CompleteResponse: Variable definition with all details. + """ + return ValidityPeriodsApi( + VardefClient.get_client(), + ).create_validity_period( + variable_definition_id=self.id, + active_group=config.get_active_group(), + validity_period=validity_period, + ) diff --git a/tests/variable_definitions/conftest.py b/tests/variable_definitions/conftest.py index a6f661e..9b4f87a 100644 --- a/tests/variable_definitions/conftest.py +++ b/tests/variable_definitions/conftest.py @@ -25,6 +25,9 @@ from dapla_metadata.variable_definitions.generated.vardef_client.models.patch import ( Patch, ) +from dapla_metadata.variable_definitions.generated.vardef_client.models.person import ( + Person, +) from dapla_metadata.variable_definitions.generated.vardef_client.models.update_draft import ( UpdateDraft, ) @@ -34,6 +37,8 @@ from dapla_metadata.variable_definitions.generated.vardef_client.models.variable_status import ( VariableStatus, ) +from dapla_metadata.variable_definitions.variable_definition import VariableDefinition +from tests.utils.constants import VARDEF_EXAMPLE_DEFINITION_ID from tests.utils.microcks_testcontainer import MicrocksContainer @@ -85,6 +90,34 @@ def draft(language_string_type, contact) -> Draft: ) +@pytest.fixture +def variable_definition(language_string_type, contact, owner) -> VariableDefinition: + return VariableDefinition( + id=VARDEF_EXAMPLE_DEFINITION_ID, + patch_id=1, + name=language_string_type, + short_name="var_test", + definition=language_string_type, + classification_reference="91", + unit_types=["01"], + subject_fields=["a", "b"], + contains_special_categories_of_personal_data=True, + variable_status=VariableStatus.PUBLISHED_EXTERNAL, + measurement_type="test", + valid_from=date(2024, 11, 1), + valid_until=None, + external_reference_uri="http://www.example.com", + comment=language_string_type, + related_variable_definition_uris=["http://www.example.com"], + contact=contact, + owner=owner, + created_at=date(2024, 11, 1), + created_by=Person(code="724", name="name"), + last_updated_at=date(2024, 11, 1), + last_updated_by=Person(code="724", name="name"), + ) + + @pytest.fixture def update_draft(language_string_type, contact, owner) -> UpdateDraft: return UpdateDraft( @@ -136,7 +169,6 @@ def patch(language_string_type, contact, owner) -> Patch: contains_special_categories_of_personal_data=True, variable_status=VariableStatus.PUBLISHED_EXTERNAL, measurement_type="test", - valid_until=date(2024, 11, 1), external_reference_uri="http://www.example.com", comment=language_string_type, related_variable_definition_uris=["http://www.example.com"], diff --git a/tests/variable_definitions/resources/variable-definitions-0.1.yml b/tests/variable_definitions/resources/variable-definitions-0.1.yml index 21661a1..6c017c0 100644 --- a/tests/variable_definitions/resources/variable-definitions-0.1.yml +++ b/tests/variable_definitions/resources/variable-definitions-0.1.yml @@ -1284,7 +1284,7 @@ paths: Create patch: value: id: wypvb3wd - patch_id: 1 + patch_id: 2 name: en: Country Background nb: Landbakgrunn @@ -1321,7 +1321,7 @@ paths: subject_fields: - he04 contains_special_categories_of_personal_data: true - variable_status: DRAFT + variable_status: PUBLISHED_INTERNAL valid_from: 2003-01-01 external_reference_uri: https://www.ssb.no/a/metadata/conceptvariable/vardok/1919/nb comment: diff --git a/tests/variable_definitions/test_vardef.py b/tests/variable_definitions/test_vardef.py index ea5dddf..1c8e09c 100644 --- a/tests/variable_definitions/test_vardef.py +++ b/tests/variable_definitions/test_vardef.py @@ -12,6 +12,15 @@ from dapla_metadata.variable_definitions.generated.vardef_client.models.draft import ( Draft, ) +from dapla_metadata.variable_definitions.generated.vardef_client.models.patch import ( + Patch, +) +from dapla_metadata.variable_definitions.generated.vardef_client.models.update_draft import ( + UpdateDraft, +) +from dapla_metadata.variable_definitions.generated.vardef_client.models.validity_period import ( + ValidityPeriod, +) from dapla_metadata.variable_definitions.generated.vardef_client.models.variable_status import ( VariableStatus, ) @@ -22,6 +31,8 @@ from tests.utils.constants import VARDEF_EXAMPLE_DATE from tests.utils.constants import VARDEF_EXAMPLE_DEFINITION_ID +PATCH_ID = 2 + def test_list_variable_definitions(client_configuration: Configuration): VardefClient.set_config(client_configuration) @@ -111,3 +122,66 @@ def test_migrate_from_vardok( assert my_draft.id is not None assert my_draft.patch_id == 1 assert my_draft.variable_status == VariableStatus.DRAFT + + +def test_update_draft( + monkeypatch: pytest.MonkeyPatch, + client_configuration: Configuration, + update_draft: UpdateDraft, +): + monkeypatch.setenv(DAPLA_GROUP_CONTEXT, VARDEF_EXAMPLE_ACTIVE_GROUP) + VardefClient.set_config(client_configuration) + my_draft = Vardef.get_variable_definition( + variable_definition_id=VARDEF_EXAMPLE_DEFINITION_ID, + ) + assert isinstance(my_draft.update_draft(update_draft), CompleteResponse) + + +def test_delete_draft( + monkeypatch: pytest.MonkeyPatch, + client_configuration: Configuration, +): + monkeypatch.setenv(DAPLA_GROUP_CONTEXT, VARDEF_EXAMPLE_ACTIVE_GROUP) + VardefClient.set_config(client_configuration) + my_draft = Vardef.get_variable_definition( + variable_definition_id=VARDEF_EXAMPLE_DEFINITION_ID, + ) + assert my_draft.id is not None + result = my_draft.delete_draft() + assert result == f"Variable {VARDEF_EXAMPLE_DEFINITION_ID} safely deleted" + + +def test_create_patch( + monkeypatch: pytest.MonkeyPatch, + client_configuration: Configuration, + patch: Patch, + variable_definition: VariableDefinition, +): + monkeypatch.setenv(DAPLA_GROUP_CONTEXT, VARDEF_EXAMPLE_ACTIVE_GROUP) + VardefClient.set_config(client_configuration) + my_variable = variable_definition + assert my_variable.patch_id == 1 + created_patch = my_variable.create_patch( + patch=patch, + valid_from=VARDEF_EXAMPLE_DATE, + ) + assert isinstance( + created_patch, + CompleteResponse, + ) + assert created_patch.patch_id == PATCH_ID + + +def test_create_validity_period( + monkeypatch: pytest.MonkeyPatch, + client_configuration: Configuration, + validity_period: ValidityPeriod, + variable_definition: VariableDefinition, +): + monkeypatch.setenv(DAPLA_GROUP_CONTEXT, VARDEF_EXAMPLE_ACTIVE_GROUP) + VardefClient.set_config(client_configuration) + my_variable = variable_definition + assert isinstance( + my_variable.create_validity_period(validity_period), + CompleteResponse, + )