Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add TestPathRedirectionMiddleware integration tests AP-1547 #298

Merged
merged 10 commits into from
Nov 18, 2024
7 changes: 4 additions & 3 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
tutor_version: ['<18.0.0', '<19.0.0', "nightly"]
tutor_version: ['<18.0.0', '<19.0.0', 'nightly']
steps:
- name: Run Integration Tests
uses: eduNEXT/integration-test-in-tutor@main
with:
tutor_version: ${{ matrix.tutor_version }}
tutor_plugins: 'forum'
inline_tutor_plugins_folder: 'integration_tests/tutor_plugins'
app_name: 'eox-core'
openedx_extra_pip_requirements: 'eox-tenant'
shell_file_to_run: 'scripts/execute_integration_tests.sh'
shell_file_to_run: 'integration_tests/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'
tutor_extra_commands_path: 'integration_tests/scripts/execute_tutor_extra_commands.sh'
4 changes: 3 additions & 1 deletion eox_core/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,7 @@ def plugin_settings(settings): # pylint: disable=function-redefined
"API_TIMEOUT": 5,
"CLIENT_ID": "client_id",
"CLIENT_SECRET": "client_secret",
"DEMO_COURSE_ID": os.environ.get("DEMO_COURSE_ID", "course-v1:OpenedX+DemoX+DemoCourse")
"DEMO_COURSE_ID": os.environ.get("DEMO_COURSE_ID", "course-v1:OpenedX+DemoX+DemoCourse"),
"SESSION_USER_USERNAME": "admin-eox-core",
"SESSION_USER_PASSWORD": "admin",
}
262 changes: 262 additions & 0 deletions eox_core/tests/integration/test_middleware.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
"""Test Middlewares for the EOX Core."""

import ddt
import requests
from django.conf import settings as ds
from rest_framework import status

from eox_core.tests.integration.utils import BaseIntegrationTest

settings = ds.INTEGRATION_TEST_SETTINGS


@ddt.ddt
class TestPathRedirectionMiddleware(BaseIntegrationTest):
mariajgrimaldi marked this conversation as resolved.
Show resolved Hide resolved
"""Integration tests for the PathRedirectionMiddleware."""

def __init__(self, *args, **kwargs):
"""Initialize the class attributes."""
super().__init__(*args, **kwargs)
self.tenant_x_url = self.tenant_x.get("base_url")

def get_session(self) -> requests.Session:
"""
Start and returns a session to authenticate with the Open edX platform.

Returns:
requests.Session: The session object.
"""
session = requests.Session()
session.get(self.tenant_x_url)
csrf_token = session.cookies.get("csrftoken")

login_url = f"{self.tenant_x_url}/api/user/v2/account/login_session/"
login_data = {
"email_or_username": settings["SESSION_USER_USERNAME"],
"password": settings["SESSION_USER_PASSWORD"],
}
headers = {
"X-CSRFToken": csrf_token,
"Referer": self.tenant_x_url,
}

session.post(login_url, data=login_data, headers=headers)

return session

def get_request(self, url: str, with_session: bool) -> requests.Response:
"""
Make a GET request to the given URL.

Args:
url (str): The URL to make the request to.
with_session (bool): Whether to use the session or not.

Returns:
requests.Response: The response object.
"""
request_method = self.get_session().get if with_session else requests.get
return request_method(url, timeout=settings["API_TIMEOUT"])

@ddt.data(False, True)
def test_without_redirect(self, with_session: bool) -> None:
"""
Test the PathRedirectionMiddleware without any redirection.

The `/about` path is not defined in the configuration.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The status code is 200.
- The URL is the same as the requested URL.
"""
response = self.get_request(f"{self.tenant_x_url}/about", with_session)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.url, f"{self.tenant_x_url}/about")

@ddt.data(False, True)
def test_redirect_always(self, with_session: bool) -> None:
"""
Test the `redirect_always` feature.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The history contains a 302 status code.
- The status code is 200.
- The URL is the configured redirect URL.
"""
response = self.get_request(f"{self.tenant_x_url}/blog", with_session)

self.assertEqual(response.history[0].status_code, status.HTTP_302_FOUND)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.url, f"{self.tenant_x_url}/donate")

@ddt.data(False, True)
def test_login_required(self, with_session: bool) -> None:
"""
Test the `login_required` feature.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The status code is 200.
- If the user is not logged in, the URL is the login page.
- If the user is logged in, the URL is the requested URL.
"""
final_path = "tos" if with_session else "login?next=/tos"

response = self.get_request(f"{self.tenant_x_url}/tos", with_session)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.url, f"{self.tenant_x_url}/{final_path}")

@ddt.data(False, True)
def test_not_found(self, with_session: bool) -> None:
"""
Test the `not_found` feature.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The status code is 404.
- The URL is the same as the requested URL.
"""
response = self.get_request(f"{self.tenant_x_url}/privacy", with_session)

self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(response.url, f"{self.tenant_x_url}/privacy")

@ddt.data(False, True)
def test_not_found_loggedin(self, with_session: bool) -> None:
"""
Test the `not_found_loggedin` feature.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- If the user is logged in, the status code is 404.
- If the user is not logged in, the status code is 200.
"""
status_code = status.HTTP_404_NOT_FOUND if with_session else status.HTTP_200_OK

response = self.get_request(f"{self.tenant_x_url}/help", with_session)

self.assertEqual(response.status_code, status_code)
self.assertEqual(response.url, f"{self.tenant_x_url}/help")

@ddt.data(False, True)
def test_not_found_loggedout(self, with_session: bool) -> None:
"""
Test the `not_found_loggedout` feature.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- If the user is not logged in, the status code is 404.
- If the user is logged in, the status code is 200.
"""
status_code = status.HTTP_200_OK if with_session else status.HTTP_404_NOT_FOUND

response = self.get_request(f"{self.tenant_x_url}/contact", with_session)

self.assertEqual(response.status_code, status_code)
self.assertEqual(response.url, f"{self.tenant_x_url}/contact")

@ddt.data(False, True)
def test_redirect_loggedin(self, with_session: bool) -> None:
"""
Test the `redirect_loggedin` feature.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The status code is 200.
- If the user is logged in, redirect to the configured URL.
- If the user is not logged in, the URL is the requested URL.
"""
final_path = "donate" if with_session else "courses"

response = self.get_request(f"{self.tenant_x_url}/courses", with_session)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.url, f"{self.tenant_x_url}/{final_path}")
if with_session:
self.assertEqual(response.history[0].status_code, status.HTTP_302_FOUND)

@ddt.data(False, True)
def test_redirect_loggedout(self, with_session: bool) -> None:
"""
Test the `redirect_loggedout` feature.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The status code is 200.
- If the user is not logged in, redirect to the configured URL.
- If the user is logged in, the URL is the requested URL.
"""
final_path = "faq" if with_session else "donate"

response = self.get_request(f"{self.tenant_x_url}/faq", with_session)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.url, f"{self.tenant_x_url}/{final_path}")
if not with_session:
self.assertEqual(response.history[0].status_code, status.HTTP_302_FOUND)

@ddt.data(False, True)
def test_mktg_redirect_with_empty_string(self, with_session: bool) -> None:
"""
Test the `mktg_redirect` feature with an empty string.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The status code is 200.
- The URL is the same as the requested URL.
"""
response = self.get_request(f"{self.tenant_x_url}/about", with_session)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.url, f"{self.tenant_x_url}/about")

@ddt.data(False, True)
def test_mktg_redirect_with_other_url(self, with_session: bool) -> None:
"""
Test the `mktg_redirect` feature with a different URL.

Open edX definitions tested:
- `configuration_helper.has_override_value`
- `configuration_helper.get_value`

Expected result:
- The history contains a 302 status code.
- The status code is 200.
- The URL is the configured redirect URL.
"""
response = self.get_request(f"{self.tenant_x_url}/dashboard", with_session)

self.assertEqual(response.history[0].status_code, status.HTTP_302_FOUND)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.url, "https://www.example.com/")
5 changes: 3 additions & 2 deletions eox_core/tests/integration/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,11 @@ class BaseIntegrationTest(TestCase):
Base class for the integration test suite.
"""

def setUp(self):
def __init__(self, *args, **kwargs):
mariajgrimaldi marked this conversation as resolved.
Show resolved Hide resolved
"""
Set up the test suite.
Initialize the class attributes.
"""
super().__init__(*args, **kwargs)
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")
Expand Down
42 changes: 42 additions & 0 deletions fixtures/initial_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,25 @@
"fields": {
"external_key": "tenant-x-key",
"lms_configs": {
"MKTG_REDIRECTS": {
"about.html": "",
"dashboard.html": "https://www.example.com/"
},
"EDNX_CUSTOM_PATH_REDIRECTS": {
"/blog": {
"redirect_always": "/donate"
},
"/contact": "not_found_loggedout",
"/courses": {
"redirect_loggedin": "/donate"
},
"/faq": {
"redirect_loggedout": "/donate"
},
"/help": "not_found_loggedin",
"/privacy": "not_found",
"/tos": "login_required"
},
"EDNX_USE_SIGNAL": true,
"PLATFORM_NAME": "Tenant X",
"SITE_NAME": "tenant-x.local.edly.io",
Expand Down Expand Up @@ -147,6 +166,29 @@
"user_permissions": []
}
},
{
"model": "student.userprofile",
"pk": 3,
"fields": {
"user": 4,
"name": "Admin Eox Core",
"meta": "",
"courseware": "course.xml",
"language": "",
"location": "",
"year_of_birth": null,
"gender": null,
"level_of_education": null,
"mailing_address": "",
"city": "",
"country": null,
"state": null,
"goals": "",
"bio": null,
"profile_image_uploaded_at": null,
"phone_number": null
}
},
{
"model": "oauth2_provider.application",
"pk": 4,
Expand Down
7 changes: 7 additions & 0 deletions integration_tests/tutor_plugins/middleware-settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name: middleware-settings
version: 1.0.0
patches:
openedx-common-settings: |
MIDDLEWARE += [
"eox_core.middleware.PathRedirectionMiddleware",
]
Loading