Ticket #14642: inline-formset-test.diff

File inline-formset-test.diff, 6.1 KB (added by Paul Oswald, 14 years ago)
  • AUTHORS

    diff --git a/AUTHORS b/AUTHORS
    index 6c90cd0..41367e7 100644
    a b answer newbie questions, and generally made Django that much better:  
    369369    Neal Norwitz <nnorwitz@google.com>
    370370    Todd O'Bryan <toddobryan@mac.com>
    371371    Selwin Ong <selwin@ui.co.id>
     372    Paul Oswald <pauloswald@gmail.com>
    372373    Christian Oudard <christian.oudard@gmail.com>
    373374    oggie rob <oz.robharvey@gmail.com>
    374375    oggy <ognjen.maric@gmail.com>
  • tests/regressiontests/admin_inlines/models.py

    diff --git a/tests/regressiontests/admin_inlines/models.py b/tests/regressiontests/admin_inlines/models.py
    index bb299f3..c9fcc04 100644
    a b class Holder2(models.Model):  
    6666    dummy = models.IntegerField()
    6767
    6868
     69# Objects for bug #14642 Test
     70class Thing(models.Model):
     71    description = models.CharField(max_length=256)
     72
     73class ThingItem(models.Model):
     74    description = models.CharField(max_length=256)
     75    thing = models.ForeignKey(Thing)
     76
     77class ThingItemInline(admin.TabularInline):
     78    model = ThingItem
     79    extra = 0
     80
     81class ThingAdmin(admin.ModelAdmin):
     82    inlines = [ThingItemInline,]
     83
     84admin.site.register(Thing, ThingAdmin)
     85
     86
    6987class Inner2(models.Model):
    7088    dummy = models.IntegerField()
    7189    holder = models.ForeignKey(Holder2)
  • tests/regressiontests/admin_inlines/tests.py

    diff --git a/tests/regressiontests/admin_inlines/tests.py b/tests/regressiontests/admin_inlines/tests.py
    index 915c6fa..e0c17b0 100644
    a b  
    11from django.contrib.admin.helpers import InlineAdminForm
    22from django.contrib.contenttypes.models import ContentType
    33from django.test import TestCase
     4from django.core.urlresolvers import reverse
    45
    56# local test models
    67from models import (Holder, Inner, InnerInline, Holder2, Inner2, Holder3,
    7     Inner3, Person, OutfitItem, Fashionista, Teacher, Parent, Child)
    8 
     8    Inner3, Person, OutfitItem, Fashionista, Teacher, Parent, Child, Thing, ThingItem)
    99
    1010class TestInline(TestCase):
    1111    fixtures = ['admin-views-users.xml']
    class TestInlineAdminForm(TestCase):  
    136136        iaf = InlineAdminForm(None, None, {}, {}, joe)
    137137        parent_ct = ContentType.objects.get_for_model(Parent)
    138138        self.assertEqual(iaf.original.content_type, parent_ct)
     139
     140class TestEditingInlineViews(TestCase):
     141    fixtures = ['admin-views-users.xml']
     142
     143    def setUp(self):
     144        result = self.client.login(username='super', password='secret')
     145        self.failUnlessEqual(result, True)
     146        # Set up a thing to be modified in the test
     147        self.thing = Thing.objects.create(description="Parent object")
     148        self.thing_item_1 = ThingItem.objects.create(description="Item #1", thing=self.thing)
     149        self.thing_item_2 = ThingItem.objects.create(description="Item #2", thing=self.thing)
     150
     151    def tearDown(self):
     152        self.client.logout()
     153        self.thing_item_1.delete()
     154        self.thing_item_2.delete()
     155        self.thing.delete()
     156
     157    def test_concurrent_editing_views(self):
     158        """
     159        A ``POST`` to the edit view by two clients simultaneously is properly handled
     160
     161        We are going to simulate two test clients by submitting slightly different data twice.
     162        This would be equivalent to working with two tabs open in a browser. Individually each of
     163        these forms is valid but the second one is invalid when submitted one after the other. The
     164        server needs to handle this case.
     165        """
     166
     167        data = [
     168            # An existing item has been deleted.
     169            {
     170                u'description': [u'A new description'],
     171                u'thingitem_set-MAX_NUM_FORMS': [u'0'],
     172                u'thingitem_set-TOTAL_FORMS': [u'2'],
     173                u'thingitem_set-INITIAL_FORMS': [u'2'],
     174                u'thingitem_set-0-DELETE': [u''],
     175                u'thingitem_set-0-id': [u'%s' % (self.thing_item_1.pk,)],
     176                u'thingitem_set-0-thing': [u'%s' % (self.thing.pk,)],
     177                u'thingitem_set-0-description': [u'New item #1 description'],
     178                u'thingitem_set-1-DELETE': [u'on'],
     179                u'thingitem_set-1-id': [u'%s' % (self.thing_item_2.pk,)],
     180                u'thingitem_set-1-thing': [u'%s' % (self.thing.pk,)],
     181                u'thingitem_set-1-description': [u'Deleted item #2 description'],
     182            },
     183
     184            # In this second form, we are now attempting to edit the deleted item. This form is
     185            # invalid but the user submitting it doesn't know that yet.
     186            {
     187                u'description': [u'A new description #2'],
     188                u'thingitem_set-MAX_NUM_FORMS': [u'0'],
     189                u'thingitem_set-TOTAL_FORMS': [u'2'],
     190                u'thingitem_set-INITIAL_FORMS': [u'2'],
     191                u'thingitem_set-0-DELETE': [u''],
     192                u'thingitem_set-0-id': [u'%s' % (self.thing_item_1.pk,)],
     193                u'thingitem_set-0-thing': [u'%s' % (self.thing.pk,)],
     194                u'thingitem_set-0-description': [u'New item #1 description'],
     195                u'thingitem_set-1-DELETE': [u''],
     196                u'thingitem_set-1-id': [u'%s' % (self.thing_item_2.pk,)],
     197                u'thingitem_set-1-thing': [u'%s' % (self.thing.pk,)],
     198                u'thingitem_set-1-description': [u'Deleted item #2 description'],
     199            },
     200        ]
     201        edit_url = 'admin:%s_%s_change' %(self.thing._meta.app_label,  self.thing._meta.module_name)
     202        view_url = 'admin:%s_%s_changelist' %(self.thing._meta.app_label,  self.thing._meta.module_name)
     203
     204        count = Thing.objects.count()
     205        response = self.client.post(reverse(edit_url, args=[self.thing.pk]), data[0])
     206
     207        # Check our first edit was accepted
     208        self.assertRedirects(response, reverse(view_url), 302, 200)
     209
     210        # Submit the second form. (this might be a second tab in the browser, or a second user)
     211        response = self.client.post(reverse(edit_url, args=[self.thing.pk]), data[1])
     212
     213        # Check our second edit was handled
     214        self.assertRedirects(response, reverse(view_url), 302, 200)
     215
     216
Back to Top