-
-
Notifications
You must be signed in to change notification settings - Fork 694
PoC for E2E tests for protected routes authentication and mentorship tests #5454
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
Open
Mr-Rahul-Paul
wants to merge
20
commits into
OWASP:main
Choose a base branch
from
Mr-Rahul-Paul:e2eTests
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
b4fcaeb
add seed users and test redirection for missing session_id
Mr-Rahul-Paul e9e4f38
add e2e page login so protected mentorship UI can load
Mr-Rahul-Paul 0081d28
add tests
Mr-Rahul-Paul 5e405e4
change comment
Mr-Rahul-Paul 4bd6a49
make check test err
Mr-Rahul-Paul 21fcd50
fix e2e tests
Mr-Rahul-Paul 605eab2
fix e2e tests
Mr-Rahul-Paul fdcec7e
fix import
Mr-Rahul-Paul 514e0ec
fix test suite
Mr-Rahul-Paul 343b890
fix test suite
Mr-Rahul-Paul e008605
add new test
Mr-Rahul-Paul e349b49
fix e2e protected test suite
Mr-Rahul-Paul dbff05e
drop misleading csrf comment on e2e login
Mr-Rahul-Paul 6083289
fix code quality
Mr-Rahul-Paul 54d07b3
address bot issues
Mr-Rahul-Paul 79e357a
address docker issue reported by bot
Mr-Rahul-Paul a102d68
address review
Mr-Rahul-Paul c5b9b31
small error fix
Mr-Rahul-Paul 6752f36
inject authtoken in playwright
Mr-Rahul-Paul 69121bf
address bot ewview
Mr-Rahul-Paul File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """E2E app package.""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| """E2E app config.""" | ||
|
|
||
| from django.apps import AppConfig | ||
|
|
||
|
|
||
| class E2EConfig(AppConfig): | ||
| """E2E app config.""" | ||
|
|
||
| default_auto_field = "django.db.models.BigAutoField" | ||
| name = "apps.e2e" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Management package.""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Management commands package.""" |
83 changes: 83 additions & 0 deletions
83
backend/src/apps/e2e/management/commands/e2e_seed_users.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| """Seed deterministic users for end-to-end tests.""" | ||
|
|
||
| from django.conf import settings | ||
| from django.contrib.contenttypes.models import ContentType | ||
| from django.core.management.base import BaseCommand, CommandError | ||
| from django.utils import timezone | ||
|
|
||
| from apps.core.utils import index | ||
| from apps.github.models.user import User as GithubUser | ||
| from apps.mentorship.models import Mentee, Mentor | ||
| from apps.nest.models import User as NestUser | ||
| from apps.owasp.models.entity_member import EntityMember | ||
| from apps.owasp.models.project import Project | ||
|
|
||
| E2E_USERS = ( | ||
| ("e2e-mentee", "mentee"), | ||
| ("e2e-mentor", "mentor"), | ||
| ("e2e-user", ""), | ||
| ) | ||
|
|
||
|
|
||
| class Command(BaseCommand): | ||
| help = "Seed e2e test users." | ||
|
|
||
| def handle(self, *_args, **_options) -> None: | ||
| """Create GitHub, Nest, and mentorship users for e2e tests.""" | ||
| if not settings.IS_E2E_ENVIRONMENT: | ||
| error_message = "This command can only run in the e2e environment." | ||
| raise CommandError(error_message) | ||
|
|
||
| now = timezone.now() | ||
| with index.disable_indexing(): | ||
| for login, role in E2E_USERS: | ||
| github_user, _ = GithubUser.objects.get_or_create( | ||
| login=login, | ||
| defaults={ | ||
| "created_at": now, | ||
| "email": f"{login}@example.com", | ||
| "name": login, | ||
| "node_id": f"e2e_node_{login}", | ||
| "updated_at": now, | ||
| }, | ||
| ) | ||
| nest_user, _ = NestUser.objects.get_or_create( | ||
| username=login, | ||
| defaults={ | ||
| "email": f"{login}@example.com", | ||
| "github_user": github_user, | ||
| }, | ||
| ) | ||
| if nest_user.github_user_id != github_user.id: | ||
| nest_user.github_user = github_user | ||
| nest_user.save(update_fields=["github_user"]) | ||
| if role == "mentor": | ||
| Mentor.objects.get_or_create( | ||
| github_user=github_user, | ||
| defaults={"nest_user": nest_user}, | ||
| ) | ||
| elif role == "mentee": | ||
| Mentee.objects.get_or_create( | ||
| github_user=github_user, | ||
| defaults={"nest_user": nest_user}, | ||
| ) | ||
| elif login == "e2e-user": | ||
| project, _ = Project.objects.get_or_create( | ||
| key="www-project-e2e", | ||
| defaults={"name": "E2E Project"}, | ||
| ) | ||
| membership, _ = EntityMember.objects.get_or_create( | ||
| entity_id=project.id, | ||
| entity_type=ContentType.objects.get_for_model(Project), | ||
| member_name=login, | ||
| role=EntityMember.Role.LEADER, | ||
| defaults={ | ||
| "is_active": True, | ||
| "is_reviewed": True, | ||
| "member": github_user, | ||
| }, | ||
| ) | ||
| membership.is_active = True | ||
| membership.is_reviewed = True | ||
| membership.member = github_user | ||
| membership.save(update_fields=["is_active", "is_reviewed", "member"]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| """E2E app URL configuration.""" | ||
|
|
||
| from django.urls import path | ||
|
|
||
| from apps.e2e.views import e2e_login | ||
|
|
||
| app_name = "e2e" | ||
|
|
||
| urlpatterns = [ | ||
| path("login/", e2e_login, name="login"), | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| """E2E-only views.""" | ||
|
|
||
| import json | ||
|
|
||
| from django.conf import settings | ||
| from django.contrib.auth import login | ||
| from django.http import Http404, HttpRequest, JsonResponse | ||
| from django.views.decorators.csrf import csrf_exempt | ||
| from django.views.decorators.http import require_POST | ||
|
|
||
| from apps.nest.models import User | ||
|
|
||
| E2E_ALLOWED_USERS = frozenset({"e2e-user", "e2e-mentor", "e2e-mentee"}) | ||
|
|
||
|
|
||
| @csrf_exempt # NOSONAR | ||
| @require_POST | ||
| def e2e_login(request: HttpRequest) -> JsonResponse: | ||
| """Log in a seeded e2e user and set the Django session cookie.""" | ||
| if not settings.IS_E2E_ENVIRONMENT: | ||
| raise Http404 | ||
|
|
||
| try: | ||
| payload = json.loads(request.body or b"{}") | ||
| except json.JSONDecodeError: | ||
| return JsonResponse({"message": "Invalid JSON.", "ok": False}, status=400) | ||
|
|
||
| if not isinstance(payload, dict): | ||
| return JsonResponse({"message": "Invalid JSON.", "ok": False}, status=400) | ||
|
|
||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| raw_username = payload.get("username") | ||
| if not isinstance(raw_username, str) or not raw_username.strip(): | ||
| return JsonResponse({"message": "username is required.", "ok": False}, status=400) | ||
|
|
||
| username = raw_username.strip() | ||
| if username not in E2E_ALLOWED_USERS: | ||
| raise Http404 | ||
|
|
||
| try: | ||
| user = User.objects.get(username=username) | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
|
||
| except User.DoesNotExist as exc: | ||
| raise Http404 from exc | ||
|
|
||
| login(request, user) | ||
|
|
||
| return JsonResponse({"ok": True, "username": username}) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Tests for apps.e2e.""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Tests for apps.e2e management.""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Tests for apps.e2e management commands.""" |
93 changes: 93 additions & 0 deletions
93
backend/tests/unit/apps/e2e/management/commands/e2e_seed_users_test.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| from unittest.mock import MagicMock, patch | ||
|
|
||
| import pytest | ||
| from django.core.management import call_command | ||
| from django.core.management.base import CommandError | ||
|
|
||
| from apps.e2e.management.commands.e2e_seed_users import E2E_USERS, Command | ||
|
|
||
|
|
||
| class TestE2ESeedUsersCommand: | ||
| def test_metadata(self): | ||
| assert Command.help == "Seed e2e test users." | ||
| assert E2E_USERS == ( | ||
| ("e2e-mentee", "mentee"), | ||
| ("e2e-mentor", "mentor"), | ||
| ("e2e-user", ""), | ||
| ) | ||
|
|
||
| def test_requires_e2e_environment(self): | ||
| with ( | ||
| patch( | ||
| "apps.e2e.management.commands.e2e_seed_users.settings.IS_E2E_ENVIRONMENT", | ||
| new=False, | ||
| ), | ||
| pytest.raises(CommandError, match="e2e environment"), | ||
| ): | ||
|
Check warning on line 26 in backend/tests/unit/apps/e2e/management/commands/e2e_seed_users_test.py
|
||
| call_command(Command()) | ||
|
|
||
| @patch("apps.e2e.management.commands.e2e_seed_users.index.disable_indexing") | ||
| @patch("apps.e2e.management.commands.e2e_seed_users.ContentType") | ||
| @patch("apps.e2e.management.commands.e2e_seed_users.EntityMember") | ||
| @patch("apps.e2e.management.commands.e2e_seed_users.Project") | ||
| @patch("apps.e2e.management.commands.e2e_seed_users.Mentee") | ||
| @patch("apps.e2e.management.commands.e2e_seed_users.Mentor") | ||
| @patch("apps.e2e.management.commands.e2e_seed_users.NestUser") | ||
| @patch("apps.e2e.management.commands.e2e_seed_users.GithubUser") | ||
| def test_creates_users( | ||
| self, | ||
| mock_github_user, | ||
| mock_nest_user, | ||
| mock_mentor, | ||
| mock_mentee, | ||
| mock_project, | ||
| mock_entity_member, | ||
| mock_content_type, | ||
| mock_disable_indexing, | ||
| ): | ||
| github_user = MagicMock() | ||
| github_user.id = 10 | ||
| nest_user = MagicMock() | ||
| nest_user.github_user_id = 10 | ||
| project = MagicMock(id=1) | ||
| membership = MagicMock() | ||
| mock_github_user.objects.get_or_create.return_value = (github_user, True) | ||
| mock_nest_user.objects.get_or_create.return_value = (nest_user, True) | ||
| mock_project.objects.get_or_create.return_value = (project, True) | ||
| mock_entity_member.objects.get_or_create.return_value = (membership, True) | ||
|
|
||
| with patch( | ||
| "apps.e2e.management.commands.e2e_seed_users.settings.IS_E2E_ENVIRONMENT", | ||
| new=True, | ||
| ): | ||
| call_command(Command()) | ||
|
|
||
| mock_disable_indexing.assert_called_once() | ||
| assert mock_github_user.objects.get_or_create.call_count == 3 | ||
| assert mock_nest_user.objects.get_or_create.call_count == 3 | ||
| mock_mentor.objects.get_or_create.assert_called_once_with( | ||
| github_user=github_user, | ||
| defaults={"nest_user": nest_user}, | ||
| ) | ||
| mock_mentee.objects.get_or_create.assert_called_once_with( | ||
| github_user=github_user, | ||
| defaults={"nest_user": nest_user}, | ||
| ) | ||
| mock_project.objects.get_or_create.assert_called_once_with( | ||
| key="www-project-e2e", | ||
| defaults={"name": "E2E Project"}, | ||
| ) | ||
| mock_entity_member.objects.get_or_create.assert_called_once_with( | ||
| entity_id=project.id, | ||
| entity_type=mock_content_type.objects.get_for_model.return_value, | ||
| member_name="e2e-user", | ||
| role=mock_entity_member.Role.LEADER, | ||
| defaults={ | ||
| "is_active": True, | ||
| "is_reviewed": True, | ||
| "member": github_user, | ||
| }, | ||
| ) | ||
| membership.save.assert_called_once_with( | ||
| update_fields=["is_active", "is_reviewed", "member"] | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| """Tests for apps.e2e views.""" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.