From 7816830f216d3b053ce180ef268d1d629aacdeda Mon Sep 17 00:00:00 2001 From: milemik Date: Mon, 28 Jul 2025 21:23:44 +0200 Subject: [PATCH 1/2] Fixed django.yml workflow --- .github/workflows/django.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index 70fe020..052cba1 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -30,5 +30,4 @@ jobs: - name: Run Tests run: | echo "Running tests in example! For now!" - cd example pytest From a7e69b772a8c8890276dc611504ba4fcb007a878 Mon Sep 17 00:00:00 2001 From: milemik Date: Mon, 28 Jul 2025 21:51:30 +0200 Subject: [PATCH 2/2] Fixed tests --- pyproject.toml | 6 +++++- tests/models.py | 38 ++++++++++++++++++++++++++++++++++++++ tests/settings.py | 8 ++++---- tests/test_api.py | 19 ++++++++++++------- 4 files changed, 59 insertions(+), 12 deletions(-) create mode 100644 tests/models.py diff --git a/pyproject.toml b/pyproject.toml index 3af9dc6..2652792 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,4 +5,8 @@ build-backend = 'setuptools.build_meta' [tool.pytest.ini_options] DJANGO_SETTINGS_MODULE = "tests.settings" -python_files = ["tests.py", "test_*.py", "*_tests.py"] \ No newline at end of file +python_files = ["tests.py", "test_*.py", "*_tests.py"] +django_find_project = false +pythonpath = "." +testpaths = "tests" +norecursedirs = ["example", "build", "dist", "*.egg"] \ No newline at end of file diff --git a/tests/models.py b/tests/models.py new file mode 100644 index 0000000..5a4c089 --- /dev/null +++ b/tests/models.py @@ -0,0 +1,38 @@ +import uuid + +from django.contrib.auth.base_user import BaseUserManager +from django.contrib.auth.models import AbstractUser +from django.db import models + + +class EmailUserManager(BaseUserManager): + """ + Custom user manager for email-based authentication + """ + + def create_user(self, email, password=None, **extra_fields): + if not email: + raise ValueError("The Email field must be set") + email = self.normalize_email(email) + user = self.model(email=email, **extra_fields) + user.set_password(password) + user.save(using=self._db) + return user + + +class EmailUser(AbstractUser): + """ + Custom user model that uses email as the username field + """ + + username = None # Remove username field + email = models.EmailField(unique=True) + secret = models.CharField(max_length=256, default=uuid.uuid4) + + USERNAME_FIELD = "email" + REQUIRED_FIELDS = [] # Remove email from required fields since it's the username + + objects = EmailUserManager() + + class Meta: + app_label = "tests" diff --git a/tests/settings.py b/tests/settings.py index b9f8aa3..c9e1ad3 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -19,8 +19,8 @@ "django.contrib.sessions", "django.contrib.messages", "rest_framework", + "tests", "django_drf_jwt", # Your package - "myuser", ] MIDDLEWARE = [ @@ -52,10 +52,10 @@ REST_FRAMEWORK = {"DEFAULT_AUTHENTICATION_CLASSES": ("django_drf_jwt.authentication.JWTAuthentication",)} -AUTH_USER_MODEL = "myuser.MyUser" - # JWT DATA JWT_DRF = { # JWT_USER_SECRET_FIELD - MUST BE DEFINED - This must be filed in User object - "JWT_USER_SECRET_FIELD": "secret", + "JWT_USER_SECRET_FIELD": "secret", # for testing purposes we can use last_name as secret field } + +AUTH_USER_MODEL = "tests.EmailUser" diff --git a/tests/test_api.py b/tests/test_api.py index 314613c..79fc771 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,19 +1,23 @@ import pytest +from django.contrib.auth import get_user_model from django.urls import reverse from rest_framework.test import APIClient -from myuser.models import MyUser + +User = get_user_model() @pytest.fixture def create_user(): email = "testuser@test.com" password = "somepassword123" - user = MyUser.objects.create_user(email=email) + user = User.objects.create_user(email=email) + user.USERNAME_FIELD = "email" user.set_password(password) user.save() - return email, password + user.secret = "somesecret" + return email, password, user GET_TOKEN_URL = reverse("get_token") @@ -40,7 +44,7 @@ def test_get_token_bad_credentials(request_data, expected_errors): @pytest.mark.django_db def test_get_token(create_user): - email, password = create_user + email, password, *_ = create_user client = APIClient() response = client.post(GET_TOKEN_URL, {"email": email, "password": password}) assert response.status_code == 201 @@ -50,12 +54,13 @@ def test_get_token(create_user): @pytest.mark.django_db def test_revoke_token(create_user): - email, password = create_user + email, password, user = create_user + old_secret = user.secret client = APIClient() response = client.post(GET_TOKEN_URL, {"email": email, "password": password}) token = response.json().get("token") client.credentials(HTTP_AUTHORIZATION="JWT " + token) response = client.post(reverse("revoke_token"), {}) assert response.status_code == 201 - user = MyUser.objects.get(email=email) - assert user.secret != token, "Expect secret to be changed after revoking token" + user = User.objects.get(email=email) + assert user.secret != old_secret, "Expect secret to be changed after revoking token"