Skip to content

Commit f783387

Browse files
author
Robert Segal
committed
Seeded and created e2e tests for commerce agreements
1 parent 8f72e0c commit f783387

File tree

17 files changed

+481
-21
lines changed

17 files changed

+481
-21
lines changed

e2e_config.test.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111
"accounts.seller.id": "SEL-7310-3075",
1212
"accounts.user.id": "USR-9673-3314",
1313
"accounts.user_group.id": "UGR-6822-0561",
14+
"commerce.agreement.id": "AGR-9850-2169-6098",
15+
"commerce.product.id": "PRD-1767-7355",
16+
"commerce.product.item.id": "ITM-1767-7355-0001",
17+
"commerce.product.listing.id": "LST-5489-0806",
18+
"commerce.product.template.id": "TPL-1767-7355-0003",
19+
"commerce.authorization.id": "AUT-0031-2873",
20+
"commerce.client.id": "ACC-1086-6867",
1421
"catalog.product.item.id": "ITM-7255-3950-0751",
1522
"catalog.product.document.id": "PDC-7255-3950-0001",
1623
"catalog.product.id": "PRD-7255-3950",

mpt_api_client/resources/commerce/agreements.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ def template(self, agreement_id: str) -> str:
4444
response = self._resource_do_request(agreement_id, action="template")
4545
return response.text
4646

47+
def render(self, agreement_id: str) -> str:
48+
"""Renders the template for the given Agreement id.
49+
50+
Args:
51+
agreement_id: Agreement ID.
52+
53+
Returns:
54+
Rendered Agreement.
55+
"""
56+
response = self._resource_do_request(agreement_id, action="render")
57+
return response.text
58+
4759
def attachments(self, agreement_id: str) -> AgreementsAttachmentService:
4860
"""Get the attachments service for the given Agreement id.
4961
@@ -79,6 +91,18 @@ async def template(self, agreement_id: str) -> str:
7991
response = await self._resource_do_request(agreement_id, action="template")
8092
return response.text
8193

94+
async def render(self, agreement_id: str) -> str:
95+
"""Renders the template for the given Agreement id.
96+
97+
Args:
98+
agreement_id: Agreement ID.
99+
100+
Returns:
101+
Rendered Agreement.
102+
"""
103+
response = await self._resource_do_request(agreement_id, action="render")
104+
return response.text
105+
82106
def attachments(self, agreement_id: str) -> AsyncAgreementsAttachmentService:
83107
"""Get the attachments service for the given Agreement id.
84108

mpt_api_client/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import datetime as dt
2+
3+
4+
def get_iso_dt_str(dt_obj: dt.datetime) -> str:
5+
"""Convert datetime to ISO 8601 string."""
6+
return dt_obj.isoformat(timespec="milliseconds").replace("+00:00", "Z")

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ dev = [
4848
"ruff==0.12.11", # force ruff version to have same formatting everywhere
4949
"typing-extensions==4.13.*",
5050
"wemake-python-styleguide==1.3.*",
51+
"types-python-dateutil",
5152
]
5253

5354
[tool.hatch.build.targets.sdist]
@@ -119,6 +120,7 @@ per-file-ignores = [
119120
"mpt_api_client/resources/catalog/mixins.py: WPS110 WPS202 WPS214 WPS215 WPS235",
120121
"mpt_api_client/resources/catalog/products.py: WPS204 WPS214 WPS215 WPS235",
121122
"mpt_api_client/rql/query_builder.py: WPS110 WPS115 WPS210 WPS214",
123+
"mpt_api_client/utils.py: WPS100 WPS453",
122124
"tests/unit/http/test_async_service.py: WPS204 WPS202",
123125
"tests/unit/http/test_service.py: WPS204 WPS202",
124126
"tests/unit/http/test_mixins.py: WPS204 WPS202 WPS210",

tests/e2e/accounts/conftest.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,6 @@ def currencies():
1818
return ["USD", "EUR"]
1919

2020

21-
@pytest.fixture
22-
def account_id(e2e_config):
23-
return e2e_config["accounts.account.id"]
24-
25-
26-
@pytest.fixture
27-
def seller_id(e2e_config):
28-
return e2e_config["accounts.seller.id"]
29-
30-
31-
@pytest.fixture
32-
def buyer_id(e2e_config):
33-
return e2e_config["accounts.buyer.id"]
34-
35-
3621
@pytest.fixture
3722
def user_group_id(e2e_config):
3823
return e2e_config["accounts.user_group.id"]

tests/e2e/accounts/licensees/conftest.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ def licensee_group_id(e2e_config):
1111
return e2e_config["accounts.licensee.group.id"]
1212

1313

14-
@pytest.fixture
15-
def licensee_id(e2e_config):
16-
return e2e_config["accounts.licensee.id"]
17-
18-
1914
@pytest.fixture
2015
def invalid_licensee_id():
2116
return "LCE-0000-0000-0000"
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import datetime as dt
2+
3+
import pytest
4+
from dateutil.relativedelta import relativedelta
5+
from freezegun import freeze_time
6+
7+
from mpt_api_client.utils import get_iso_dt_str
8+
9+
10+
@pytest.fixture
11+
def invalid_agreement_id():
12+
return "AGR-0000-0000"
13+
14+
15+
@pytest.fixture
16+
def agreement_factory( # noqa: WPS211
17+
account_id,
18+
seller_id,
19+
buyer_id,
20+
licensee_id,
21+
commerce_product_id,
22+
authorization_id,
23+
):
24+
@freeze_time("2025-11-14T09:00:00.000Z")
25+
def _agreement_factory( # noqa: WPS430
26+
name: str = "E2E Created Agreement",
27+
client_external_id: str = "test-client-external-id",
28+
vendor_external_id: str = "test-vendor-external-id",
29+
):
30+
"""Factory to create agreement data."""
31+
start_date = dt.datetime.now(tz=dt.UTC)
32+
end_date = start_date + relativedelta(years=1)
33+
34+
return {
35+
"name": name,
36+
"status": "Active",
37+
"vendor": {"id": account_id},
38+
"authorization": {"id": authorization_id},
39+
"seller": {"id": seller_id},
40+
"buyer": {"id": buyer_id},
41+
"licensee": {"id": licensee_id},
42+
"product": {"id": commerce_product_id},
43+
"value": {
44+
"PPxY": 150,
45+
"PPxM": 12.5,
46+
"SPxY": 165,
47+
"SPxM": 13.75,
48+
"markup": 0.1,
49+
"margin": 0.11,
50+
"currency": "USD",
51+
},
52+
"startDate": get_iso_dt_str(start_date),
53+
"endDate": get_iso_dt_str(end_date),
54+
"externalIds": {
55+
"client": client_external_id,
56+
"vendor": vendor_external_id,
57+
},
58+
}
59+
60+
return _agreement_factory
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import pytest
2+
3+
from mpt_api_client.exceptions import MPTAPIError
4+
from mpt_api_client.rql.query_builder import RQLQuery
5+
6+
pytestmark = [pytest.mark.flaky]
7+
8+
9+
@pytest.fixture
10+
async def created_agreement(async_mpt_ops, agreement_factory):
11+
new_agreement_request_data = agreement_factory(
12+
name="E2E Created Agreement",
13+
)
14+
15+
return await async_mpt_ops.commerce.agreements.create(new_agreement_request_data)
16+
17+
18+
async def test_get_agreement_by_id(async_mpt_ops, agreement_id):
19+
result = await async_mpt_ops.commerce.agreements.get(agreement_id)
20+
21+
assert result is not None
22+
23+
24+
async def test_list_agreements(async_mpt_ops):
25+
limit = 10
26+
27+
result = await async_mpt_ops.commerce.agreements.fetch_page(limit=limit)
28+
29+
assert len(result) > 0
30+
31+
32+
async def test_get_agreement_by_id_not_found(async_mpt_ops, invalid_agreement_id):
33+
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
34+
await async_mpt_ops.commerce.agreements.get(invalid_agreement_id) # act
35+
36+
37+
async def test_filter_agreements(async_mpt_ops, agreement_id):
38+
select_fields = ["-value"]
39+
40+
filtered_agreements = (
41+
async_mpt_ops.commerce.agreements.filter(RQLQuery(id=agreement_id))
42+
.filter(RQLQuery(name="E2E Seeded For Commerce for Test Api Client Client"))
43+
.select(*select_fields)
44+
)
45+
46+
result = [filtered_agreements async for filtered_agreement in filtered_agreements.iterate()]
47+
48+
assert len(result) == 1
49+
50+
51+
def test_create_agreement(created_agreement):
52+
result = created_agreement
53+
54+
assert result is not None
55+
56+
57+
async def test_update_agreement(async_mpt_ops, created_agreement, agreement_factory):
58+
updated_name = "E2E Updated Agreement Name"
59+
updated_agreement_data = agreement_factory(name=updated_name)
60+
61+
result = await async_mpt_ops.commerce.agreements.update(
62+
created_agreement.id, updated_agreement_data
63+
)
64+
65+
assert result is not None
66+
67+
68+
async def test_get_agreement_render(async_mpt_ops, agreement_id):
69+
result = await async_mpt_ops.commerce.agreements.render(agreement_id)
70+
71+
assert result is not None
72+
73+
74+
async def test_get_agreement_template(async_mpt_ops, agreement_id):
75+
result = await async_mpt_ops.commerce.agreements.template(agreement_id)
76+
77+
assert result is not None
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import pytest
2+
3+
from mpt_api_client.exceptions import MPTAPIError
4+
from mpt_api_client.rql.query_builder import RQLQuery
5+
6+
pytestmark = [pytest.mark.flaky]
7+
8+
9+
@pytest.fixture
10+
def created_agreement(mpt_ops, agreement_factory):
11+
new_agreement_request_data = agreement_factory(
12+
name="E2E Created Agreement",
13+
)
14+
15+
return mpt_ops.commerce.agreements.create(new_agreement_request_data)
16+
17+
18+
def test_get_agreement_by_id(mpt_ops, agreement_id):
19+
result = mpt_ops.commerce.agreements.get(agreement_id)
20+
21+
assert result is not None
22+
23+
24+
def test_list_agreements(mpt_ops):
25+
limit = 10
26+
27+
result = mpt_ops.commerce.agreements.fetch_page(limit=limit)
28+
29+
assert len(result) > 0
30+
31+
32+
def test_get_agreement_by_id_not_found(mpt_ops, invalid_agreement_id):
33+
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
34+
mpt_ops.commerce.agreements.get(invalid_agreement_id) # act
35+
36+
37+
def test_filter_agreements(mpt_ops, agreement_id):
38+
select_fields = ["-value"]
39+
filtered_agreements = (
40+
mpt_ops.commerce.agreements.filter(RQLQuery(id=agreement_id))
41+
.filter(RQLQuery(name="E2E Seeded For Commerce for Test Api Client Client"))
42+
.select(*select_fields)
43+
)
44+
45+
result = list(filtered_agreements.iterate())
46+
47+
assert len(result) == 1
48+
49+
50+
def test_create_agreement(created_agreement):
51+
result = created_agreement
52+
53+
assert result is not None
54+
55+
56+
def test_update_agreement(mpt_ops, created_agreement, agreement_factory):
57+
updated_name = "E2E Updated Agreement Name"
58+
updated_agreement_data = agreement_factory(name=updated_name)
59+
60+
result = mpt_ops.commerce.agreements.update(created_agreement.id, updated_agreement_data)
61+
62+
assert result is not None
63+
64+
65+
def test_get_agreement_render(mpt_ops, agreement_id):
66+
result = mpt_ops.commerce.agreements.render(agreement_id)
67+
68+
assert result is not None
69+
70+
71+
def test_get_agreement_template(mpt_ops, agreement_id):
72+
result = mpt_ops.commerce.agreements.template(agreement_id)
73+
74+
assert result is not None

tests/e2e/commerce/conftest.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import pytest
2+
3+
4+
@pytest.fixture
5+
def agreement_id(e2e_config):
6+
return e2e_config["commerce.agreement.id"]
7+
8+
9+
@pytest.fixture
10+
def commerce_product_id(e2e_config):
11+
return e2e_config["commerce.product.id"]

0 commit comments

Comments
 (0)