From 7ab0632eb1801db424d1ba436c8c69b981e1bbd9 Mon Sep 17 00:00:00 2001 From: ori roza Date: Sat, 27 Apr 2024 18:52:11 +0300 Subject: [PATCH] * made plugin import implicitly * removed unnecessary code --- .gitignore | 2 + LICENSE.txt | 20 ----- README.md | 44 +++++----- drf_api_action/__init__.py | 35 -------- drf_api_action/plugin.py | 37 +++++++++ pyproject.toml | 76 +++++++++++------- pytest.ini | 3 - setup.cfg | 4 - tests/db.sqlite3 | Bin 16384 -> 0 bytes tests/{functionality_tests => }/plugin.py | 0 tests/test_app/migrations/0001_initial.py | 21 ----- tests/test_app/migrations/__init__.py | 0 .../__init__.py | 0 tests/{ => test_server}/manage.py | 0 tests/{test_app => test_server}/settings.py | 4 +- tests/{ => test_server}/test_app/__init__.py | 0 tests/{ => test_server}/test_app/models.py | 0 tests/{ => test_server}/test_app/views.py | 0 tests/{test_app => test_server}/urls.py | 2 +- tests/{functionality_tests => }/tests.py | 4 +- 20 files changed, 110 insertions(+), 142 deletions(-) delete mode 100644 LICENSE.txt create mode 100644 drf_api_action/plugin.py delete mode 100644 pytest.ini delete mode 100644 setup.cfg delete mode 100644 tests/db.sqlite3 rename tests/{functionality_tests => }/plugin.py (100%) delete mode 100644 tests/test_app/migrations/0001_initial.py delete mode 100644 tests/test_app/migrations/__init__.py rename tests/{functionality_tests => test_server}/__init__.py (100%) rename tests/{ => test_server}/manage.py (100%) rename tests/{test_app => test_server}/settings.py (96%) rename tests/{ => test_server}/test_app/__init__.py (100%) rename tests/{ => test_server}/test_app/models.py (100%) rename tests/{ => test_server}/test_app/views.py (100%) rename tests/{test_app => test_server}/urls.py (78%) rename tests/{functionality_tests => }/tests.py (91%) diff --git a/.gitignore b/.gitignore index d602cc1..7269a80 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ coverage.xml .pytest_cache/ .DS_Store *.sqlite3 +/tests/test_server/test_app/migrations/ +notes diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 1b59042..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2012-2023 Ori Roza and others - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 0d53026..8352f1b 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,8 @@ pip install drf-api-action ```python import pytest -from tests.test_app.models import DummyModel -from tests.test_app.views import DummyViewSetFixture +from tests.test_server.test_app.models import DummyModel +from tests.test_server.test_app.views import DummyViewSetFixture ``` #### Step 2: use the following action_api mark decorator: @@ -49,13 +49,15 @@ from tests.test_app.views import DummyViewSetFixture e.g: our ViewSet is called `DummyViewSetFixture` + ```python import pytest -from tests.test_app.views import DummyViewSetFixture +from tests.test_server.test_app.views import DummyViewSetFixture + @pytest.mark.action_api(view_set_class=DummyViewSetFixture) def test_call_as_api_fixture(db, action_api): - pass + pass ``` Now you can use all `DummyViewSetFixture` functionality! @@ -63,29 +65,32 @@ Now you can use all `DummyViewSetFixture` functionality! e.g: our ViewSet is called `DummyViewSetFixture` + ```python import pytest -from tests.test_app.models import DummyModel -from tests.test_app.views import DummyViewSetFixture +from tests.test_server.test_app.models import DummyModel +from tests.test_server.test_app.views import DummyViewSetFixture + @pytest.mark.action_api(view_set_class=DummyViewSetFixture) def test_call_as_api_fixture(db, action_api): - dummy_model = DummyModel() - dummy_model.dummy_int = 1 - dummy_model.save() - res = action_api.api_dummy(pk=1) - assert res["dummy_int"] == 1 + dummy_model = DummyModel() + dummy_model.dummy_int = 1 + dummy_model.save() + res = action_api.api_dummy(pk=1) + assert res["dummy_int"] == 1 ``` ```python import pytest -from tests.test_app.views import DummyViewSetFixture +from tests.test_server.test_app.views import DummyViewSetFixture + @pytest.mark.action_api(view_set_class=DummyViewSetFixture) def test_dummy(db, action_api): - result = action_api.dummy(pk='bbb') - assert result['dummy_int'] == 1 + result = action_api.dummy(pk='bbb') + assert result['dummy_int'] == 1 ``` ```shell @@ -123,17 +128,10 @@ and so on.... ## Package Testing -The `drf-api-action` library includes tests to ensure the functionality works as expected. To run the tests, follow these steps: - -1. Navigate to the root directory of the `drf-api-action/` project. -```shell -cd tests/ -``` - -2. Run the tests using `pytest` +The `drf-api-action` library includes tests to ensure the functionality works as expected. To run the tests run `pytest`: ```shell - python -m pytest -vv + PYTHONPATH=`pwd` pytest ``` The tests will be executed, and the results will be displayed in the console. diff --git a/drf_api_action/__init__.py b/drf_api_action/__init__.py index aec1246..e69de29 100644 --- a/drf_api_action/__init__.py +++ b/drf_api_action/__init__.py @@ -1,35 +0,0 @@ -import pytest - -from drf_api_action.utils import run_as_api -from drf_api_action.exceptions import ActionsAPIException -from drf_api_action.mixins import APIRestMixin - - -def run_function(self, func): - def api_item(*args, **kwargs): - serializer_class = func.kwargs['serializer_class'] - return run_as_api(self, func, serializer_class, *args, **kwargs) - return api_item - - -@pytest.fixture(scope="session") -def action_api(request): - """ - Make Dango WebView endpoints accessible - """ - if request.keywords['action_api'].kwargs.get("view_set_class") is None: - raise ActionsAPIException('using action_api fixture must require a view_set_class kwarg') - - view_set_class = request.keywords['action_api'].kwargs["view_set_class"] - - class WrapperApiClass(APIRestMixin, view_set_class): - def __getattribute__(self, item): - class_attribute = super().__getattribute__(item) - - if callable(class_attribute) and hasattr(class_attribute, 'detail'): - return run_function(self, class_attribute) - - return class_attribute - - api = WrapperApiClass() - return api diff --git a/drf_api_action/plugin.py b/drf_api_action/plugin.py new file mode 100644 index 0000000..613c715 --- /dev/null +++ b/drf_api_action/plugin.py @@ -0,0 +1,37 @@ +import pytest + +from drf_api_action.utils import run_as_api +from drf_api_action.exceptions import ActionsAPIException + + +def run_function(self, func): + def api_item(*args, **kwargs): + serializer_class = func.kwargs['serializer_class'] + return run_as_api(self, func, serializer_class, *args, **kwargs) + + return api_item + + +@pytest.fixture +def action_api(request): + """ + Make Dango WebView endpoints accessible + """ + from drf_api_action.mixins import APIRestMixin + + if request.keywords['action_api'].kwargs.get("view_set_class") is None: + raise ActionsAPIException('using action_api fixture must require a view_set_class kwarg') + + view_set_class = request.keywords['action_api'].kwargs["view_set_class"] + + class WrapperApiClass(APIRestMixin, view_set_class): + def __getattribute__(self, item): + class_attribute = super().__getattribute__(item) + + if callable(class_attribute) and hasattr(class_attribute, 'detail'): + return run_function(self, class_attribute) + + return class_attribute + + api = WrapperApiClass() + return api diff --git a/pyproject.toml b/pyproject.toml index 793eede..11c2556 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,48 +1,62 @@ -[project] +[build-system] +requires = ["poetry_core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] name = "drf_api_action" +version = "1.2.0" description = "drf-api-action elevates DRF testing by simplifying REST endpoint testing to a seamless, function-like experience." -version = "1.1.0" readme = "README.md" -license = {file = "LICENSE.txt"} -dependencies = ["Django>=4.2.8", "djangorestframework>=3.14.0", "pytest-django>=4.5.2", "pytest-cov>=4.1.0"] -maintainers = [ - { name="Ori Roza", email="ori75660@gmail.com" }, -] -authors = [ - { name="Ori Roza", email="ori75660@gmail.com" }, -] -requires-python = ">=3.8" - -[tool.poetry.plugins.pytest11] -drf_api_action = "drf_api_action.plugin" - -classifiers = [ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", -] +authors = ["Ori Roza "] +license = "MIT" +repository = "https://github.com/Ori-Roza/drf-api-action" +homepage = "https://github.com/Ori-Roza/drf-api-action" keywords = [ "pytest", "mocks", "testing", "fixtures", - "tests" + "tests", + "django" +] + +# Pypi classifiers: https://pypi.org/classifiers/ +classifiers = [ + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Topic :: Software Development :: Testing", + 'Framework :: Pytest', + "License :: OSI Approved :: MIT License", + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Operating System :: OS Independent", ] -[tool.setuptools] -py-modules = [] +[tool.pytest.ini_options] +DJANGO_SETTINGS_MODULE = "tests.test_server.settings" +python_files = "tests.py test_*.py *_tests.py" +markers = [ + "action_api: Viewset" +] +testpaths = ["tests"] + +[tool.poetry.plugins.pytest11] +api_action = "drf_api_action.plugin" -[project.urls] -Home-page = "https://github.com/Ori-Roza/drf-api-action" -Documentation = "https://github.com/Ori-Roza/drf-api-action" -"Source Code" = "https://github.com/Ori-Roza/drf-api-action" -"Issue Tracker" = "https://github.com/Ori-Roza/drf-api-action/issues/" +[tool.poetry.dependencies] +python = "^3.7" +importlib_metadata = {version = "^4.5.0", python = "<3.8"} +Django = ">=4.2.8" +djangorestframework = ">=3.14.0" +pytest-django = ">=4.5.2" +pytest-cov = "4.1.0" -[build-system] -build-backend = "flit_core.buildapi" -requires = ["flit_core >=3.8.0,<4"] [tool.pylint.master] fail-under = 10.0 diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index a20c0bd..0000000 --- a/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -DJANGO_SETTINGS_MODULE = tests.test_app.settings -python_files = tests.py test_*.py *_tests.py diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index fdf4a0e..0000000 --- a/setup.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[metadata] -url = https://github.com/Ori-Roza/drf-api-action -author = Ori-Roza -author_email = ori75660@gmail.com \ No newline at end of file diff --git a/tests/db.sqlite3 b/tests/db.sqlite3 deleted file mode 100644 index 94b203ba69bd4d7462f214a4ce61ee5d9426b884..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI&F>ljA6bJA-JFS(09s^P)q^ku|qP9tF6B>2GAP*I3T7o-dvX1(i8re?kTq`k# zug3&C3ky=k!otGBIZ~>$DGW@l^nZ$!wxnJUUI3c$Z2gCn^%Br%`;KWgoI}EYn+VRbCAOKMZ*2zw8CvzU2v<*X<;>d6FwR zk_GSYhrEB->+yrZ?w&sw^4GzT`-kEFZeNeJ7xcqTZqNQR(j^OZx~6eptkyO*=x{c} z$yutGx6wqNoy+`4-e{WFW_F{qo{LOw>dMA+NUd6{ML&w!nDKj&kH%4!j0&NWaXwkP zVO$&6Uh4m^_tnlezYxXIi74uBr_;D%(ir7j|K6)h(?n|ESSYEIOkR~X%C$LVpNRe; zAOHafKmY;|fB*y_009U<00I!W`vM+aA&;N>^Zk`}yY1-hkwhgTb=$7DCyQfz`}