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
54 changes: 54 additions & 0 deletions mpt_api_client/resources/helpdesk/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from mpt_api_client.http import AsyncService, Service
from mpt_api_client.http.mixins import (
AsyncCollectionMixin,
AsyncManagedResourceMixin,
CollectionMixin,
ManagedResourceMixin,
)
from mpt_api_client.models import Model, ResourceData


class Form(Model):
"""Helpdesk Form resource."""


class FormsServiceConfig:
"""Helpdesk Forms service configuration."""

_endpoint = "/public/v1/helpdesk/forms"
_model_class = Form
_collection_key = "data"


class FormsService(
ManagedResourceMixin[Form],
CollectionMixin[Form],
Service[Form],
FormsServiceConfig,
):
"""Helpdesk Forms service."""

def publish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
"""Switch form to published state."""
return self._resource_action(resource_id, "POST", "publish", json=resource_data)

def unpublish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
"""Switch form to unpublished state."""
return self._resource_action(resource_id, "POST", "unpublish", json=resource_data)


class AsyncFormsService(
AsyncManagedResourceMixin[Form],
AsyncCollectionMixin[Form],
AsyncService[Form],
FormsServiceConfig,
):
"""Async Helpdesk Forms service."""

async def publish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
"""Switch form to published state."""
return await self._resource_action(resource_id, "POST", "publish", json=resource_data)

async def unpublish(self, resource_id: str, resource_data: ResourceData | None = None) -> Form:
"""Switch form to unpublished state."""
return await self._resource_action(resource_id, "POST", "unpublish", json=resource_data)
11 changes: 11 additions & 0 deletions mpt_api_client/resources/helpdesk/helpdesk.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from mpt_api_client.resources.helpdesk.cases import AsyncCasesService, CasesService
from mpt_api_client.resources.helpdesk.channels import AsyncChannelsService, ChannelsService
from mpt_api_client.resources.helpdesk.chats import AsyncChatsService, ChatsService
from mpt_api_client.resources.helpdesk.forms import AsyncFormsService, FormsService
from mpt_api_client.resources.helpdesk.parameter_groups import (
AsyncParameterGroupsService,
ParameterGroupsService,
Expand Down Expand Up @@ -44,6 +45,11 @@ def parameters(self) -> ParametersService: # noqa: WPS110
"""Parameters service."""
return ParametersService(http_client=self.http_client)

@property
def forms(self) -> FormsService:
"""Forms service."""
return FormsService(http_client=self.http_client)

@property
def parameter_groups(self) -> ParameterGroupsService:
"""Parameter groups service."""
Expand Down Expand Up @@ -81,6 +87,11 @@ def parameters(self) -> AsyncParametersService: # noqa: WPS110
"""Async parameters service."""
return AsyncParametersService(http_client=self.http_client)

@property
def forms(self) -> AsyncFormsService:
"""Async forms service."""
return AsyncFormsService(http_client=self.http_client)

@property
def parameter_groups(self) -> AsyncParameterGroupsService:
"""Async parameter groups service."""
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ per-file-ignores = [
"mpt_api_client/resources/catalog/*.py: WPS110 WPS214 WPS215 WPS235",
"mpt_api_client/resources/catalog/products.py: WPS204 WPS214 WPS215 WPS235",
"mpt_api_client/resources/commerce/*.py: WPS235 WPS215",
"mpt_api_client/resources/helpdesk/*.py: WPS204 WPS215",
"mpt_api_client/resources/helpdesk/*.py: WPS204 WPS215 WPS214",
"mpt_api_client/rql/query_builder.py: WPS110 WPS115 WPS210 WPS214",
"tests/e2e/accounts/*.py: WPS430 WPS202",
"tests/e2e/billing/*.py: WPS202 WPS421 WPS118",
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/helpdesk/forms/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

33 changes: 33 additions & 0 deletions tests/e2e/helpdesk/forms/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import pytest

from tests.e2e.helper import (
async_create_fixture_resource_and_delete,
create_fixture_resource_and_delete,
)


@pytest.fixture
def form_data(short_uuid):
return {
"name": f"E2E Helpdesk Form {short_uuid}",
"description": "E2E Created Helpdesk Form",
}


@pytest.fixture
def invalid_form_id():
return "FRM-0000-0000"


@pytest.fixture
def created_form(mpt_ops, form_data):
with create_fixture_resource_and_delete(mpt_ops.helpdesk.forms, form_data) as form:
yield form


@pytest.fixture
async def async_created_form(async_mpt_ops, form_data):
async with async_create_fixture_resource_and_delete(
async_mpt_ops.helpdesk.forms, form_data
) as form:
yield form
60 changes: 60 additions & 0 deletions tests/e2e/helpdesk/forms/test_async_forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import pytest

from mpt_api_client.exceptions import MPTAPIError

pytestmark = [pytest.mark.flaky]


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
async def test_get_form(async_mpt_ops, async_created_form):
result = await async_mpt_ops.helpdesk.forms.get(async_created_form.id)

assert result.id == async_created_form.id


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
async def test_list_forms(async_mpt_ops):
result = await async_mpt_ops.helpdesk.forms.fetch_page(limit=1)

assert len(result) > 0


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_create_form(async_created_form):
result = async_created_form

assert result is not None


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
async def test_update_form(async_mpt_ops, async_created_form, short_uuid):
update_data = {"description": f"e2e update {short_uuid}"}

result = await async_mpt_ops.helpdesk.forms.update(async_created_form.id, update_data)

assert result.id == async_created_form.id
assert result.to_dict().get("description") == update_data["description"]


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
async def test_publish_form(async_mpt_ops, async_created_form):
result = await async_mpt_ops.helpdesk.forms.publish(async_created_form.id)

assert result is not None


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
async def test_unpublish_form(async_mpt_ops, async_created_form):
result = await async_mpt_ops.helpdesk.forms.unpublish(async_created_form.id)

assert result is not None


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
async def test_delete_form(async_mpt_ops, async_created_form):
await async_mpt_ops.helpdesk.forms.delete(async_created_form.id) # act


async def test_not_found(async_mpt_ops, invalid_form_id):
with pytest.raises(MPTAPIError):
await async_mpt_ops.helpdesk.forms.get(invalid_form_id)
60 changes: 60 additions & 0 deletions tests/e2e/helpdesk/forms/test_sync_forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import pytest

from mpt_api_client.exceptions import MPTAPIError

pytestmark = [pytest.mark.flaky]


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_get_form(mpt_ops, created_form):
result = mpt_ops.helpdesk.forms.get(created_form.id)

assert result.id == created_form.id


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_list_forms(mpt_ops):
result = mpt_ops.helpdesk.forms.fetch_page(limit=1)

assert len(result) > 0


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_create_form(created_form):
result = created_form

assert result is not None


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_update_form(mpt_ops, created_form, short_uuid):
update_data = {"description": f"e2e update {short_uuid}"}

result = mpt_ops.helpdesk.forms.update(created_form.id, update_data)

assert result.id == created_form.id
assert result.to_dict().get("description") == update_data["description"]


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_publish_form(mpt_ops, created_form):
result = mpt_ops.helpdesk.forms.publish(created_form.id)

assert result is not None


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_unpublish_form(mpt_ops, created_form):
result = mpt_ops.helpdesk.forms.unpublish(created_form.id)

assert result is not None


@pytest.mark.skip(reason="Unskip after MPT-19124 completed")
def test_delete_form(mpt_ops, created_form):
mpt_ops.helpdesk.forms.delete(created_form.id) # act


def test_not_found(mpt_ops, invalid_form_id):
with pytest.raises(MPTAPIError):
mpt_ops.helpdesk.forms.get(invalid_form_id)
93 changes: 93 additions & 0 deletions tests/unit/resources/helpdesk/test_forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import httpx
import pytest
import respx

from mpt_api_client.resources.helpdesk.forms import AsyncFormsService, Form, FormsService


@pytest.fixture
def forms_service(http_client):
return FormsService(http_client=http_client)


@pytest.fixture
def async_forms_service(async_http_client):
return AsyncFormsService(http_client=async_http_client)


def test_endpoint(forms_service):
result = forms_service.path == "/public/v1/helpdesk/forms"

assert result is True


def test_async_endpoint(async_forms_service):
result = async_forms_service.path == "/public/v1/helpdesk/forms"

assert result is True


@pytest.mark.parametrize(
"method",
["get", "create", "update", "delete", "fetch_page", "iterate", "publish", "unpublish"],
)
def test_methods_present(forms_service, method):
result = hasattr(forms_service, method)

assert result is True


@pytest.mark.parametrize(
"method",
["get", "create", "update", "delete", "fetch_page", "iterate", "publish", "unpublish"],
)
def test_async_methods_present(async_forms_service, method):
result = hasattr(async_forms_service, method)

assert result is True


@pytest.mark.parametrize("action", ["publish", "unpublish"])
def test_custom_resource_actions(forms_service, action):
response_expected_data = {"id": "FRM-1234-5678", "status": "Updated"}
with respx.mock:
mock_route = respx.post(
f"https://api.example.com/public/v1/helpdesk/forms/FRM-1234-5678/{action}"
).mock(
return_value=httpx.Response(
status_code=httpx.codes.OK,
headers={"content-type": "application/json"},
json=response_expected_data,
)
)

result = getattr(forms_service, action)("FRM-1234-5678")

assert mock_route.call_count == 1
request = mock_route.calls[0].request
assert request.content == b""
assert result.to_dict() == response_expected_data
assert isinstance(result, Form)


@pytest.mark.parametrize("action", ["publish", "unpublish"])
async def test_async_custom_resource_actions(async_forms_service, action):
response_expected_data = {"id": "FRM-1234-5678", "status": "Updated"}
with respx.mock:
mock_route = respx.post(
f"https://api.example.com/public/v1/helpdesk/forms/FRM-1234-5678/{action}"
).mock(
return_value=httpx.Response(
status_code=httpx.codes.OK,
headers={"content-type": "application/json"},
json=response_expected_data,
)
)

result = await getattr(async_forms_service, action)("FRM-1234-5678")

assert mock_route.call_count == 1
request = mock_route.calls[0].request
assert request.content == b""
assert result.to_dict() == response_expected_data
assert isinstance(result, Form)
3 changes: 3 additions & 0 deletions tests/unit/resources/helpdesk/test_helpdesk.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from mpt_api_client.resources.helpdesk.cases import AsyncCasesService, CasesService
from mpt_api_client.resources.helpdesk.channels import AsyncChannelsService, ChannelsService
from mpt_api_client.resources.helpdesk.chats import AsyncChatsService, ChatsService
from mpt_api_client.resources.helpdesk.forms import AsyncFormsService, FormsService
from mpt_api_client.resources.helpdesk.parameter_groups import (
AsyncParameterGroupsService,
ParameterGroupsService,
Expand Down Expand Up @@ -38,6 +39,7 @@ def test_async_helpdesk_init(async_http_client):
("queues", QueuesService),
("parameters", ParametersService),
("parameter_groups", ParameterGroupsService),
("forms", FormsService),
],
)
def test_helpdesk_properties(http_client, attr_name, expected):
Expand All @@ -57,6 +59,7 @@ def test_helpdesk_properties(http_client, attr_name, expected):
("queues", AsyncQueuesService),
("parameters", AsyncParametersService),
("parameter_groups", AsyncParameterGroupsService),
("forms", AsyncFormsService),
],
)
def test_async_helpdesk_properties(async_http_client, attr_name, expected):
Expand Down
Loading