From c26df6d68b76f114a1992027459f09581efb1b00 Mon Sep 17 00:00:00 2001
From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
Date: Mon, 26 Sep 2022 23:26:15 +0200
Subject: [PATCH] Update for Django 4.1 support. (#43)

Django now raises a TypeError when middleware is missing `get_response`.
Removed MiddlewareMixin from SEOBackendBase and added `get_response` argument to tests.
Added django 4.1 to tox for tests.
Fixes issue 42.
---
 django_seo_js/backends/base.py          |  2 +-
 django_seo_js/tests/test_helpers.py     |  6 ++--
 django_seo_js/tests/test_middlewares.py | 38 ++++++++++++-------------
 django_seo_js/tests/utils.py            |  5 ++++
 tox.ini                                 |  5 ++--
 5 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/django_seo_js/backends/base.py b/django_seo_js/backends/base.py
index 5cfffc8..f79b8b8 100644
--- a/django_seo_js/backends/base.py
+++ b/django_seo_js/backends/base.py
@@ -25,7 +25,7 @@ def __init__(self, get_response=None, *args, **kwargs):
         self.backend = getattr(backend_module, module_path.split(".")[-1])()
 
 
-class SEOBackendBase(MiddlewareMixin):
+class SEOBackendBase:
     """The base class to inherit for SEO_JS backends"""
 
     def build_absolute_uri(self, request):
diff --git a/django_seo_js/tests/test_helpers.py b/django_seo_js/tests/test_helpers.py
index 5735f6b..fc0f657 100644
--- a/django_seo_js/tests/test_helpers.py
+++ b/django_seo_js/tests/test_helpers.py
@@ -1,6 +1,6 @@
 from django.test import TestCase
 
-from django_seo_js.tests.utils import override_settings
+from django_seo_js.tests.utils import override_settings, get_response_empty
 from django_seo_js.middleware import EscapedFragmentMiddleware
 
 
@@ -9,11 +9,11 @@ class HelpersTest(TestCase):
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def test_update_the_render_cache(self):
         from django_seo_js.helpers import update_cache_for_url
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.assertEqual(update_cache_for_url("http://example.com"), True)
 
     @override_settings(BACKEND='django_seo_js.backends.TestBackend', ENABLED=False)
     def test_update_skips_if_disabled(self):
         from django_seo_js.helpers import update_cache_for_url
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.assertEqual(update_cache_for_url("http://example.com"), False)
diff --git a/django_seo_js/tests/test_middlewares.py b/django_seo_js/tests/test_middlewares.py
index 58f5c79..c4777f9 100644
--- a/django_seo_js/tests/test_middlewares.py
+++ b/django_seo_js/tests/test_middlewares.py
@@ -3,7 +3,7 @@
 from mock import Mock
 from django.test import TestCase
 
-from django_seo_js.tests.utils import override_settings
+from django_seo_js.tests.utils import override_settings, get_response_empty
 from django_seo_js.middleware import EscapedFragmentMiddleware, UserAgentMiddleware, HashBangMiddleware
 
 print(override_settings)
@@ -18,7 +18,7 @@ class EscapedFragmentMiddlewareTest(TestCase):
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def setUp(self):
         super(EscapedFragmentMiddlewareTest, self).setUp()
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.request = Mock()
         self.request.path = "/"
         self.request.GET = {}
@@ -33,19 +33,19 @@ def test_does_not_have_escaped_fragment(self):
 
     @override_settings(BACKEND='django_seo_js.backends.TestBackend', ENABLED=False)
     def test_has_escaped_fragment_skips_if_disabled_via_enabled(self):
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.request.GET = {}
         self.assertEqual(self.middleware.process_request(self.request), None)
 
     @override_settings(BACKEND='django_seo_js.backends.TestServiceDownBackend')
     def test_has_escaped_fragment_skips_if_service_is_down(self):
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.request.GET = {"_escaped_fragment_": None}
         self.assertEqual(self.middleware.process_request(self.request), None)
 
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def test_overriding_skips_sitemap_xml_by_default(self):
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.request.path = "/sitemap.xml"
         self.request.GET = {"_escaped_fragment_": None}
         self.assertEqual(self.middleware.process_request(self.request), None)
@@ -56,7 +56,7 @@ def test_overriding_skips_sitemap_xml_by_default(self):
         IGNORE_EXTENSIONS=[],
     )
     def test_overriding_skips_custom_overrides_xml_by_default(self):
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.request.path = "/sitemap.xml"
         self.request.GET = {"_escaped_fragment_": None}
         self.assertEqual(self.middleware.process_request(self.request).content, b"Test")
@@ -69,7 +69,7 @@ def test_overriding_skips_custom_overrides_xml_by_default(self):
 
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def test_overriding_skips_gifs_by_default(self):
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.request.path = "/sitemap.xml"
         self.request.GET = {"_escaped_fragment_": None}
         self.assertEqual(self.middleware.process_request(self.request), None)
@@ -79,7 +79,7 @@ def test_overriding_skips_gifs_by_default(self):
         IGNORE_EXTENSIONS=[".html", ".txt", ]
     )
     def test_overriding_skips_custom_overrides_gifs_by_default(self):
-        self.middleware = EscapedFragmentMiddleware()
+        self.middleware = EscapedFragmentMiddleware(get_response_empty)
         self.request.path = "/foo.gif"
         self.request.GET = {"_escaped_fragment_": None}
         self.assertEqual(self.middleware.process_request(self.request).content, b"Test")
@@ -96,7 +96,7 @@ class HashBangMiddlewareTest(EscapedFragmentMiddlewareTest):
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def setUp(self):
         super(HashBangMiddlewareTest, self).setUp()
-        self.middleware = HashBangMiddleware()
+        self.middleware = HashBangMiddleware(get_response_empty)
         self.request = Mock()
         self.request.path = "/"
         self.request.GET = {}
@@ -107,7 +107,7 @@ class UserAgentMiddlewareTest(TestCase):
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def setUp(self):
         super(UserAgentMiddlewareTest, self).setUp()
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request = Mock()
         self.request.path = "/"
         self.request.META = {}
@@ -130,7 +130,7 @@ def test_does_not_match_one_of_the_default_user_agents(self):
         BACKEND='django_seo_js.backends.TestBackend'
     )
     def test_overriding_matches(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.META = {
             "HTTP_USER_AGENT": "The TestUserAgent v1.0"
         }
@@ -141,7 +141,7 @@ def test_overriding_matches(self):
         BACKEND='django_seo_js.backends.TestBackend'
     )
     def test_overriding_does_not_match_properly(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.META = {
             "HTTP_USER_AGENT":
             "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://about.ask.com/en/docs/about/webmasters.shtml)"
@@ -153,13 +153,13 @@ def test_overriding_does_not_match_properly(self):
         BACKEND='django_seo_js.backends.TestBackend'
     )
     def test_missing_user_agent_still_works(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.META = {}
         self.assertEqual(self.middleware.process_request(self.request), None)
 
     @override_settings(BACKEND='django_seo_js.backends.TestBackend', ENABLED=False)
     def test_overriding_matches_skips_if_disabled_via_enabled(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.META = {
             "HTTP_USER_AGENT": "The TestUserAgent v1.0"
         }
@@ -167,7 +167,7 @@ def test_overriding_matches_skips_if_disabled_via_enabled(self):
 
     @override_settings(BACKEND='django_seo_js.backends.TestServiceDownBackend')
     def test_overriding_matches_skips_if_service_is_down(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.META = {
             "HTTP_USER_AGENT":
             "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://about.ask.com/en/docs/about/webmasters.shtml)"
@@ -176,7 +176,7 @@ def test_overriding_matches_skips_if_service_is_down(self):
 
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def test_overriding_skips_sitemap_xml_by_default(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.path = "/sitemap.xml"
         self.request.META = {
             "HTTP_USER_AGENT":
@@ -190,7 +190,7 @@ def test_overriding_skips_sitemap_xml_by_default(self):
         IGNORE_EXTENSIONS=[],
     )
     def test_overriding_skips_custom_overrides_xml_by_default(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.path = "/sitemap.xml"
         self.request.META = {
             "HTTP_USER_AGENT":
@@ -206,7 +206,7 @@ def test_overriding_skips_custom_overrides_xml_by_default(self):
 
     @override_settings(BACKEND='django_seo_js.backends.TestBackend')
     def test_overriding_skips_gifs_by_default(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.path = "/foo.gif"
         self.request.META = {
             "HTTP_USER_AGENT":
@@ -219,7 +219,7 @@ def test_overriding_skips_gifs_by_default(self):
         IGNORE_EXTENSIONS=[".html", ".txt", ]
     )
     def test_overriding_skips_custom_overrides_gifs_by_default(self):
-        self.middleware = UserAgentMiddleware()
+        self.middleware = UserAgentMiddleware(get_response_empty)
         self.request.path = "/foo.gif"
         self.request.META = {
             "HTTP_USER_AGENT":
diff --git a/django_seo_js/tests/utils.py b/django_seo_js/tests/utils.py
index e9f2344..5880cc6 100644
--- a/django_seo_js/tests/utils.py
+++ b/django_seo_js/tests/utils.py
@@ -1,4 +1,5 @@
 from functools import wraps
+from django.http.response import HttpResponse
 from django_seo_js import settings
 
 
@@ -28,3 +29,7 @@ def enable(self):
     def disable(self):
         for k, v in self.originals.items():
             setattr(settings, k, v)
+
+
+def get_response_empty(request):
+    return HttpResponse()
diff --git a/tox.ini b/tox.ini
index a4a46df..d11b8f7 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,14 +4,15 @@
 # and then run "tox" from this directory.
 
 [tox]
-envlist = python{37}-dj{2,3}
+envlist = python{37,38,39}-dj{2,3,4}
 
 [testenv]
 deps =
     -rrequirements.tests.txt
 
     dj2: Django ~=2.2
-    dj3: Django ~=3.2.9
+    dj3: Django ~=3.2.15
+    dj4: Django ~=4.1.1
 
 commands =
     {envpython} manage.py test