Skip to content

Commit

Permalink
Merge pull request #370 from pinax/django-4.2-and-fix-tests
Browse files Browse the repository at this point in the history
Django 4.2 and fix tests
  • Loading branch information
uhurusurfa authored Sep 6, 2023
2 parents a69832f + a239c8f commit e6a1f0c
Show file tree
Hide file tree
Showing 44 changed files with 235 additions and 151 deletions.
12 changes: 10 additions & 2 deletions .deepsource.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
version = 1

exclude_patterns = [
"makemigrations.py",
"runtests.py",
"tests/**",
]

[[analyzers]]
name = "python"
enabled = true
runtime_version = "3.x.x"


[analyzers.meta]
max_line_length = 120
runtime_version = "3.x.x"
49 changes: 43 additions & 6 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,55 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: pinax/linting@v2
- uses: actions/checkout@v2

- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install lint dependencies
run: |
python -m pip install --upgrade pip
pip install ruff
- name: Lint with ruff
run: |
ruff --format=github --target-version=py311 account tests
test:
name: Testing
runs-on: ubuntu-latest
strategy:
matrix:
python: [3.6, 3.7, 3.8, 3.9, "3.10"]
django: [2.2.*, 3.2.*]
python:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
django:
- "3.2.*"
- "4.2.*"
exclude:
- python: "3.11"
django: "3.2.*"

steps:
- uses: pinax/testing@v2
- uses: actions/checkout@v2

- name: Setup Python
uses: actions/setup-python@v4
with:
python: ${{ matrix.python }}
django: ${{ matrix.django }}
python-version: ${{ matrix.python }}

- name: Install Django
shell: bash
run: pip install Django==${{ matrix.django }} 'django-appconf>=1.0.4' 'pytz>=2020.4'

- name: Install test utilities
shell: bash
run: pip install pytest pytest-django

- name: Running Python Tests
shell: bash
run: pytest
2 changes: 0 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
include .coveragerc
include CHANGELOG.md
include LICENSE
include tox.ini
include README.md
include runtests.py
recursive-include account *.html
recursive-include account *.txt
recursive-include account/locale *
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ Pinax is an open-source platform built on the Django Web Framework. It is an eco

#### Supported Django and Python versions

Django / Python | 3.6 | 3.7 | 3.8 | 3.9 | 3.10
--------------- | --- | --- | --- | --- | ----
2.2 | * | * | * | * | *
3.2 | * | * | * | * | *
Django / Python | 3.8 | 3.9 | 3.10 | 3.11
--------------- | --- | --- | ---- | ----
3.2 | * | * | * |
4.2 | * | * | * | *


## Requirements

* Django 2.2 or 3.2
* Python 3.6, 3.7, 3.8, 3.9, 3.10
* Django 3.2 or 4.2
* Python 3.8, 3.9, 3.10, 3.11
* django-appconf (included in ``install_requires``)
* pytz (included in ``install_requires``)

Expand Down
4 changes: 1 addition & 3 deletions account/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import pkg_resources

__version__ = pkg_resources.get_distribution("django-user-accounts").version
__version__ = "3.2.1"
4 changes: 3 additions & 1 deletion account/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ class SignupForm(forms.Form):

def clean_username(self):
if not alnum_re.search(self.cleaned_data["username"]):
raise forms.ValidationError(_("Usernames can only contain letters, numbers and the following special characters ./+/-/_"))
raise forms.ValidationError(
_("Usernames can only contain letters, numbers and the following special characters ./+/-/_")
)
lookup_kwargs = get_user_lookup_kwargs({
"{username}__iexact": self.cleaned_data["username"]
})
Expand Down
14 changes: 12 additions & 2 deletions account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@

class Account(models.Model):

user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name="account", verbose_name=_("user"), on_delete=models.CASCADE)
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
related_name="account",
verbose_name=_("user"),
on_delete=models.CASCADE,
)
timezone = TimeZoneField(_("timezone"))
language = models.CharField(
_("language"),
Expand Down Expand Up @@ -407,5 +412,10 @@ class PasswordExpiry(models.Model):
"""
Holds the password expiration period for a single user.
"""
user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name="password_expiry", verbose_name=_("user"), on_delete=models.CASCADE)
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
related_name="password_expiry",
verbose_name=_("user"),
on_delete=models.CASCADE,
)
expiry = models.PositiveIntegerField(default=0)
5 changes: 0 additions & 5 deletions account/tests/urls.py

This file was deleted.

6 changes: 5 additions & 1 deletion account/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
path("confirm_email/<str:key>/", ConfirmEmailView.as_view(), name="account_confirm_email"),
path("password/", ChangePasswordView.as_view(), name="account_password"),
path("password/reset/", PasswordResetView.as_view(), name="account_password_reset"),
path("password/reset/<str:uidb36>/<str:token>/", PasswordResetTokenView.as_view(), name="account_password_reset_token"),
path(
"password/reset/<str:uidb36>/<str:token>/",
PasswordResetTokenView.as_view(),
name="account_password_reset_token",
),
path("settings/", SettingsView.as_view(), name="account_settings"),
path("delete/", DeleteView.as_view(), name="account_delete"),
]
4 changes: 2 additions & 2 deletions account/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
from django.core.exceptions import SuspiciousOperation
from django.http import HttpResponseRedirect, QueryDict
from django.urls import NoReverseMatch, reverse
from django.utils import timezone
from django.utils.encoding import force_str

import pytz
from account.conf import settings

from .models import PasswordHistory
Expand Down Expand Up @@ -139,7 +139,7 @@ def check_password_expired(user):
except PasswordHistory.DoesNotExist:
return False

now = datetime.datetime.now()
now = timezone.now()
expiration = latest.timestamp + datetime.timedelta(seconds=expiry)

if expiration < now:
Expand Down
98 changes: 51 additions & 47 deletions account/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ def get_context_data(self, **kwargs):
redirect_field_name = self.get_redirect_field_name()
ctx.update({
"redirect_field_name": redirect_field_name,
"redirect_field_value": self.request.POST.get(redirect_field_name, self.request.GET.get(redirect_field_name, "")),
"redirect_field_value": self.request.POST.get(
redirect_field_name,
self.request.GET.get(redirect_field_name, ""),
),
})
return ctx

Expand Down Expand Up @@ -197,8 +200,7 @@ def get_initial(self):
def get_template_names(self):
if is_ajax(self.request):
return [self.template_name_ajax]
else:
return [self.template_name]
return [self.template_name]

def get_form_kwargs(self):
kwargs = super(SignupView, self).get_form_kwargs()
Expand Down Expand Up @@ -232,25 +234,25 @@ def form_valid(self, form):
self.send_email_confirmation(email_address)
if settings.ACCOUNT_EMAIL_CONFIRMATION_REQUIRED and not email_address.verified:
return self.email_confirmation_required_response()
else:
show_message = [
settings.ACCOUNT_EMAIL_CONFIRMATION_EMAIL,
self.messages.get("email_confirmation_sent"),
not email_address.verified
]
if all(show_message):
messages.add_message(
self.request,
self.messages["email_confirmation_sent"]["level"],
self.messages["email_confirmation_sent"]["text"].format(**{
"email": form.cleaned_data["email"]
})
)
# attach form to self to maintain compatibility with login_user
# API. this should only be relied on by d-u-a and it is not a stable
# API for site developers.
self.form = form
self.login_user()

show_message = [
settings.ACCOUNT_EMAIL_CONFIRMATION_EMAIL,
self.messages.get("email_confirmation_sent"),
not email_address.verified
]
if all(show_message):
messages.add_message(
self.request,
self.messages["email_confirmation_sent"]["level"],
self.messages["email_confirmation_sent"]["text"].format(**{
"email": form.cleaned_data["email"]
})
)
# attach form to self to maintain compatibility with login_user
# API. this should only be relied on by d-u-a and it is not a stable
# API for site developers.
self.form = form # skipcq: PYL-W0201
self.login_user()
return redirect(self.get_success_url())

def create_user(self, form, commit=True, model=None, **kwargs):
Expand Down Expand Up @@ -314,16 +316,16 @@ def get_code(self):
def is_open(self):
if self.signup_code:
return True
else:
if self.signup_code_present:
if self.messages.get("invalid_signup_code"):
messages.add_message(
self.request,
self.messages["invalid_signup_code"]["level"],
self.messages["invalid_signup_code"]["text"].format(**{
"code": self.get_code(),
})
)

if self.signup_code_present and self.messages.get("invalid_signup_code"):
messages.add_message(
self.request,
self.messages["invalid_signup_code"]["level"],
self.messages["invalid_signup_code"]["text"].format(**{
"code": self.get_code(),
})
)

return settings.ACCOUNT_OPEN_SIGNUP

def email_confirmation_required_response(self):
Expand Down Expand Up @@ -375,15 +377,17 @@ def get(self, *args, **kwargs):
def get_template_names(self):
if is_ajax(self.request):
return [self.template_name_ajax]
else:
return [self.template_name]
return [self.template_name]

def get_context_data(self, **kwargs):
ctx = super(LoginView, self).get_context_data(**kwargs)
redirect_field_name = self.get_redirect_field_name()
ctx.update({
"redirect_field_name": redirect_field_name,
"redirect_field_value": self.request.POST.get(redirect_field_name, self.request.GET.get(redirect_field_name, "")),
"redirect_field_value": self.request.POST.get(
redirect_field_name,
self.request.GET.get(redirect_field_name, ""),
),
})
return ctx

Expand Down Expand Up @@ -448,7 +452,10 @@ def get_context_data(self, **kwargs):
redirect_field_name = self.get_redirect_field_name()
ctx.update({
"redirect_field_name": redirect_field_name,
"redirect_field_value": self.request.POST.get(redirect_field_name, self.request.GET.get(redirect_field_name, "")),
"redirect_field_value": self.request.POST.get(
redirect_field_name,
self.request.GET.get(redirect_field_name, ""),
),
})
return ctx

Expand Down Expand Up @@ -541,8 +548,7 @@ def get_redirect_url(self):
if not settings.ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL:
return settings.ACCOUNT_LOGIN_REDIRECT_URL
return settings.ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL
else:
return settings.ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL
return settings.ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL

def after_confirmation(self, confirmation):
user = confirmation.email_address.user
Expand Down Expand Up @@ -589,9 +595,7 @@ def get_user(self):
return self.request.user

def get_form_kwargs(self):
"""
Returns the keyword arguments for instantiating the form.
"""
"""Returns the keyword arguments for instantiating the form."""
kwargs = {"user": self.request.user, "initial": self.get_initial()}
if self.request.method in ["POST", "PUT"]:
kwargs.update({
Expand Down Expand Up @@ -641,11 +645,8 @@ def send_email(self, email):
for user in User.objects.filter(pk__in=email_qs.values("user")):
uid = int_to_base36(user.id)
token = self.make_token(user)
password_reset_url = "{0}://{1}{2}".format(
protocol,
current_site.domain,
reverse(settings.ACCOUNT_PASSWORD_RESET_TOKEN_URL, kwargs=dict(uidb36=uid, token=token))
)
path = reverse(settings.ACCOUNT_PASSWORD_RESET_TOKEN_URL, kwargs=dict(uidb36=uid, token=token))
password_reset_url = f"{protocol}://{current_site.domain}{path}"
ctx = {
"user": user,
"current_site": current_site,
Expand Down Expand Up @@ -790,7 +791,10 @@ def get_context_data(self, **kwargs):
redirect_field_name = self.get_redirect_field_name()
ctx.update({
"redirect_field_name": redirect_field_name,
"redirect_field_value": self.request.POST.get(redirect_field_name, self.request.GET.get(redirect_field_name, "")),
"redirect_field_value": self.request.POST.get(
redirect_field_name,
self.request.GET.get(redirect_field_name, ""),
),
})
return ctx

Expand Down
4 changes: 2 additions & 2 deletions makemigrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"django.contrib.contenttypes",
"django.contrib.sites",
"account",
"account.tests"
"tests"
],
MIDDLEWARE_CLASSES=[],
DATABASES={
Expand All @@ -21,7 +21,7 @@
}
},
SITE_ID=1,
ROOT_URLCONF="account.tests.urls",
ROOT_URLCONF="tests.urls",
SECRET_KEY="notasecret",
)

Expand Down
10 changes: 10 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tests.settings")

from django.core.management import execute_from_command_line

execute_from_command_line(sys.argv)
Loading

0 comments on commit e6a1f0c

Please sign in to comment.