Skip to content

Commit

Permalink
Test against Django 4.2a
Browse files Browse the repository at this point in the history
  • Loading branch information
mbi committed Jan 17, 2023
1 parent e3073a9 commit 17216e4
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 28 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Version 0.5.18 (unreleased)
* Test against Django 4.1a
* Stopped testing Django < 3.2
* BaseCaptchaTextInput should set autocomplete=off on the hashkey HiddenInput (#201, thanks @eerotal)
* Test against Django 4.2a
* Fix some deprecation warnings in Pillow 9.2+


Version 0.5.17
Expand Down
49 changes: 34 additions & 15 deletions captcha/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
import warnings

import django
from captcha.conf import settings
from captcha.fields import CaptchaField, CaptchaTextInput
from captcha.models import CaptchaStore
from django.core import management
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase, override_settings
from django.utils import timezone
from PIL import Image
from testfixtures import LogCapture

from captcha.conf import settings
from captcha.fields import CaptchaField, CaptchaTextInput
from captcha.models import CaptchaStore

if django.VERSION < (1, 10): # NOQA
from django.core.urlresolvers import reverse # NOQA
else: # NOQA
Expand Down Expand Up @@ -49,13 +50,17 @@ def setUp(self):
settings.CAPTCHA_WORDS_DICTIONARY = "/usr/share/dict/words"
settings.CAPTCHA_PUNCTUATION = ";-,."
tested_helpers.append("captcha.helpers.word_challenge")
tested_helpers.append("captcha.helpers.huge_words_and_punctuation_challenge")
tested_helpers.append(
"captcha.helpers.huge_words_and_punctuation_challenge"
)
for helper in tested_helpers:
challenge, response = settings._callable_from_string(helper)()
(
self.stores[helper.rsplit(".", 1)[-1].replace("_challenge", "_store")],
_,
) = CaptchaStore.objects.get_or_create(challenge=challenge, response=response)
) = CaptchaStore.objects.get_or_create(
challenge=challenge, response=response
)
challenge, response = settings.get_challenge()()
self.stores["default_store"], _ = CaptchaStore.objects.get_or_create(
challenge=challenge, response=response
Expand All @@ -67,6 +72,12 @@ def tearDown(self):
settings.CAPTCHA_WORDS_DICTIONARY = self.__current_settings_dictionary
settings.CAPTCHA_PUNCTUATION = self.__current_settings_punctuation

def _assertFormError(self, response, form_name, *args, **kwargs):
if django.VERSION >= (4, 1):
self.assertFormError(response.context.get(form_name), *args, **kwargs)
else:
self.assertFormError(response, form_name, *args, **kwargs)

def __extract_hash_and_response(self, r):
hash_ = re.findall(r'value="([0-9a-f]+)"', str(r.content))[0]
response = CaptchaStore.objects.get(hashkey=hash_).response
Expand Down Expand Up @@ -164,7 +175,9 @@ def test_wrong_submit(self):
sender="asasd@asdasd.com",
),
)
self.assertFormError(r, "form", "captcha", ugettext_lazy("Invalid CAPTCHA"))
self._assertFormError(
r, "form", "captcha", ugettext_lazy("Invalid CAPTCHA")
)

def test_deleted_expired(self):
self.default_store.expiration = timezone.now() - datetime.timedelta(minutes=5)
Expand Down Expand Up @@ -198,13 +211,13 @@ def test_custom_error_message(self):
reverse("captcha-test-custom-error-message"),
dict(captcha_0="abc", captcha_1="wrong response"),
)
self.assertFormError(r, "form", "captcha", "TEST CUSTOM ERROR MESSAGE")
self._assertFormError(r, "form", "captcha", "TEST CUSTOM ERROR MESSAGE")
# empty answer
r = self.client.post(
reverse("captcha-test-custom-error-message"),
dict(captcha_0="abc", captcha_1=""),
)
self.assertFormError(
self._assertFormError(
r, "form", "captcha", ugettext_lazy("This field is required.")
)

Expand Down Expand Up @@ -355,7 +368,7 @@ def test_test_mode_issue15(self):
sender="asasd@asdasd.com",
),
)
self.assertFormError(r, "form", "captcha", ugettext_lazy("Invalid CAPTCHA"))
self._assertFormError(r, "form", "captcha", ugettext_lazy("Invalid CAPTCHA"))

settings.CAPTCHA_TEST_MODE = True
# Test mode, only 'PASSED' is accepted
Expand All @@ -370,7 +383,7 @@ def test_test_mode_issue15(self):
sender="asasd@asdasd.com",
),
)
self.assertFormError(r, "form", "captcha", ugettext_lazy("Invalid CAPTCHA"))
self._assertFormError(r, "form", "captcha", ugettext_lazy("Invalid CAPTCHA"))

r = self.client.get(reverse("captcha-test"))
self.assertEqual(r.status_code, 200)
Expand Down Expand Up @@ -433,12 +446,14 @@ def test_issue201_autocomplete_off_on_hiddeninput(self):
r = self.client.get(reverse("captcha-test"))

# Inspect the response context to find out the captcha key.
key = r.context['form']['captcha'].field.widget._key
key = r.context["form"]["captcha"].field.widget._key

# Assety that autocomplete=off is set on the hidden captcha field.
self.assertInHTML(
'<input type="hidden" name="captcha_0" value="{}" id="id_captcha_0" autocomplete="off" required />'.format(key),
str(r.content)
'<input type="hidden" name="captcha_0" value="{}" id="id_captcha_0" autocomplete="off" required />'.format(
key
),
str(r.content),
)

def test_transparent_background(self):
Expand Down Expand Up @@ -502,7 +517,9 @@ def test_multiple_fonts(self):
settings.CAPTCHA_FONT_PATH = False
for key in [store.hashkey for store in self.stores.values()]:
try:
response = self.client.get(reverse("captcha-image", kwargs=dict(key=key)))
response = self.client.get(
reverse("captcha-image", kwargs=dict(key=key))
)
self.fail()
except ImproperlyConfigured:
pass
Expand Down Expand Up @@ -535,7 +552,9 @@ def test_math_challenge(self):
response,
str(
eval(
challenge.replace(settings.CAPTCHA_MATH_CHALLENGE_OPERATOR, "*")[:-1]
challenge.replace(settings.CAPTCHA_MATH_CHALLENGE_OPERATOR, "*")[
:-1
]
)
),
)
Expand Down
15 changes: 11 additions & 4 deletions captcha/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@


def getsize(font, text):
if hasattr(font, "getoffset"):
if hasattr(font, "getbbox"):
_top, _left, _right, _bottom = font.getbbox(text)
return _right - _left, _bottom - _top
elif hasattr(font, "getoffset"):
return tuple([x + y for x, y in zip(font.getsize(text), font.getoffset(text))])
else:
return font.getsize(text)
Expand Down Expand Up @@ -93,7 +96,7 @@ def captcha_image(request, key, scale=1):
charimage = charimage.rotate(
random.randrange(*settings.CAPTCHA_LETTER_ROTATION),
expand=0,
resample=Image.Resampling.BICUBIC,
resample=Image.BICUBIC,
)
charimage = charimage.crop(charimage.getbbox())
maskimage = Image.new("L", size)
Expand Down Expand Up @@ -199,7 +202,9 @@ def captcha_audio(request, key):
response = RangedFileResponse(
request, open(path, "rb"), content_type="audio/wav"
)
response["Content-Disposition"] = 'attachment; filename="{}.wav"'.format(key)
response["Content-Disposition"] = 'attachment; filename="{}.wav"'.format(
key
)
return response
raise Http404

Expand All @@ -213,6 +218,8 @@ def captcha_refresh(request):
to_json_response = {
"key": new_key,
"image_url": captcha_image_url(new_key),
"audio_url": captcha_audio_url(new_key) if settings.CAPTCHA_FLITE_PATH else None,
"audio_url": captcha_audio_url(new_key)
if settings.CAPTCHA_FLITE_PATH
else None,
}
return HttpResponse(json.dumps(to_json_response), content_type="application/json")
12 changes: 9 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import sys

from captcha import get_version as get_captcha_version
from setuptools import find_packages, setup
from setuptools.command.test import test as test_command

from captcha import get_version as get_captcha_version


class Tox(test_command):
user_options = [("tox-args=", "a", "Arguments to pass to tox")]
Expand All @@ -19,17 +20,22 @@ def finalize_options(self):

def run_tests(self):
# import here, cause outside the eggs aren't loaded
import tox
import shlex

import tox

args = self.tox_args
if args:
args = shlex.split(self.tox_args)
errno = tox.cmdline(args=args)
sys.exit(errno)


install_requires = ["Django >= 2.2", "Pillow >=6.2.0", "django-ranged-response == 0.2.0"]
install_requires = [
"Django >= 3.2",
"Pillow >=6.2.0",
"django-ranged-response == 0.2.0",
]
EXTRAS_REQUIRE = {"test": ("testfixtures",)}


Expand Down
22 changes: 16 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

[tox]
envlist =
py{38,39,310}-django{32,40,41},
py{38,39,310}-django{32,40,41}-jinja2,
py{38,39,310}-django{32,40,41,42},
py{38,39,310}-django{32,40,41,42}-jinja2,
gettext,flake8,docs

[gh-actions]
python =
3.10: py310-django32, py310-django32-jinja2, py310-django40, py310-django40-jinja2, py310-django41, py310-django41-jinja2
3.9: py39-django32, py39-django32-jinja2, py39-django40, py39-django40-jinja2, py39-django41, py39-django41-jinja2
3.8: py38-django32, py38-django32-jinja2, py38-django40, py38-django40-jinja2, py38-django41, py38-django41-jinja2
3.10: py310-django32, py310-django32-jinja2, py310-django40, py310-django40-jinja2, py310-django41, py310-django41-jinja2, py310-django42, py310-django42-jinja2
3.9: py39-django32, py39-django32-jinja2, py39-django40, py39-django40-jinja2, py39-django41, py39-django41-jinja2, py39-django42, py39-django42-jinja2
3.8: py38-django32, py38-django32-jinja2, py38-django40, py38-django40-jinja2, py38-django41, py38-django41-jinja2, py38-django42, py38-django42-jinja2

[testenv]
changedir = testproject
Expand All @@ -23,7 +23,8 @@ deps =
django32: Django>=3.2,<3.3
django40: Django>=4.0,<4.1
django41: Django>=4.1a,<4.2
py{38,39,310}-django{32,40,41}: python3-memcached
django42: Django>=4.2a,<4.3
py{38,39,310}-django{32,40,41,42}: python3-memcached
jinja2

extras =
Expand Down Expand Up @@ -59,6 +60,15 @@ commands = python -Wd manage.py test captcha --settings jinja2_settings
commands = python -Wd manage.py test captcha --settings jinja2_settings


[testenv:py38-django42-jinja2]
commands = python -Wd manage.py test captcha --settings jinja2_settings

[testenv:py39-django42-jinja2]
commands = python -Wd manage.py test captcha --settings jinja2_settings

[testenv:py310-django42-jinja2]
commands = python -Wd manage.py test captcha --settings jinja2_settings


[testenv:gettext]
basepython = python3
Expand Down

0 comments on commit 17216e4

Please sign in to comment.