diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index eeb1629..c27ce49 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -3,17 +3,15 @@ on: [pull_request] jobs: integration-test: - name: Tutor Integration Test + name: Tutor Integration Tests runs-on: ubuntu-latest strategy: matrix: - tutor_version: ["<17.0.0", "<18.0.0", "<19.0.0"] + tutor_version: ['<18.0.0', '<19.0.0', 'nightly'] steps: - - uses: actions/checkout@v4 - with: - path: eox-theming - - uses: eduNEXT/integration-test-in-tutor@main + - name: Run Integration Tests + uses: eduNEXT/integration-test-in-tutor@main with: tutor_version: ${{ matrix.tutor_version }} - app_name: "eox-theming" - shell_file_to_run: "eox_theming/tests/tutor/integration.sh" + app_name: 'eox-theming' + openedx_imports_test_file_path: 'eox_theming/edxapp_wrapper/tests/integration/test_backends.py' diff --git a/Makefile b/Makefile index f03224e..646f451 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,13 @@ upgrade: ## update the requirements/*.txt files with the latest packages satisfy sed '/^[dD]jango==/d;' requirements/test.txt > requirements/test.tmp mv requirements/test.tmp requirements/test.txt +run-integration-tests: +# Install setuptools before running tests because pkg_resources is used +# in paths.py, which is required by the apps.py `ready()` method. + pip install setuptools + pip install -r requirements/test.txt + pytest -rPf ./eox_theming/management/tests/integration + quality: clean ## check coding style with pycodestyle and pylint $(TOX) pycodestyle ./eox_theming $(TOX) pylint ./eox_theming --rcfile=./setup.cfg @@ -48,7 +55,7 @@ quality: clean ## check coding style with pycodestyle and pylint test-python: clean ## Run test suite. $(TOX) pip install -r requirements/test.txt --exists-action w - $(TOX) coverage run --source ./eox_theming manage.py test + $(TOX) coverage run --source="." -m pytest ./eox_theming --ignore-glob='**/integration/*' $(TOX) coverage report -m --fail-under=74 run-tests: test-python quality diff --git a/eox_theming/tests/tutor/__init__.py b/eox_theming/edxapp_wrapper/tests/__init__.py similarity index 100% rename from eox_theming/tests/tutor/__init__.py rename to eox_theming/edxapp_wrapper/tests/__init__.py diff --git a/eox_theming/edxapp_wrapper/tests/integration/__init__.py b/eox_theming/edxapp_wrapper/tests/integration/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eox_theming/edxapp_wrapper/tests/integration/test_backends.py b/eox_theming/edxapp_wrapper/tests/integration/test_backends.py new file mode 100644 index 0000000..a42b049 --- /dev/null +++ b/eox_theming/edxapp_wrapper/tests/integration/test_backends.py @@ -0,0 +1,17 @@ +""" +This module tests the backends of the edxapp_wrapper +""" + + +# pylint: disable=import-outside-toplevel, unused-import +def test_current_settings_code_imports(): + """ + Running this imports means that our backends import the right signature + """ + import eox_theming.edxapp_wrapper.backends.j_configuration_helpers + import eox_theming.edxapp_wrapper.backends.j_finders + import eox_theming.edxapp_wrapper.backends.j_loaders + import eox_theming.edxapp_wrapper.backends.j_models + import eox_theming.edxapp_wrapper.backends.j_theming_helpers + import eox_theming.edxapp_wrapper.backends.l_mako + import eox_theming.edxapp_wrapper.backends.l_storage diff --git a/eox_theming/management/tests/__init__.py b/eox_theming/management/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eox_theming/management/tests/integration/__init__.py b/eox_theming/management/tests/integration/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/eox_theming/management/tests/integration/test_views.py b/eox_theming/management/tests/integration/test_views.py new file mode 100644 index 0000000..3043aaa --- /dev/null +++ b/eox_theming/management/tests/integration/test_views.py @@ -0,0 +1,33 @@ +""" +Integration test for EOX Info view. +""" +import requests +from django.conf import settings as ds +from django.test import TestCase +from django.urls import reverse +from rest_framework import status + +settings = ds.INTEGRATION_TEST_SETTINGS + + +class TestInfoView(TestCase): + """ + Integration test suite for the info view. + """ + + def test_info_view_success(self) -> None: + """Test the info view. + + Expected result: + - The status code is 200. + - The response contains the version, name and git commit hash. + """ + url = f"{settings['EOX_THEMING_BASE_URL']}{reverse('eox-theming-management:eox-info')}" + + response = requests.get(url, timeout=settings["API_TIMEOUT"]) + + response_data = response.json() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIn("version", response_data) + self.assertIn("name", response_data) + self.assertIn("git", response_data) diff --git a/eox_theming/management/urls.py b/eox_theming/management/urls.py index 2295da5..fc93fc0 100644 --- a/eox_theming/management/urls.py +++ b/eox_theming/management/urls.py @@ -6,5 +6,5 @@ from eox_theming.management import views urlpatterns = [ - re_path(r'^eox-info$', views.info_view), + re_path(r'^eox-info$', views.info_view, name='eox-info'), ] diff --git a/eox_theming/settings/test.py b/eox_theming/settings/test.py index fd95b76..de99bc5 100644 --- a/eox_theming/settings/test.py +++ b/eox_theming/settings/test.py @@ -74,3 +74,11 @@ def plugin_settings(settings): # pylint: disable=function-redefined with codecs.open(lms_cfg, encoding='utf-8') as file: env_tokens = yaml.safe_load(file) settings.DATABASES = env_tokens['DATABASES'] + + +# Integration tests settings +INTEGRATION_TEST_SETTINGS = { + # Retrieved from the Tutor environment where the integration tests run + "EOX_THEMING_BASE_URL": f"http://{os.environ.get('LMS_HOST', 'local.edly.io')}/eox-theming", + "API_TIMEOUT": 5, +} diff --git a/eox_theming/tests/tutor/conftest.py b/eox_theming/tests/tutor/conftest.py deleted file mode 100644 index 00e8274..0000000 --- a/eox_theming/tests/tutor/conftest.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -The conftest module sets up the database connection for pytest-django. - -The integration tests will reuse the database from tutor local so a noop -django_db_setup is required. -See: https://pytest-django.readthedocs.io/en/latest/database.html -""" - -import pytest # pylint: disable=import-error - - -@pytest.fixture(scope="session") -def django_db_setup(): - """ - Makes the tests reuse the existing database - """ diff --git a/eox_theming/tests/tutor/integration.sh b/eox_theming/tests/tutor/integration.sh deleted file mode 100644 index 1606802..0000000 --- a/eox_theming/tests/tutor/integration.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# This script installs the package in the edxapp environment, installs test requirements from Open edX and runs the tests using the Tutor settings. -echo "Install package" -pip install -e /openedx/eox-theming - -echo "Install test-requirements" -make test-requirements - -echo "Run tests" -pytest -s --ds=lms.envs.tutor.test /openedx/eox-theming/eox_theming/tests/tutor diff --git a/eox_theming/tests/tutor/integration_test_tutor.py b/eox_theming/tests/tutor/integration_test_tutor.py deleted file mode 100644 index 86b63d1..0000000 --- a/eox_theming/tests/tutor/integration_test_tutor.py +++ /dev/null @@ -1,24 +0,0 @@ -""" -Test integration file. -""" -from django.test import TestCase - - -class TutorIntegrationTestCase(TestCase): - """ - Tests integration with Open edX - """ - - # pylint: disable=import-outside-toplevel, unused-import - def test_current_settings_code_imports(self): - """ - Running this imports means that our backends import the right signature - """ - # isort: off - import eox_theming.edxapp_wrapper.backends.j_configuration_helpers - import eox_theming.edxapp_wrapper.backends.j_finders - import eox_theming.edxapp_wrapper.backends.j_loaders - import eox_theming.edxapp_wrapper.backends.j_models - import eox_theming.edxapp_wrapper.backends.j_theming_helpers - import eox_theming.edxapp_wrapper.backends.l_mako - import eox_theming.edxapp_wrapper.backends.l_storage diff --git a/eox_theming/tests/tutor/pytest.ini b/eox_theming/tests/tutor/pytest.ini deleted file mode 100644 index f3b7462..0000000 --- a/eox_theming/tests/tutor/pytest.ini +++ /dev/null @@ -1,7 +0,0 @@ -[pytest] -python_files = integration_test_*.py -filterwarnings = - default - # We ignore every warning while we actually get the testing infrastructure - # running for different version of tutor in gh actions - ignore: diff --git a/requirements/base.txt b/requirements/base.txt index f2f0f28..4d02ac7 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -10,7 +10,7 @@ backports-zoneinfo==0.2.1 ; python_version < "3.9" # via # -c requirements/constraints.txt # django -django==4.2.14 +django==4.2.16 # via # -c https://raw.githubusercontent.com/openedx/edx-lint/master/edx_lint/files/common_constraints.txt # -r requirements/base.in diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 80f54ee..bec98f4 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -12,4 +12,8 @@ -c https://raw.githubusercontent.com/openedx/edx-lint/master/edx_lint/files/common_constraints.txt # backports.zoneinfo is only needed for Python < 3.9 -backports.zoneinfo; python_version<'3.9' \ No newline at end of file +backports.zoneinfo; python_version<'3.9' + +# Adding pin to avoid any major upgrade. +# 3.15.1 is the latest version that works with Django 3.2 +djangorestframework<3.15.2 diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index 69e02c9..c939293 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -4,29 +4,27 @@ # # make upgrade # -build==1.2.1 +build==1.2.2.post1 # via pip-tools click==8.1.7 # via pip-tools -importlib-metadata==6.11.0 - # via - # -c https://raw.githubusercontent.com/openedx/edx-lint/master/edx_lint/files/common_constraints.txt - # build +importlib-metadata==8.5.0 + # via build packaging==24.1 # via build pip-tools==7.4.1 # via -r requirements/pip-tools.in -pyproject-hooks==1.1.0 +pyproject-hooks==1.2.0 # via # build # pip-tools -tomli==2.0.1 +tomli==2.0.2 # via # build # pip-tools -wheel==0.43.0 +wheel==0.44.0 # via pip-tools -zipp==3.19.2 +zipp==3.20.2 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/test.in b/requirements/test.in index 8726fc5..1eeb232 100644 --- a/requirements/test.in +++ b/requirements/test.in @@ -2,12 +2,16 @@ -r base.txt Django +djangorestframework mock pylint +pytest +pytest-django astroid pycodestyle coverage mako path-py testfixtures +requests pyyaml diff --git a/requirements/test.txt b/requirements/test.txt index f1e7ede..b77dd00 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -17,16 +17,32 @@ backports-zoneinfo==0.2.1 ; python_version < "3.9" # -c requirements/constraints.txt # -r requirements/base.txt # django -coverage==7.6.0 + # djangorestframework +certifi==2024.8.30 + # via requests +charset-normalizer==3.4.0 + # via requests +coverage==7.6.1 # via -r requirements/test.in -dill==0.3.8 +dill==0.3.9 # via pylint # via # -c https://raw.githubusercontent.com/openedx/edx-lint/master/edx_lint/files/common_constraints.txt # -r requirements/base.txt # -r requirements/test.in + # djangorestframework +djangorestframework==3.15.1 + # via + # -c requirements/constraints.txt + # -r requirements/test.in eox-tenant==11.7.0 # via -r requirements/base.txt +exceptiongroup==1.2.2 + # via pytest +idna==3.10 + # via requests +iniconfig==2.0.0 + # via pytest isort==5.13.2 # via pylint mako==1.3.5 @@ -37,17 +53,29 @@ mccabe==0.7.0 # via pylint mock==5.1.0 # via -r requirements/test.in +packaging==24.1 + # via pytest path==17.0.0 # via path-py path-py==12.5.0 # via -r requirements/test.in -platformdirs==4.2.2 +platformdirs==4.3.6 # via pylint -pycodestyle==2.12.0 +pluggy==1.5.0 + # via pytest +pycodestyle==2.12.1 + # via -r requirements/test.in +pylint==3.2.7 + # via -r requirements/test.in +pytest==8.3.3 + # via + # -r requirements/test.in + # pytest-django +pytest-django==4.9.0 # via -r requirements/test.in -pylint==3.2.6 +pyyaml==6.0.2 # via -r requirements/test.in -pyyaml==6.0.1 +requests==2.32.3 # via -r requirements/test.in six==1.16.0 # via -r requirements/base.txt @@ -57,9 +85,11 @@ sqlparse==0.5.1 # django testfixtures==8.3.0 # via -r requirements/test.in -tomli==2.0.1 - # via pylint -tomlkit==0.13.0 +tomli==2.0.2 + # via + # pylint + # pytest +tomlkit==0.13.2 # via pylint typing-extensions==4.12.2 # via @@ -67,3 +97,5 @@ typing-extensions==4.12.2 # asgiref # astroid # pylint +urllib3==2.2.3 + # via requests diff --git a/requirements/tox.txt b/requirements/tox.txt index 67e374e..2836025 100644 --- a/requirements/tox.txt +++ b/requirements/tox.txt @@ -4,15 +4,15 @@ # # make upgrade # -cachetools==5.4.0 +cachetools==5.5.0 # via tox chardet==5.2.0 # via tox colorama==0.4.6 # via tox -distlib==0.3.8 +distlib==0.3.9 # via virtualenv -filelock==3.15.4 +filelock==3.16.1 # via # tox # virtualenv @@ -20,19 +20,21 @@ packaging==24.1 # via # pyproject-api # tox -platformdirs==4.2.2 +platformdirs==4.3.6 # via # tox # virtualenv pluggy==1.5.0 # via tox -pyproject-api==1.7.1 +pyproject-api==1.8.0 # via tox -tomli==2.0.1 +tomli==2.0.2 # via # pyproject-api # tox -tox==4.16.0 +tox==4.21.2 # via -r requirements/tox.in -virtualenv==20.26.3 +typing-extensions==4.12.2 + # via tox +virtualenv==20.26.6 # via tox diff --git a/scripts/execute_integration_tests.sh b/scripts/execute_integration_tests.sh new file mode 100644 index 0000000..c1f256c --- /dev/null +++ b/scripts/execute_integration_tests.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +make run-integration-tests diff --git a/setup.cfg b/setup.cfg index a00ee50..715a0cc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,6 +3,9 @@ current_version = 7.2.0 commit = False tag = False +[tool:pytest] +DJANGO_SETTINGS_MODULE = eox_theming.settings.test + [pylint] ignore = migrations,CVS max-line-length = 120 diff --git a/tox.ini b/tox.ini index bc413ac..ab2b3b3 100644 --- a/tox.ini +++ b/tox.ini @@ -11,6 +11,6 @@ envdir= deps = django32: -r requirements/django32.txt django42: -r requirements/django42.txt - -rrequirements/test.txt + -r requirements/test.txt commands = {posargs}