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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,6 @@ cython_debug/

# VS Code dev container
.devcontainer/

# E2E report
e2e-report.xml
3 changes: 2 additions & 1 deletion e2e_config.test.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"catalog.product.id": "PRD-7255-3950"
"catalog.product.id": "PRD-7255-3950",
"accounts.seller.id": "SEL-7310-3075"
}
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ per-file-ignores =
tests/unit/resources/*/test_mixins.py: WPS118 WPS202 WPS204 WPS235
tests/unit/resources/accounts/test_users.py: WPS204 WPS202 WPS210
tests/unit/test_mpt_client.py: WPS235
tests/e2e/accounts/*.py: WPS430 WPS202

tests/*:
# Allow magic strings.
Expand Down
58 changes: 58 additions & 0 deletions tests/e2e/accounts/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import datetime as dt
import pathlib

import pytest


@pytest.fixture(scope="session")
def timestamp():
return int(dt.datetime.now(tz=dt.UTC).strftime("%Y%m%d%H%M%S"))


@pytest.fixture
def account_data():
return {
"name": "Test Api Client Vendor",
"address": {
"addressLine1": "123 Test St",
"city": "San Francisco",
"state": "CA",
"postCode": "12345",
"country": "US",
},
"type": "Vendor",
"status": "Active",
}


@pytest.fixture
def account_icon():
return pathlib.Path(__file__).parent / "logo.png"


@pytest.fixture
def currencies():
return ["USD", "EUR"]


@pytest.fixture
def seller(currencies):
def _seller(
external_id: str, # Must be unique in Marketplace
name="E2E Test Seller",
currencies=currencies,
):
return {
"name": name,
"address": {
"addressLine1": "123 Main St",
"city": "Anytown",
"state": "CA",
"postCode": "12345",
"country": "US",
},
"currencies": currencies,
"externalId": external_id,
}

return _seller
134 changes: 134 additions & 0 deletions tests/e2e/accounts/test_async_sellers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import pytest

from mpt_api_client.exceptions import MPTAPIError
from mpt_api_client.rql.query_builder import RQLQuery

pytestmark = [pytest.mark.flaky]


# TODO: Handle create and teardown more gracefully with fixture that doesn't cause teardown issues
@pytest.fixture
async def async_created_seller(async_mpt_ops, seller, logger):
ret_seller = None

async def _async_created_seller(
external_id: str,
name: str = "E2E Test Seller",
):
nonlocal ret_seller # noqa: WPS420
seller_data = seller(external_id=external_id, name=name)
ret_seller = await async_mpt_ops.accounts.sellers.create(seller_data)
return ret_seller

yield _async_created_seller

if ret_seller:
try:
await async_mpt_ops.accounts.sellers.delete(ret_seller.id)
except MPTAPIError:
logger.exception("TEARDOWN - Unable to delete seller %s", ret_seller.id)


async def test_get_seller_by_id(async_mpt_ops, seller_id):
seller = await async_mpt_ops.accounts.sellers.get(seller_id)
assert seller is not None


async def test_list_sellers(async_mpt_ops):
limit = 10

sellers = await async_mpt_ops.accounts.sellers.fetch_page(limit=limit)

assert len(sellers) > 0


async def test_get_seller_by_id_not_found(async_mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_ops.accounts.sellers.get(invalid_seller_id)


async def test_filter_sellers(async_mpt_ops, seller_id):
select_fields = ["-address"]

async_filtered_sellers = (
async_mpt_ops.accounts.sellers.filter(RQLQuery(id=seller_id))
.filter(RQLQuery(name="E2E Seeded Seller"))
.select(*select_fields)
)

sellers = [filtered_seller async for filtered_seller in async_filtered_sellers.iterate()]

assert len(sellers) == 1


async def test_create_seller(async_created_seller, timestamp):
seller_data = await async_created_seller(external_id=f"Async Create E2E Seller - {timestamp}")
assert seller_data is not None


async def test_delete_seller(async_mpt_ops, async_created_seller, timestamp):
seller_data = await async_created_seller(external_id=f"Async Delete E2E Seller - {timestamp}")
await async_mpt_ops.accounts.sellers.delete(seller_data.id)


async def test_delete_seller_not_found(async_mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
await async_mpt_ops.accounts.sellers.delete(invalid_seller_id)


async def test_update_seller(async_mpt_ops, seller, async_created_seller, timestamp):
seller_data = await async_created_seller(external_id=f"Async Update E2E Seller - {timestamp}")
update_data = seller(
external_id=f"Async Update E2E Seller - {timestamp}",
name=f"Updated Update E2E Seller - {timestamp}",
)
updated_seller = await async_mpt_ops.accounts.sellers.update(seller_data.id, update_data)
assert updated_seller is not None


async def test_update_seller_mpt_error(async_mpt_ops, seller, timestamp, invalid_seller_id):
update_data = seller(
external_id=f"Async Update E2E Seller Not Found - {timestamp}",
name=f"Updated Update E2E Seller Not Found - {timestamp}",
)
with pytest.raises(MPTAPIError):
await async_mpt_ops.accounts.sellers.update(invalid_seller_id, update_data)


async def test_activate_seller(async_mpt_ops, async_created_seller, timestamp):
seller_data = await async_created_seller(external_id=f"Async Activate E2E Seller - {timestamp}")
await async_mpt_ops.accounts.sellers.deactivate(seller_data.id)
activated_seller = await async_mpt_ops.accounts.sellers.activate(seller_data.id)

assert activated_seller is not None


async def test_activate_seller_mpt_error(async_mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError):
await async_mpt_ops.accounts.sellers.activate(invalid_seller_id)


async def test_deactivate_seller(async_mpt_ops, async_created_seller, timestamp):
seller_data = await async_created_seller(
external_id=f"Async Deactivate E2E Seller - {timestamp}"
)
deactivated_seller = await async_mpt_ops.accounts.sellers.deactivate(seller_data.id)

assert deactivated_seller is not None


async def test_deactivate_seller_mpt_error(async_mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError):
await async_mpt_ops.accounts.sellers.deactivate(invalid_seller_id)


async def test_disable_seller(async_mpt_ops, async_created_seller, timestamp):
seller_data = await async_created_seller(external_id=f"Async Disable E2E Seller - {timestamp}")
disabled_seller = await async_mpt_ops.accounts.sellers.disable(seller_data.id)

assert disabled_seller is not None


async def test_disable_seller_mpt_error(async_mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError):
await async_mpt_ops.accounts.sellers.disable(invalid_seller_id)
131 changes: 131 additions & 0 deletions tests/e2e/accounts/test_sync_sellers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import pytest

from mpt_api_client.exceptions import MPTAPIError
from mpt_api_client.rql.query_builder import RQLQuery

pytestmark = [pytest.mark.flaky]


@pytest.fixture
def created_seller(mpt_ops, seller, logger):
ret_seller = None

def _created_seller(
external_id: str,
name: str = "E2E Test Seller",
):
nonlocal ret_seller # noqa: WPS420
seller_data = seller(external_id=external_id, name=name)
ret_seller = mpt_ops.accounts.sellers.create(seller_data)
return ret_seller

yield _created_seller

if ret_seller:
try:
mpt_ops.accounts.sellers.delete(ret_seller.id)
except MPTAPIError:
logger.exception("TEARDOWN - Unable to delete seller %s", ret_seller.id)


def test_get_seller_by_id(mpt_ops, seller_id):
seller = mpt_ops.accounts.sellers.get(seller_id)
assert seller is not None


def test_list_sellers(mpt_ops):
limit = 10

sellers = mpt_ops.accounts.sellers.fetch_page(limit=limit)

assert len(sellers) > 0


def test_get_seller_by_id_not_found(mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
mpt_ops.accounts.sellers.get(invalid_seller_id)


def test_filter_sellers(mpt_ops, seller_id):
select_fields = ["-address"]

filtered_sellers = (
mpt_ops.accounts.sellers.filter(RQLQuery(id=seller_id))
.filter(RQLQuery(name="E2E Seeded Seller"))
.select(*select_fields)
)

sellers = list(filtered_sellers.iterate())

assert len(sellers) == 1


def test_create_seller(created_seller, timestamp):
seller_data = created_seller(external_id=f"Create E2E Seller - {timestamp}")
assert seller_data is not None


def test_delete_seller(mpt_ops, created_seller, timestamp):
seller_data = created_seller(external_id=f"Delete E2E Seller - {timestamp}")
mpt_ops.accounts.sellers.delete(seller_data.id)


def test_delete_seller_not_found(mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError, match=r"404 Not Found"):
mpt_ops.accounts.sellers.delete(invalid_seller_id)


def test_update_seller(mpt_ops, seller, created_seller, timestamp):
seller_data = created_seller(external_id=f"Update E2E Seller - {timestamp}")
update_data = seller(
external_id=f"Update E2E Seller - {timestamp}",
name=f"Updated Update E2E Seller - {timestamp}",
)
updated_seller = mpt_ops.accounts.sellers.update(seller_data.id, update_data)
assert updated_seller is not None


def test_update_seller_mpt_error(mpt_ops, seller, timestamp, invalid_seller_id):
update_data = seller(
external_id=f"Async Update E2E Seller Not Found - {timestamp}",
name=f"Updated Update E2E Seller Not Found - {timestamp}",
)
with pytest.raises(MPTAPIError):
mpt_ops.accounts.sellers.update(invalid_seller_id, update_data)


def test_activate_seller(mpt_ops, created_seller, timestamp):
seller_data = created_seller(external_id=f"Activate E2E Seller - {timestamp}")
mpt_ops.accounts.sellers.deactivate(seller_data.id)
activated_seller = mpt_ops.accounts.sellers.activate(seller_data.id)

assert activated_seller is not None


def test_activate_seller_mpt_error(mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError):
mpt_ops.accounts.sellers.activate(invalid_seller_id)


def test_deactivate_seller(mpt_ops, created_seller, timestamp):
seller_data = created_seller(external_id=f"Deactivate E2E Seller - {timestamp}")
deactivated_seller = mpt_ops.accounts.sellers.deactivate(seller_data.id)

assert deactivated_seller is not None


def test_deactivate_seller_mpt_error(mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError):
mpt_ops.accounts.sellers.deactivate(invalid_seller_id)


def test_disable_seller(mpt_ops, created_seller, timestamp):
seller_data = created_seller(external_id=f"Disable E2E Seller - {timestamp}")
disabled_seller = mpt_ops.accounts.sellers.disable(seller_data.id)

assert disabled_seller is not None


def test_disable_seller_mpt_error(mpt_ops, invalid_seller_id):
with pytest.raises(MPTAPIError):
mpt_ops.accounts.sellers.disable(invalid_seller_id)
10 changes: 10 additions & 0 deletions tests/e2e/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,13 @@ def e2e_config(project_root_path):
@pytest.fixture
def product_id(e2e_config):
return e2e_config["catalog.product.id"]


@pytest.fixture
def invalid_seller_id():
return "SEL-0000-0000"


@pytest.fixture
def seller_id(e2e_config):
return e2e_config["accounts.seller.id"]