Skip to content

Commit 9b0ac03

Browse files
author
Robert Segal
committed
Added sellers E2E tests
1 parent 262d20c commit 9b0ac03

File tree

7 files changed

+339
-1
lines changed

7 files changed

+339
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,6 @@ cython_debug/
170170

171171
# VS Code dev container
172172
.devcontainer/
173+
174+
# E2E report
175+
e2e-report.xml

e2e_config.test.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"catalog.product.id": "PRD-7255-3950"
2+
"catalog.product.id": "PRD-7255-3950",
3+
"accounts.seller.id": "SEL-7310-3075"
34
}

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ per-file-ignores =
4747
tests/unit/resources/*/test_mixins.py: WPS118 WPS202 WPS204 WPS235
4848
tests/unit/resources/accounts/test_users.py: WPS204 WPS202 WPS210
4949
tests/unit/test_mpt_client.py: WPS235
50+
tests/e2e/accounts/*.py: WPS430 WPS202
5051

5152
tests/*:
5253
# Allow magic strings.

tests/e2e/accounts/conftest.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import datetime as dt
2+
import pathlib
3+
4+
import pytest
5+
6+
7+
@pytest.fixture(scope="session")
8+
def timestamp():
9+
return int(dt.datetime.now(tz=dt.UTC).strftime("%Y%m%d%H%M%S"))
10+
11+
12+
@pytest.fixture
13+
def account_data():
14+
return {
15+
"name": "Test Api Client Vendor",
16+
"address": {
17+
"addressLine1": "123 Test St",
18+
"city": "San Francisco",
19+
"state": "CA",
20+
"postCode": "12345",
21+
"country": "US",
22+
},
23+
"type": "Vendor",
24+
"status": "Active",
25+
}
26+
27+
28+
@pytest.fixture
29+
def account_icon():
30+
return pathlib.Path(__file__).parent / "logo.png"
31+
32+
33+
@pytest.fixture
34+
def currencies():
35+
return ["USD", "EUR"]
36+
37+
38+
@pytest.fixture
39+
def seller(currencies):
40+
def _seller(
41+
external_id: str, # Must be unique in Marketplace
42+
name="E2E Test Seller",
43+
currencies=currencies,
44+
):
45+
return {
46+
"name": name,
47+
"address": {
48+
"addressLine1": "123 Main St",
49+
"city": "Anytown",
50+
"state": "CA",
51+
"postCode": "12345",
52+
"country": "US",
53+
},
54+
"currencies": currencies,
55+
"externalId": external_id,
56+
}
57+
58+
return _seller
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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+
# TODO: Handle create and teardown more gracefully with fixture that doesn't cause teardown issues
10+
@pytest.fixture
11+
async def async_created_seller(async_mpt_ops, seller, logger):
12+
ret_seller = None
13+
14+
async def _async_created_seller(
15+
external_id: str,
16+
name: str = "E2E Test Seller",
17+
):
18+
nonlocal ret_seller # noqa: WPS420
19+
seller_data = seller(external_id=external_id, name=name)
20+
ret_seller = await async_mpt_ops.accounts.sellers.create(seller_data)
21+
return ret_seller
22+
23+
yield _async_created_seller
24+
25+
if ret_seller:
26+
try:
27+
await async_mpt_ops.accounts.sellers.delete(ret_seller.id)
28+
except MPTAPIError:
29+
logger.exception("TEARDOWN - Unable to delete seller %s", ret_seller.id)
30+
31+
32+
async def test_get_seller_by_id(async_mpt_ops, seller_id):
33+
seller = await async_mpt_ops.accounts.sellers.get(seller_id)
34+
assert seller is not None
35+
36+
37+
async def test_list_sellers(async_mpt_ops):
38+
limit = 10
39+
40+
sellers = await async_mpt_ops.accounts.sellers.fetch_page(limit=limit)
41+
42+
assert len(sellers) > 0
43+
44+
45+
async def test_get_seller_by_id_not_found(async_mpt_ops, invalid_seller_id):
46+
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
47+
await async_mpt_ops.accounts.sellers.get(invalid_seller_id)
48+
49+
50+
async def test_filter_sellers(async_mpt_ops, seller_id):
51+
select_fields = ["-address"]
52+
53+
async_filtered_sellers = (
54+
async_mpt_ops.accounts.sellers.filter(RQLQuery(id=seller_id))
55+
.filter(RQLQuery(name="E2E Seeded Seller"))
56+
.select(*select_fields)
57+
)
58+
59+
sellers = [filtered_seller async for filtered_seller in async_filtered_sellers.iterate()]
60+
61+
assert len(sellers) == 1
62+
63+
64+
async def test_create_seller(async_created_seller, timestamp):
65+
seller_data = await async_created_seller(external_id=f"Async Create E2E Seller - {timestamp}")
66+
assert seller_data is not None
67+
68+
69+
async def test_delete_seller(async_mpt_ops, async_created_seller, timestamp):
70+
seller_data = await async_created_seller(external_id=f"Async Delete E2E Seller - {timestamp}")
71+
await async_mpt_ops.accounts.sellers.delete(seller_data.id)
72+
73+
74+
async def test_delete_seller_not_found(async_mpt_ops, invalid_seller_id):
75+
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
76+
await async_mpt_ops.accounts.sellers.delete(invalid_seller_id)
77+
78+
79+
async def test_update_seller(async_mpt_ops, seller, async_created_seller, timestamp):
80+
seller_data = await async_created_seller(external_id=f"Async Update E2E Seller - {timestamp}")
81+
update_data = seller(
82+
external_id=f"Async Update E2E Seller - {timestamp}",
83+
name=f"Updated Update E2E Seller - {timestamp}",
84+
)
85+
updated_seller = await async_mpt_ops.accounts.sellers.update(seller_data.id, update_data)
86+
assert updated_seller is not None
87+
88+
89+
async def test_update_seller_mpt_error(async_mpt_ops, seller, timestamp, invalid_seller_id):
90+
update_data = seller(
91+
external_id=f"Async Update E2E Seller Not Found - {timestamp}",
92+
name=f"Updated Update E2E Seller Not Found - {timestamp}",
93+
)
94+
with pytest.raises(MPTAPIError):
95+
await async_mpt_ops.accounts.sellers.update(invalid_seller_id, update_data)
96+
97+
98+
async def test_activate_seller(async_mpt_ops, async_created_seller, timestamp):
99+
seller_data = await async_created_seller(external_id=f"Async Activate E2E Seller - {timestamp}")
100+
await async_mpt_ops.accounts.sellers.deactivate(seller_data.id)
101+
activated_seller = await async_mpt_ops.accounts.sellers.activate(seller_data.id)
102+
103+
assert activated_seller is not None
104+
105+
106+
async def test_activate_seller_mpt_error(async_mpt_ops, invalid_seller_id):
107+
with pytest.raises(MPTAPIError):
108+
await async_mpt_ops.accounts.sellers.activate(invalid_seller_id)
109+
110+
111+
async def test_deactivate_seller(async_mpt_ops, async_created_seller, timestamp):
112+
seller_data = await async_created_seller(
113+
external_id=f"Async Deactivate E2E Seller - {timestamp}"
114+
)
115+
deactivated_seller = await async_mpt_ops.accounts.sellers.deactivate(seller_data.id)
116+
117+
assert deactivated_seller is not None
118+
119+
120+
async def test_deactivate_seller_mpt_error(async_mpt_ops, invalid_seller_id):
121+
with pytest.raises(MPTAPIError):
122+
await async_mpt_ops.accounts.sellers.deactivate(invalid_seller_id)
123+
124+
125+
async def test_disable_seller(async_mpt_ops, async_created_seller, timestamp):
126+
seller_data = await async_created_seller(external_id=f"Async Disable E2E Seller - {timestamp}")
127+
disabled_seller = await async_mpt_ops.accounts.sellers.disable(seller_data.id)
128+
129+
assert disabled_seller is not None
130+
131+
132+
async def test_disable_seller_mpt_error(async_mpt_ops, invalid_seller_id):
133+
with pytest.raises(MPTAPIError):
134+
await async_mpt_ops.accounts.sellers.disable(invalid_seller_id)
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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_seller(mpt_ops, seller, logger):
11+
ret_seller = None
12+
13+
def _created_seller(
14+
external_id: str,
15+
name: str = "E2E Test Seller",
16+
):
17+
nonlocal ret_seller # noqa: WPS420
18+
seller_data = seller(external_id=external_id, name=name)
19+
ret_seller = mpt_ops.accounts.sellers.create(seller_data)
20+
return ret_seller
21+
22+
yield _created_seller
23+
24+
if ret_seller:
25+
try:
26+
mpt_ops.accounts.sellers.delete(ret_seller.id)
27+
except MPTAPIError:
28+
logger.exception("TEARDOWN - Unable to delete seller %s", ret_seller.id)
29+
30+
31+
def test_get_seller_by_id(mpt_ops, seller_id):
32+
seller = mpt_ops.accounts.sellers.get(seller_id)
33+
assert seller is not None
34+
35+
36+
def test_list_sellers(mpt_ops):
37+
limit = 10
38+
39+
sellers = mpt_ops.accounts.sellers.fetch_page(limit=limit)
40+
41+
assert len(sellers) > 0
42+
43+
44+
def test_get_seller_by_id_not_found(mpt_ops, invalid_seller_id):
45+
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
46+
mpt_ops.accounts.sellers.get(invalid_seller_id)
47+
48+
49+
def test_filter_sellers(mpt_ops, seller_id):
50+
select_fields = ["-address"]
51+
52+
filtered_sellers = (
53+
mpt_ops.accounts.sellers.filter(RQLQuery(id=seller_id))
54+
.filter(RQLQuery(name="E2E Seeded Seller"))
55+
.select(*select_fields)
56+
)
57+
58+
sellers = list(filtered_sellers.iterate())
59+
60+
assert len(sellers) == 1
61+
62+
63+
def test_create_seller(created_seller, timestamp):
64+
seller_data = created_seller(external_id=f"Create E2E Seller - {timestamp}")
65+
assert seller_data is not None
66+
67+
68+
def test_delete_seller(mpt_ops, created_seller, timestamp):
69+
seller_data = created_seller(external_id=f"Delete E2E Seller - {timestamp}")
70+
mpt_ops.accounts.sellers.delete(seller_data.id)
71+
72+
73+
def test_delete_seller_not_found(mpt_ops, invalid_seller_id):
74+
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
75+
mpt_ops.accounts.sellers.delete(invalid_seller_id)
76+
77+
78+
def test_update_seller(mpt_ops, seller, created_seller, timestamp):
79+
seller_data = created_seller(external_id=f"Update E2E Seller - {timestamp}")
80+
update_data = seller(
81+
external_id=f"Update E2E Seller - {timestamp}",
82+
name=f"Updated Update E2E Seller - {timestamp}",
83+
)
84+
updated_seller = mpt_ops.accounts.sellers.update(seller_data.id, update_data)
85+
assert updated_seller is not None
86+
87+
88+
def test_update_seller_mpt_error(mpt_ops, seller, timestamp, invalid_seller_id):
89+
update_data = seller(
90+
external_id=f"Async Update E2E Seller Not Found - {timestamp}",
91+
name=f"Updated Update E2E Seller Not Found - {timestamp}",
92+
)
93+
with pytest.raises(MPTAPIError):
94+
mpt_ops.accounts.sellers.update(invalid_seller_id, update_data)
95+
96+
97+
def test_activate_seller(mpt_ops, created_seller, timestamp):
98+
seller_data = created_seller(external_id=f"Activate E2E Seller - {timestamp}")
99+
mpt_ops.accounts.sellers.deactivate(seller_data.id)
100+
activated_seller = mpt_ops.accounts.sellers.activate(seller_data.id)
101+
102+
assert activated_seller is not None
103+
104+
105+
def test_activate_seller_mpt_error(mpt_ops, invalid_seller_id):
106+
with pytest.raises(MPTAPIError):
107+
mpt_ops.accounts.sellers.activate(invalid_seller_id)
108+
109+
110+
def test_deactivate_seller(mpt_ops, created_seller, timestamp):
111+
seller_data = created_seller(external_id=f"Deactivate E2E Seller - {timestamp}")
112+
deactivated_seller = mpt_ops.accounts.sellers.deactivate(seller_data.id)
113+
114+
assert deactivated_seller is not None
115+
116+
117+
def test_deactivate_seller_mpt_error(mpt_ops, invalid_seller_id):
118+
with pytest.raises(MPTAPIError):
119+
mpt_ops.accounts.sellers.deactivate(invalid_seller_id)
120+
121+
122+
def test_disable_seller(mpt_ops, created_seller, timestamp):
123+
seller_data = created_seller(external_id=f"Disable E2E Seller - {timestamp}")
124+
disabled_seller = mpt_ops.accounts.sellers.disable(seller_data.id)
125+
126+
assert disabled_seller is not None
127+
128+
129+
def test_disable_seller_mpt_error(mpt_ops, invalid_seller_id):
130+
with pytest.raises(MPTAPIError):
131+
mpt_ops.accounts.sellers.disable(invalid_seller_id)

tests/e2e/conftest.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,13 @@ def e2e_config(project_root_path):
7878
@pytest.fixture
7979
def product_id(e2e_config):
8080
return e2e_config["catalog.product.id"]
81+
82+
83+
@pytest.fixture
84+
def invalid_seller_id():
85+
return "SEL-0000-0000"
86+
87+
88+
@pytest.fixture
89+
def seller_id(e2e_config):
90+
return e2e_config["accounts.seller.id"]

0 commit comments

Comments
 (0)