Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tests/settings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
SECRET_KEY = 'test-secret-key'
DATABASES = {}
INSTALLED_APPS = []

ROOT_URLCONF = 'tests.urls'

MIDDLEWARE = [
'prerender_django.middleware.PrerenderMiddleware',
]

ALLOWED_HOSTS = ['*']
73 changes: 40 additions & 33 deletions tests/test_middleware.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
"""Tests against the real Django request pipeline.

Uses django.test.Client (not RequestFactory) so MIDDLEWARE ordering, URL
resolution, and full request/response wiring are exercised. The upstream
Prerender service is faked by patching urllib.request.urlopen — replacing
that with a real mock server is the contract-test layer.
"""
import urllib.error
from unittest.mock import MagicMock, patch

from django.http import HttpResponse
from django.test import RequestFactory

from prerender_django.middleware import PrerenderMiddleware
import pytest
from django.test import Client

BOT_UA = 'Mozilla/5.0 (compatible; Googlebot/2.1)'
BROWSER_UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
PRERENDERED_HTML = '<html><body>prerendered</body></html>'

factory = RequestFactory()


def normal_response(_request):
return HttpResponse('original')


def mock_urlopen(status=200, body=PRERENDERED_HTML):
def _fake_urlopen(status=200, body=PRERENDERED_HTML):
cm = MagicMock()
cm.__enter__ = MagicMock(return_value=cm)
cm.__exit__ = MagicMock(return_value=False)
Expand All @@ -26,44 +25,52 @@ def mock_urlopen(status=200, body=PRERENDERED_HTML):
return cm


def test_browser_passes_through():
middleware = PrerenderMiddleware(normal_response)
request = factory.get('/', HTTP_USER_AGENT=BROWSER_UA)
response = middleware(request)
@pytest.fixture
def client():
return Client()


def test_browser_passes_through(client):
response = client.get('/', HTTP_USER_AGENT=BROWSER_UA)
assert response.status_code == 200
assert response.content == b'original'


def test_bot_receives_prerendered_response():
middleware = PrerenderMiddleware(normal_response)
request = factory.get('/', HTTP_USER_AGENT=BOT_UA)
with patch('urllib.request.urlopen', return_value=mock_urlopen()):
response = middleware(request)
def test_bot_receives_prerendered_response(client):
with patch('urllib.request.urlopen', return_value=_fake_urlopen()):
response = client.get('/about', HTTP_USER_AGENT=BOT_UA)
assert response.status_code == 200
assert PRERENDERED_HTML in response.content.decode()


def test_static_asset_with_bot_ua_passes_through():
middleware = PrerenderMiddleware(normal_response)
request = factory.get('/style.css', HTTP_USER_AGENT=BOT_UA)
response = middleware(request)
def test_static_asset_with_bot_ua_passes_through(client):
response = client.get('/style.css', HTTP_USER_AGENT=BOT_UA)
assert response.status_code == 200
assert response.content == b'original'


def test_escaped_fragment_triggers_prerender():
middleware = PrerenderMiddleware(normal_response)
request = factory.get('/', {'_escaped_fragment_': ''}, HTTP_USER_AGENT=BROWSER_UA)
with patch('urllib.request.urlopen', return_value=mock_urlopen()):
response = middleware(request)
def test_escaped_fragment_triggers_prerender(client):
with patch('urllib.request.urlopen', return_value=_fake_urlopen()):
response = client.get('/?_escaped_fragment_=', HTTP_USER_AGENT=BROWSER_UA)
assert response.status_code == 200
assert PRERENDERED_HTML in response.content.decode()


def test_network_error_falls_back_to_normal_response():
middleware = PrerenderMiddleware(normal_response)
request = factory.get('/', HTTP_USER_AGENT=BOT_UA)
def test_x_bufferbot_header_triggers_prerender(client):
with patch('urllib.request.urlopen', return_value=_fake_urlopen()):
response = client.get('/', HTTP_USER_AGENT=BROWSER_UA, HTTP_X_BUFFERBOT='true')
assert response.status_code == 200
assert PRERENDERED_HTML in response.content.decode()


def test_post_request_passes_through(client):
response = client.post('/', HTTP_USER_AGENT=BOT_UA)
assert response.status_code == 200
assert response.content == b'original'


def test_network_error_falls_back_to_normal_response(client):
with patch('urllib.request.urlopen', side_effect=urllib.error.URLError('network error')):
response = middleware(request)
response = client.get('/', HTTP_USER_AGENT=BOT_UA)
assert response.status_code == 200
assert response.content == b'original'
11 changes: 11 additions & 0 deletions tests/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.http import HttpResponse
from django.urls import re_path


def _original(request):
return HttpResponse('original')


urlpatterns = [
re_path(r'^.*$', _original),
]
Loading