diff --git a/pyproject.toml b/pyproject.toml index 14d74458..c2a85aa1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,51 +5,51 @@ description = "SoftwareOne Marketplace API Client for Python" authors = [{ name = "SoftwareOne AG" }] requires-python = ">=3.12,<4" readme = "docs/PROJECT_DESCRIPTION.md" -license = {text = "Apache-2.0 license"} +license = { text = "Apache-2.0 license" } keywords = [ - "openapi", - "client", - "softwareone", - "marketplace", + "openapi", + "client", + "softwareone", + "marketplace", ] classifiers = [ - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3.12", - "Topic :: Utilities", + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.12", + "Topic :: Utilities", ] dependencies = [ - "httpx==0.28.*", + "httpx==0.28.*", ] [dependency-groups] dev = [ - "dependency-injector==4.49.*", - "flake8==7.3.*", # force flake8 version to have same formatting everywhere, also update in pre-commit config - "flake8-aaa==0.17.*", # also update pre-commit config - "flake8-pyproject==1.2.*", # also update pre-commit config - "freezegun==1.5.*", - "ipdb==0.13.*", - "ipython==9.*", - "mypy==1.19.*", - "pre-commit==4.5.*", - "pyfakefs==6.1.*", - "pytest==9.0.*", - "pytest-asyncio==1.3.*", - "pytest-cov==7.1.*", - "pytest-deadfixtures==3.1.*", - "pytest-mock==3.15.*", - "pytest-randomly==4.0.*", - "pytest-reportportal==5.6.*", - "pytest-rerunfailures==16.1.*", - "pytest-xdist==3.8.*", - "responses==0.26.*", - "respx==0.22.*", - "ruff==0.15.*", # force ruff version to have same formatting everywhere - "typing-extensions==4.15.*", - "wemake-python-styleguide==1.6.*", - "types-python-dateutil==2.9.*", + "dependency-injector==4.49.*", + "flake8==7.3.*", # force flake8 version to have same formatting everywhere, also update in pre-commit config + "flake8-aaa==0.17.*", # also update pre-commit config + "flake8-pyproject==1.2.*", # also update pre-commit config + "freezegun==1.5.*", + "ipdb==0.13.*", + "ipython==9.*", + "mypy==1.19.*", + "pre-commit==4.5.*", + "pyfakefs==6.1.*", + "pytest==9.0.*", + "pytest-asyncio==1.3.*", + "pytest-cov==7.1.*", + "pytest-deadfixtures==3.1.*", + "pytest-mock==3.15.*", + "pytest-randomly==4.0.*", + "pytest-reportportal==5.6.*", + "pytest-rerunfailures==16.1.*", + "pytest-xdist==3.8.*", + "responses==0.26.*", + "respx==0.22.*", + "ruff==0.15.*", # force ruff version to have same formatting everywhere + "typing-extensions==4.15.*", + "wemake-python-styleguide==1.6.*", + "types-python-dateutil==2.9.*", ] [tool.hatch.build.targets.sdist] @@ -70,8 +70,8 @@ log_cli = false asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" filterwarnings = [ - "ignore:Support for class-based `config` is deprecated:DeprecationWarning", - "ignore:pkg_resources is deprecated as an API:DeprecationWarning", + "ignore:Support for class-based `config` is deprecated:DeprecationWarning", + "ignore:pkg_resources is deprecated as an API:DeprecationWarning", ] rp_project = "mpt-api-python-client" markers = [ @@ -85,11 +85,11 @@ source = ["mpt_api_client"] [tool.coverage.report] exclude_also = [ - "if __name__ == \"__main__\":", - "raise NotImplementedError", + "if __name__ == \"__main__\":", + "raise NotImplementedError", ] omit = [ - "*/__init__.py" + "*/__init__.py" ] [tool.flake8] @@ -134,6 +134,7 @@ per-file-ignores = [ "tests/e2e/commerce/order/*.py: WPS202 WPS204", "tests/e2e/commerce/order/asset/*.py: WPS211 WPS202", "tests/e2e/commerce/subscription/*.py: WPS202", + "tests/e2e/helpdesk/chats/links/*.py: WPS221 WPS202", "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", @@ -159,48 +160,48 @@ docstring-code-format = false [tool.ruff.lint] select = [ - "A", # flake8-builtins - "B", # flake8-bugbear - "C4", # flake8-comprehensions - "C90", # maccabe - "COM", # flake8-commas - "D", # pydocstyle - "DTZ", # flake8-datetimez - "E", # pycodestyle - "ERA", # flake8-eradicate - "EXE", # flake8-executable - "F", # pyflakes - "FBT", # flake8-boolean-trap - "FLY", # pyflint + "A", # flake8-builtins + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "C90", # maccabe + "COM", # flake8-commas + "D", # pydocstyle + "DTZ", # flake8-datetimez + "E", # pycodestyle + "ERA", # flake8-eradicate + "EXE", # flake8-executable + "F", # pyflakes + "FBT", # flake8-boolean-trap + "FLY", # pyflint "FURB", # refurb - "G", # flake8-logging-format - "I", # isort - "ICN", # flake8-import-conventions - "ISC", # flake8-implicit-str-concat - "LOG", # flake8-logging - "N", # pep8-naming + "G", # flake8-logging-format + "I", # isort + "ICN", # flake8-import-conventions + "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging + "N", # pep8-naming "PERF", # perflint - "PIE", # flake8-pie - "PL", # pylint - "PT", # flake8-pytest-style - "PTH", # flake8-use-pathlib - "Q", # flake8-quotes - "RET", # flake8-return - "RSE", # flake8-raise - "RUF", # ruff - "S", # flake8-bandit - "SIM", # flake8-simpify - "SLF", # flake8-self + "PIE", # flake8-pie + "PL", # pylint + "PT", # flake8-pytest-style + "PTH", # flake8-use-pathlib + "Q", # flake8-quotes + "RET", # flake8-return + "RSE", # flake8-raise + "RUF", # ruff + "S", # flake8-bandit + "SIM", # flake8-simpify + "SLF", # flake8-self "SLOT", # flake8-slots "T100", # flake8-debugger - "TRY", # tryceratops - "UP", # pyupgrade - "W", # pycodestyle - "YTT", # flake8-2020 + "TRY", # tryceratops + "UP", # pyupgrade + "W", # pycodestyle + "YTT", # flake8-2020 ] ignore = [ - "A005", # allow to shadow stdlib and builtin module names - "B904", # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling + "A005", # allow to shadow stdlib and builtin module names + "B904", # Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling "COM812", # trailing comma, conflicts with `ruff format` # Different doc rules that we don't really care about: "D100", @@ -213,15 +214,15 @@ ignore = [ "D401", "D404", "D405", - "ISC001", # implicit string concat conflicts with `ruff format` - "ISC003", # prefer explicit string concat over implicit concat - "PLR09", # we have our own complexity rules + "ISC001", # implicit string concat conflicts with `ruff format` + "ISC003", # prefer explicit string concat over implicit concat + "PLR09", # we have our own complexity rules "PLR2004", # do not report magic numbers "PLR6301", # do not require classmethod / staticmethod when self not used "PT011", # pytest.raises({exception}) is too broad, set the match parameter or use a more specific exception - "TRY003", # long exception messages from `tryceratops` + "TRY003", # long exception messages from `tryceratops` ] -external = [ "AAA", "WPS" ] +external = ["AAA", "WPS"] # Plugin configs: [tool.ruff.lint.flake8-import-conventions] diff --git a/tests/e2e/helpdesk/chats/conftest.py b/tests/e2e/helpdesk/chats/conftest.py index 2a772443..dc5521af 100644 --- a/tests/e2e/helpdesk/chats/conftest.py +++ b/tests/e2e/helpdesk/chats/conftest.py @@ -1,5 +1,10 @@ import pytest +from tests.e2e.helper import ( + async_create_fixture_resource_and_delete, + create_fixture_resource_and_delete, +) + @pytest.fixture(scope="session") def chat_id(e2e_config): @@ -9,3 +14,41 @@ def chat_id(e2e_config): @pytest.fixture(scope="session") def invalid_chat_id(): return "CHT-0000-0000-0000" + + +@pytest.fixture +def chat_messages_service(mpt_ops, created_chat): + return mpt_ops.helpdesk.chats.messages(created_chat.id) + + +@pytest.fixture +def async_chat_messages_service(async_mpt_ops, created_chat): + return async_mpt_ops.helpdesk.chats.messages(created_chat.id) + + +@pytest.fixture +def chat_message_data(short_uuid): + return { + "content": f"e2e message - {short_uuid}", + } + + +@pytest.fixture +def created_chat_message(chat_messages_service, chat_message_data): + with create_fixture_resource_and_delete( + chat_messages_service, chat_message_data + ) as chat_message: + yield chat_message + + +@pytest.fixture +async def async_created_chat_message(async_chat_messages_service, chat_message_data): + async with async_create_fixture_resource_and_delete( + async_chat_messages_service, chat_message_data + ) as chat_message: + yield chat_message + + +@pytest.fixture(scope="session") +def invalid_chat_message_id(): + return "MSG-0000-0000-0000" diff --git a/tests/e2e/helpdesk/chats/links/conftest.py b/tests/e2e/helpdesk/chats/links/conftest.py index 001885e1..574eb061 100644 --- a/tests/e2e/helpdesk/chats/links/conftest.py +++ b/tests/e2e/helpdesk/chats/links/conftest.py @@ -7,29 +7,36 @@ @pytest.fixture -def chat_links_service(mpt_ops, chat_id): - return mpt_ops.helpdesk.chats.links(chat_id) +def chat_links_service(mpt_ops, created_chat): + return mpt_ops.helpdesk.chats.links(created_chat.id) @pytest.fixture -def async_chat_links_service(async_mpt_ops, chat_id): - return async_mpt_ops.helpdesk.chats.links(chat_id) +def async_chat_links_service(async_mpt_ops, created_chat): + return async_mpt_ops.helpdesk.chats.links(created_chat.id) @pytest.fixture -def chat_link_data(short_uuid): +def chat_link_data(created_chat_message, short_uuid): return { "uri": f"https://example.com/e2e-link-{short_uuid}", "name": f"e2e link - {short_uuid}", + "message": created_chat_message.to_dict(), } @pytest.fixture -def created_chat_link(chat_links_service, chat_link_data): +def created_chat_link(mpt_ops, chat_links_service, chat_link_data): with create_fixture_resource_and_delete(chat_links_service, chat_link_data) as chat_link: yield chat_link +@pytest.fixture +def created_chat_link_service(chat_links_service, chat_link_data): + with create_fixture_resource_and_delete(chat_links_service, chat_link_data): + yield chat_links_service + + @pytest.fixture async def async_created_chat_link(async_chat_links_service, chat_link_data): async with async_create_fixture_resource_and_delete( @@ -38,6 +45,12 @@ async def async_created_chat_link(async_chat_links_service, chat_link_data): yield chat_link +@pytest.fixture +async def async_created_chat_link_service(async_chat_links_service, chat_link_data): + async with async_create_fixture_resource_and_delete(async_chat_links_service, chat_link_data): + yield async_chat_links_service + + @pytest.fixture(scope="session") def invalid_chat_link_id(): return "LNK-0000-0000-0000" diff --git a/tests/e2e/helpdesk/chats/links/test_async_links.py b/tests/e2e/helpdesk/chats/links/test_async_links.py index ab5e7f21..24a2f52a 100644 --- a/tests/e2e/helpdesk/chats/links/test_async_links.py +++ b/tests/e2e/helpdesk/chats/links/test_async_links.py @@ -8,21 +8,18 @@ pytestmark = [pytest.mark.flaky] -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") -async def test_list_chat_links(async_chat_links_service): - result = await async_chat_links_service.fetch_page(limit=1) +async def test_list_chat_links(async_created_chat_link_service): + result = await async_created_chat_link_service.fetch_page(limit=1) assert len(result) > 0 assert all(isinstance(link, ChatLink) for link in result) -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") # noqa: AAA01 -def test_create_chat_link(async_created_chat_link, chat_link_data): +def test_create_chat_link(async_created_chat_link, chat_link_data): # noqa: AAA01 assert async_created_chat_link.id is not None assert async_created_chat_link.to_dict().get("uri") == chat_link_data["uri"] -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") async def test_update_chat_link_name(async_chat_links_service, async_created_chat_link, short_uuid): new_name = f"e2e updated link - {short_uuid}" @@ -35,7 +32,6 @@ async def test_update_chat_link_name(async_chat_links_service, async_created_cha assert result.to_dict().get("name") == new_name -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") async def test_delete_chat_link(async_chat_links_service, async_created_chat_link): result = async_created_chat_link diff --git a/tests/e2e/helpdesk/chats/links/test_sync_links.py b/tests/e2e/helpdesk/chats/links/test_sync_links.py index c9195c2c..201e30bb 100644 --- a/tests/e2e/helpdesk/chats/links/test_sync_links.py +++ b/tests/e2e/helpdesk/chats/links/test_sync_links.py @@ -8,21 +8,18 @@ pytestmark = [pytest.mark.flaky] -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") -def test_list_chat_links(chat_links_service): - result = chat_links_service.fetch_page(limit=1) +def test_list_chat_links(created_chat_link_service): + result = created_chat_link_service.fetch_page(limit=1) assert len(result) > 0 assert all(isinstance(link, ChatLink) for link in result) -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") # noqa: AAA01 -def test_create_chat_link(created_chat_link, chat_link_data): +def test_create_chat_link(created_chat_link, chat_link_data): # noqa: AAA01 assert created_chat_link.id is not None assert created_chat_link.to_dict().get("uri") == chat_link_data["uri"] -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") def test_update_chat_link_name(chat_links_service, created_chat_link, short_uuid): new_name = f"e2e updated link - {short_uuid}" @@ -32,7 +29,6 @@ def test_update_chat_link_name(chat_links_service, created_chat_link, short_uuid assert result.to_dict().get("name") == new_name -@pytest.mark.skip(reason="Unskip after MPT-19124 completed") def test_delete_chat_link(chat_links_service, created_chat_link): result = created_chat_link diff --git a/tests/e2e/helpdesk/chats/messages/conftest.py b/tests/e2e/helpdesk/chats/messages/conftest.py deleted file mode 100644 index fb2d7a53..00000000 --- a/tests/e2e/helpdesk/chats/messages/conftest.py +++ /dev/null @@ -1,44 +0,0 @@ -import pytest - -from tests.e2e.helper import ( - async_create_fixture_resource_and_delete, - create_fixture_resource_and_delete, -) - - -@pytest.fixture -def chat_messages_service(mpt_ops, created_chat): - return mpt_ops.helpdesk.chats.messages(created_chat.id) - - -@pytest.fixture -def async_chat_messages_service(async_mpt_ops, created_chat): - return async_mpt_ops.helpdesk.chats.messages(created_chat.id) - - -@pytest.fixture -def chat_message_data(short_uuid): - return { - "content": f"e2e message - {short_uuid}", - } - - -@pytest.fixture -def created_chat_message(chat_messages_service, chat_message_data): - with create_fixture_resource_and_delete( - chat_messages_service, chat_message_data - ) as chat_message: - yield chat_message - - -@pytest.fixture -async def async_created_chat_message(async_chat_messages_service, chat_message_data): - async with async_create_fixture_resource_and_delete( - async_chat_messages_service, chat_message_data - ) as chat_message: - yield chat_message - - -@pytest.fixture(scope="session") -def invalid_chat_message_id(): - return "MSG-0000-0000-0000"