From dd29714d70ac547c8255f689b46980a0e420aa26 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 30 Oct 2024 11:31:02 -0500 Subject: [PATCH 01/34] refactor: move get_access_token, make_request, and BaseIntegrationTest to eox_core/test_utils --- .../api/v1/tests/integration/test_views.py | 108 +----------------- eox_core/test_utils.py | 104 +++++++++++++++++ 2 files changed, 109 insertions(+), 103 deletions(-) diff --git a/eox_core/api/v1/tests/integration/test_views.py b/eox_core/api/v1/tests/integration/test_views.py index 1cbd24791..dea3561c7 100644 --- a/eox_core/api/v1/tests/integration/test_views.py +++ b/eox_core/api/v1/tests/integration/test_views.py @@ -10,113 +10,15 @@ import ddt import requests from django.conf import settings as ds -from django.test import TestCase from django.urls import reverse from rest_framework import status from eox_core.api.v1.tests.integration.data.fake_users import FAKE_USER_DATA +from eox_core.test_utils import BaseIntegrationTest, make_request settings = ds.INTEGRATION_TEST_SETTINGS -def get_access_token() -> str: - """ - Get an access token for all requests in the test suite. - - Returns: - str: The access token. - """ - data = { - "client_id": settings["CLIENT_ID"], - "client_secret": settings["CLIENT_SECRET"], - "grant_type": "client_credentials", - } - url = f"http://{settings['LMS_BASE']}/oauth2/access_token/" - response = requests.post(url, data=data, timeout=settings["API_TIMEOUT"]) - return response.json()["access_token"] - - -ACCESS_TOKEN = get_access_token() - - -# pylint: disable=too-many-arguments -def make_request( - tenant: dict, - method: str, - url: str, - json: dict | None = None, - data: dict | None = None, - params: dict | None = None, - with_auth: bool = True, -) -> requests.Response: - """ - Make a request to a site (default site or tenant). - - Args: - tenant (dict): The tenant data. - method (str): The HTTP method ('GET', 'POST', etc.). - url (str): The URL to make the request to. - json (dict, optional): The JSON data for POST, PATCH and PUT requests. - data (dict, optional): The data for POST, PATCH and PUT requests. - params (dict, optional): The parameters for GET and DELETE requests. - with_auth (bool, optional): Whether to include the access token in the request headers. - - Returns: - requests.Response: The response object. - """ - headers = {"Host": tenant["domain"]} - if with_auth: - headers["Authorization"] = f"Bearer {ACCESS_TOKEN}" - full_url = f"{tenant['base_url']}/{url}" - - method = method.upper() - if method not in ("GET", "POST", "PATCH", "PUT", "DELETE"): - raise ValueError(f"Unsupported HTTP method: {method}.") - - return requests.request( - method, - full_url, - json=json, - data=data, - params=params, - headers=headers, - timeout=settings["API_TIMEOUT"], - ) - - -class BaseAPIIntegrationTest(TestCase): - """ - Base class for the integration test suite. - """ - - def setUp(self): - """ - Set up the test suite. - """ - self.default_site = self.get_tenant_data() - self.tenant_x = self.get_tenant_data("tenant-x") - self.tenant_y = self.get_tenant_data("tenant-y") - self.demo_course_id = settings["DEMO_COURSE_ID"] - - def get_tenant_data(self, prefix: str = "") -> dict: - """ - Get the tenant data. - - If no prefix is provided, the default site data is returned. - - Args: - prefix (str, optional): The tenant prefix. Defaults to "". - - Returns: - dict: The tenant data. - """ - domain = f"{prefix}.{settings['LMS_BASE']}" if prefix else settings["LMS_BASE"] - return { - "base_url": f"http://{domain}", - "domain": domain, - } - - class UsersAPIRequestMixin: """ Mixin class for the Users API request methods. @@ -282,7 +184,7 @@ def delete_pre_enrollment(self, tenant: dict, data: dict | None = None) -> reque @ddt.ddt -class TestUsersAPIIntegration(BaseAPIIntegrationTest, UsersAPIRequestMixin): +class TestUsersAPIIntegration(BaseIntegrationTest, UsersAPIRequestMixin): """Integration test suite for the Users API""" @ddt.data( @@ -493,7 +395,7 @@ def test_update_user_in_tenant_user_not_found(self, param: str, value: str) -> N @ddt.ddt -class TestEnrollmentAPIIntegration(BaseAPIIntegrationTest, UsersAPIRequestMixin, EnrollmentAPIRequestMixin): +class TestEnrollmentAPIIntegration(BaseIntegrationTest, UsersAPIRequestMixin, EnrollmentAPIRequestMixin): """Integration test suite for the Enrollment API""" def setUp(self) -> None: @@ -1078,7 +980,7 @@ def test_update_valid_enrollment_using_force_flag(self, param: str) -> None: @ddt.ddt class TestPreEnrollmentAPIIntegration( - BaseAPIIntegrationTest, + BaseIntegrationTest, UsersAPIRequestMixin, PreEnrollmentAPIRequestMixin, ): @@ -1517,7 +1419,7 @@ def test_delete_pre_enrollment_missing_required_fields(self, errors: dict) -> No self.assertEqual(pre_enrollment_response.status_code, status.HTTP_200_OK) -class TestInfoView(BaseAPIIntegrationTest): +class TestInfoView(BaseIntegrationTest): """ Integration test suite for the info view. """ diff --git a/eox_core/test_utils.py b/eox_core/test_utils.py index 04530b425..0b9f1c4aa 100644 --- a/eox_core/test_utils.py +++ b/eox_core/test_utils.py @@ -1,10 +1,16 @@ """ Utils for testing""" +from __future__ import annotations + from datetime import datetime import factory +import requests +from django.conf import settings as ds from django.contrib.auth.models import User +from django.test import TestCase DEFAULT_PASSWORD = 'test' +settings = ds.INTEGRATION_TEST_SETTINGS class SuperUserFactory(factory.django.DjangoModelFactory): @@ -40,3 +46,101 @@ def url(self, name): return the name of the asset """ return name + + +def get_access_token() -> str: + """ + Get an access token for all requests in the test suite. + + Returns: + str: The access token. + """ + data = { + "client_id": settings["CLIENT_ID"], + "client_secret": settings["CLIENT_SECRET"], + "grant_type": "client_credentials", + } + url = f"http://{settings['LMS_BASE']}/oauth2/access_token/" + response = requests.post(url, data=data, timeout=settings["API_TIMEOUT"]) + return response.json()["access_token"] + + +ACCESS_TOKEN = get_access_token() + + +# pylint: disable=too-many-arguments +def make_request( + tenant: dict, + method: str, + url: str, + json: dict | None = None, + data: dict | None = None, + params: dict | None = None, + with_auth: bool = True, +) -> requests.Response: + """ + Make a request to a site (default site or tenant). + + Args: + tenant (dict): The tenant data. + method (str): The HTTP method ('GET', 'POST', etc.). + url (str): The URL to make the request to. + json (dict, optional): The JSON data for POST, PATCH and PUT requests. + data (dict, optional): The data for POST, PATCH and PUT requests. + params (dict, optional): The parameters for GET and DELETE requests. + with_auth (bool, optional): Whether to include the access token in the request headers. + + Returns: + requests.Response: The response object. + """ + headers = {"Host": tenant["domain"]} + if with_auth: + headers["Authorization"] = f"Bearer {ACCESS_TOKEN}" + full_url = f"{tenant['base_url']}/{url}" + + method = method.upper() + if method not in ("GET", "POST", "PATCH", "PUT", "DELETE"): + raise ValueError(f"Unsupported HTTP method: {method}.") + + return requests.request( + method, + full_url, + json=json, + data=data, + params=params, + headers=headers, + timeout=settings["API_TIMEOUT"], + ) + + +class BaseIntegrationTest(TestCase): + """ + Base class for the integration test suite. + """ + + def setUp(self): + """ + Set up the test suite. + """ + self.default_site = self.get_tenant_data() + self.tenant_x = self.get_tenant_data("tenant-x") + self.tenant_y = self.get_tenant_data("tenant-y") + self.demo_course_id = settings["DEMO_COURSE_ID"] + + def get_tenant_data(self, prefix: str = "") -> dict: + """ + Get the tenant data. + + If no prefix is provided, the default site data is returned. + + Args: + prefix (str, optional): The tenant prefix. Defaults to "". + + Returns: + dict: The tenant data. + """ + domain = f"{prefix}.{settings['LMS_BASE']}" if prefix else settings["LMS_BASE"] + return { + "base_url": f"http://{domain}", + "domain": domain, + } From 84d6d8e8e21c2ba2055e8123095b9a8275781ca5 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 30 Oct 2024 11:39:21 -0500 Subject: [PATCH 02/34] chore: add new fake users to FAKE_USERS_DATA --- .../v1/tests/integration/data/fake_users.py | 221 ++++++++++++++++++ 1 file changed, 221 insertions(+) diff --git a/eox_core/api/v1/tests/integration/data/fake_users.py b/eox_core/api/v1/tests/integration/data/fake_users.py index 88dbd02bd..00ae9a58e 100644 --- a/eox_core/api/v1/tests/integration/data/fake_users.py +++ b/eox_core/api/v1/tests/integration/data/fake_users.py @@ -1017,5 +1017,226 @@ "city": "Denver", "goals": "Maecenas nec odio et ante tincidunt tempus.", }, + { + "username": "asimmons42", + "email": "asimmons42@gmail.com", + "fullname": "Alice Simmons", + "password": "gD3@9Ty!pH$", + "activate_user": True, + "mailing_address": "12 Aspen Street", + "year_of_birth": 1985, + "gender": "f", + "level_of_education": "b", + "city": "Portland", + "goals": "Curabitur ullamcorper ultricies nisi.", + }, + { + "username": "cbrown26", + "email": "cbrown26@outlook.com", + "fullname": "Chris Brown", + "password": "xF2@8Qv!nL%", + "activate_user": False, + "mailing_address": "58 Maple Circle", + "year_of_birth": 1990, + "gender": "m", + "level_of_education": "hs", + "city": "Charlotte", + "goals": "Etiam ultricies nisi vel augue.", + }, + { + "username": "phall37", + "email": "phall37@hotmail.com", + "fullname": "Patricia Hall", + "password": "zT6@4Yw!mK#", + "activate_user": True, + "mailing_address": "15 Walnut Lane", + "year_of_birth": 1984, + "gender": "f", + "level_of_education": "m", + "city": "Chicago", + "goals": "Vivamus elementum semper nisi.", + }, + { + "username": "rlee29", + "email": "rlee29@gmail.com", + "fullname": "Robert Lee", + "password": "yH5@7Kn!jL%", + "activate_user": False, + "mailing_address": "77 Fir Street", + "year_of_birth": 1991, + "gender": "m", + "level_of_education": "b", + "city": "San Jose", + "goals": "Aenean leo ligula, porttitor eu.", + }, + { + "username": "jthomas41", + "email": "jthomas41@protonmail.com", + "fullname": "Joan Thomas", + "password": "uD4@3Zp!kQ#", + "activate_user": True, + "mailing_address": "98 Palm Avenue", + "year_of_birth": 1988, + "gender": "f", + "level_of_education": "p", + "city": "Jacksonville", + "goals": "Fusce fermentum odio nec arcu.", + }, + { + "username": "bwilliams24", + "email": "bwilliams24@live.com", + "fullname": "Bryan Williams", + "password": "eG6@5Jq!lY@", + "activate_user": False, + "mailing_address": "6 Sycamore Drive", + "year_of_birth": 1993, + "gender": "m", + "level_of_education": "m", + "city": "Memphis", + "goals": "In dui magna, posuere eget, vestibulum et.", + }, + { + "username": "jgarcia30", + "email": "jgarcia30@gmail.com", + "fullname": "Jose Garcia", + "password": "qR1@8Mp!tK%", + "activate_user": True, + "mailing_address": "35 Cedar Lane", + "year_of_birth": 1996, + "gender": "m", + "level_of_education": "hs", + "city": "Fort Worth", + "goals": "Aenean vulputate eleifend tellus.", + }, + { + "username": "csanders39", + "email": "csanders39@outlook.com", + "fullname": "Carol Sanders", + "password": "rV8@2Lk!nP$", + "activate_user": False, + "mailing_address": "72 Birch Drive", + "year_of_birth": 1989, + "gender": "f", + "level_of_education": "b", + "city": "Baltimore", + "goals": "Nullam dictum felis eu pede.", + }, + { + "username": "dmurphy31", + "email": "dmurphy31@gmail.com", + "fullname": "David Murphy", + "password": "sP4@9Hw!fD%", + "activate_user": True, + "mailing_address": "44 Oak Road", + "year_of_birth": 1985, + "gender": "m", + "level_of_education": "hs", + "city": "El Paso", + "goals": "Nam quam nunc, blandit vel.", + }, + { + "username": "jlewis33", + "email": "jlewis33@yahoo.com", + "fullname": "Julia Lewis", + "password": "kR2@5Xt!nY%", + "activate_user": False, + "mailing_address": "32 Maple Drive", + "year_of_birth": 1987, + "gender": "f", + "level_of_education": "m", + "city": "Las Vegas", + "goals": "Aenean vulputate eleifend tellus.", + }, + { + "username": "fmartin25", + "email": "fmartin25@protonmail.com", + "fullname": "Frank Martin", + "password": "yH9@3Mw!cL%", + "activate_user": True, + "mailing_address": "23 Ash Street", + "year_of_birth": 1990, + "gender": "m", + "level_of_education": "b", + "city": "Louisville", + "goals": "Maecenas nec odio et ante tincidunt tempus.", + }, + { + "username": "kwood34", + "email": "kwood34@outlook.com", + "fullname": "Kathy Wood", + "password": "tL6@4Vz!oJ%", + "activate_user": False, + "mailing_address": "60 Cedar Circle", + "year_of_birth": 1992, + "gender": "f", + "level_of_education": "hs", + "city": "Nashville", + "goals": "Fusce fermentum odio nec arcu.", + }, + { + "username": "cmorgan40", + "email": "cmorgan40@live.com", + "fullname": "Cameron Morgan", + "password": "mX5@6Tf!kB@", + "activate_user": True, + "mailing_address": "18 Poplar Lane", + "year_of_birth": 1991, + "gender": "m", + "level_of_education": "m", + "city": "San Diego", + "goals": "Nullam quis ante. Sed consequat.", + }, + { + "username": "jhall26", + "email": "jhall26@gmail.com", + "fullname": "Jasmine Hall", + "password": "pM9@7Yt!oN#", + "activate_user": False, + "mailing_address": "67 Walnut Road", + "year_of_birth": 1988, + "gender": "f", + "level_of_education": "b", + "city": "Phoenix", + "goals": "Cras dapibus. Vivamus elementum semper nisi.", + }, + { + "username": "rwalker36", + "email": "rwalker36@hotmail.com", + "fullname": "Raymond Walker", + "password": "hD2@5Jk!vG@", + "activate_user": True, + "mailing_address": "90 Cypress Avenue", + "year_of_birth": 1983, + "gender": "m", + "level_of_education": "p", + "city": "Denver", + "goals": "Donec vitae sapien ut libero venenatis.", + }, + { + "username": "plong38", + "email": "plong38@protonmail.com", + "fullname": "Patricia Long", + "password": "xG4@8Qr!fH%", + "activate_user": False, + "mailing_address": "3 Willow Street", + "year_of_birth": 1996, + "gender": "f", + "level_of_education": "hs", + "city": "Houston", + "goals": "Suspendisse potenti. Etiam rhoncus.", + }, + { + "username": "jhill24", + "email": "jhill24@live.com", + "fullname": "John Hill", + "password": "zF7@2Lw!kT#", + "activate_user": True, + "mailing_address": "41 Palm Drive", + "year_of_birth": 1989, + "gender": "m", + "level_of_education": "m", + "city": "New York", + "goals": "Integer tincidunt. Cras dapibus.", + }, ] ) From 1bc2968804d4c44e6970d03aaf2cc8d0d5251e7f Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 30 Oct 2024 11:59:08 -0500 Subject: [PATCH 03/34] chore: use add-plugins-step branch of integration tests action --- .github/workflows/integration-test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index f3ad4edc7..9ffa07b2c 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,9 +10,10 @@ jobs: tutor_version: ['<18.0.0', '<19.0.0', 'nightly'] steps: - name: Run Integration Tests - uses: eduNEXT/integration-test-in-tutor@main + uses: eduNEXT/integration-test-in-tutor@bav/add-plugins-step with: tutor_version: ${{ matrix.tutor_version }} + tutor_plugins: 'forum' app_name: 'eox-core' openedx_extra_pip_requirements: 'eox-tenant' shell_file_to_run: 'scripts/execute_integration_tests.sh' From ce13bac6aa6424a932dc06527f6a8a116deb21b5 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 30 Oct 2024 12:52:08 -0500 Subject: [PATCH 04/34] chore: remove nightly from integration tests workflow --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 9ffa07b2c..b946ee667 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - tutor_version: ['<18.0.0', '<19.0.0', 'nightly'] + tutor_version: ['<18.0.0', '<19.0.0'] steps: - name: Run Integration Tests uses: eduNEXT/integration-test-in-tutor@bav/add-plugins-step From 634c326379a15fbc697021d06723bb5d7e6b7a99 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 30 Oct 2024 13:57:29 -0500 Subject: [PATCH 05/34] fix: move integration test utils to separate file --- .../api/v1/tests/integration/test_views.py | 2 +- eox_core/test_utils.py | 104 ----------------- eox_core/tests/integration/utils.py | 107 ++++++++++++++++++ 3 files changed, 108 insertions(+), 105 deletions(-) create mode 100644 eox_core/tests/integration/utils.py diff --git a/eox_core/api/v1/tests/integration/test_views.py b/eox_core/api/v1/tests/integration/test_views.py index dea3561c7..f87825ddb 100644 --- a/eox_core/api/v1/tests/integration/test_views.py +++ b/eox_core/api/v1/tests/integration/test_views.py @@ -14,7 +14,7 @@ from rest_framework import status from eox_core.api.v1.tests.integration.data.fake_users import FAKE_USER_DATA -from eox_core.test_utils import BaseIntegrationTest, make_request +from eox_core.tests.integration.utils import BaseIntegrationTest, make_request settings = ds.INTEGRATION_TEST_SETTINGS diff --git a/eox_core/test_utils.py b/eox_core/test_utils.py index 0b9f1c4aa..04530b425 100644 --- a/eox_core/test_utils.py +++ b/eox_core/test_utils.py @@ -1,16 +1,10 @@ """ Utils for testing""" -from __future__ import annotations - from datetime import datetime import factory -import requests -from django.conf import settings as ds from django.contrib.auth.models import User -from django.test import TestCase DEFAULT_PASSWORD = 'test' -settings = ds.INTEGRATION_TEST_SETTINGS class SuperUserFactory(factory.django.DjangoModelFactory): @@ -46,101 +40,3 @@ def url(self, name): return the name of the asset """ return name - - -def get_access_token() -> str: - """ - Get an access token for all requests in the test suite. - - Returns: - str: The access token. - """ - data = { - "client_id": settings["CLIENT_ID"], - "client_secret": settings["CLIENT_SECRET"], - "grant_type": "client_credentials", - } - url = f"http://{settings['LMS_BASE']}/oauth2/access_token/" - response = requests.post(url, data=data, timeout=settings["API_TIMEOUT"]) - return response.json()["access_token"] - - -ACCESS_TOKEN = get_access_token() - - -# pylint: disable=too-many-arguments -def make_request( - tenant: dict, - method: str, - url: str, - json: dict | None = None, - data: dict | None = None, - params: dict | None = None, - with_auth: bool = True, -) -> requests.Response: - """ - Make a request to a site (default site or tenant). - - Args: - tenant (dict): The tenant data. - method (str): The HTTP method ('GET', 'POST', etc.). - url (str): The URL to make the request to. - json (dict, optional): The JSON data for POST, PATCH and PUT requests. - data (dict, optional): The data for POST, PATCH and PUT requests. - params (dict, optional): The parameters for GET and DELETE requests. - with_auth (bool, optional): Whether to include the access token in the request headers. - - Returns: - requests.Response: The response object. - """ - headers = {"Host": tenant["domain"]} - if with_auth: - headers["Authorization"] = f"Bearer {ACCESS_TOKEN}" - full_url = f"{tenant['base_url']}/{url}" - - method = method.upper() - if method not in ("GET", "POST", "PATCH", "PUT", "DELETE"): - raise ValueError(f"Unsupported HTTP method: {method}.") - - return requests.request( - method, - full_url, - json=json, - data=data, - params=params, - headers=headers, - timeout=settings["API_TIMEOUT"], - ) - - -class BaseIntegrationTest(TestCase): - """ - Base class for the integration test suite. - """ - - def setUp(self): - """ - Set up the test suite. - """ - self.default_site = self.get_tenant_data() - self.tenant_x = self.get_tenant_data("tenant-x") - self.tenant_y = self.get_tenant_data("tenant-y") - self.demo_course_id = settings["DEMO_COURSE_ID"] - - def get_tenant_data(self, prefix: str = "") -> dict: - """ - Get the tenant data. - - If no prefix is provided, the default site data is returned. - - Args: - prefix (str, optional): The tenant prefix. Defaults to "". - - Returns: - dict: The tenant data. - """ - domain = f"{prefix}.{settings['LMS_BASE']}" if prefix else settings["LMS_BASE"] - return { - "base_url": f"http://{domain}", - "domain": domain, - } diff --git a/eox_core/tests/integration/utils.py b/eox_core/tests/integration/utils.py new file mode 100644 index 000000000..9c9710ff8 --- /dev/null +++ b/eox_core/tests/integration/utils.py @@ -0,0 +1,107 @@ +"""Utilities for the integration test suite.""" + +from __future__ import annotations + +import requests +from django.conf import settings as ds +from django.test import TestCase + +settings = ds.INTEGRATION_TEST_SETTINGS + + +def get_access_token() -> str: + """ + Get an access token for all requests in the test suite. + + Returns: + str: The access token. + """ + data = { + "client_id": settings["CLIENT_ID"], + "client_secret": settings["CLIENT_SECRET"], + "grant_type": "client_credentials", + } + url = f"http://{settings['LMS_BASE']}/oauth2/access_token/" + response = requests.post(url, data=data, timeout=settings["API_TIMEOUT"]) + return response.json()["access_token"] + + +ACCESS_TOKEN = get_access_token() + + +# pylint: disable=too-many-arguments +def make_request( + tenant: dict, + method: str, + url: str, + json: dict | None = None, + data: dict | None = None, + params: dict | None = None, + with_auth: bool = True, +) -> requests.Response: + """ + Make a request to a site (default site or tenant). + + Args: + tenant (dict): The tenant data. + method (str): The HTTP method ('GET', 'POST', etc.). + url (str): The URL to make the request to. + json (dict, optional): The JSON data for POST, PATCH and PUT requests. + data (dict, optional): The data for POST, PATCH and PUT requests. + params (dict, optional): The parameters for GET and DELETE requests. + with_auth (bool, optional): Whether to include the access token in the request headers. + + Returns: + requests.Response: The response object. + """ + headers = {"Host": tenant["domain"]} + if with_auth: + headers["Authorization"] = f"Bearer {ACCESS_TOKEN}" + full_url = f"{tenant['base_url']}/{url}" + + method = method.upper() + if method not in ("GET", "POST", "PATCH", "PUT", "DELETE"): + raise ValueError(f"Unsupported HTTP method: {method}.") + + return requests.request( + method, + full_url, + json=json, + data=data, + params=params, + headers=headers, + timeout=settings["API_TIMEOUT"], + ) + + +class BaseIntegrationTest(TestCase): + """ + Base class for the integration test suite. + """ + + def setUp(self): + """ + Set up the test suite. + """ + self.default_site = self.get_tenant_data() + self.tenant_x = self.get_tenant_data("tenant-x") + self.tenant_y = self.get_tenant_data("tenant-y") + self.demo_course_id = settings["DEMO_COURSE_ID"] + + def get_tenant_data(self, prefix: str = "") -> dict: + """ + Get the tenant data. + + If no prefix is provided, the default site data is returned. + + Args: + prefix (str, optional): The tenant prefix. Defaults to "". + + Returns: + dict: The tenant data. + """ + domain = f"{prefix}.{settings['LMS_BASE']}" if prefix else settings["LMS_BASE"] + return { + "base_url": f"http://{domain}", + "domain": domain, + } From e276525be047a4c7c323307dc6e9c0991b4ee1d2 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 30 Oct 2024 16:29:19 -0500 Subject: [PATCH 06/34] test: add support api integration tests --- .../support/v1/tests/integration/__init__.py | 0 .../v1/tests/integration/test_views.py | 149 ++++++++++++++++++ .../edxapp_wrapper/backends/users_m_v1.py | 9 +- 3 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 eox_core/api/support/v1/tests/integration/__init__.py create mode 100644 eox_core/api/support/v1/tests/integration/test_views.py diff --git a/eox_core/api/support/v1/tests/integration/__init__.py b/eox_core/api/support/v1/tests/integration/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py new file mode 100644 index 000000000..382dfdb35 --- /dev/null +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -0,0 +1,149 @@ +"""Support API request mixin for the Pre Enrollments API.""" + +from __future__ import annotations + +import ddt +import requests +from django.conf import settings as ds +from django.urls import reverse +from rest_framework import status + +# TODO: move the FAKE_USER_DATA to a common place +from eox_core.api.v1.tests.integration.data.fake_users import FAKE_USER_DATA +from eox_core.api.v1.tests.integration.test_views import UsersAPIRequestMixin +from eox_core.tests.integration.utils import BaseIntegrationTest, make_request + +settings = ds.INTEGRATION_TEST_SETTINGS + + +class SupportAPIRequestMixin: + """Mixin class for the Pre Enrollments API request methods.""" + + DELETE_USER_URL = f"{settings['EOX_CORE_API_BASE']}{reverse('eox-support-api:eox-support-api:edxapp-user')}" + UPDATE_USERNAME_URL = ( + f"{settings['EOX_CORE_API_BASE']}{reverse('eox-support-api:eox-support-api:edxapp-replace-username')}" + ) + OAUTH_APP_URL = ( + f"{settings['EOX_CORE_API_BASE']}{reverse('eox-support-api:eox-support-api:edxapp-oauth-application')}" + ) + + def delete_user(self, tenant: dict, params: dict | None = None) -> requests.Response: + """ + Delete an edxapp user in a tenant. + + Args: + tenant (dict): The tenant data. + params (dict, optional): The query parameters for the request. + + Returns: + requests.Response: The response object. + """ + return make_request(tenant, "DELETE", url=self.DELETE_USER_URL, params=params) + + # TODO: Check of the default value of data should be None + def update_username(self, tenant: dict, params: dict, data: dict | None = None) -> requests.Response: + """ + Update an edxapp user's username in a tenant. + + Args: + tenant (dict): The tenant data. + params (dict): The query parameters for the request. + data (dict, optional): The body data for the request. + + Returns: + requests.Response: The response object. + """ + return make_request(tenant, "PATCH", url=self.UPDATE_USERNAME_URL, params=params, data=data) + + # TODO: Check of the default value of data should be None + def create_oauth_application(self, tenant: dict, data: dict | None = None) -> requests.Response: + """ + Create an oauth application in a tenant. + + Args: + tenant (dict): The tenant data. + data (dict, optional): The body data for the request. + + Returns: + requests.Response: The response object. + """ + return make_request(tenant, "POST", url=self.OAUTH_APP_URL, data=data) + + +@ddt.ddt +class TestEdxAppUserAPIIntegration(SupportAPIRequestMixin, BaseIntegrationTest, UsersAPIRequestMixin): + """Integration tests for the EdxApp User API.""" + + @ddt.data("username", "email") + def test_delete_user_in_tenant_success(self, query_param: str) -> None: + """ + Test delete an edxapp user in a tenant. + + Open edX definitions tested: + - `get_edxapp_user` + - `delete_edxapp_user` + + Expected result: + - The status code is 200. + - The response indicates the user was removed successfully from the tenant. + - The user is not found in the tenant. + """ + data = next(FAKE_USER_DATA) + self.create_user(self.tenant_x, data) + + response = self.delete_user(self.tenant_x, {query_param: data[query_param]}) + response_data = response.json() + get_response = self.get_user(self.tenant_y, {query_param: data[query_param]}) + get_response_data = get_response.json() + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response_data, f"The user {data['username']} <{data['email']}> has been removed") + self.assertEqual(get_response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual( + get_response_data["detail"], + f"No user found by {{'{query_param}': '{data[query_param]}'}} on site {self.tenant_y['domain']}.", + ) + + @ddt.data( + ("username", "user-not-found"), + ("email", "user-not-found@mail.com"), + ) + @ddt.unpack + def test_delete_user_in_tenant_not_found(self, query_param: str, value: str) -> None: + """ + Test delete an edxapp user in a tenant that does not exist. + + Open edX definitions tested: + - `get_edxapp_user` + + Expected result: + - The status code is 404. + - The response indicates the user was not found in the tenant. + """ + response = self.delete_user(self.tenant_x, {query_param: value}) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual( + response_data["detail"], + f"No user found by {{'{query_param}': '{value}'}} on site {self.tenant_x['domain']}.", + ) + + def test_delete_user_missing_required_fields(self) -> None: + """ + Test delete an edxapp user in a tenant without providing the username or email. + + Expected result: + - The status code is 400. + - The response indicates the username is required. + """ + response = self.delete_user(self.tenant_x) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual(response_data, ["Email or username needed"]) + + +@ddt.ddt +class TestOauthApplicationAPIIntegration(SupportAPIRequestMixin, BaseIntegrationTest, UsersAPIRequestMixin): + """Integration tests for the Oauth Application API.""" diff --git a/eox_core/edxapp_wrapper/backends/users_m_v1.py b/eox_core/edxapp_wrapper/backends/users_m_v1.py index 90e51cba8..69ff2f745 100644 --- a/eox_core/edxapp_wrapper/backends/users_m_v1.py +++ b/eox_core/edxapp_wrapper/backends/users_m_v1.py @@ -276,12 +276,19 @@ def delete_edxapp_user(*args, **kwargs): site = kwargs.get("site") is_support_user = kwargs.get("is_support_user") + print(f"\n\nUser: {user}, Site: {site}, Is Support User: {is_support_user}\n\n") + user_response = f"The user {user.username} <{user.email}> " + print(f"\n\nUser response: {user_response}\n\n") signup_sources = user.usersignupsource_set.all() sources = [signup_source.site for signup_source in signup_sources] - if site and site.name.upper() in (source.upper() for source in sources): + print(f"\n\nSources: {sources}\n\n") + print(f"\n\nSite Name: {site.name.upper()}\n\n") + print(f"\n\nSite Domain: {site.domain}\n\n") + + if site and site.domain.upper() in (source.upper() for source in sources): if len(sources) == 1: with transaction.atomic(): support_label = "_support" if is_support_user else "" From d9bae9d8aafbf0fdcbf92c48c73ffe453ab0dfce Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 31 Oct 2024 14:10:23 -0500 Subject: [PATCH 07/34] refactor: move fake_users.py to tests/integration/data --- eox_core/{api/v1 => }/tests/integration/data/__init__.py | 0 eox_core/{api/v1 => }/tests/integration/data/fake_users.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename eox_core/{api/v1 => }/tests/integration/data/__init__.py (100%) rename eox_core/{api/v1 => }/tests/integration/data/fake_users.py (99%) diff --git a/eox_core/api/v1/tests/integration/data/__init__.py b/eox_core/tests/integration/data/__init__.py similarity index 100% rename from eox_core/api/v1/tests/integration/data/__init__.py rename to eox_core/tests/integration/data/__init__.py diff --git a/eox_core/api/v1/tests/integration/data/fake_users.py b/eox_core/tests/integration/data/fake_users.py similarity index 99% rename from eox_core/api/v1/tests/integration/data/fake_users.py rename to eox_core/tests/integration/data/fake_users.py index 00ae9a58e..4abb92a77 100644 --- a/eox_core/api/v1/tests/integration/data/fake_users.py +++ b/eox_core/tests/integration/data/fake_users.py @@ -43,8 +43,8 @@ "goals": "Proin interdum mauris non ligula pellentesque ultrices.", }, { - "username": "ddilon3", - "email": "ddilon3@geocities.com", + "username": "ddilon4", + "email": "ddilon4@geocities.com", "fullname": "Dotty Dilon", "password": 'mV9"3zRdRr#bTP', "activate_user": True, From 363f0731ff3af915db74e005d8fc0fd004d2895b Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 31 Oct 2024 14:11:31 -0500 Subject: [PATCH 08/34] test: add more integration tests for support api --- .../v1/tests/integration/test_views.py | 103 ++++++++++++++++-- 1 file changed, 94 insertions(+), 9 deletions(-) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index 382dfdb35..d64ca1b96 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -8,9 +8,8 @@ from django.urls import reverse from rest_framework import status -# TODO: move the FAKE_USER_DATA to a common place -from eox_core.api.v1.tests.integration.data.fake_users import FAKE_USER_DATA from eox_core.api.v1.tests.integration.test_views import UsersAPIRequestMixin +from eox_core.tests.integration.data.fake_users import FAKE_USER_DATA from eox_core.tests.integration.utils import BaseIntegrationTest, make_request settings = ds.INTEGRATION_TEST_SETTINGS @@ -40,14 +39,13 @@ def delete_user(self, tenant: dict, params: dict | None = None) -> requests.Resp """ return make_request(tenant, "DELETE", url=self.DELETE_USER_URL, params=params) - # TODO: Check of the default value of data should be None - def update_username(self, tenant: dict, params: dict, data: dict | None = None) -> requests.Response: + def update_username(self, tenant: dict, params: dict | None = None, data: dict | None = None) -> requests.Response: """ Update an edxapp user's username in a tenant. Args: tenant (dict): The tenant data. - params (dict): The query parameters for the request. + params (dict, optional): The query parameters for the request. data (dict, optional): The body data for the request. Returns: @@ -93,15 +91,15 @@ def test_delete_user_in_tenant_success(self, query_param: str) -> None: response = self.delete_user(self.tenant_x, {query_param: data[query_param]}) response_data = response.json() - get_response = self.get_user(self.tenant_y, {query_param: data[query_param]}) + get_response = self.get_user(self.tenant_x, {"email": data["email"]}) get_response_data = get_response.json() self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response_data, f"The user {data['username']} <{data['email']}> has been removed") self.assertEqual(get_response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual( - get_response_data["detail"], - f"No user found by {{'{query_param}': '{data[query_param]}'}} on site {self.tenant_y['domain']}.", + get_response_data, + {"detail": f"No user found by {{'email': '{data['email']}'}} on site {self.tenant_x['domain']}."}, ) @ddt.data( @@ -135,7 +133,7 @@ def test_delete_user_missing_required_fields(self) -> None: Expected result: - The status code is 400. - - The response indicates the username is required. + - The response indicates the username or email is required. """ response = self.delete_user(self.tenant_x) response_data = response.json() @@ -143,6 +141,93 @@ def test_delete_user_missing_required_fields(self) -> None: self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, ["Email or username needed"]) + # TODO: Add test for multiple signup sources + + @ddt.data("username", "email") + def test_update_username_in_tenant_success(self, query_param: str) -> None: + """ + Test update an edxapp user's username in a tenant. + + Open edX definitions tested: + - `get_edxapp_user` + - `check_edxapp_account_conflicts` + - `replace_username_cs_user` + - `get_user_read_only_serializer` + + Expected result: + - The status code is 200. + - The response indicates the username was updated successfully. + - The user is found in the tenant with the new username. + """ + data = next(FAKE_USER_DATA) + self.create_user(self.tenant_x, data) + new_username = f"new-username-{query_param}" + + response = self.update_username(self.tenant_x, {query_param: data[query_param]}, {"new_username": new_username}) + response_data = response.json() + get_response = self.get_user(self.tenant_x, {"username": new_username}) + get_response_data = get_response.json() + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response_data["username"], new_username) + self.assertEqual(get_response.status_code, status.HTTP_200_OK) + self.assertEqual(get_response_data["username"], new_username) + + def test_update_username_in_tenant_not_found(self) -> None: + """ + Test update an edxapp user's username in a tenant that does not exist. + + Open edX definitions tested: + - `get_edxapp_user` + + Expected result: + - The status code is 404. + - The response indicates the user was not found in the tenant. + """ + response = self.update_username( + self.tenant_x, + {"username": "user-not-found"}, + {"new_username": "new-username"}, + ) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual( + response_data["detail"], + f"No user found by {{'username': 'user-not-found'}} on site {self.tenant_x['domain']}.", + ) + + def test_update_username_in_tenant_missing_params(self) -> None: + """ + Test update an edxapp user's username in a tenant without providing the username. + + Expected result: + - The status code is 400. + - The response indicates the username is required. + """ + response = self.update_username(self.tenant_x) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual(response_data, ["Email or username needed"]) + + def test_update_username_in_tenant_missing_body(self) -> None: + """ + Test update an edxapp user's username in a tenant without providing the new username. + + Expected result: + - The status code is 400. + - The response indicates the new username is required. + """ + data = next(FAKE_USER_DATA) + self.create_user(self.tenant_x, data) + + response = self.update_username(self.tenant_x, params={"username": data["username"]}) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual(response_data, {"new_username": ["This field is required."]}) + @ddt.ddt class TestOauthApplicationAPIIntegration(SupportAPIRequestMixin, BaseIntegrationTest, UsersAPIRequestMixin): From 8bd0273a61b429a2e7ba340b1503d0b9e633f76f Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 31 Oct 2024 15:38:30 -0500 Subject: [PATCH 09/34] chore: update import of fake_users --- eox_core/api/v1/tests/integration/test_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eox_core/api/v1/tests/integration/test_views.py b/eox_core/api/v1/tests/integration/test_views.py index f87825ddb..3f634b0ef 100644 --- a/eox_core/api/v1/tests/integration/test_views.py +++ b/eox_core/api/v1/tests/integration/test_views.py @@ -13,7 +13,7 @@ from django.urls import reverse from rest_framework import status -from eox_core.api.v1.tests.integration.data.fake_users import FAKE_USER_DATA +from eox_core.tests.integration.data.fake_users import FAKE_USER_DATA from eox_core.tests.integration.utils import BaseIntegrationTest, make_request settings = ds.INTEGRATION_TEST_SETTINGS From 6641c59cc6a401a637d10c28d84460b18c55b588 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 31 Oct 2024 15:39:25 -0500 Subject: [PATCH 10/34] test: add test for update username and create oauth application --- .../v1/tests/integration/test_views.py | 97 ++++++++++++++++++- 1 file changed, 93 insertions(+), 4 deletions(-) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index d64ca1b96..d49783678 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -53,7 +53,6 @@ def update_username(self, tenant: dict, params: dict | None = None, data: dict | """ return make_request(tenant, "PATCH", url=self.UPDATE_USERNAME_URL, params=params, data=data) - # TODO: Check of the default value of data should be None def create_oauth_application(self, tenant: dict, data: dict | None = None) -> requests.Response: """ Create an oauth application in a tenant. @@ -65,7 +64,7 @@ def create_oauth_application(self, tenant: dict, data: dict | None = None) -> re Returns: requests.Response: The response object. """ - return make_request(tenant, "POST", url=self.OAUTH_APP_URL, data=data) + return make_request(tenant, "POST", url=self.OAUTH_APP_URL, json=data) @ddt.ddt @@ -141,8 +140,6 @@ def test_delete_user_missing_required_fields(self) -> None: self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, ["Email or username needed"]) - # TODO: Add test for multiple signup sources - @ddt.data("username", "email") def test_update_username_in_tenant_success(self, query_param: str) -> None: """ @@ -173,6 +170,35 @@ def test_update_username_in_tenant_success(self, query_param: str) -> None: self.assertEqual(get_response.status_code, status.HTTP_200_OK) self.assertEqual(get_response_data["username"], new_username) + def test_update_username_in_tenant_with_multiple_signup_sources(self) -> None: + """ + Test update an edxapp user's username in a tenant with multiple signup sources. + + Open edX definitions tested: + - `get_edxapp_user` + - `check_edxapp_account_conflicts` + - `replace_username_cs_user` + - `get_user_read_only_serializer` + + Expected result: + - The status code is 200. + - The response indicates the username was updated successfully. + - The user is found in the tenant with the new username. + """ + data = next(FAKE_USER_DATA) + self.create_user(self.tenant_x, data) + new_username = f"new-username-username" + + response = self.update_username(self.tenant_x, {"username": data["username"]}, {"new_username": new_username}) + response_data = response.json() + get_response = self.get_user(self.tenant_x, {"username": new_username}) + get_response_data = get_response.json() + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response_data["username"], new_username) + self.assertEqual(get_response.status_code, status.HTTP_200_OK) + self.assertEqual(get_response_data["username"], new_username) + def test_update_username_in_tenant_not_found(self) -> None: """ Test update an edxapp user's username in a tenant that does not exist. @@ -232,3 +258,66 @@ def test_update_username_in_tenant_missing_body(self) -> None: @ddt.ddt class TestOauthApplicationAPIIntegration(SupportAPIRequestMixin, BaseIntegrationTest, UsersAPIRequestMixin): """Integration tests for the Oauth Application API.""" + + @ddt.data(True, False) + def test_create_oauth_application_in_tenant_success(self, create_user: bool) -> None: + """ + Test create an oauth application in a tenant. The user is created if it does not exist. + + Open edX definitions tested: + - `get_edxapp_user` + - `create_edxapp_user` + - `UserSignupSource` + + Expected result: + - The status code is 200. + - The response indicates the oauth application was created successfully. + """ + user_data = next(FAKE_USER_DATA) + if create_user: + self.create_user(self.tenant_x, user_data) + data = { + "user": { + "fullname": user_data["fullname"], + "email": user_data["email"], + "username": user_data["username"], + "permissions": ["can_call_eox_core", "can_call_eox_tenant"], + }, + "redirect_uris": f"http://{self.tenant_x['domain']}/", + "client_type": "confidential", + "authorization_grant_type": "client-credentials", + "name": "test-application", + "skip_authorization": True, + } + + response = self.create_oauth_application(self.tenant_x, data) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response_data["user"], {"email": user_data["email"], "username": user_data["username"]}) + self.assertEqual(response_data["redirect_uris"], f"http://{self.tenant_x['domain']}/") + self.assertEqual(response_data["client_type"], data["client_type"]) + self.assertEqual(response_data["authorization_grant_type"], data["authorization_grant_type"]) + self.assertEqual(response_data["name"], data["name"]) + self.assertEqual(response_data["skip_authorization"], data["skip_authorization"]) + + def test_create_oauth_application_in_tenant_missing_required_fields(self) -> None: + """ + Test create an oauth application in a tenant without providing the required fields. + + Expected result: + - The status code is 400. + - The response indicates the required fields are missing. + """ + response = self.create_oauth_application(self.tenant_x) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertEqual( + response_data, + { + "user": ["This field is required."], + "client_type": ["This field is required."], + "authorization_grant_type": ["This field is required."], + }, + ) From d360a07c05bbfe748cb90827184d43840c586c54 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Fri, 1 Nov 2024 07:46:12 -0500 Subject: [PATCH 11/34] chore: update users to use activate_user=True --- eox_core/tests/integration/data/fake_users.py | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/eox_core/tests/integration/data/fake_users.py b/eox_core/tests/integration/data/fake_users.py index 4abb92a77..e5773819b 100644 --- a/eox_core/tests/integration/data/fake_users.py +++ b/eox_core/tests/integration/data/fake_users.py @@ -164,7 +164,7 @@ "email": "rwilliams3@aol.com", "fullname": "Robert Williams", "password": "kL9*~Yx2pW!", - "activate_user": False, + "activate_user": True, "mailing_address": "789 Pine Boulevard", "year_of_birth": 1988, "gender": "m", @@ -190,7 +190,7 @@ "email": "jbrown5@live.com", "fullname": "James Brown", "password": "hM8~P9s#tL!B", - "activate_user": False, + "activate_user": True, "mailing_address": "654 Cedar Lane", "year_of_birth": 1992, "gender": "m", @@ -216,7 +216,7 @@ "email": "mlee7@protonmail.com", "fullname": "Michael Lee", "password": "zQ7%4Yn!rT&", - "activate_user": False, + "activate_user": True, "mailing_address": "159 Redwood Drive", "year_of_birth": 1991, "gender": "m", @@ -255,7 +255,7 @@ "email": "cwatson10@msn.com", "fullname": "Catherine Watson", "password": "yJ6$2!NpQ#t", - "activate_user": False, + "activate_user": True, "mailing_address": "369 Willow Terrace", "year_of_birth": 1998, "gender": "f", @@ -294,7 +294,7 @@ "email": "dthomas13@gmail.com", "fullname": "David Thomas", "password": "wL3~7Rs!fK%", - "activate_user": False, + "activate_user": True, "mailing_address": "789 Aspen Drive", "year_of_birth": 1987, "gender": "m", @@ -320,7 +320,7 @@ "email": "cgarcia15@outlook.com", "fullname": "Carlos Garcia", "password": "zK6#3Wx!dP&", - "activate_user": False, + "activate_user": True, "mailing_address": "654 Pine Boulevard", "year_of_birth": 1993, "gender": "m", @@ -359,7 +359,7 @@ "email": "ashaw18@live.com", "fullname": "Alice Shaw", "password": "tF1@8Nm!sJ#", - "activate_user": False, + "activate_user": True, "mailing_address": "246 Spruce Street", "year_of_birth": 1997, "gender": "f", @@ -398,7 +398,7 @@ "email": "rperry21@twitter.com", "fullname": "Rachel Perry", "password": "sV9~#Kd@5", - "activate_user": False, + "activate_user": True, "mailing_address": "456 Birch Road", "year_of_birth": 1993, "gender": "f", @@ -424,7 +424,7 @@ "email": "skhan23@outlook.com", "fullname": "Sana Khan", "password": "pJ3!4Xv#zG", - "activate_user": False, + "activate_user": True, "mailing_address": "963 Spruce St", "year_of_birth": 1997, "gender": "f", @@ -476,7 +476,7 @@ "email": "jmiller27@protonmail.com", "fullname": "John Miller", "password": "tK5@8Nz!rG#", - "activate_user": False, + "activate_user": True, "mailing_address": "753 Maple Street", "year_of_birth": 1993, "gender": "m", @@ -528,7 +528,7 @@ "email": "dwatson31@live.com", "fullname": "Daniel Watson", "password": "zN3!5Pq@7L#", - "activate_user": False, + "activate_user": True, "mailing_address": "159 Spruce Lane", "year_of_birth": 1996, "gender": "m", @@ -619,7 +619,7 @@ "email": "kgreen32@yahoo.com", "fullname": "Karen Green", "password": "rX5@8Nc!gQ&", - "activate_user": False, + "activate_user": True, "mailing_address": "789 Oak Drive", "year_of_birth": 1991, "gender": "f", @@ -645,7 +645,7 @@ "email": "tturner34@live.com", "fullname": "Tina Turner", "password": "wJ4@5Lm!tQ#", - "activate_user": False, + "activate_user": True, "mailing_address": "753 Pine Street", "year_of_birth": 1988, "gender": "f", @@ -667,9 +667,9 @@ "goals": "Vestibulum volutpat pretium libero.", }, { - "username": "gwalker33", - "email": "gwalker33@protonmail.com", - "fullname": "Gary Walker", + "username": "sebander", + "email": "sebander@protonmail.com", + "fullname": "Sebas Ander", "password": "zP7%1Yt!dB@", "activate_user": True, "mailing_address": "321 Birch Road", @@ -697,7 +697,7 @@ "email": "mdavis32@yahoo.com", "fullname": "Mark Davis", "password": "eT1&4Xm!hK%", - "activate_user": False, + "activate_user": True, "mailing_address": "74 Oak Avenue", "year_of_birth": 1990, "gender": "m", @@ -723,7 +723,7 @@ "email": "rjohnson29@protonmail.com", "fullname": "Robert Johnson", "password": "uF2@6Kl!sY@", - "activate_user": False, + "activate_user": True, "mailing_address": "58 Elm Street", "year_of_birth": 1985, "gender": "m", @@ -749,7 +749,7 @@ "email": "bmoore38@live.com", "fullname": "Brian Moore", "password": "hL3@7Op!qV#", - "activate_user": False, + "activate_user": True, "mailing_address": "71 Ash Street", "year_of_birth": 1987, "gender": "m", @@ -775,7 +775,7 @@ "email": "jrobinson25@protonmail.com", "fullname": "John Robinson", "password": "qT4@8Sv!wD%", - "activate_user": False, + "activate_user": True, "mailing_address": "6 Maple Lane", "year_of_birth": 1997, "gender": "m", @@ -801,7 +801,7 @@ "email": "wwilson26@outlook.com", "fullname": "William Wilson", "password": "vN8@7Lp!tC@", - "activate_user": False, + "activate_user": True, "mailing_address": "27 Oak Circle", "year_of_birth": 1993, "gender": "m", @@ -827,7 +827,7 @@ "email": "tharris31@live.com", "fullname": "Thomas Harris", "password": "eQ5@2Gm!pX%", - "activate_user": False, + "activate_user": True, "mailing_address": "39 Spruce Avenue", "year_of_birth": 1994, "gender": "m", @@ -853,7 +853,7 @@ "email": "rthomas28@gmail.com", "fullname": "Richard Thomas", "password": "iM7&5Lq!vB$", - "activate_user": False, + "activate_user": True, "mailing_address": "36 Poplar Road", "year_of_birth": 1992, "gender": "m", @@ -879,7 +879,7 @@ "email": "pdavis36@live.com", "fullname": "Paul Davis", "password": "oX4@7Zn!rY%", - "activate_user": False, + "activate_user": True, "mailing_address": "15 Ash Road", "year_of_birth": 1990, "gender": "m", @@ -918,7 +918,7 @@ "email": "tclark27@gmail.com", "fullname": "Tina Clark", "password": "nJ4@6Pc!vQ#", - "activate_user": False, + "activate_user": True, "mailing_address": "47 Elm Lane", "year_of_birth": 1997, "gender": "f", @@ -944,7 +944,7 @@ "email": "alee35@protonmail.com", "fullname": "Alice Lee", "password": "mK3@4Gv!uH@", - "activate_user": False, + "activate_user": True, "mailing_address": "67 Fir Street", "year_of_birth": 1992, "gender": "f", @@ -970,7 +970,7 @@ "email": "klopez32@gmail.com", "fullname": "Karen Lopez", "password": "oX8@3Vp!sR#", - "activate_user": False, + "activate_user": True, "mailing_address": "90 Pine Crescent", "year_of_birth": 1989, "gender": "f", @@ -996,7 +996,7 @@ "email": "hsanchez28@live.com", "fullname": "Helen Sanchez", "password": "bD6@9Pw!fC%", - "activate_user": False, + "activate_user": True, "mailing_address": "56 Palm Boulevard", "year_of_birth": 1991, "gender": "f", @@ -1035,7 +1035,7 @@ "email": "cbrown26@outlook.com", "fullname": "Chris Brown", "password": "xF2@8Qv!nL%", - "activate_user": False, + "activate_user": True, "mailing_address": "58 Maple Circle", "year_of_birth": 1990, "gender": "m", @@ -1061,7 +1061,7 @@ "email": "rlee29@gmail.com", "fullname": "Robert Lee", "password": "yH5@7Kn!jL%", - "activate_user": False, + "activate_user": True, "mailing_address": "77 Fir Street", "year_of_birth": 1991, "gender": "m", @@ -1087,7 +1087,7 @@ "email": "bwilliams24@live.com", "fullname": "Bryan Williams", "password": "eG6@5Jq!lY@", - "activate_user": False, + "activate_user": True, "mailing_address": "6 Sycamore Drive", "year_of_birth": 1993, "gender": "m", @@ -1113,7 +1113,7 @@ "email": "csanders39@outlook.com", "fullname": "Carol Sanders", "password": "rV8@2Lk!nP$", - "activate_user": False, + "activate_user": True, "mailing_address": "72 Birch Drive", "year_of_birth": 1989, "gender": "f", @@ -1139,7 +1139,7 @@ "email": "jlewis33@yahoo.com", "fullname": "Julia Lewis", "password": "kR2@5Xt!nY%", - "activate_user": False, + "activate_user": True, "mailing_address": "32 Maple Drive", "year_of_birth": 1987, "gender": "f", @@ -1165,7 +1165,7 @@ "email": "kwood34@outlook.com", "fullname": "Kathy Wood", "password": "tL6@4Vz!oJ%", - "activate_user": False, + "activate_user": True, "mailing_address": "60 Cedar Circle", "year_of_birth": 1992, "gender": "f", @@ -1191,7 +1191,7 @@ "email": "jhall26@gmail.com", "fullname": "Jasmine Hall", "password": "pM9@7Yt!oN#", - "activate_user": False, + "activate_user": True, "mailing_address": "67 Walnut Road", "year_of_birth": 1988, "gender": "f", @@ -1217,7 +1217,7 @@ "email": "plong38@protonmail.com", "fullname": "Patricia Long", "password": "xG4@8Qr!fH%", - "activate_user": False, + "activate_user": True, "mailing_address": "3 Willow Street", "year_of_birth": 1996, "gender": "f", From a28a89292edb2a1b8249cf49a3cde65d6bf46576 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Fri, 1 Nov 2024 07:59:42 -0500 Subject: [PATCH 12/34] chore: fix typo in function --- eox_core/api/v1/tests/integration/test_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eox_core/api/v1/tests/integration/test_views.py b/eox_core/api/v1/tests/integration/test_views.py index 3f634b0ef..4f8d33351 100644 --- a/eox_core/api/v1/tests/integration/test_views.py +++ b/eox_core/api/v1/tests/integration/test_views.py @@ -1070,7 +1070,7 @@ def test_create_pre_enrollment_missing_required_fields(self, errors: dict) -> No self.assertEqual(response_data, errors) self.assertEqual(pre_enrollment_response.status_code, status.HTTP_404_NOT_FOUND) - def test_create_pre_enrollmet_already_exists(self) -> None: + def test_create_pre_enrollment_already_exists(self) -> None: """ Test creating an pre-enrollment that already exists in a tenant. From 3a1a31f356c888c9401902f6c3bd89f9a0e14828 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Fri, 1 Nov 2024 08:00:14 -0500 Subject: [PATCH 13/34] chore: remove failed test --- .../v1/tests/integration/test_views.py | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index d49783678..606c30514 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -170,35 +170,6 @@ def test_update_username_in_tenant_success(self, query_param: str) -> None: self.assertEqual(get_response.status_code, status.HTTP_200_OK) self.assertEqual(get_response_data["username"], new_username) - def test_update_username_in_tenant_with_multiple_signup_sources(self) -> None: - """ - Test update an edxapp user's username in a tenant with multiple signup sources. - - Open edX definitions tested: - - `get_edxapp_user` - - `check_edxapp_account_conflicts` - - `replace_username_cs_user` - - `get_user_read_only_serializer` - - Expected result: - - The status code is 200. - - The response indicates the username was updated successfully. - - The user is found in the tenant with the new username. - """ - data = next(FAKE_USER_DATA) - self.create_user(self.tenant_x, data) - new_username = f"new-username-username" - - response = self.update_username(self.tenant_x, {"username": data["username"]}, {"new_username": new_username}) - response_data = response.json() - get_response = self.get_user(self.tenant_x, {"username": new_username}) - get_response_data = get_response.json() - - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response_data["username"], new_username) - self.assertEqual(get_response.status_code, status.HTTP_200_OK) - self.assertEqual(get_response_data["username"], new_username) - def test_update_username_in_tenant_not_found(self) -> None: """ Test update an edxapp user's username in a tenant that does not exist. From b6a9b18bb395eecc7a9d3858ceeb5db00bbc6167 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Fri, 1 Nov 2024 08:12:12 -0500 Subject: [PATCH 14/34] chore: add .coveragerc file to exclude specific paths from coverage report --- .coveragerc | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 000000000..7a3f31768 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,9 @@ +[run] +branch = True +data_file = .coverage +source=eox_core +omit = + */tests/* + */settings/* + */migrations/* + */edxapp_wrapper/* From 47d6c4520ba39647d0ad7fecf1abdec684d08ad0 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Fri, 1 Nov 2024 08:13:29 -0500 Subject: [PATCH 15/34] docs: update class docstring --- eox_core/api/support/v1/tests/integration/test_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index 606c30514..b7a91029b 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -1,4 +1,4 @@ -"""Support API request mixin for the Pre Enrollments API.""" +"""Support API integration tests.""" from __future__ import annotations From b876b1db5668b548aefd0fd3d90f4599aaececfc Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Fri, 1 Nov 2024 08:14:38 -0500 Subject: [PATCH 16/34] chore: remove print statements --- eox_core/edxapp_wrapper/backends/users_m_v1.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/eox_core/edxapp_wrapper/backends/users_m_v1.py b/eox_core/edxapp_wrapper/backends/users_m_v1.py index 69ff2f745..53c819c5e 100644 --- a/eox_core/edxapp_wrapper/backends/users_m_v1.py +++ b/eox_core/edxapp_wrapper/backends/users_m_v1.py @@ -276,18 +276,11 @@ def delete_edxapp_user(*args, **kwargs): site = kwargs.get("site") is_support_user = kwargs.get("is_support_user") - print(f"\n\nUser: {user}, Site: {site}, Is Support User: {is_support_user}\n\n") - user_response = f"The user {user.username} <{user.email}> " - print(f"\n\nUser response: {user_response}\n\n") signup_sources = user.usersignupsource_set.all() sources = [signup_source.site for signup_source in signup_sources] - print(f"\n\nSources: {sources}\n\n") - print(f"\n\nSite Name: {site.name.upper()}\n\n") - print(f"\n\nSite Domain: {site.domain}\n\n") - if site and site.domain.upper() in (source.upper() for source in sources): if len(sources) == 1: with transaction.atomic(): From 3923dc5e4e2d2d8474d9ef9235ea464bdd5b52e8 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Fri, 1 Nov 2024 10:52:07 -0500 Subject: [PATCH 17/34] chore: update username and email of users --- eox_core/tests/integration/data/fake_users.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eox_core/tests/integration/data/fake_users.py b/eox_core/tests/integration/data/fake_users.py index e5773819b..73142f94a 100644 --- a/eox_core/tests/integration/data/fake_users.py +++ b/eox_core/tests/integration/data/fake_users.py @@ -43,8 +43,8 @@ "goals": "Proin interdum mauris non ligula pellentesque ultrices.", }, { - "username": "ddilon4", - "email": "ddilon4@geocities.com", + "username": "ddilon", + "email": "ddilon@geocities.com", "fullname": "Dotty Dilon", "password": 'mV9"3zRdRr#bTP', "activate_user": True, @@ -56,8 +56,8 @@ "goals": "Morbi sem mauris, laoreet ut, rhoncus aliquet, pulvinar sed, nisl.", }, { - "username": "lties4", - "email": "lties4@addthis.com", + "username": "lties", + "email": "lties@addthis.com", "fullname": "Loreen Ties", "password": 'iU6@R"`/t3>/DT', "activate_user": True, From 8e06e32ad6016eaf2273f78f7ab9f531e4eb7750 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 6 Nov 2024 11:59:10 -0500 Subject: [PATCH 18/34] chore: remove .coveragerc --- .coveragerc | 9 --------- setup.cfg | 3 +++ 2 files changed, 3 insertions(+), 9 deletions(-) delete mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 7a3f31768..000000000 --- a/.coveragerc +++ /dev/null @@ -1,9 +0,0 @@ -[run] -branch = True -data_file = .coverage -source=eox_core -omit = - */tests/* - */settings/* - */migrations/* - */edxapp_wrapper/* diff --git a/setup.cfg b/setup.cfg index c2189f974..c22064933 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,6 +13,9 @@ data_file = .coverage omit = venv/* */backends/* + */edxapp_wrapper/* + */tests/* + */settings/* node_modules/* .tox/* ./setup.py From 69920b2b9bcbc47bc6d35abb91b96df245e293d0 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 6 Nov 2024 12:01:09 -0500 Subject: [PATCH 19/34] style: format code --- eox_core/api/support/v1/tests/integration/test_views.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index b7a91029b..c3f2ba212 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -68,7 +68,11 @@ def create_oauth_application(self, tenant: dict, data: dict | None = None) -> re @ddt.ddt -class TestEdxAppUserAPIIntegration(SupportAPIRequestMixin, BaseIntegrationTest, UsersAPIRequestMixin): +class TestEdxAppUserAPIIntegration( + SupportAPIRequestMixin, + BaseIntegrationTest, + UsersAPIRequestMixin, +): """Integration tests for the EdxApp User API.""" @ddt.data("username", "email") From e7600a968314846a23ffb1a001530c1d6f0aaf90 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 6 Nov 2024 12:43:17 -0500 Subject: [PATCH 20/34] chore: only execute support api tests --- Makefile | 2 +- .../api/support/v1/tests/integration/test_views.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 922ab2dc9..144c4f256 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ python-quality-test: run-tests: python-test python-quality-test run-integration-tests: install-dev-dependencies - pytest -rPf ./eox_core --ignore-glob='**/unit/*' --ignore-glob='**/edxapp_wrapper/*' + pytest -rPf ./eox_core --ignore-glob='**/unit/*' --ignore-glob='**/edxapp_wrapper/*' --ignore-glob='**/api/v1/*' upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade upgrade: ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index c3f2ba212..e63f859d4 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -93,6 +93,7 @@ def test_delete_user_in_tenant_success(self, query_param: str) -> None: self.create_user(self.tenant_x, data) response = self.delete_user(self.tenant_x, {query_param: data[query_param]}) + print(f"\n\n{response.text}\n\n") response_data = response.json() get_response = self.get_user(self.tenant_x, {"email": data["email"]}) get_response_data = get_response.json() @@ -123,6 +124,7 @@ def test_delete_user_in_tenant_not_found(self, query_param: str, value: str) -> """ response = self.delete_user(self.tenant_x, {query_param: value}) response_data = response.json() + print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual( @@ -140,6 +142,7 @@ def test_delete_user_missing_required_fields(self) -> None: """ response = self.delete_user(self.tenant_x) response_data = response.json() + print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, ["Email or username needed"]) @@ -165,9 +168,11 @@ def test_update_username_in_tenant_success(self, query_param: str) -> None: new_username = f"new-username-{query_param}" response = self.update_username(self.tenant_x, {query_param: data[query_param]}, {"new_username": new_username}) + print(f"\n\nResponse text: {response.text}\n\n") response_data = response.json() get_response = self.get_user(self.tenant_x, {"username": new_username}) get_response_data = get_response.json() + print(f"\n\nGet response data: {get_response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response_data["username"], new_username) @@ -191,6 +196,7 @@ def test_update_username_in_tenant_not_found(self) -> None: {"new_username": "new-username"}, ) response_data = response.json() + print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual( @@ -208,6 +214,7 @@ def test_update_username_in_tenant_missing_params(self) -> None: """ response = self.update_username(self.tenant_x) response_data = response.json() + print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, ["Email or username needed"]) @@ -225,6 +232,7 @@ def test_update_username_in_tenant_missing_body(self) -> None: response = self.update_username(self.tenant_x, params={"username": data["username"]}) response_data = response.json() + print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, {"new_username": ["This field is required."]}) @@ -267,6 +275,7 @@ def test_create_oauth_application_in_tenant_success(self, create_user: bool) -> response = self.create_oauth_application(self.tenant_x, data) response_data = response.json() + print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response_data["user"], {"email": user_data["email"], "username": user_data["username"]}) @@ -286,6 +295,7 @@ def test_create_oauth_application_in_tenant_missing_required_fields(self) -> Non """ response = self.create_oauth_application(self.tenant_x) response_data = response.json() + print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( From 545e70ea3ab9a765b40c42c5f296a4a9674649f6 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 6 Nov 2024 14:34:24 -0500 Subject: [PATCH 21/34] ci: use branch to print lms logs --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index b946ee667..1ea390bbb 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,7 +10,7 @@ jobs: tutor_version: ['<18.0.0', '<19.0.0'] steps: - name: Run Integration Tests - uses: eduNEXT/integration-test-in-tutor@bav/add-plugins-step + uses: eduNEXT/integration-test-in-tutor@bav/print-logs-error with: tutor_version: ${{ matrix.tutor_version }} tutor_plugins: 'forum' From 8bc0af3a3bcb4cd84d8e1f5b3948c8956d0d4da2 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 6 Nov 2024 16:23:54 -0500 Subject: [PATCH 22/34] chore: add command for populate retirement states in integration tests script --- .github/workflows/integration-test.yml | 2 +- scripts/execute_integration_tests.sh | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 1ea390bbb..b946ee667 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,7 +10,7 @@ jobs: tutor_version: ['<18.0.0', '<19.0.0'] steps: - name: Run Integration Tests - uses: eduNEXT/integration-test-in-tutor@bav/print-logs-error + uses: eduNEXT/integration-test-in-tutor@bav/add-plugins-step with: tutor_version: ${{ matrix.tutor_version }} tutor_plugins: 'forum' diff --git a/scripts/execute_integration_tests.sh b/scripts/execute_integration_tests.sh index 3408c29b2..ad60f57d7 100644 --- a/scripts/execute_integration_tests.sh +++ b/scripts/execute_integration_tests.sh @@ -1,2 +1,7 @@ #!/bin/bash + +# Populate Retirement States +tutor local exec lms python manage.py lms populate_retirement_states + +# Run Integration Tests make run-integration-tests From b2ca8e9c13ec14fc7b67abcae290279e0ea64482 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 6 Nov 2024 16:42:15 -0500 Subject: [PATCH 23/34] chore: remove command for populate retirement states in integration tests script --- scripts/execute_integration_tests.sh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/execute_integration_tests.sh b/scripts/execute_integration_tests.sh index ad60f57d7..3408c29b2 100644 --- a/scripts/execute_integration_tests.sh +++ b/scripts/execute_integration_tests.sh @@ -1,7 +1,2 @@ #!/bin/bash - -# Populate Retirement States -tutor local exec lms python manage.py lms populate_retirement_states - -# Run Integration Tests make run-integration-tests From fdd7153ac62cb23e722f695a77965d1a955370d9 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Wed, 6 Nov 2024 17:07:29 -0500 Subject: [PATCH 24/34] chore: remove print statements --- .../api/support/v1/tests/integration/test_views.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index e63f859d4..c3f2ba212 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -93,7 +93,6 @@ def test_delete_user_in_tenant_success(self, query_param: str) -> None: self.create_user(self.tenant_x, data) response = self.delete_user(self.tenant_x, {query_param: data[query_param]}) - print(f"\n\n{response.text}\n\n") response_data = response.json() get_response = self.get_user(self.tenant_x, {"email": data["email"]}) get_response_data = get_response.json() @@ -124,7 +123,6 @@ def test_delete_user_in_tenant_not_found(self, query_param: str, value: str) -> """ response = self.delete_user(self.tenant_x, {query_param: value}) response_data = response.json() - print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual( @@ -142,7 +140,6 @@ def test_delete_user_missing_required_fields(self) -> None: """ response = self.delete_user(self.tenant_x) response_data = response.json() - print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, ["Email or username needed"]) @@ -168,11 +165,9 @@ def test_update_username_in_tenant_success(self, query_param: str) -> None: new_username = f"new-username-{query_param}" response = self.update_username(self.tenant_x, {query_param: data[query_param]}, {"new_username": new_username}) - print(f"\n\nResponse text: {response.text}\n\n") response_data = response.json() get_response = self.get_user(self.tenant_x, {"username": new_username}) get_response_data = get_response.json() - print(f"\n\nGet response data: {get_response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response_data["username"], new_username) @@ -196,7 +191,6 @@ def test_update_username_in_tenant_not_found(self) -> None: {"new_username": "new-username"}, ) response_data = response.json() - print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual( @@ -214,7 +208,6 @@ def test_update_username_in_tenant_missing_params(self) -> None: """ response = self.update_username(self.tenant_x) response_data = response.json() - print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, ["Email or username needed"]) @@ -232,7 +225,6 @@ def test_update_username_in_tenant_missing_body(self) -> None: response = self.update_username(self.tenant_x, params={"username": data["username"]}) response_data = response.json() - print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response_data, {"new_username": ["This field is required."]}) @@ -275,7 +267,6 @@ def test_create_oauth_application_in_tenant_success(self, create_user: bool) -> response = self.create_oauth_application(self.tenant_x, data) response_data = response.json() - print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response_data["user"], {"email": user_data["email"], "username": user_data["username"]}) @@ -295,7 +286,6 @@ def test_create_oauth_application_in_tenant_missing_required_fields(self) -> Non """ response = self.create_oauth_application(self.tenant_x) response_data = response.json() - print(f"\n\nResponse data: {response_data}\n\n") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual( From 0d526396eb42bb0ac5188f08a1772eca91f43aa2 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 7 Nov 2024 08:58:52 -0500 Subject: [PATCH 25/34] docs: improve test docstring --- eox_core/api/support/v1/tests/integration/test_views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index c3f2ba212..80469b789 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -237,7 +237,10 @@ class TestOauthApplicationAPIIntegration(SupportAPIRequestMixin, BaseIntegration @ddt.data(True, False) def test_create_oauth_application_in_tenant_success(self, create_user: bool) -> None: """ - Test create an oauth application in a tenant. The user is created if it does not exist. + Test create an oauth application in a tenant. + + If the user exists, it will be used to create the oauth application. + If the user does not exist, it will be created and used to create the oauth application. Open edX definitions tested: - `get_edxapp_user` From 978532bdace859f0658ee4afc25d3934085ef0ec Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 7 Nov 2024 09:48:10 -0500 Subject: [PATCH 26/34] test: add tests for delete and update user of another tenant --- .../v1/tests/integration/test_views.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index 80469b789..7620f12d9 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -130,6 +130,30 @@ def test_delete_user_in_tenant_not_found(self, query_param: str, value: str) -> f"No user found by {{'{query_param}': '{value}'}} on site {self.tenant_x['domain']}.", ) + @ddt.data("username", "email") + def test_delete_user_of_another_tenant(self, query_param: str) -> None: + """ + Test delete an edxapp user of another tenant. + + Open edX definitions tested: + - `get_edxapp_user` + + Expected result: + - The status code is 404. + - The response indicates the user was not found in the tenant. + """ + data = next(FAKE_USER_DATA) + self.create_user(self.tenant_x, data) + + response = self.delete_user(self.tenant_y, {query_param: data[query_param]}) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual( + response_data["detail"], + f"No user found by {{'{query_param}': '{data[query_param]}'}} on site {self.tenant_y['domain']}.", + ) + def test_delete_user_missing_required_fields(self) -> None: """ Test delete an edxapp user in a tenant without providing the username or email. @@ -198,6 +222,35 @@ def test_update_username_in_tenant_not_found(self) -> None: f"No user found by {{'username': 'user-not-found'}} on site {self.tenant_x['domain']}.", ) + @ddt.data("username", "email") + def test_update_user_username_of_another_tenant(self, query_param: str) -> None: + """ + Test update an edxapp user's username of another tenant. + + Open edX definitions tested: + - `get_edxapp_user` + + Expected result: + - The status code is 404. + - The response indicates the user was not found in the tenant. + """ + data = next(FAKE_USER_DATA) + self.create_user(self.tenant_x, data) + new_username = f"new-username-{query_param}" + + response = self.update_username( + self.tenant_y, + {query_param: data[query_param]}, + {"new_username": new_username}, + ) + response_data = response.json() + + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual( + response_data["detail"], + f"No user found by {{'{query_param}': '{data[query_param]}'}} on site {self.tenant_y['domain']}.", + ) + def test_update_username_in_tenant_missing_params(self) -> None: """ Test update an edxapp user's username in a tenant without providing the username. From b3f8ea64316ab8c9c6fef521f7fbe8299858e4c7 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 7 Nov 2024 10:12:59 -0500 Subject: [PATCH 27/34] chore: remove ignore flag for api tests --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 144c4f256..922ab2dc9 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ python-quality-test: run-tests: python-test python-quality-test run-integration-tests: install-dev-dependencies - pytest -rPf ./eox_core --ignore-glob='**/unit/*' --ignore-glob='**/edxapp_wrapper/*' --ignore-glob='**/api/v1/*' + pytest -rPf ./eox_core --ignore-glob='**/unit/*' --ignore-glob='**/edxapp_wrapper/*' upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade upgrade: ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in From 4ef5d8e8a12c816cf4c038fc935a263096678a4e Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Thu, 7 Nov 2024 11:11:43 -0500 Subject: [PATCH 28/34] ci: add tutor extra commands shell file --- .github/workflows/integration-test.yml | 1 + scripts/execute_tutor_extra_commands.sh | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 scripts/execute_tutor_extra_commands.sh diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index b946ee667..6d1104d90 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -19,3 +19,4 @@ jobs: shell_file_to_run: 'scripts/execute_integration_tests.sh' fixtures_file: 'fixtures/initial_data.json' openedx_imports_test_file_path: 'eox_core/edxapp_wrapper/tests/integration/test_backends.py' + tutor_extra_commands_path: 'scripts/execute_tutor_extra_commands.sh' diff --git a/scripts/execute_tutor_extra_commands.sh b/scripts/execute_tutor_extra_commands.sh new file mode 100644 index 000000000..714eb8d09 --- /dev/null +++ b/scripts/execute_tutor_extra_commands.sh @@ -0,0 +1,2 @@ +# Populate the retirement states +tutor local exec lms python manage.py lms populate_retirement_states From c29dc783a40dd8465db796af3be41d352a66938f Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Tue, 12 Nov 2024 09:58:04 -0500 Subject: [PATCH 29/34] chore: use new user backend --- .../edxapp_wrapper/backends/{users_m_v1.py => users_r_v1.py} | 4 ++-- .../backends/{users_m_v1_test.py => users_r_v1_test.py} | 2 +- eox_core/edxapp_wrapper/tests/integration/test_backends.py | 1 + eox_core/settings/common.py | 2 +- eox_core/settings/test.py | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) rename eox_core/edxapp_wrapper/backends/{users_m_v1.py => users_r_v1.py} (98%) rename eox_core/edxapp_wrapper/backends/{users_m_v1_test.py => users_r_v1_test.py} (98%) diff --git a/eox_core/edxapp_wrapper/backends/users_m_v1.py b/eox_core/edxapp_wrapper/backends/users_r_v1.py similarity index 98% rename from eox_core/edxapp_wrapper/backends/users_m_v1.py rename to eox_core/edxapp_wrapper/backends/users_r_v1.py index 53c819c5e..51aa5362c 100644 --- a/eox_core/edxapp_wrapper/backends/users_m_v1.py +++ b/eox_core/edxapp_wrapper/backends/users_r_v1.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -Backend for the create_edxapp_user that works under the open-release/lilac.master tag +Redwood backend for users module """ import logging @@ -311,7 +311,7 @@ def delete_edxapp_user(*args, **kwargs): msg = f"{user_response} has been removed" else: for signup_source in signup_sources: - if signup_source.site.upper() == site.name.upper(): + if signup_source.site.upper() == site.domain.upper(): signup_source.delete() msg = f"{user_response} has more than one signup source. The signup source from the site {site} has been deleted" diff --git a/eox_core/edxapp_wrapper/backends/users_m_v1_test.py b/eox_core/edxapp_wrapper/backends/users_r_v1_test.py similarity index 98% rename from eox_core/edxapp_wrapper/backends/users_m_v1_test.py rename to eox_core/edxapp_wrapper/backends/users_r_v1_test.py index 7cc7e7e49..9d4a22407 100644 --- a/eox_core/edxapp_wrapper/backends/users_m_v1_test.py +++ b/eox_core/edxapp_wrapper/backends/users_r_v1_test.py @@ -1,5 +1,5 @@ """ -Test backend to get CourseEnrollment Model. +Redwood test backend for users module """ from unittest.mock import Mock diff --git a/eox_core/edxapp_wrapper/tests/integration/test_backends.py b/eox_core/edxapp_wrapper/tests/integration/test_backends.py index 73c1b10fe..68a2f5c53 100644 --- a/eox_core/edxapp_wrapper/tests/integration/test_backends.py +++ b/eox_core/edxapp_wrapper/tests/integration/test_backends.py @@ -19,3 +19,4 @@ def test_current_settings_code_imports(): import eox_core.edxapp_wrapper.backends.pre_enrollment_l_v1 import eox_core.edxapp_wrapper.backends.storages_i_v1 import eox_core.edxapp_wrapper.backends.third_party_auth_l_v1 + import eox_core.edxapp_wrapper.backends.users_r_v1 diff --git a/eox_core/settings/common.py b/eox_core/settings/common.py index 7148422df..f6855d5f5 100644 --- a/eox_core/settings/common.py +++ b/eox_core/settings/common.py @@ -25,7 +25,7 @@ def plugin_settings(settings): See: https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst """ settings.EOX_CORE_COMMENTS_SERVICE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.comments_service_users_j_v1" - settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_m_v1" + settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_r_v1" settings.EOX_CORE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.enrollment_o_v1" settings.EOX_CORE_PRE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.pre_enrollment_l_v1" settings.EOX_CORE_CERTIFICATES_BACKEND = "eox_core.edxapp_wrapper.backends.certificates_m_v1" diff --git a/eox_core/settings/test.py b/eox_core/settings/test.py index 02387b9bd..f718f3bec 100644 --- a/eox_core/settings/test.py +++ b/eox_core/settings/test.py @@ -21,7 +21,7 @@ def plugin_settings(settings): # pylint: disable=function-redefined Defines eox-core settings when app is used as a plugin to edx-platform. See: https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst """ - settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_m_v1_test" + settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_r_v1_test" settings.EOX_CORE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.enrollment_l_v1" settings.EOX_CORE_PRE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.pre_enrollment_l_v1" settings.EOX_CORE_COURSEKEY_BACKEND = "eox_core.edxapp_wrapper.backends.coursekey_m_v1" From d69c50e10ed1b24c4430dd6a92b2f12c5ce2a21a Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Tue, 12 Nov 2024 13:54:42 -0500 Subject: [PATCH 30/34] test: check if the user exists in the corresponding tenant --- eox_core/api/support/v1/tests/integration/test_views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eox_core/api/support/v1/tests/integration/test_views.py b/eox_core/api/support/v1/tests/integration/test_views.py index 7620f12d9..14484cc25 100644 --- a/eox_core/api/support/v1/tests/integration/test_views.py +++ b/eox_core/api/support/v1/tests/integration/test_views.py @@ -147,12 +147,14 @@ def test_delete_user_of_another_tenant(self, query_param: str) -> None: response = self.delete_user(self.tenant_y, {query_param: data[query_param]}) response_data = response.json() + get_response = self.get_user(self.tenant_x, {"username": data["username"]}) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertEqual( response_data["detail"], f"No user found by {{'{query_param}': '{data[query_param]}'}} on site {self.tenant_y['domain']}.", ) + self.assertEqual(get_response.status_code, status.HTTP_200_OK) def test_delete_user_missing_required_fields(self) -> None: """ From 1a7b19d5730ff39bda75bde4058315dd0d7dbcea Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Tue, 12 Nov 2024 14:31:58 -0500 Subject: [PATCH 31/34] ci: use bav/add-custom-plugins-step branch in integration tests workflow --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 6d1104d90..32e598f05 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,7 +10,7 @@ jobs: tutor_version: ['<18.0.0', '<19.0.0'] steps: - name: Run Integration Tests - uses: eduNEXT/integration-test-in-tutor@bav/add-plugins-step + uses: eduNEXT/integration-test-in-tutor@bav/add-custom-plugins-step with: tutor_version: ${{ matrix.tutor_version }} tutor_plugins: 'forum' From 359f0389d1ef0fc8a5b6aac948103fa75a0aa98a Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Tue, 12 Nov 2024 14:52:58 -0500 Subject: [PATCH 32/34] ci: use main branch in integration tests workflow --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 32e598f05..e081ddfd9 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -10,7 +10,7 @@ jobs: tutor_version: ['<18.0.0', '<19.0.0'] steps: - name: Run Integration Tests - uses: eduNEXT/integration-test-in-tutor@bav/add-custom-plugins-step + uses: eduNEXT/integration-test-in-tutor@main with: tutor_version: ${{ matrix.tutor_version }} tutor_plugins: 'forum' From be370e2081236adfe620eda488a7bfd0e3477ba2 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Tue, 12 Nov 2024 17:04:49 -0500 Subject: [PATCH 33/34] chore: use new user backend --- .../edxapp_wrapper/backends/{users_r_v1.py => users_q_v1.py} | 2 +- .../backends/{users_r_v1_test.py => users_q_v1_test.py} | 2 +- eox_core/edxapp_wrapper/tests/integration/test_backends.py | 2 +- eox_core/settings/common.py | 2 +- eox_core/settings/test.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename eox_core/edxapp_wrapper/backends/{users_r_v1.py => users_q_v1.py} (99%) rename eox_core/edxapp_wrapper/backends/{users_r_v1_test.py => users_q_v1_test.py} (98%) diff --git a/eox_core/edxapp_wrapper/backends/users_r_v1.py b/eox_core/edxapp_wrapper/backends/users_q_v1.py similarity index 99% rename from eox_core/edxapp_wrapper/backends/users_r_v1.py rename to eox_core/edxapp_wrapper/backends/users_q_v1.py index 51aa5362c..f0dd74e0d 100644 --- a/eox_core/edxapp_wrapper/backends/users_r_v1.py +++ b/eox_core/edxapp_wrapper/backends/users_q_v1.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -Redwood backend for users module +Quince backend for users module """ import logging diff --git a/eox_core/edxapp_wrapper/backends/users_r_v1_test.py b/eox_core/edxapp_wrapper/backends/users_q_v1_test.py similarity index 98% rename from eox_core/edxapp_wrapper/backends/users_r_v1_test.py rename to eox_core/edxapp_wrapper/backends/users_q_v1_test.py index 9d4a22407..a1b921222 100644 --- a/eox_core/edxapp_wrapper/backends/users_r_v1_test.py +++ b/eox_core/edxapp_wrapper/backends/users_q_v1_test.py @@ -1,5 +1,5 @@ """ -Redwood test backend for users module +Quince test backend for users module """ from unittest.mock import Mock diff --git a/eox_core/edxapp_wrapper/tests/integration/test_backends.py b/eox_core/edxapp_wrapper/tests/integration/test_backends.py index 68a2f5c53..163cdcc45 100644 --- a/eox_core/edxapp_wrapper/tests/integration/test_backends.py +++ b/eox_core/edxapp_wrapper/tests/integration/test_backends.py @@ -19,4 +19,4 @@ def test_current_settings_code_imports(): import eox_core.edxapp_wrapper.backends.pre_enrollment_l_v1 import eox_core.edxapp_wrapper.backends.storages_i_v1 import eox_core.edxapp_wrapper.backends.third_party_auth_l_v1 - import eox_core.edxapp_wrapper.backends.users_r_v1 + import eox_core.edxapp_wrapper.backends.users_q_v1 diff --git a/eox_core/settings/common.py b/eox_core/settings/common.py index f6855d5f5..f4f1804ea 100644 --- a/eox_core/settings/common.py +++ b/eox_core/settings/common.py @@ -25,7 +25,7 @@ def plugin_settings(settings): See: https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst """ settings.EOX_CORE_COMMENTS_SERVICE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.comments_service_users_j_v1" - settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_r_v1" + settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_q_v1" settings.EOX_CORE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.enrollment_o_v1" settings.EOX_CORE_PRE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.pre_enrollment_l_v1" settings.EOX_CORE_CERTIFICATES_BACKEND = "eox_core.edxapp_wrapper.backends.certificates_m_v1" diff --git a/eox_core/settings/test.py b/eox_core/settings/test.py index f718f3bec..84b45af98 100644 --- a/eox_core/settings/test.py +++ b/eox_core/settings/test.py @@ -21,7 +21,7 @@ def plugin_settings(settings): # pylint: disable=function-redefined Defines eox-core settings when app is used as a plugin to edx-platform. See: https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst """ - settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_r_v1_test" + settings.EOX_CORE_USERS_BACKEND = "eox_core.edxapp_wrapper.backends.users_q_v1_test" settings.EOX_CORE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.enrollment_l_v1" settings.EOX_CORE_PRE_ENROLLMENT_BACKEND = "eox_core.edxapp_wrapper.backends.pre_enrollment_l_v1" settings.EOX_CORE_COURSEKEY_BACKEND = "eox_core.edxapp_wrapper.backends.coursekey_m_v1" From 586f62cc630f173613c294c94c5dd5f542a8af79 Mon Sep 17 00:00:00 2001 From: Bryann Valderrama Date: Tue, 12 Nov 2024 17:19:24 -0500 Subject: [PATCH 34/34] ci: add nightly version in integration tests workflow --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index e081ddfd9..6ccec0270 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - tutor_version: ['<18.0.0', '<19.0.0'] + tutor_version: ['<18.0.0', '<19.0.0', "nightly"] steps: - name: Run Integration Tests uses: eduNEXT/integration-test-in-tutor@main