Skip to content

Commit 1a287eb

Browse files
committed
MPT-16512 E2E for Notification batch attachments
1 parent aa89e23 commit 1a287eb

File tree

8 files changed

+174
-21
lines changed

8 files changed

+174
-21
lines changed

e2e_config.test.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"commerce.subscription.agreement.id": "AGR-2473-3299-1721",
4848
"commerce.subscription.id": "SUB-3678-1831-2188",
4949
"commerce.subscription.product.item.id": "ITM-1767-7355-0001",
50+
"notifications.batch.attachment.id": "ATT-7183-1965-7758",
5051
"notifications.batch.id": "MST-3638-2460-4825",
5152
"notifications.category.id": "NTC-6157-0397",
5253
"notifications.subscriber.id": "NTS-0829-7123-7123",

mpt_api_client/http/async_client.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ def __init__(
4848
base_headers = {
4949
"User-Agent": "swo-marketplace-client/1.0",
5050
"Authorization": f"Bearer {api_token}",
51-
"Accept": "application/json",
5251
}
5352
self.httpx_client = AsyncClient(
5453
base_url=base_url,

mpt_api_client/resources/notifications/batches.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ class Batch(Model):
1414
"""Notifications Batch resource."""
1515

1616

17+
class BatchAttachment(Model):
18+
"""Notifications Batch Attachment resource."""
19+
20+
1721
class BatchesServiceConfig:
1822
"""Notifications Batches service configuration."""
1923

@@ -33,9 +37,27 @@ class BatchesService(
3337
):
3438
"""Notifications Batches service."""
3539

36-
def get_batch_attachment(self, batch_id: str, attachment_id: str) -> FileModel:
40+
def get_attachment(self, batch_id: str, attachment_id: str) -> BatchAttachment:
3741
"""Get batch attachment.
3842
43+
Args:
44+
batch_id: Batch ID.
45+
attachment_id: Attachment ID.
46+
47+
Returns:
48+
BatchAttachment containing the attachment data.
49+
"""
50+
response = self.http_client.request(
51+
"get",
52+
f"{self.path}/{batch_id}/attachments/{attachment_id}",
53+
headers={"Accept": "application/json"},
54+
)
55+
56+
return BatchAttachment.from_response(response)
57+
58+
def download_attachment(self, batch_id: str, attachment_id: str) -> FileModel:
59+
"""Download batch attachment.
60+
3961
Args:
4062
batch_id: Batch ID.
4163
attachment_id: Attachment ID.
@@ -59,9 +81,26 @@ class AsyncBatchesService(
5981
):
6082
"""Async Notifications Batches service."""
6183

62-
async def get_batch_attachment(self, batch_id: str, attachment_id: str) -> FileModel:
84+
async def get_attachment(self, batch_id: str, attachment_id: str) -> BatchAttachment:
6385
"""Get batch attachment.
6486
87+
Args:
88+
batch_id: Batch ID.
89+
attachment_id: Attachment ID.
90+
91+
Returns:
92+
BatchAttachment containing the attachment data.
93+
"""
94+
response = await self.http_client.request(
95+
"get",
96+
f"{self.path}/{batch_id}/attachments/{attachment_id}",
97+
headers={"Accept": "application/json"},
98+
)
99+
return BatchAttachment.from_response(response)
100+
101+
async def download_attachment(self, batch_id: str, attachment_id: str) -> FileModel:
102+
"""Download batch attachment.
103+
65104
Args:
66105
batch_id: Batch ID.
67106
attachment_id: Attachment ID.

tests/e2e/notifications/batch/conftest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ def batch_data(category_id, short_uuid):
2424
"body": "Hello world",
2525
"contacts": [{"email": f"{short_uuid}@example.com"}],
2626
}
27+
28+
29+
@pytest.fixture
30+
def batch_attachment_id(e2e_config):
31+
return e2e_config["notifications.batch.attachment.id"]

tests/e2e/notifications/batch/test_async_batches.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ async def test_create_batch(async_batch_service, batch_data):
1111

1212

1313
async def test_get_batch(async_batch_service, batch_id):
14-
result = await async_batch_service.get(batch_id)
14+
result = await async_batch_service.get(batch_id, select=["attachments"])
1515

1616
assert result.id == batch_id
1717

@@ -30,7 +30,13 @@ async def test_create_batch_with_file(async_batch_service, batch_data, logo_fd):
3030
assert result is not None
3131

3232

33-
@pytest.mark.skip(reason="Batches attachments not implemented")
34-
async def test_download_attachment():
35-
# TODO - Implement get and download E2E tests for attachments
36-
raise NotImplementedError
33+
async def test_download_attachment(async_batch_service, batch_id, batch_attachment_id):
34+
result = await async_batch_service.download_attachment(batch_id, batch_attachment_id)
35+
36+
assert result.filename == "logo.png"
37+
38+
39+
async def test_get_attachment(async_batch_service, batch_id, batch_attachment_id):
40+
result = await async_batch_service.get_attachment(batch_id, batch_attachment_id)
41+
42+
assert result.id == batch_attachment_id

tests/e2e/notifications/batch/test_batches.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def test_create_batch(batch_service, batch_data):
1111

1212

1313
def test_get_batch(batch_service, batch_id):
14-
result = batch_service.get(batch_id)
14+
result = batch_service.get(batch_id, select=["attachments"])
1515

1616
assert result.id == batch_id
1717

@@ -30,7 +30,13 @@ def test_create_batch_with_file(batch_service, batch_data, logo_fd):
3030
assert result is not None
3131

3232

33-
@pytest.mark.skip(reason="Batches attachments not implemented") # noqa: AAA01
34-
def test_download_attachment():
35-
# TODO - Implement get and download E2E tests for attachment
36-
raise NotImplementedError
33+
def test_download_attachment(batch_service, batch_id, batch_attachment_id):
34+
result = batch_service.download_attachment(batch_id, batch_attachment_id)
35+
36+
assert result.filename == "logo.png"
37+
38+
39+
def test_get_attachment(batch_service, batch_id, batch_attachment_id):
40+
result = batch_service.get_attachment(batch_id, batch_attachment_id)
41+
42+
assert result.id == batch_attachment_id

tests/unit/http/test_async_client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ def test_async_http_initialization(mocker):
3131
headers={
3232
"User-Agent": "swo-marketplace-client/1.0",
3333
"Authorization": "Bearer test-token",
34-
"Accept": "application/json",
3534
},
3635
timeout=10.0,
3736
transport=mocker.ANY,
@@ -51,7 +50,6 @@ def test_async_env_initialization(monkeypatch, mocker):
5150
headers={
5251
"User-Agent": "swo-marketplace-client/1.0",
5352
"Authorization": f"Bearer {API_TOKEN}",
54-
"Accept": "application/json",
5553
},
5654
timeout=10.0,
5755
transport=mocker.ANY,
Lines changed: 105 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,129 @@
11
import pytest
22

3+
from mpt_api_client.http import AsyncHTTPClient, HTTPClient
4+
from mpt_api_client.http.types import Response
5+
from mpt_api_client.models import FileModel
36
from mpt_api_client.resources.notifications.batches import (
47
AsyncBatchesService,
8+
BatchAttachment,
59
BatchesService,
610
)
711

812

913
@pytest.fixture
10-
def batches_service(http_client):
14+
def batches_service(http_client: HTTPClient) -> BatchesService:
1115
return BatchesService(http_client=http_client)
1216

1317

1418
@pytest.fixture
15-
def async_batches_service(async_http_client):
19+
def async_batches_service(async_http_client: AsyncHTTPClient) -> AsyncBatchesService:
1620
return AsyncBatchesService(http_client=async_http_client)
1721

1822

19-
@pytest.mark.parametrize("method", ["get", "create", "iterate", "get_batch_attachment"])
20-
def test_sync_batches_service_methods(batches_service, method):
23+
@pytest.fixture
24+
def attachment_response() -> Response:
25+
return Response(
26+
headers={"content-disposition": 'attachment; filename="test.csv"'},
27+
status_code=200,
28+
content=b"content",
29+
)
30+
31+
32+
@pytest.fixture
33+
def batch_attachment_response() -> Response:
34+
return Response(
35+
headers={"Content-Type": "application/json"},
36+
status_code=200,
37+
content=b'{"id": "A-123", "name": "test.csv"}',
38+
)
39+
40+
41+
@pytest.mark.parametrize(
42+
"method", ["get", "create", "iterate", "download_attachment", "get_attachment"]
43+
)
44+
def test_sync_batches_service_methods(batches_service: BatchesService, method: str) -> None:
2145
result = hasattr(batches_service, method)
2246

2347
assert result is True
2448

2549

26-
@pytest.mark.parametrize("method", ["get", "create", "iterate", "get_batch_attachment"])
27-
def test_async_batches_service_methods(async_batches_service, method):
50+
@pytest.mark.parametrize(
51+
"method", ["get", "create", "iterate", "download_attachment", "get_attachment"]
52+
)
53+
def test_async_batches_service_methods(
54+
async_batches_service: AsyncBatchesService, method: str
55+
) -> None:
2856
result = hasattr(async_batches_service, method)
2957

3058
assert result is True
59+
60+
61+
def test_get_attachment(mocker, batches_service, batch_attachment_response) -> None:
62+
batch_id = "B-123"
63+
attachment_id = "A-123"
64+
mock_request = mocker.patch.object(
65+
batches_service.http_client, "request", return_value=batch_attachment_response
66+
)
67+
68+
result = batches_service.get_attachment(batch_id, attachment_id)
69+
70+
assert isinstance(result, BatchAttachment)
71+
assert result.id == "A-123"
72+
mock_request.assert_called_once_with(
73+
"get",
74+
f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}",
75+
headers={"Accept": "application/json"},
76+
)
77+
78+
79+
async def test_async_get_attachment(
80+
mocker, async_batches_service, batch_attachment_response
81+
) -> None:
82+
batch_id = "B-123"
83+
attachment_id = "A-123"
84+
mock_request = mocker.patch.object(
85+
async_batches_service.http_client, "request", return_value=batch_attachment_response
86+
)
87+
88+
result = await async_batches_service.get_attachment(batch_id, attachment_id)
89+
90+
assert isinstance(result, BatchAttachment)
91+
assert result.id == "A-123"
92+
mock_request.assert_called_once_with(
93+
"get",
94+
f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}",
95+
headers={"Accept": "application/json"},
96+
)
97+
98+
99+
def test_download_attachment(mocker, batches_service, attachment_response) -> None:
100+
batch_id = "B-123"
101+
attachment_id = "A-123"
102+
mock_request = mocker.patch.object(
103+
batches_service.http_client, "request", return_value=attachment_response
104+
)
105+
106+
result = batches_service.download_attachment(batch_id, attachment_id)
107+
108+
assert isinstance(result, FileModel)
109+
mock_request.assert_called_once_with(
110+
"get", f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}"
111+
)
112+
113+
114+
async def test_async_download_attachment( # noqa: WPS210
115+
mocker, async_batches_service, attachment_response
116+
) -> None:
117+
batch_id = "B-123"
118+
attachment_id = "A-123"
119+
mock_request = mocker.patch.object(
120+
async_batches_service.http_client, "request", return_value=attachment_response
121+
)
122+
123+
result = await async_batches_service.download_attachment(batch_id, attachment_id)
124+
125+
assert isinstance(result, FileModel)
126+
127+
mock_request.assert_called_once_with(
128+
"get", f"/public/v1/notifications/batches/{batch_id}/attachments/{attachment_id}"
129+
)

0 commit comments

Comments
 (0)