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
2 changes: 2 additions & 0 deletions e2e_config.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
"commerce.subscription.agreement.id": "AGR-2473-3299-1721",
"commerce.subscription.id": "SUB-3678-1831-2188",
"commerce.subscription.product.item.id": "ITM-1767-7355-0001",
"notifications.batch.id": "MST-3638-2460-4825",
"notifications.category.id": "NTC-6157-0397",
"notifications.subscriber.id": "NTS-0829-7123-7123",
"notifications.message.id": "MSG-0000-6215-1019-0139"
}
67 changes: 7 additions & 60 deletions mpt_api_client/resources/notifications/batches.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
from httpx._types import FileTypes

from mpt_api_client.http import AsyncService, Service
from mpt_api_client.http.client import json_to_file_payload
from mpt_api_client.http.mixins import (
AsyncCollectionMixin,
AsyncCreateFileMixin,
AsyncGetMixin,
CollectionMixin,
CreateFileMixin,
GetMixin,
)
from mpt_api_client.models import FileModel, Model, ResourceData
from mpt_api_client.models import FileModel, Model


class Batch(Model):
Expand All @@ -21,44 +20,19 @@ class BatchesServiceConfig:
_endpoint = "/public/v1/notifications/batches"
_model_class = Batch
_collection_key = "data"
_upload_file_key = "attachment"
_upload_data_key = "batch"


class BatchesService(
CreateFileMixin[Batch],
GetMixin[Batch],
CollectionMixin[Batch],
Service[Batch],
BatchesServiceConfig,
):
"""Notifications Batches service."""

def create(
self,
resource_data: ResourceData | None = None,
files: dict[str, FileTypes] | None = None, # noqa: WPS221
data_key: str = "_attachment_data",
) -> Model:
"""Create batch with attachments.

Args:
resource_data: batch data.
files: Files data.
data_key: Key to use for the JSON data in the multipart form.

Returns:
Created resource.
"""
files = files or {}

if resource_data:
files[data_key] = (
None,
json_to_file_payload(resource_data),
"application/json",
)

response = self.http_client.request("post", self.path, files=files)
return self._model_class.from_response(response)

def get_batch_attachment(self, batch_id: str, attachment_id: str) -> FileModel:
"""Get batch attachment.

Expand All @@ -77,41 +51,14 @@ def get_batch_attachment(self, batch_id: str, attachment_id: str) -> FileModel:


class AsyncBatchesService(
AsyncCreateFileMixin[Batch],
AsyncGetMixin[Batch],
AsyncCollectionMixin[Batch],
AsyncService[Batch],
BatchesServiceConfig,
):
"""Async Notifications Batches service."""

async def create(
self,
resource_data: ResourceData | None = None,
files: dict[str, FileTypes] | None = None, # noqa: WPS221
data_key: str = "_attachment_data",
) -> Model:
"""Create batch with attachments.

Args:
resource_data: batch data.
files: Files data.
data_key: Key to use for the JSON data in the multipart form.

Returns:
Created resource.
"""
files = files or {}

if resource_data:
files[data_key] = (
None,
json_to_file_payload(resource_data),
"application/json",
)

response = await self.http_client.request("post", self.path, files=files)
return self._model_class.from_response(response)

async def get_batch_attachment(self, batch_id: str, attachment_id: str) -> FileModel:
"""Get batch attachment.

Expand Down
26 changes: 26 additions & 0 deletions tests/e2e/notifications/batch/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytest


@pytest.fixture
def batch_service(mpt_ops):
return mpt_ops.notifications.batches


@pytest.fixture
def async_batch_service(async_mpt_ops):
return async_mpt_ops.notifications.batches


@pytest.fixture
def batch_id(e2e_config):
return e2e_config["notifications.batch.id"]


@pytest.fixture
def batch_data(category_id, short_uuid):
return {
"category": {"id": category_id},
"subject": f"E2E - please delete - {short_uuid}",
"body": "Hello world",
"contacts": [{"email": f"{short_uuid}@example.com"}],
}
36 changes: 36 additions & 0 deletions tests/e2e/notifications/batch/test_async_batches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest

from mpt_api_client.rql.query_builder import RQLQuery


@pytest.mark.skip(reason="Batches can not be deleted")
async def test_create_batch(async_batch_service, batch_data):
result = await async_batch_service.create(batch_data)

assert result is not None


async def test_get_batch(async_batch_service, batch_id):
result = await async_batch_service.get(batch_id)

assert result.id == batch_id


async def test_iterate_and_filter(async_batch_service, batch_id):
batches = [batch async for batch in async_batch_service.filter(RQLQuery(id=batch_id)).iterate()]

assert len(batches) == 1
assert batches[0].id == batch_id


@pytest.mark.skip(reason="Batches can not be deleted")
async def test_create_batch_with_file(async_batch_service, batch_data, logo_fd):
result = await async_batch_service.create(batch_data, file=logo_fd)

assert result is not None


@pytest.mark.skip(reason="Batches attachments not implemented")
async def test_download_attachment():
# TODO - Implement get and download E2E tests for attachments
raise NotImplementedError
36 changes: 36 additions & 0 deletions tests/e2e/notifications/batch/test_batches.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest

from mpt_api_client import RQLQuery


@pytest.mark.skip(reason="Batches can not be deleted")
def test_create_batch(batch_service, batch_data):
result = batch_service.create(batch_data)

assert result is not None


def test_get_batch(batch_service, batch_id):
result = batch_service.get(batch_id)

assert result.id == batch_id


def test_iterate_and_filter(batch_service, batch_id):
result = list(batch_service.filter(RQLQuery(id=batch_id)).iterate())

assert len(result) == 1
assert result[0].id == batch_id


@pytest.mark.skip(reason="Batches can not be deleted")
def test_create_batch_with_file(batch_service, batch_data, logo_fd):
result = batch_service.create(batch_data, file=logo_fd)

assert result is not None


@pytest.mark.skip(reason="Batches attachments not implemented") # noqa: AAA01
def test_download_attachment():
# TODO - Implement get and download E2E tests for attachment
raise NotImplementedError
Comment on lines +33 to +36
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused noqa directive.

The # noqa: AAA01 directive references an unknown linting code and should be removed.

🔎 Apply this diff to remove the unused directive:
-@pytest.mark.skip(reason="Batches attachments not implemented")  # noqa: AAA01
+@pytest.mark.skip(reason="Batches attachments not implemented")
 def test_download_attachment():
     # TODO - Implement get and download E2E tests for attachment
     raise NotImplementedError
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@pytest.mark.skip(reason="Batches attachments not implemented") # noqa: AAA01
def test_download_attachment():
# TODO - Implement get and download E2E tests for attachment
raise NotImplementedError
@pytest.mark.skip(reason="Batches attachments not implemented")
def test_download_attachment():
# TODO - Implement get and download E2E tests for attachment
raise NotImplementedError
🧰 Tools
🪛 Ruff (0.14.8)

33-33: Unused noqa directive (unknown: AAA01)

Remove unused noqa directive

(RUF100)

🤖 Prompt for AI Agents
In tests/e2e/notifications/batch/test_batches.py around lines 33 to 36, the test
function has an unused lint suppression comment "# noqa: AAA01" that references
a nonexistent rule; remove that noqa directive so the line reads simply
@pytest.mark.skip(reason="Batches attachments not implemented") and keep the
rest of the test (TODO and raise) unchanged.

35 changes: 7 additions & 28 deletions tests/e2e/notifications/categories/test_async_categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,19 @@ async def async_created_category(async_mpt_ops, category_data):
print(f"TEARDOWN - Unable to delete category {category.id}: {error.title}") # noqa: WPS421


@pytest.mark.skip(reason="async_created_category kills performance due to MPT-13785") # noqa: AAA01
def test_create_category(async_created_category, category_data):
def test_create_category(async_created_category, category_data): # noqa: AAA01
assert async_created_category.name == category_data["name"]
assert async_created_category.description == category_data["description"]
Comment on lines +20 to 22
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused noqa directive.

The # noqa: AAA01 directive references an unknown linting code and should be removed.

🔎 Apply this diff to remove the unused directive:
-def test_create_category(async_created_category, category_data):  # noqa: AAA01
+def test_create_category(async_created_category, category_data):
     assert async_created_category.name == category_data["name"]
     assert async_created_category.description == category_data["description"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_create_category(async_created_category, category_data): # noqa: AAA01
assert async_created_category.name == category_data["name"]
assert async_created_category.description == category_data["description"]
def test_create_category(async_created_category, category_data):
assert async_created_category.name == category_data["name"]
assert async_created_category.description == category_data["description"]
🧰 Tools
🪛 Ruff (0.14.8)

20-20: Unused noqa directive (unknown: AAA01)

Remove unused noqa directive

(RUF100)

🤖 Prompt for AI Agents
In tests/e2e/notifications/categories/test_async_categories.py around lines 20
to 22, the test function declaration contains an unused noqa directive "# noqa:
AAA01"; remove that directive from the function definition so the line reads
without the trailing comment, leaving the test intact and ensuring no unknown
linter code is suppressed.



@pytest.mark.skip(reason="async_created_category kills performance due to MPT-13785")
async def test_get_category(async_mpt_vendor, async_created_category):
async def test_get_category(async_mpt_vendor, category_id):
service = async_mpt_vendor.notifications.categories

result = await service.get(async_created_category.id)
result = await service.get(category_id)

assert result.id == async_created_category.id
assert result.name == async_created_category.name
assert result.id == category_id


@pytest.mark.skip(reason="async_created_category kills performance due to MPT-13785")
async def test_update_category(async_mpt_ops, async_created_category):
service = async_mpt_ops.notifications.categories
update_data = {
Expand All @@ -47,26 +43,13 @@ async def test_update_category(async_mpt_ops, async_created_category):
assert result.description == "Async updated description"


@pytest.mark.skip(reason="async_created_category kills performance due to MPT-13785")
async def test_list_categories(async_mpt_vendor, async_created_category):
async def test_filter_categories(async_mpt_vendor, category_id):
service = async_mpt_vendor.notifications.categories

result = [category async for category in service.iterate()]

assert any(category.id == async_created_category.id for category in result)


@pytest.mark.skip(reason="async_created_category kills performance due to MPT-13785")
async def test_filter_categories(async_mpt_vendor, async_created_category):
service = async_mpt_vendor.notifications.categories

result = [
category
async for category in service.filter(RQLQuery(id=async_created_category.id)).iterate()
]
result = [category async for category in service.filter(RQLQuery(id=category_id)).iterate()]

assert len(result) == 1
assert result[0].id == async_created_category.id
assert result[0].id == category_id


@pytest.mark.skip(reason="async_created_category kills performance due to MPT-13785")
Expand Down Expand Up @@ -98,15 +81,11 @@ async def test_category_not_found(async_mpt_vendor, invalid_category_id):
await service.get(invalid_category_id)


@pytest.mark.skip(reason="async_created_category kills performance due to MPT-13785")
async def test_delete_category(async_mpt_ops, async_created_category):
service = async_mpt_ops.notifications.categories

await service.delete(async_created_category.id)

with pytest.raises(MPTAPIError):
await service.get(async_created_category.id)


async def test_delete_category_not_found(async_mpt_ops, invalid_category_id):
service = async_mpt_ops.notifications.categories
Expand Down
29 changes: 6 additions & 23 deletions tests/e2e/notifications/categories/test_sync_categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,18 @@ def created_category(mpt_ops, category_data):
print(f"TEARDOWN - Unable to delete category {category.id}: {error.title}") # noqa: WPS421


@pytest.mark.skip(reason="created_category kills performance due to MPT-13785")
def test_create_category(created_category, category_data):
assert created_category.name == category_data["name"] # act

assert created_category.description == category_data["description"]


@pytest.mark.skip(reason="created_category kills performance due to MPT-13785")
def test_get_category(mpt_client, created_category):
def test_get_category(mpt_client, category_id):
service = mpt_client.notifications.categories

result = service.get(created_category.id)
result = service.get(category_id)

assert result.id == created_category.id
assert result.name == created_category.name
assert result.id == category_id


@pytest.mark.skip(reason="created_category kills performance due to MPT-13785")
Expand All @@ -48,23 +45,13 @@ def test_update_category(mpt_ops, created_category):
assert result.description == "Updated description"


@pytest.mark.skip(reason="created_category kills performance due to MPT-13785")
def test_list_categories(mpt_client, created_category):
def test_filter_categories(mpt_client, category_id):
service = mpt_client.notifications.categories

result = list(service.iterate())

assert any(category.id == created_category.id for category in result)


@pytest.mark.skip(reason="created_category kills performance due to MPT-13785")
def test_filter_categories(mpt_client, created_category):
service = mpt_client.notifications.categories

result = list(service.filter(RQLQuery(id=created_category.id)).iterate())
result = list(service.filter(RQLQuery(id=category_id)).iterate())

assert len(result) == 1
assert result[0].id == created_category.id
assert result[0].id == category_id


@pytest.mark.skip(reason="created_category kills performance due to MPT-13785")
Expand Down Expand Up @@ -96,15 +83,11 @@ def test_category_not_found(mpt_client, invalid_category_id):
service.get(invalid_category_id)


@pytest.mark.skip(reason="created_category kills performance due to MPT-13785")
def test_delete_category(mpt_ops, created_category):
service = mpt_ops.notifications.categories

service.delete(created_category.id) # act

with pytest.raises(MPTAPIError):
service.get(created_category.id)


def test_delete_category_not_found(mpt_ops, invalid_category_id):
service = mpt_ops.notifications.categories
Expand Down
6 changes: 6 additions & 0 deletions tests/e2e/notifications/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import pytest


@pytest.fixture
def category_id(e2e_config):
return e2e_config["notifications.category.id"]
Loading