Commit 7b21bfc0 authored by Ramiro Morales's avatar Ramiro Morales
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
parent fc06ec0d
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
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)
+12 −62
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@ from __future__ import with_statement
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 django.contrib.auth.models import User
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 @@ class ChangeListTests(TestCase):
            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 @@ class ChangeListTests(TestCase):
            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 @@ class ChangeListTests(TestCase):
        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 @@ class ChangeListTests(TestCase):
        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
+7 −0
Original line number Diff line number Diff line
from django.conf.urls import patterns, include

import admin

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
)
+117 −0
Original line number Diff line number Diff line
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)
+5 −100
Original line number Diff line number Diff line
@@ -3,10 +3,9 @@ Testing of admin inline formsets.

"""
from django.db import models
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django import forms


class Parent(models.Model):
    name = models.CharField(max_length=50)
@@ -14,12 +13,14 @@ class Parent(models.Model):
    def __unicode__(self):
        return self.name


class Teacher(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name


class Child(models.Model):
    name = models.CharField(max_length=50)
    teacher = models.ForeignKey(Teacher)
@@ -31,20 +32,15 @@ class Child(models.Model):
    def __unicode__(self):
        return u'I am %s, a child of %s' % (self.name, self.parent)


class Book(models.Model):
    name = models.CharField(max_length=50)


class Author(models.Model):
    name = models.CharField(max_length=50)
    books = models.ManyToManyField(Book)

class BookInline(admin.TabularInline):
    model = Author.books.through

class AuthorAdmin(admin.ModelAdmin):
    inlines = [BookInline]

admin.site.register(Author, AuthorAdmin)

class Holder(models.Model):
    dummy = models.IntegerField()
@@ -56,12 +52,6 @@ class Inner(models.Model):
    readonly = models.CharField("Inner readonly label", max_length=1)


class InnerInline(admin.StackedInline):
    model = Inner
    can_delete = False
    readonly_fields = ('readonly',) # For bug #13174 tests.


class Holder2(models.Model):
    dummy = models.IntegerField()

@@ -70,17 +60,6 @@ class Inner2(models.Model):
    dummy = models.IntegerField()
    holder = models.ForeignKey(Holder2)

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 Holder3(models.Model):
    dummy = models.IntegerField()

@@ -89,21 +68,6 @@ class Inner3(models.Model):
    dummy = models.IntegerField()
    holder = models.ForeignKey(Holder3)

class InnerInline3(admin.StackedInline):
    model = Inner3

    class Media:
        js = ('my_awesome_inline_scripts.js',)

# Test bug #12561 and #12778
# only ModelAdmin media
admin.site.register(Holder, HolderAdmin, inlines=[InnerInline])
# ModelAdmin and Inline media
admin.site.register(Holder2, HolderAdmin, inlines=[InnerInline2])
# only Inline media
admin.site.register(Holder3, inlines=[InnerInline3])


# Models for ticket #8190

class Holder4(models.Model):
@@ -117,17 +81,6 @@ class Inner4Tabular(models.Model):
    dummy = models.IntegerField(help_text="Awesome tabular help text is awesome.")
    holder = models.ForeignKey(Holder4)

class Inner4StackedInline(admin.StackedInline):
    model = Inner4Stacked

class Inner4TabularInline(admin.TabularInline):
    model = Inner4Tabular

class Holder4Admin(admin.ModelAdmin):
    inlines = [Inner4StackedInline, Inner4TabularInline]

admin.site.register(Holder4, Holder4Admin)


# Models for #12749

@@ -145,12 +98,6 @@ class ShoppingWeakness(models.Model):
    fashionista = models.ForeignKey(Fashionista)
    item = models.ForeignKey(OutfitItem)

class InlineWeakness(admin.TabularInline):
    model = ShoppingWeakness
    extra = 1

admin.site.register(Fashionista, inlines=[InlineWeakness])

# Models for #13510

class TitleCollection(models.Model):
@@ -161,23 +108,6 @@ class Title(models.Model):
    title1 = models.CharField(max_length=100)
    title2 = models.CharField(max_length=100)

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

admin.site.register(TitleCollection, inlines=[TitleInline])

# Models for #15424

class Poll(models.Model):
@@ -186,34 +116,9 @@ class Poll(models.Model):
class Question(models.Model):
    poll = models.ForeignKey(Poll)

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 Novel(models.Model):
    name = models.CharField(max_length=40)

class Chapter(models.Model):
    novel = models.ForeignKey(Novel)
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]

admin.site.register(Poll, PollAdmin)
admin.site.register(Novel, NovelAdmin)
Loading