diff --git a/changelog.md b/changelog.md index f11cb01..5a42e79 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.13.0] - 2025-08-13 + +### Added + +- Nova: Function to set the state of an existing case. + ## [2.12.1] - 2025-08-07 ### Fixed @@ -232,7 +238,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Initial release -[Unreleased]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/compare/2.12.1...HEAD +[Unreleased]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/compare/2.13.0...HEAD +[2.13.0]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.13.0 [2.12.1]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.12.1 [2.12.0]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.12.0 [2.11.1]: https://github.com/itk-dev-rpa/ITK-dev-shared-components/releases/tag/2.11.1 diff --git a/itk_dev_shared_components/kmd_nova/nova_cases.py b/itk_dev_shared_components/kmd_nova/nova_cases.py index 16dc8e5..e7a7097 100644 --- a/itk_dev_shared_components/kmd_nova/nova_cases.py +++ b/itk_dev_shared_components/kmd_nova/nova_cases.py @@ -3,6 +3,7 @@ import uuid import urllib.parse +from typing import Literal import requests @@ -348,3 +349,28 @@ def add_case(case: NovaCase, nova_access: NovaAccess): response = requests.post(url, params=params, headers=headers, json=payload, timeout=60) response.raise_for_status() + + +def set_case_state(case_uuid: str, new_state: Literal["Opstaaet", "Oplyst", "Afgjort", "Bestilt", "Udfoert", "Afsluttet"], nova_access: NovaAccess): + """Set the state of an existing case. + + Args: + case_uuid: The uuid of the case. + new_state: The new state of the case. + nova_access: The NovaAccess object used to authenticate. + """ + url = urllib.parse.urljoin(nova_access.domain, "api/Case/Update") + params = {"api-version": "2.0-Case"} + + headers = {'Content-Type': 'application/json', 'Authorization': f"Bearer {nova_access.get_bearer_token()}"} + + payload = { + "common": { + "transactionId": str(uuid.uuid4()), + "uuid": case_uuid + }, + "state": new_state + } + + response = requests.patch(url, params=params, headers=headers, json=payload, timeout=60) + response.raise_for_status() diff --git a/pyproject.toml b/pyproject.toml index 1ff963e..2231fbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "itk_dev_shared_components" -version = "2.12.1" +version = "2.13.0" authors = [ { name="ITK Development", email="itk-rpa@mkb.aarhus.dk" }, ] diff --git a/tests/test_nova_api/test_cases.py b/tests/test_nova_api/test_cases.py index 87b2112..adc0ffa 100644 --- a/tests/test_nova_api/test_cases.py +++ b/tests/test_nova_api/test_cases.py @@ -86,23 +86,9 @@ def test_add_case(self): """Test adding a case to Nova. Also tests getting a case on uuid. """ - nova_party = os.getenv('NOVA_PARTY').split(',') - party = CaseParty( - role="Primær", - identification_type="CprNummer", - identification=nova_party[0], - name=nova_party[1] - ) - - caseworker_dict = json.loads(os.environ['NOVA_USER']) - caseworker = Caseworker( - **caseworker_dict - ) - - department_dict = json.loads(os.environ['NOVA_DEPARTMENT']) - department = Department( - **department_dict - ) + party = _get_test_party() + caseworker = _get_test_caseworker() + department = _get_test_department() case = NovaCase( uuid=str(uuid.uuid4()), @@ -119,16 +105,7 @@ def test_add_case(self): ) nova_cases.add_case(case, self.nova_access) - - # Wait up to 10 seconds for the case to be created in Nova - nova_case = None - for _ in range(10): - time.sleep(1) - try: - nova_case = nova_cases.get_case(case.uuid, self.nova_access) - break - except ValueError: - pass + nova_case = _get_case(case.uuid, self.nova_access) self.assertIsNotNone(nova_case) @@ -164,19 +141,31 @@ def test_user_groups(self): self.assertEqual(nova_case.caseworker, caseworker) # Add case - nova_party = os.getenv('NOVA_PARTY').split(',') - party = CaseParty( - role="Primær", - identification_type="CprNummer", - identification=nova_party[0], - name=nova_party[1] - ) + party = _get_test_party() + department = _get_test_department() - department_dict = json.loads(os.environ['NOVA_DEPARTMENT']) - department = Department( - **department_dict + case = NovaCase( + uuid=str(uuid.uuid4()), + title=f"Test {datetime.now()}", + case_date=datetime.now(), + progress_state="Opstaaet", + case_parties=[party], + kle_number="23.05.01", + proceeding_facet="G01", + sensitivity="Fortrolige", + caseworker=caseworker, + responsible_department=department, + security_unit=department ) + nova_cases.add_case(case, self.nova_access) + + def test_set_case_state(self): + """Test setting the state of an existing case.""" + party = _get_test_party() + caseworker = _get_test_caseworker() + department = _get_test_department() + case = NovaCase( uuid=str(uuid.uuid4()), title=f"Test {datetime.now()}", @@ -193,6 +182,71 @@ def test_user_groups(self): nova_cases.add_case(case, self.nova_access) + nova_case = _get_case(case.uuid, self.nova_access) + self.assertEqual(nova_case.progress_state, "Opstaaet") + + nova_cases.set_case_state(case.uuid, "Afsluttet", self.nova_access) + nova_case = _get_case(case.uuid, self.nova_access) + self.assertEqual(nova_case.progress_state, "Afsluttet") + + +def _get_case(case_uuid: str, nova_access: NovaAccess) -> NovaCase | None: + """Get a case by the given uuid. Retry for up to 10 seconds until the case appears. + + Args: + case_uuid: The uuid of the case to get. + nova_access: The NovaAccess object used to authenticate. + + Returns: + The case with the given uuid if it exists. + """ + for _ in range(10): + time.sleep(1) + try: + return nova_cases.get_case(case_uuid, nova_access) + except ValueError: + pass + return None + + +def _get_test_party() -> CaseParty: + """Get the case party used for tests defined in NOVA_PARTY envvar. + + Returns: + A CaseParty object based on the NOVA_PARTY envvar. + """ + nova_party = os.getenv('NOVA_PARTY').split(',') + return CaseParty( + role="Primær", + identification_type="CprNummer", + identification=nova_party[0], + name=nova_party[1] + ) + + +def _get_test_caseworker() -> Caseworker: + """Get the caseworker used for tests defined in the NOVA_USER envvar. + + Returns: + A Caseworker object based on the NOVA_USER envvar. + """ + caseworker_dict = json.loads(os.environ['NOVA_USER']) + return Caseworker( + **caseworker_dict + ) + + +def _get_test_department() -> Department: + """Get the department used for tests defined in the NOVA_DEPARTMENT envvar. + + Returns: + A Department object based on the NOVA_DEPARTMENT envvar. + """ + department_dict = json.loads(os.environ['NOVA_DEPARTMENT']) + return Department( + **department_dict + ) + if __name__ == '__main__': unittest.main()