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: 2 additions & 1 deletion e2e_config.test.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,6 @@
"program.parameter.group.id": "PPG-9643-3741-0002",
"program.parameter.id": "PPM-9643-3741-0001",
"program.program.id": "PRG-9643-3741",
"program.template.id": "PTM-9643-3741-0004"
"program.template.id": "PTM-9643-3741-0004",
"program.terms.id": "PTC-9643-3741-0001"
}
14 changes: 14 additions & 0 deletions mpt_api_client/resources/program/programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
AsyncTemplatesService,
TemplatesService,
)
from mpt_api_client.resources.program.programs_terms import (
AsyncTermService,
TermService,
)


class Program(Model):
Expand Down Expand Up @@ -121,6 +125,10 @@ def templates(self, program_id: str) -> TemplatesService:
http_client=self.http_client, endpoint_params={"program_id": program_id}
)

def terms(self, program_id: str) -> TermService:
"""Return program terms service."""
return TermService(http_client=self.http_client, endpoint_params={"program_id": program_id})


class AsyncProgramsService(
AsyncGetMixin[Program],
Expand Down Expand Up @@ -172,3 +180,9 @@ def templates(self, program_id: str) -> AsyncTemplatesService:
return AsyncTemplatesService(
http_client=self.http_client, endpoint_params={"program_id": program_id}
)

def terms(self, program_id: str) -> AsyncTermService:
"""Return async program terms service."""
return AsyncTermService(
http_client=self.http_client, endpoint_params={"program_id": program_id}
)
61 changes: 61 additions & 0 deletions mpt_api_client/resources/program/programs_terms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from mpt_api_client.http import AsyncService, Service
from mpt_api_client.http.mixins import (
AsyncCollectionMixin,
AsyncManagedResourceMixin,
CollectionMixin,
ManagedResourceMixin,
)
from mpt_api_client.models import Model
from mpt_api_client.models.model import BaseModel
from mpt_api_client.resources.program.mixins import (
AsyncPublishableMixin,
PublishableMixin,
)


class Term(Model):
"""Program term resource.

Attributes:
name: Program term name.
description: Program term description.
display_order: Display order of the program term.
status: Program term status.
program: Reference to the program.
audit: Audit information (created, updated events).
"""

name: str | None
description: str | None
display_order: int | None
status: str | None
program: BaseModel | None
audit: BaseModel | None


class TermServiceConfig:
"""Program term service configuration."""

_endpoint = "/public/v1/program/programs/{program_id}/terms"
_model_class = Term
_collection_key = "data"


class TermService(
PublishableMixin[Term],
ManagedResourceMixin[Term],
CollectionMixin[Term],
Service[Term],
TermServiceConfig,
):
"""Program term service."""


class AsyncTermService(
AsyncPublishableMixin[Term],
AsyncManagedResourceMixin[Term],
AsyncCollectionMixin[Term],
AsyncService[Term],
TermServiceConfig,
):
"""Async program term service."""
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ per-file-ignores = [
"tests/e2e/commerce/order/asset/*.py: WPS211 WPS202",
"tests/e2e/commerce/subscription/*.py: WPS202",
"tests/e2e/helpdesk/chats/links/*.py: WPS221 WPS202",
"tests/e2e/program/program/term/*.py: WPS202 WPS204",
"tests/unit/http/test_async_service.py: WPS204 WPS202",
"tests/unit/http/test_resource_accessor.py: WPS204 WPS202 WPS210 WPS219",
"tests/unit/http/test_service.py: WPS204 WPS202",
Expand Down
20 changes: 20 additions & 0 deletions tests/e2e/program/program/term/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import pytest


@pytest.fixture
def term_id(e2e_config):
return e2e_config["program.terms.id"]


@pytest.fixture
def invalid_term_id():
return "PTC-0000-0000-0000"


@pytest.fixture
def term_data():
return {
"name": "E2E Created Program Terms",
"description": "E2E Created Program Terms",
"displayOrder": 100,
}
85 changes: 85 additions & 0 deletions tests/e2e/program/program/term/test_async_term.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import pytest

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

pytestmark = [pytest.mark.flaky]


@pytest.fixture
async def created_term(async_mpt_vendor, program_id, term_data):
service = async_mpt_vendor.program.programs.terms(program_id)
term = await service.create(term_data)
yield term
try:
await service.delete(term.id)
except MPTAPIError as error:
print(f"TEARDOWN - Unable to delete term {term.id}: {error.title}") # noqa: WPS421


def test_create_term(created_term):
result = created_term.name == "E2E Created Program Terms"

assert result is True


async def test_update_term(async_mpt_vendor, program_id, created_term):
service = async_mpt_vendor.program.programs.terms(program_id)
update_data = {"name": "E2E Updated Program Terms"}

result = await service.update(created_term.id, update_data)

assert result.name == update_data["name"]


async def test_get_term(async_mpt_vendor, program_id, term_id):
service = async_mpt_vendor.program.programs.terms(program_id)

result = await service.get(term_id)

assert result.id == term_id


async def test_get_invalid_term(async_mpt_vendor, program_id, invalid_term_id):
with pytest.raises(MPTAPIError):
await async_mpt_vendor.program.programs.terms(program_id).get(invalid_term_id)


async def test_delete_term(async_mpt_vendor, program_id, created_term):
term_data = created_term

result = async_mpt_vendor.program.programs.terms(program_id)

await result.delete(term_data.id)


async def test_filter_and_select_terms(async_mpt_vendor, program_id, term_id):
select_fields = ["-description", "-audit"]
filtered_terms = (
async_mpt_vendor.program.programs
.terms(program_id)
.filter(RQLQuery(id=term_id))
.filter(RQLQuery(name="E2E Seeded Program Terms"))
.select(*select_fields)
)

result = [terms async for terms in filtered_terms.iterate()]

assert len(result) == 1


async def test_publish_term(async_mpt_vendor, program_id, created_term):
service = async_mpt_vendor.program.programs.terms(program_id)

result = await service.publish(created_term.id)

assert result.status == "Published"


async def test_unpublish_term(async_mpt_vendor, program_id, created_term):
service = async_mpt_vendor.program.programs.terms(program_id)
await service.publish(created_term.id)

result = await service.unpublish(created_term.id)

assert result.status == "Unpublished"
85 changes: 85 additions & 0 deletions tests/e2e/program/program/term/test_sync_term.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
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_term(mpt_vendor, program_id, term_data):
service = mpt_vendor.program.programs.terms(program_id)
term = service.create(term_data)
yield term
try:
service.delete(term.id)
except MPTAPIError as error:
print(f"TEARDOWN - Unable to delete term {term.id}: {error.title}") # noqa: WPS421


def test_create_term(created_term):
result = created_term.name == "E2E Created Program Terms"

assert result is True


def test_update_term(mpt_vendor, program_id, created_term):
service = mpt_vendor.program.programs.terms(program_id)
update_data = {"name": "E2E Updated Program Terms"}

result = service.update(created_term.id, update_data)

assert result.name == update_data["name"]


def test_get_term(mpt_vendor, program_id, term_id):
service = mpt_vendor.program.programs.terms(program_id)

result = service.get(term_id)

assert result.id == term_id


def test_get_invalid_term(mpt_vendor, program_id, invalid_term_id):
with pytest.raises(MPTAPIError):
mpt_vendor.program.programs.terms(program_id).get(invalid_term_id)


def test_delete_term(mpt_vendor, program_id, created_term):
term_data = created_term

result = mpt_vendor.program.programs.terms(program_id)

result.delete(term_data.id)


def test_filter_and_select_terms(mpt_vendor, program_id, term_id):
select_fields = ["-description", "-audit"]
filtered_terms = (
mpt_vendor.program.programs
.terms(program_id)
.filter(RQLQuery(id=term_id))
.filter(RQLQuery(name="E2E Seeded Program Terms"))
.select(*select_fields)
)

result = list(filtered_terms.iterate())

assert len(result) == 1


def test_publish_term(mpt_vendor, program_id, created_term):
service = mpt_vendor.program.programs.terms(program_id)

result = service.publish(created_term.id)

assert result.status == "Published"


def test_unpublish_term(mpt_vendor, program_id, created_term):
service = mpt_vendor.program.programs.terms(program_id)
service.publish(created_term.id)

result = service.unpublish(created_term.id)

assert result.status == "Unpublished"
6 changes: 6 additions & 0 deletions tests/unit/resources/program/test_programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
AsyncTemplatesService,
TemplatesService,
)
from mpt_api_client.resources.program.programs_terms import (
AsyncTermService,
TermService,
)


@pytest.fixture
Expand Down Expand Up @@ -104,6 +108,7 @@ def test_async_mixins_present(async_programs_service, method):
("parameter_groups", ParameterGroupsService),
("parameters", ParametersService),
("templates", TemplatesService),
("terms", TermService),
],
)
def test_property_services(programs_service, service_method, expected_service_class):
Expand All @@ -121,6 +126,7 @@ def test_property_services(programs_service, service_method, expected_service_cl
("parameter_groups", AsyncParameterGroupsService),
("parameters", AsyncParametersService),
("templates", AsyncTemplatesService),
("terms", AsyncTermService),
],
)
def test_async_property_services(async_programs_service, service_method, expected_service_class):
Expand Down
Loading