Skip to content

Commit ea01cda

Browse files
committed
feat: add helpdesk forms services and tests
1 parent 676f1c1 commit ea01cda

File tree

8 files changed

+315
-0
lines changed

8 files changed

+315
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from mpt_api_client.http import AsyncService, Service
2+
from mpt_api_client.http.mixins import (
3+
AsyncCollectionMixin,
4+
AsyncManagedResourceMixin,
5+
CollectionMixin,
6+
ManagedResourceMixin,
7+
)
8+
from mpt_api_client.models import Model, ResourceData
9+
10+
11+
class Form(Model):
12+
"""Helpdesk Form resource."""
13+
14+
15+
class FormsServiceConfig:
16+
"""Helpdesk Forms service configuration."""
17+
18+
_endpoint = "/public/v1/helpdesk/forms"
19+
_model_class = Form
20+
_collection_key = "data"
21+
22+
23+
class FormsService(
24+
ManagedResourceMixin[Form],
25+
CollectionMixin[Form],
26+
Service[Form],
27+
FormsServiceConfig,
28+
):
29+
"""Helpdesk Forms service."""
30+
31+
def publish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
32+
"""Switch form to published state."""
33+
return self._resource_action(resource_id, "POST", "publish", json=resource_data)
34+
35+
def unpublish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
36+
"""Switch form to unpublished state."""
37+
return self._resource_action(resource_id, "POST", "unpublish", json=resource_data)
38+
39+
40+
class AsyncFormsService(
41+
AsyncManagedResourceMixin[Form],
42+
AsyncCollectionMixin[Form],
43+
AsyncService[Form],
44+
FormsServiceConfig,
45+
):
46+
"""Async Helpdesk Forms service."""
47+
48+
async def publish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
49+
"""Switch form to published state."""
50+
return await self._resource_action(resource_id, "POST", "publish", json=resource_data)
51+
52+
async def unpublish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
53+
"""Switch form to unpublished state."""
54+
return await self._resource_action(resource_id, "POST", "unpublish", json=resource_data)

mpt_api_client/resources/helpdesk/helpdesk.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from mpt_api_client.http import AsyncHTTPClient, HTTPClient
22
from mpt_api_client.resources.helpdesk.cases import AsyncCasesService, CasesService
33
from mpt_api_client.resources.helpdesk.chats import AsyncChatsService, ChatsService
4+
from mpt_api_client.resources.helpdesk.forms import AsyncFormsService, FormsService
45
from mpt_api_client.resources.helpdesk.parameter_groups import (
56
AsyncParameterGroupsService,
67
ParameterGroupsService,
@@ -38,6 +39,11 @@ def parameters(self) -> ParametersService: # noqa: WPS110
3839
"""Parameters service."""
3940
return ParametersService(http_client=self.http_client)
4041

42+
@property
43+
def forms(self) -> FormsService:
44+
"""Forms service."""
45+
return FormsService(http_client=self.http_client)
46+
4147
@property
4248
def parameter_groups(self) -> ParameterGroupsService:
4349
"""Parameter groups service."""
@@ -70,6 +76,11 @@ def parameters(self) -> AsyncParametersService: # noqa: WPS110
7076
"""Async parameters service."""
7177
return AsyncParametersService(http_client=self.http_client)
7278

79+
@property
80+
def forms(self) -> AsyncFormsService:
81+
"""Async forms service."""
82+
return AsyncFormsService(http_client=self.http_client)
83+
7384
@property
7485
def parameter_groups(self) -> AsyncParameterGroupsService:
7586
"""Async parameter groups service."""
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import pytest
2+
3+
from tests.e2e.helper import (
4+
async_create_fixture_resource_and_delete,
5+
create_fixture_resource_and_delete,
6+
)
7+
8+
9+
@pytest.fixture
10+
def form_data(short_uuid):
11+
return {
12+
"name": f"E2E Helpdesk Form {short_uuid}",
13+
"description": "E2E Created Helpdesk Form",
14+
}
15+
16+
17+
@pytest.fixture
18+
def invalid_form_id():
19+
return "FRM-0000-0000"
20+
21+
22+
@pytest.fixture
23+
def created_form(mpt_ops, form_data):
24+
with create_fixture_resource_and_delete(mpt_ops.helpdesk.forms, form_data) as form:
25+
yield form
26+
27+
28+
@pytest.fixture
29+
async def async_created_form(async_mpt_ops, form_data):
30+
async with async_create_fixture_resource_and_delete(
31+
async_mpt_ops.helpdesk.forms, form_data
32+
) as form:
33+
yield form
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import pytest
2+
3+
from mpt_api_client.exceptions import MPTAPIError
4+
5+
pytestmark = [pytest.mark.flaky]
6+
7+
8+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
9+
async def test_get_form(async_mpt_ops, async_created_form):
10+
result = await async_mpt_ops.helpdesk.forms.get(async_created_form.id)
11+
12+
assert result.id == async_created_form.id
13+
14+
15+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
16+
async def test_list_forms(async_mpt_ops):
17+
result = await async_mpt_ops.helpdesk.forms.fetch_page(limit=1)
18+
19+
assert len(result) > 0
20+
21+
22+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
23+
def test_create_form(async_created_form):
24+
result = async_created_form
25+
26+
assert result is not None
27+
28+
29+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
30+
async def test_update_form(async_mpt_ops, async_created_form, short_uuid):
31+
update_data = {"description": f"e2e update {short_uuid}"}
32+
33+
result = await async_mpt_ops.helpdesk.forms.update(async_created_form.id, update_data)
34+
35+
assert result.id == async_created_form.id
36+
assert result.to_dict().get("description") == update_data["description"]
37+
38+
39+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
40+
async def test_publish_form(async_mpt_ops, async_created_form):
41+
result = await async_mpt_ops.helpdesk.forms.publish(async_created_form.id)
42+
43+
assert result is not None
44+
45+
46+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
47+
async def test_unpublish_form(async_mpt_ops, async_created_form):
48+
result = await async_mpt_ops.helpdesk.forms.unpublish(async_created_form.id)
49+
50+
assert result is not None
51+
52+
53+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
54+
async def test_delete_form(async_mpt_ops, async_created_form):
55+
await async_mpt_ops.helpdesk.forms.delete(async_created_form.id) # act
56+
57+
58+
async def test_not_found(async_mpt_ops, invalid_form_id):
59+
with pytest.raises(MPTAPIError):
60+
await async_mpt_ops.helpdesk.forms.get(invalid_form_id)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import pytest
2+
3+
from mpt_api_client.exceptions import MPTAPIError
4+
5+
pytestmark = [pytest.mark.flaky]
6+
7+
8+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
9+
def test_get_form(mpt_ops, created_form):
10+
result = mpt_ops.helpdesk.forms.get(created_form.id)
11+
12+
assert result.id == created_form.id
13+
14+
15+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
16+
def test_list_forms(mpt_ops):
17+
result = mpt_ops.helpdesk.forms.fetch_page(limit=1)
18+
19+
assert len(result) > 0
20+
21+
22+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
23+
def test_create_form(created_form):
24+
result = created_form
25+
26+
assert result is not None
27+
28+
29+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
30+
def test_update_form(mpt_ops, created_form, short_uuid):
31+
update_data = {"description": f"e2e update {short_uuid}"}
32+
33+
result = mpt_ops.helpdesk.forms.update(created_form.id, update_data)
34+
35+
assert result.id == created_form.id
36+
assert result.to_dict().get("description") == update_data["description"]
37+
38+
39+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
40+
def test_publish_form(mpt_ops, created_form):
41+
result = mpt_ops.helpdesk.forms.publish(created_form.id)
42+
43+
assert result is not None
44+
45+
46+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
47+
def test_unpublish_form(mpt_ops, created_form):
48+
result = mpt_ops.helpdesk.forms.unpublish(created_form.id)
49+
50+
assert result is not None
51+
52+
53+
@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
54+
def test_delete_form(mpt_ops, created_form):
55+
mpt_ops.helpdesk.forms.delete(created_form.id) # act
56+
57+
58+
def test_not_found(mpt_ops, invalid_form_id):
59+
with pytest.raises(MPTAPIError):
60+
mpt_ops.helpdesk.forms.get(invalid_form_id)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import httpx
2+
import pytest
3+
import respx
4+
5+
from mpt_api_client.resources.helpdesk.forms import AsyncFormsService, Form, FormsService
6+
7+
8+
@pytest.fixture
9+
def forms_service(http_client):
10+
return FormsService(http_client=http_client)
11+
12+
13+
@pytest.fixture
14+
def async_forms_service(async_http_client):
15+
return AsyncFormsService(http_client=async_http_client)
16+
17+
18+
def test_endpoint(forms_service):
19+
result = forms_service.path == "/public/v1/helpdesk/forms"
20+
21+
assert result is True
22+
23+
24+
def test_async_endpoint(async_forms_service):
25+
result = async_forms_service.path == "/public/v1/helpdesk/forms"
26+
27+
assert result is True
28+
29+
30+
@pytest.mark.parametrize(
31+
"method",
32+
["get", "create", "update", "delete", "fetch_page", "iterate", "publish", "unpublish"],
33+
)
34+
def test_methods_present(forms_service, method):
35+
result = hasattr(forms_service, method)
36+
37+
assert result is True
38+
39+
40+
@pytest.mark.parametrize(
41+
"method",
42+
["get", "create", "update", "delete", "fetch_page", "iterate", "publish", "unpublish"],
43+
)
44+
def test_async_methods_present(async_forms_service, method):
45+
result = hasattr(async_forms_service, method)
46+
47+
assert result is True
48+
49+
50+
@pytest.mark.parametrize("action", ["publish", "unpublish"])
51+
def test_custom_resource_actions(forms_service, action):
52+
response_expected_data = {"id": "FRM-1234-5678", "status": "Updated"}
53+
with respx.mock:
54+
mock_route = respx.post(
55+
f"https://api.example.com/public/v1/helpdesk/forms/FRM-1234-5678/{action}"
56+
).mock(
57+
return_value=httpx.Response(
58+
status_code=httpx.codes.OK,
59+
headers={"content-type": "application/json"},
60+
json=response_expected_data,
61+
)
62+
)
63+
64+
result = getattr(forms_service, action)("FRM-1234-5678")
65+
66+
assert mock_route.call_count == 1
67+
request = mock_route.calls[0].request
68+
assert request.content == b""
69+
assert result.to_dict() == response_expected_data
70+
assert isinstance(result, Form)
71+
72+
73+
@pytest.mark.parametrize("action", ["publish", "unpublish"])
74+
async def test_async_custom_resource_actions(async_forms_service, action):
75+
response_expected_data = {"id": "FRM-1234-5678", "status": "Updated"}
76+
with respx.mock:
77+
mock_route = respx.post(
78+
f"https://api.example.com/public/v1/helpdesk/forms/FRM-1234-5678/{action}"
79+
).mock(
80+
return_value=httpx.Response(
81+
status_code=httpx.codes.OK,
82+
headers={"content-type": "application/json"},
83+
json=response_expected_data,
84+
)
85+
)
86+
87+
result = await getattr(async_forms_service, action)("FRM-1234-5678")
88+
89+
assert mock_route.call_count == 1
90+
request = mock_route.calls[0].request
91+
assert request.content == b""
92+
assert result.to_dict() == response_expected_data
93+
assert isinstance(result, Form)

tests/unit/resources/helpdesk/test_helpdesk.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from mpt_api_client.resources.helpdesk import AsyncHelpdesk, Helpdesk
44
from mpt_api_client.resources.helpdesk.cases import AsyncCasesService, CasesService
55
from mpt_api_client.resources.helpdesk.chats import AsyncChatsService, ChatsService
6+
from mpt_api_client.resources.helpdesk.forms import AsyncFormsService, FormsService
67
from mpt_api_client.resources.helpdesk.parameter_groups import (
78
AsyncParameterGroupsService,
89
ParameterGroupsService,
@@ -36,6 +37,7 @@ def test_async_helpdesk_init(async_http_client):
3637
("queues", QueuesService),
3738
("parameters", ParametersService),
3839
("parameter_groups", ParameterGroupsService),
40+
("forms", FormsService),
3941
],
4042
)
4143
def test_helpdesk_properties(http_client, attr_name, expected):
@@ -54,6 +56,7 @@ def test_helpdesk_properties(http_client, attr_name, expected):
5456
("queues", AsyncQueuesService),
5557
("parameters", AsyncParametersService),
5658
("parameter_groups", AsyncParameterGroupsService),
59+
("forms", AsyncFormsService),
5760
],
5861
)
5962
def test_async_helpdesk_properties(async_http_client, attr_name, expected):

0 commit comments

Comments
 (0)