Skip to content

Commit

Permalink
feat: signer data from Ahjo
Browse files Browse the repository at this point in the history
  • Loading branch information
rikuke committed Nov 27, 2024
1 parent ba803f7 commit 828a9ec
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ def execute(self):
call_command("delete_applications", keep=180, status="draft")
call_command("check_drafts_to_delete", notify=14, keep=180)
call_command("get_decision_maker")
call_command("get_signer")
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from applications.enums import AhjoRequestType
from applications.management.commands.ahjo_base_command import AhjoRequestBaseClass


class Command(AhjoRequestBaseClass):
help = (
"Get the decision maker from Ahjo and store it in the database in Ahjo settings"
)
request_type = AhjoRequestType.GET_SIGNER
5 changes: 3 additions & 2 deletions backend/benefit/applications/services/ahjo/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ class AhjoSettingName(Enum):
Enum representing different Ahjo setting names.
The @unique decorator ensures that no two enum members have the same value.
Using auto() generates unique, incrementing values, but we'll use string values
to maintain readability and compatibility with existing database entries.
"""

DECISION_MAKER = "ahjo_decision_maker"
DECISION_MAKER_ORG_ID = "ahjo_org_identifier"
SIGNER = "ahjo_signer"
SIGNER_ORG_IDS = "ahjo_signer_org_ids"

def __str__(self):
"""
Expand Down
19 changes: 15 additions & 4 deletions backend/benefit/applications/services/ahjo/request_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
AhjoApiClient,
AhjoDecisionMakerRequest,
AhjoRequest,
AhjoSignerRequest,
)


Expand All @@ -18,11 +19,21 @@ def __init__(self, ahjo_token: AhjoToken, ahjo_request_type: AhjoRequest):

def handle_request_without_application(self):
if self.ahjo_request_type == AhjoRequestType.GET_DECISION_MAKER:
self.get_decision_maker_from_ahjo()
self.get_setting_from_ahjo(
request_class=AhjoDecisionMakerRequest,
setting_name=AhjoSettingName.DECISION_MAKER,
)
if self.ahjo_request_type == AhjoRequestType.GET_SIGNER:
self.get_setting_from_ahjo(
request_class=AhjoSignerRequest,
setting_name=AhjoSettingName.SIGNER,
)

def get_decision_maker_from_ahjo(self) -> Union[List, None]:
ahjo_client = AhjoApiClient(self.ahjo_token, AhjoDecisionMakerRequest())
def get_setting_from_ahjo(
self, request_class: AhjoRequest, setting_name: AhjoSettingName
) -> Union[List, None]:
ahjo_client = AhjoApiClient(self.ahjo_token, request_class())
_, result = ahjo_client.send_request_to_ahjo()
AhjoResponseHandler.handle_ahjo_query_response(
setting_name=AhjoSettingName.DECISION_MAKER, data=result
setting_name=setting_name, data=result
)
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ def handle_ahjo_query_response(
raise ValidationError(
f"Invalid response format for setting {setting_name}: expected dictionary"
)

filtered_data = AhjoResponseHandler.filter_decision_makers(data)
if setting_name == AhjoSettingName.DECISION_MAKER:
filtered_data = AhjoResponseHandler.filter_decision_makers(data)
if setting_name == AhjoSettingName.SIGNER:
filtered_data = AhjoResponseHandler.filter_signers(data)

if not filtered_data:
LOGGER.warning("No valid decision makers found in response")
Expand Down Expand Up @@ -129,3 +131,22 @@ def _save_ahjo_setting(
raise ValidationError(
f"Failed to save setting {setting_name} to database: {str(e)}"
)

@staticmethod
def filter_signers(data: Dict) -> List[Dict[str, str]]:
"""
Filter the signers Name and ID from the Ahjo response.
Args:
data: Response data dictionary
Returns:
List of filtered signer dictionaries
Raises:
ValidationError: If required fields are missing
"""
result = []
for item in data["agentList"]:
result.append({"ID": item["ID"], "Name": item["Name"]})
return result
7 changes: 5 additions & 2 deletions backend/benefit/applications/services/ahjo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from applications.enums import AhjoRequestType, AhjoStatus as AhjoStatusEnum
from applications.models import AhjoSetting, AhjoStatus, Application
from applications.services.ahjo.enums import AhjoSettingName
from applications.services.ahjo.exceptions import (
AhjoApiClientException,
InvalidAhjoTokenException,
Expand Down Expand Up @@ -151,7 +152,9 @@ class AhjoDecisionMakerRequest(AhjoRequest):
@staticmethod
def org_identifier() -> str:
try:
return AhjoSetting.objects.get(name="ahjo_org_identifier").data["id"]
return AhjoSetting.objects.get(
name=AhjoSettingName.DECISION_MAKER_ORG_ID
).data["id"]
except AhjoSetting.DoesNotExist:
raise MissingOrganizationIdentifier(
"No organization identifier found in the database."
Expand All @@ -170,7 +173,7 @@ class AhjoSignerRequest(AhjoRequest):
@staticmethod
def org_identifier() -> str:
try:
setting = AhjoSetting.objects.get(name="ahjo_signer_org_ids")
setting = AhjoSetting.objects.get(name=AhjoSettingName.SIGNER_ORG_IDS)
if not setting.data:
raise ValueError("Signer organization identifier list is empty")

Expand Down
37 changes: 37 additions & 0 deletions backend/benefit/applications/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,43 @@ def signer_settings(fake_signers):
)


@pytest.fixture
def signer_response():
return {
"agentList": [
{
"agentId": "kissa213",
"links": [],
"ID": "kissa213",
"Name": "Testaaja, Tiina",
"Title": None,
"Role": "decisionMaker",
"Email": None,
},
{
"agentId": "koira123",
"links": [],
"ID": "koira123",
"Name": "Testaaja, Timo",
"Title": None,
"Role": "decisionMaker",
"Email": None,
},
{
"agentId": "kala123",
"links": [],
"ID": "kala123",
"Name": "Testaaja, Teppo",
"Title": None,
"Role": "decisionMaker",
"Email": None,
},
],
"count": 3,
"links": [],
}


@pytest.fixture
def non_expired_token():
return AhjoToken(
Expand Down
21 changes: 21 additions & 0 deletions backend/benefit/applications/tests/test_ahjo_request_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pytest

from applications.enums import AhjoRequestType
from applications.services.ahjo.request_handler import AhjoRequestHandler


@pytest.mark.parametrize(
"request_type",
[
(AhjoRequestType.GET_DECISION_MAKER),
(AhjoRequestType.GET_SIGNER),
],
)
def test_init_sets_token_and_request_type(request_type, non_expired_token):
"""
Test that the constructor correctly sets token and request type
"""
request_handler = AhjoRequestHandler(non_expired_token, request_type)

assert request_handler.ahjo_token == non_expired_token
assert request_handler.ahjo_request_type == request_type
9 changes: 7 additions & 2 deletions backend/benefit/applications/tests/test_ahjo_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from applications.enums import AhjoRequestType, AhjoStatus as AhjoStatusEnum
from applications.models import AhjoSetting, AhjoStatus
from applications.services.ahjo.enums import AhjoSettingName
from applications.services.ahjo.exceptions import (
AhjoApiClientException,
InvalidAhjoTokenException,
Expand Down Expand Up @@ -67,8 +68,12 @@ def test_ahjo_requests_without_application(
settings,
non_expired_token,
):
AhjoSetting.objects.create(name="ahjo_org_identifier", data={"id": "1234567-8"})
AhjoSetting.objects.create(name="ahjo_signer_org_ids", data=["1234567", "7654321"])
AhjoSetting.objects.create(
name=AhjoSettingName.DECISION_MAKER_ORG_ID, data={"id": "1234567-8"}
)
AhjoSetting.objects.create(
name=AhjoSettingName.SIGNER_ORG_IDS, data=["1234567", "7654321"]
)

settings.API_BASE_URL = "http://test.com"
request_instance = ahjo_request_class()
Expand Down
100 changes: 73 additions & 27 deletions backend/benefit/applications/tests/test_ahjo_response_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,43 +26,81 @@ def test_ahjo_response_handler_filter_decision_makers(decisionmaker_response):
]


def test_ahjo_response_handler_filter_signers(signer_response):
result = AhjoResponseHandler.filter_signers(signer_response)
assert len(result) == 3
assert result == [
{
"Name": signer_response["agentList"][0]["Name"],
"ID": signer_response["agentList"][0]["ID"],
},
{
"Name": signer_response["agentList"][1]["Name"],
"ID": signer_response["agentList"][1]["ID"],
},
{
"Name": signer_response["agentList"][2]["Name"],
"ID": signer_response["agentList"][2]["ID"],
},
]


@pytest.mark.parametrize(
"setting_name, test_data",
"setting_name",
[
(AhjoSettingName.DECISION_MAKER, {"Name": "Test Org", "ID": "ORG001"}),
(AhjoSettingName.DECISION_MAKER),
(AhjoSettingName.SIGNER),
],
)
@patch("applications.models.AhjoSetting.objects.update_or_create")
def test_handle_ahjo_query_response_successful(
mock_update_or_create, decisionmaker_response, setting_name, test_data
mock_update_or_create, decisionmaker_response, setting_name, signer_response
):
"""Test successful handling of decision maker response"""
mock_response = decisionmaker_response[1]

AhjoResponseHandler.handle_ahjo_query_response(setting_name, mock_response)
"""Test successful handling of setting response"""
if setting_name == AhjoSettingName.DECISION_MAKER:
mock_response = decisionmaker_response[1]
data = [
{
"Name": decisionmaker_response[1]["decisionMakers"][0]["Organization"][
"Name"
],
"ID": decisionmaker_response[1]["decisionMakers"][0]["Organization"][
"ID"
],
},
{
"Name": decisionmaker_response[1]["decisionMakers"][1]["Organization"][
"Name"
],
"ID": decisionmaker_response[1]["decisionMakers"][1]["Organization"][
"ID"
],
},
]
if setting_name == AhjoSettingName.SIGNER:
mock_response = signer_response
data = [
{
"Name": signer_response["agentList"][0]["Name"],
"ID": signer_response["agentList"][0]["ID"],
},
{
"Name": signer_response["agentList"][1]["Name"],
"ID": signer_response["agentList"][1]["ID"],
},
{
"Name": signer_response["agentList"][2]["Name"],
"ID": signer_response["agentList"][2]["ID"],
},
]

AhjoResponseHandler.handle_ahjo_query_response(
setting_name=setting_name, data=mock_response
)

mock_update_or_create.assert_called_once_with(
name=setting_name,
defaults={
"data": [
{
"Name": decisionmaker_response[1]["decisionMakers"][0][
"Organization"
]["Name"],
"ID": decisionmaker_response[1]["decisionMakers"][0][
"Organization"
]["ID"],
},
{
"Name": decisionmaker_response[1]["decisionMakers"][1][
"Organization"
]["Name"],
"ID": decisionmaker_response[1]["decisionMakers"][1][
"Organization"
]["ID"],
},
]
},
defaults={"data": data},
)


Expand All @@ -88,6 +126,7 @@ def test_filter_decision_makers_missing_decisionmakers_key():
"setting_name, test_data",
[
(AhjoSettingName.DECISION_MAKER, {"Name": "Test Org", "ID": "ORG001"}),
(AhjoSettingName.SIGNER, [{"Name": "Test Signer", "ID": "SIGN001"}]),
],
)
@patch("applications.models.AhjoSetting.objects.update_or_create")
Expand All @@ -105,6 +144,13 @@ def test_save_ahjo_setting(mock_update_or_create, setting_name, test_data):
"setting_name, test_data",
[
(AhjoSettingName.DECISION_MAKER, {"Name": "Test Org", "ID": "ORG001"}),
(
AhjoSettingName.SIGNER,
[
{"Name": "Test Signer", "ID": "SIGN001"},
{"Name": "Test Signer 2", "ID": "SIGN002"},
],
),
],
)
def test_save_ahjo_settings_database_error(setting_name, test_data):
Expand Down

0 comments on commit 828a9ec

Please sign in to comment.