Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
26 changes: 26 additions & 0 deletions itk_dev_shared_components/kmd_nova/nova_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import uuid
import urllib.parse
from typing import Literal

import requests

Expand Down Expand Up @@ -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()
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
]
Expand Down
128 changes: 91 additions & 37 deletions tests/test_nova_api/test_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand All @@ -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)

Expand Down Expand Up @@ -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()}",
Expand All @@ -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()
Loading