Permalink
Browse files

Improved test isolation of the admin tests and assigned custom admin …

…sites to

prevent test order dependant failures.

This involves introducing usage of `TestCase.urls` and implementing proper
admin.py modules for some of the test apps.

Thanks Florian Apolloner for finding the issue and contributing the patch.

Refs #15294 (it solves these problems so the fix for that ticket we are going
to commit doesn't introduce obscure and hard to reproduce test failures when
running the Django test suite.)

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16856 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent fc06ec0 commit 7b21bfc0745f92f83a6826a3d3e58797fb74e326 @ramiro ramiro committed Sep 20, 2011
@@ -0,0 +1,67 @@
+from django.core.paginator import Paginator
+from django.contrib import admin
+
+from models import (Child, Parent, Genre, Band, Musician, Group, Quartet,
+ Membership, ChordsMusician, ChordsBand, Invitation)
+
+site = admin.AdminSite(name="admin")
+
+class CustomPaginator(Paginator):
+ def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True):
+ super(CustomPaginator, self).__init__(queryset, 5, orphans=2,
+ allow_empty_first_page=allow_empty_first_page)
+
+
+class ParentAdmin(admin.ModelAdmin):
+ list_filter = ['child__name']
+ search_fields = ['child__name']
+
+
+class ChildAdmin(admin.ModelAdmin):
+ list_display = ['name', 'parent']
+ list_per_page = 10
+
+ def queryset(self, request):
+ return super(ChildAdmin, self).queryset(request).select_related("parent__name")
+
+
+class CustomPaginationAdmin(ChildAdmin):
+ paginator = CustomPaginator
+
+
+class FilteredChildAdmin(admin.ModelAdmin):
+ list_display = ['name', 'parent']
+ list_per_page = 10
+
+ def queryset(self, request):
+ return super(FilteredChildAdmin, self).queryset(request).filter(
+ name__contains='filtered')
+
+
+class BandAdmin(admin.ModelAdmin):
+ list_filter = ['genres']
+
+
+class GroupAdmin(admin.ModelAdmin):
+ list_filter = ['members']
+
+
+class QuartetAdmin(admin.ModelAdmin):
+ list_filter = ['members']
+
+
+class ChordsBandAdmin(admin.ModelAdmin):
+ list_filter = ['members']
+
+
+class DynamicListDisplayChildAdmin(admin.ModelAdmin):
+ list_display = ('name', 'parent')
+
+ def get_list_display(self, request):
+ my_list_display = list(self.list_display)
+ if request.user.username == 'noparents':
+ my_list_display.remove('parent')
+
+ return my_list_display
+
+site.register(Child, DynamicListDisplayChildAdmin)
@@ -3,7 +3,6 @@
from django.contrib import admin
from django.contrib.admin.options import IncorrectLookupParameters
from django.contrib.admin.views.main import ChangeList, SEARCH_VAR, ALL_VAR
-from django.core.paginator import Paginator
from django.template import Context, Template
from django.test import TestCase
from django.test.client import RequestFactory
@@ -12,8 +11,14 @@
from models import (Child, Parent, Genre, Band, Musician, Group, Quartet,
Membership, ChordsMusician, ChordsBand, Invitation)
+from admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin,
+ GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin, CustomPaginationAdmin,
+ FilteredChildAdmin, CustomPaginator, site as custom_site)
+
class ChangeListTests(TestCase):
+ urls = "regressiontests.admin_changelist.urls"
+
def setUp(self):
self.factory = RequestFactory()
@@ -129,11 +134,7 @@ def test_custom_paginator(self):
new_child = Child.objects.create(name='name %s' % i, parent=new_parent)
request = self.factory.get('/child/')
- m = ChildAdmin(Child, admin.site)
- m.list_display = ['id', 'name', 'parent']
- m.list_display_links = ['id']
- m.list_editable = ['name']
- m.paginator = CustomPaginator
+ m = CustomPaginationAdmin(Child, admin.site)
cl = ChangeList(request, Child, m.list_display, m.list_display_links,
m.list_filter, m.date_hierarchy, m.search_fields,
@@ -331,7 +332,7 @@ def _mocked_authenticated_request(user):
return request
# Test with user 'noparents'
- m = DynamicListDisplayChildAdmin(Child, admin.site)
+ m = custom_site._registry[Child]
request = _mocked_authenticated_request(user_noparents)
response = m.changelist_view(request)
# XXX - Calling render here to avoid ContentNotRenderedError to be
@@ -347,8 +348,11 @@ def _mocked_authenticated_request(user):
response.render()
self.assertContains(response, 'Parent object')
+ custom_site.unregister(Child)
+
# Test default implementation
- m = ChildAdmin(Child, admin.site)
+ custom_site.register(Child, ChildAdmin)
+ m = custom_site._registry[Child]
request = _mocked_authenticated_request(user_noparents)
response = m.changelist_view(request)
# XXX - #15826
@@ -383,57 +387,3 @@ def test_show_all(self):
cl.get_results(request)
self.assertEqual(len(cl.result_list), 10)
-
-class ParentAdmin(admin.ModelAdmin):
- list_filter = ['child__name']
- search_fields = ['child__name']
-
-
-class ChildAdmin(admin.ModelAdmin):
- list_display = ['name', 'parent']
- list_per_page = 10
-
- def queryset(self, request):
- return super(ChildAdmin, self).queryset(request).select_related("parent__name")
-
-
-class FilteredChildAdmin(admin.ModelAdmin):
- list_display = ['name', 'parent']
- list_per_page = 10
-
- def queryset(self, request):
- return super(FilteredChildAdmin, self).queryset(request).filter(
- name__contains='filtered')
-
-
-class CustomPaginator(Paginator):
- def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True):
- super(CustomPaginator, self).__init__(queryset, 5, orphans=2,
- allow_empty_first_page=allow_empty_first_page)
-
-
-class BandAdmin(admin.ModelAdmin):
- list_filter = ['genres']
-
-
-class GroupAdmin(admin.ModelAdmin):
- list_filter = ['members']
-
-
-class QuartetAdmin(admin.ModelAdmin):
- list_filter = ['members']
-
-
-class ChordsBandAdmin(admin.ModelAdmin):
- list_filter = ['members']
-
-
-class DynamicListDisplayChildAdmin(admin.ModelAdmin):
- list_display = ('name', 'parent')
-
- def get_list_display(self, request):
- my_list_display = list(self.list_display)
- if request.user.username == 'noparents':
- my_list_display.remove('parent')
-
- return my_list_display
@@ -0,0 +1,7 @@
+from django.conf.urls import patterns, include
+
+import admin
+
+urlpatterns = patterns('',
+ (r'^admin/', include(admin.site.urls)),
+)
@@ -0,0 +1,117 @@
+from django.contrib import admin
+from django import forms
+
+from models import *
+
+site = admin.AdminSite(name="admin")
+
+
+class BookInline(admin.TabularInline):
+ model = Author.books.through
+
+
+class AuthorAdmin(admin.ModelAdmin):
+ inlines = [BookInline]
+
+
+class InnerInline(admin.StackedInline):
+ model = Inner
+ can_delete = False
+ readonly_fields = ('readonly',) # For bug #13174 tests.
+
+
+class HolderAdmin(admin.ModelAdmin):
+
+ class Media:
+ js = ('my_awesome_admin_scripts.js',)
+
+
+class InnerInline2(admin.StackedInline):
+ model = Inner2
+
+ class Media:
+ js = ('my_awesome_inline_scripts.js',)
+
+
+class InnerInline3(admin.StackedInline):
+ model = Inner3
+
+ class Media:
+ js = ('my_awesome_inline_scripts.js',)
+
+
+class TitleForm(forms.ModelForm):
+
+ def clean(self):
+ cleaned_data = self.cleaned_data
+ title1 = cleaned_data.get("title1")
+ title2 = cleaned_data.get("title2")
+ if title1 != title2:
+ raise forms.ValidationError("The two titles must be the same")
+ return cleaned_data
+
+
+class TitleInline(admin.TabularInline):
+ model = Title
+ form = TitleForm
+ extra = 1
+
+
+class Inner4StackedInline(admin.StackedInline):
+ model = Inner4Stacked
+
+
+class Inner4TabularInline(admin.TabularInline):
+ model = Inner4Tabular
+
+
+class Holder4Admin(admin.ModelAdmin):
+ inlines = [Inner4StackedInline, Inner4TabularInline]
+
+
+class InlineWeakness(admin.TabularInline):
+ model = ShoppingWeakness
+ extra = 1
+
+
+class QuestionInline(admin.TabularInline):
+ model = Question
+ readonly_fields=['call_me']
+
+ def call_me(self, obj):
+ return 'Callable in QuestionInline'
+
+
+class PollAdmin(admin.ModelAdmin):
+ inlines = [QuestionInline]
+
+ def call_me(self, obj):
+ return 'Callable in PollAdmin'
+
+
+class ChapterInline(admin.TabularInline):
+ model = Chapter
+ readonly_fields=['call_me']
+
+ def call_me(self, obj):
+ return 'Callable in ChapterInline'
+
+
+class NovelAdmin(admin.ModelAdmin):
+ inlines = [ChapterInline]
+
+
+site.register(TitleCollection, inlines=[TitleInline])
+# Test bug #12561 and #12778
+# only ModelAdmin media
+site.register(Holder, HolderAdmin, inlines=[InnerInline])
+# ModelAdmin and Inline media
+site.register(Holder2, HolderAdmin, inlines=[InnerInline2])
+# only Inline media
+site.register(Holder3, inlines=[InnerInline3])
+
+site.register(Poll, PollAdmin)
+site.register(Novel, NovelAdmin)
+site.register(Fashionista, inlines=[InlineWeakness])
+site.register(Holder4, Holder4Admin)
+site.register(Author, AuthorAdmin)
Oops, something went wrong.

0 comments on commit 7b21bfc

Please sign in to comment.