Skip to content

Commit 8c9119d

Browse files
committed
Merge pull request #213 from lucaswiman/unset-middleware-request
Unset middleware request
2 parents 18866a5 + b851c50 commit 8c9119d

File tree

6 files changed

+93
-29
lines changed

6 files changed

+93
-29
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Authors
3131
- Trey Hunner
3232
- Ulysses Vilela
3333
- vnagendra
34+
- Lucas Wiman
3435

3536
Background
3637
==========

CHANGES.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
Changes
22
=======
33

4+
tip (unreleased)
5+
----------------
6+
- Clear the threadlocal request object when processing the response to prevent test interactions. (gh-213)
7+
48
1.8.0 (2016-02-02)
59
------------------
610
- History tracking can be inherited by passing `inherit=True`. (gh-63)

simple_history/middleware.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ class HistoryRequestMiddleware(object):
1111

1212
def process_request(self, request):
1313
HistoricalRecords.thread.request = request
14+
15+
def process_response(self, request, response):
16+
if hasattr(HistoricalRecords.thread, 'request'):
17+
del HistoricalRecords.thread.request
18+
return response

simple_history/tests/models.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,35 @@ class TrackedConcreteBase(models.Model):
311311

312312
class UntrackedConcreteBase(models.Model):
313313
pass
314+
315+
316+
class TrackedWithAbstractBase(TrackedAbstractBaseA):
317+
pass
318+
319+
320+
class TrackedWithConcreteBase(TrackedConcreteBase):
321+
pass
322+
323+
324+
class TrackedWithTrackedAbstractAndUntrackedConcreteBase(TrackedAbstractBaseA, UntrackedConcreteBase):
325+
pass
326+
327+
328+
class BaseTrackedWithIndirectTrackedAbstractBase(TrackedAbstractBaseA):
329+
pass
330+
331+
332+
class TrackedWithIndirectTrackedAbstractBase(BaseTrackedWithIndirectTrackedAbstractBase):
333+
pass
334+
335+
336+
class BaseTrackedWithIndirectTrackedConcreteBase(TrackedAbstractBaseA):
337+
pass
338+
339+
340+
class TrackedWithIndirectTrackedConcreteBase(BaseTrackedWithIndirectTrackedConcreteBase):
341+
pass
342+
343+
344+
class TrackedWithAbstractBaseToRegister(TrackedAbstractBaseA):
345+
pass

simple_history/tests/tests/test_admin.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django_webtest import WebTest
55
from django.contrib.admin import AdminSite
66
from django.contrib.messages.storage.fallback import FallbackStorage
7+
from django.db.transaction import atomic
78
from django.test.utils import override_settings
89
from django.test.client import RequestFactory
910
from django import VERSION
@@ -191,12 +192,53 @@ def test_middleware_saves_user(self):
191192
}
192193
with override_settings(**overridden_settings):
193194
self.login()
194-
poll = Poll.objects.create(question="why?", pub_date=today)
195-
historical_poll = poll.history.all()[0]
196-
self.assertEqual(historical_poll.history_user, self.user,
195+
form = self.app.get(reverse('admin:tests_book_add')).form
196+
form["isbn"] = "9780147_513731"
197+
form.submit()
198+
book = Book.objects.get()
199+
historical_book = book.history.all()[0]
200+
201+
self.assertEqual(historical_book.history_user, self.user,
197202
"Middleware should make the request available to "
198203
"retrieve history_user.")
199204

205+
def test_middleware_unsets_request(self):
206+
overridden_settings = {
207+
'MIDDLEWARE_CLASSES':
208+
settings.MIDDLEWARE_CLASSES
209+
+ ['simple_history.middleware.HistoryRequestMiddleware'],
210+
}
211+
with override_settings(**overridden_settings):
212+
self.login()
213+
self.app.get(reverse('admin:tests_book_add'))
214+
self.assertFalse(hasattr(HistoricalRecords.thread, 'request'))
215+
216+
def test_rolled_back_user_does_not_lead_to_foreign_key_error(self):
217+
# This test simulates the rollback of a user after a request (which
218+
# happens, e.g. in test cases), and verifies that subsequently
219+
# creating a new entry does not fail with a foreign key error.
220+
221+
overridden_settings = {
222+
'MIDDLEWARE_CLASSES':
223+
settings.MIDDLEWARE_CLASSES
224+
+ ['simple_history.middleware.HistoryRequestMiddleware'],
225+
}
226+
with override_settings(**overridden_settings):
227+
self.login()
228+
self.assertEqual(
229+
self.app.get(reverse('admin:tests_book_add')).status_code,
230+
200,
231+
)
232+
233+
book = Book.objects.create(isbn="9780147_513731")
234+
235+
historical_book = book.history.all()[0]
236+
237+
self.assertIsNone(
238+
historical_book.history_user,
239+
"No way to know of request, history_user should be unset.",
240+
)
241+
200242
def test_middleware_anonymous_user(self):
201243
overridden_settings = {
202244
'MIDDLEWARE_CLASSES':

simple_history/tests/tests/test_models.py

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@
2020
HistoricalState, HistoricalCustomFKError, Series, SeriesWork, PollInfo,
2121
UserAccessorDefault, UserAccessorOverride, Employee, Country, Province,
2222
City, Contact, ContactRegister,
23-
TrackedAbstractBaseA, TrackedAbstractBaseB, UntrackedAbstractBase,
24-
TrackedConcreteBase, UntrackedConcreteBase,
23+
TrackedAbstractBaseA, TrackedAbstractBaseB,
24+
TrackedWithAbstractBase, TrackedWithConcreteBase,
25+
TrackedWithTrackedAbstractAndUntrackedConcreteBase,
26+
TrackedWithIndirectTrackedAbstractBase,
27+
TrackedWithIndirectTrackedConcreteBase,
28+
TrackedWithAbstractBaseToRegister,
2529
)
2630
from ..external.models import ExternalModel2, ExternalModel4
2731

@@ -786,18 +790,12 @@ def test_custom_table_name_from_register(self):
786790
class TestTrackingInheritance(TestCase):
787791

788792
def test_tracked_abstract_base(self):
789-
class TrackedWithAbstractBase(TrackedAbstractBaseA):
790-
pass
791-
792793
self.assertEqual(
793794
[f.attname for f in TrackedWithAbstractBase.history.model._meta.fields],
794795
['id', 'history_id', 'history_date', 'history_user_id', 'history_type'],
795796
)
796797

797798
def test_tracked_concrete_base(self):
798-
class TrackedWithConcreteBase(TrackedConcreteBase):
799-
pass
800-
801799
self.assertEqual(
802800
[f.attname for f in TrackedWithConcreteBase.history.model._meta.fields],
803801
['id', 'trackedconcretebase_ptr_id', 'history_id', 'history_date', 'history_user_id', 'history_type'],
@@ -809,21 +807,12 @@ class TrackedWithMultipleAbstractBases(TrackedAbstractBaseA, TrackedAbstractBase
809807
pass
810808

811809
def test_tracked_abstract_and_untracked_concrete_base(self):
812-
class TrackedWithTrackedAbstractAndUntrackedConcreteBase(TrackedAbstractBaseA, UntrackedConcreteBase):
813-
pass
814-
815810
self.assertEqual(
816811
[f.attname for f in TrackedWithTrackedAbstractAndUntrackedConcreteBase.history.model._meta.fields],
817812
['id', 'untrackedconcretebase_ptr_id', 'history_id', 'history_date', 'history_user_id', 'history_type'],
818813
)
819814

820815
def test_indirect_tracked_abstract_base(self):
821-
class BaseTrackedWithIndirectTrackedAbstractBase(TrackedAbstractBaseA):
822-
pass
823-
824-
class TrackedWithIndirectTrackedAbstractBase(BaseTrackedWithIndirectTrackedAbstractBase):
825-
pass
826-
827816
self.assertEqual(
828817
[f.attname for f in TrackedWithIndirectTrackedAbstractBase.history.model._meta.fields],
829818
[
@@ -832,12 +821,6 @@ class TrackedWithIndirectTrackedAbstractBase(BaseTrackedWithIndirectTrackedAbstr
832821
)
833822

834823
def test_indirect_tracked_concrete_base(self):
835-
class BaseTrackedWithIndirectTrackedConcreteBase(TrackedAbstractBaseA):
836-
pass
837-
838-
class TrackedWithIndirectTrackedConcreteBase(BaseTrackedWithIndirectTrackedConcreteBase):
839-
pass
840-
841824
self.assertEqual(
842825
[f.attname for f in TrackedWithIndirectTrackedConcreteBase.history.model._meta.fields],
843826
[
@@ -846,8 +829,5 @@ class TrackedWithIndirectTrackedConcreteBase(BaseTrackedWithIndirectTrackedConcr
846829
)
847830

848831
def test_registering_with_tracked_abstract_base(self):
849-
class TrackedWithAbstractBaseToRegister(TrackedAbstractBaseA):
850-
pass
851-
852832
with self.assertRaises(exceptions.MultipleRegistrationsError):
853833
register(TrackedWithAbstractBaseToRegister)

0 commit comments

Comments
 (0)