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
1 change: 1 addition & 0 deletions e2e_config.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"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.attachment.id": "ATT-7183-1965-7758",
"notifications.batch.id": "MST-3638-2460-4825",
"notifications.category.id": "NTC-6157-0397",
"notifications.subscriber.id": "NTS-0829-7123-7123",
Expand Down
1 change: 0 additions & 1 deletion mpt_api_client/http/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ def __init__(
base_headers = {
"User-Agent": "swo-marketplace-client/1.0",
"Authorization": f"Bearer {api_token}",
"Accept": "application/json",
}
self.httpx_client = AsyncClient(
base_url=base_url,
Expand Down
43 changes: 41 additions & 2 deletions mpt_api_client/resources/notifications/batches.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ class Batch(Model):
"""Notifications Batch resource."""


class BatchAttachment(Model):
"""Notifications Batch Attachment resource."""


class BatchesServiceConfig:
"""Notifications Batches service configuration."""

Expand All @@ -33,9 +37,27 @@ class BatchesService(
):
"""Notifications Batches service."""

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

Args:
batch_id: Batch ID.
attachment_id: Attachment ID.

Returns:
BatchAttachment containing the attachment data.
"""
response = self.http_client.request(
"get",
f"{self.path}/{batch_id}/attachments/{attachment_id}",
headers={"Accept": "application/json"},
)

return BatchAttachment.from_response(response)

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

Args:
batch_id: Batch ID.
attachment_id: Attachment ID.
Expand All @@ -59,9 +81,26 @@ class AsyncBatchesService(
):
"""Async Notifications Batches service."""

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

Args:
batch_id: Batch ID.
attachment_id: Attachment ID.

Returns:
BatchAttachment containing the attachment data.
"""
response = await self.http_client.request(
"get",
f"{self.path}/{batch_id}/attachments/{attachment_id}",
headers={"Accept": "application/json"},
)
return BatchAttachment.from_response(response)

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

Args:
batch_id: Batch ID.
attachment_id: Attachment ID.
Expand Down
5 changes: 5 additions & 0 deletions tests/e2e/notifications/batch/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ def batch_data(category_id, short_uuid):
"body": "Hello world",
"contacts": [{"email": f"{short_uuid}@example.com"}],
}


@pytest.fixture
def batch_attachment_id(e2e_config):
return e2e_config["notifications.batch.attachment.id"]
16 changes: 11 additions & 5 deletions tests/e2e/notifications/batch/test_async_batches.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async def test_create_batch(async_batch_service, batch_data):


async def test_get_batch(async_batch_service, batch_id):
result = await async_batch_service.get(batch_id)
result = await async_batch_service.get(batch_id, select=["attachments"])

assert result.id == batch_id

Expand All @@ -30,7 +30,13 @@ async def test_create_batch_with_file(async_batch_service, batch_data, 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
async def test_download_attachment(async_batch_service, batch_id, batch_attachment_id):
result = await async_batch_service.download_attachment(batch_id, batch_attachment_id)

assert result.filename == "logo.png"


async def test_get_attachment(async_batch_service, batch_id, batch_attachment_id):
result = await async_batch_service.get_attachment(batch_id, batch_attachment_id)

assert result.id == batch_attachment_id
16 changes: 11 additions & 5 deletions tests/e2e/notifications/batch/test_batches.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def test_create_batch(batch_service, batch_data):


def test_get_batch(batch_service, batch_id):
result = batch_service.get(batch_id)
result = batch_service.get(batch_id, select=["attachments"])

assert result.id == batch_id

Expand All @@ -30,7 +30,13 @@ def test_create_batch_with_file(batch_service, batch_data, 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
def test_download_attachment(batch_service, batch_id, batch_attachment_id):
result = batch_service.download_attachment(batch_id, batch_attachment_id)

assert result.filename == "logo.png"


def test_get_attachment(batch_service, batch_id, batch_attachment_id):
result = batch_service.get_attachment(batch_id, batch_attachment_id)

assert result.id == batch_attachment_id
2 changes: 0 additions & 2 deletions tests/unit/http/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def test_async_http_initialization(mocker):
headers={
"User-Agent": "swo-marketplace-client/1.0",
"Authorization": "Bearer test-token",
"Accept": "application/json",
},
timeout=10.0,
transport=mocker.ANY,
Expand All @@ -51,7 +50,6 @@ def test_async_env_initialization(monkeypatch, mocker):
headers={
"User-Agent": "swo-marketplace-client/1.0",
"Authorization": f"Bearer {API_TOKEN}",
"Accept": "application/json",
},
timeout=10.0,
transport=mocker.ANY,
Expand Down
111 changes: 105 additions & 6 deletions tests/unit/resources/notifications/test_batches.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,129 @@
import pytest

from mpt_api_client.http import AsyncHTTPClient, HTTPClient
from mpt_api_client.http.types import Response
from mpt_api_client.models import FileModel
from mpt_api_client.resources.notifications.batches import (
AsyncBatchesService,
BatchAttachment,
BatchesService,
)


@pytest.fixture
def batches_service(http_client):
def batches_service(http_client: HTTPClient) -> BatchesService:
return BatchesService(http_client=http_client)


@pytest.fixture
def async_batches_service(async_http_client):
def async_batches_service(async_http_client: AsyncHTTPClient) -> AsyncBatchesService:
return AsyncBatchesService(http_client=async_http_client)


@pytest.mark.parametrize("method", ["get", "create", "iterate", "get_batch_attachment"])
def test_sync_batches_service_methods(batches_service, method):
@pytest.fixture
def attachment_response() -> Response:
return Response(
headers={"content-disposition": 'attachment; filename="test.csv"'},
status_code=200,
content=b"content",
)


@pytest.fixture
def batch_attachment_response() -> Response:
return Response(
headers={"Content-Type": "application/json"},
status_code=200,
content=b'{"id": "A-123", "name": "test.csv"}',
)


@pytest.mark.parametrize(
"method", ["get", "create", "iterate", "download_attachment", "get_attachment"]
)
def test_sync_batches_service_methods(batches_service: BatchesService, method: str) -> None:
result = hasattr(batches_service, method)

assert result is True


@pytest.mark.parametrize("method", ["get", "create", "iterate", "get_batch_attachment"])
def test_async_batches_service_methods(async_batches_service, method):
@pytest.mark.parametrize(
"method", ["get", "create", "iterate", "download_attachment", "get_attachment"]
)
def test_async_batches_service_methods(
async_batches_service: AsyncBatchesService, method: str
) -> None:
result = hasattr(async_batches_service, method)

assert result is True


def test_get_attachment(mocker, batches_service, batch_attachment_response) -> None:
batch_id = "B-123"
attachment_id = "A-123"
mock_request = mocker.patch.object(
batches_service.http_client, "request", return_value=batch_attachment_response
)

result = batches_service.get_attachment(batch_id, attachment_id)

assert isinstance(result, BatchAttachment)
assert result.id == "A-123"
mock_request.assert_called_once_with(
"get",
f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}",
headers={"Accept": "application/json"},
)


async def test_async_get_attachment(
mocker, async_batches_service, batch_attachment_response
) -> None:
batch_id = "B-123"
attachment_id = "A-123"
mock_request = mocker.patch.object(
async_batches_service.http_client, "request", return_value=batch_attachment_response
)

result = await async_batches_service.get_attachment(batch_id, attachment_id)

assert isinstance(result, BatchAttachment)
assert result.id == "A-123"
mock_request.assert_called_once_with(
"get",
f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}",
headers={"Accept": "application/json"},
)


def test_download_attachment(mocker, batches_service, attachment_response) -> None:
batch_id = "B-123"
attachment_id = "A-123"
mock_request = mocker.patch.object(
batches_service.http_client, "request", return_value=attachment_response
)

result = batches_service.download_attachment(batch_id, attachment_id)

assert isinstance(result, FileModel)
mock_request.assert_called_once_with(
"get", f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}"
)


async def test_async_download_attachment( # noqa: WPS210
mocker, async_batches_service, attachment_response
) -> None:
batch_id = "B-123"
attachment_id = "A-123"
mock_request = mocker.patch.object(
async_batches_service.http_client, "request", return_value=attachment_response
)

result = await async_batches_service.download_attachment(batch_id, attachment_id)

assert isinstance(result, FileModel)

mock_request.assert_called_once_with(
"get", f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}"
)