|
1 from django.contrib.admin.helpers import InlineAdminForm |
|
2 from django.contrib.contenttypes.models import ContentType |
|
3 from django.test import TestCase |
|
4 |
|
5 # local test models |
|
6 from models import (Holder, Inner, InnerInline, Holder2, Inner2, Holder3, |
|
7 Inner3, Person, OutfitItem, Fashionista, Teacher, Parent, Child) |
|
8 |
|
9 |
|
10 class TestInline(TestCase): |
|
11 fixtures = ['admin-views-users.xml'] |
|
12 |
|
13 def setUp(self): |
|
14 holder = Holder(dummy=13) |
|
15 holder.save() |
|
16 Inner(dummy=42, holder=holder).save() |
|
17 self.change_url = '/test_admin/admin/admin_inlines/holder/%i/' % holder.id |
|
18 |
|
19 result = self.client.login(username='super', password='secret') |
|
20 self.assertEqual(result, True) |
|
21 |
|
22 def tearDown(self): |
|
23 self.client.logout() |
|
24 |
|
25 def test_can_delete(self): |
|
26 """ |
|
27 can_delete should be passed to inlineformset factory. |
|
28 """ |
|
29 response = self.client.get(self.change_url) |
|
30 inner_formset = response.context[-1]['inline_admin_formsets'][0].formset |
|
31 expected = InnerInline.can_delete |
|
32 actual = inner_formset.can_delete |
|
33 self.assertEqual(expected, actual, 'can_delete must be equal') |
|
34 |
|
35 def test_readonly_stacked_inline_label(self): |
|
36 """Bug #13174.""" |
|
37 holder = Holder.objects.create(dummy=42) |
|
38 inner = Inner.objects.create(holder=holder, dummy=42, readonly='') |
|
39 response = self.client.get('/test_admin/admin/admin_inlines/holder/%i/' |
|
40 % holder.id) |
|
41 self.assertContains(response, '<label>Inner readonly label:</label>') |
|
42 |
|
43 def test_many_to_many_inlines(self): |
|
44 "Autogenerated many-to-many inlines are displayed correctly (#13407)" |
|
45 response = self.client.get('/test_admin/admin/admin_inlines/author/add/') |
|
46 # The heading for the m2m inline block uses the right text |
|
47 self.assertContains(response, '<h2>Author-book relationships</h2>') |
|
48 # The "add another" label is correct |
|
49 self.assertContains(response, 'Add another Author-Book Relationship') |
|
50 # The '+' is dropped from the autogenerated form prefix (Author_books+) |
|
51 self.assertContains(response, 'id="id_Author_books-TOTAL_FORMS"') |
|
52 |
|
53 def test_inline_primary(self): |
|
54 person = Person.objects.create(firstname='Imelda') |
|
55 item = OutfitItem.objects.create(name='Shoes') |
|
56 # Imelda likes shoes, but can't cary her own bags. |
|
57 data = { |
|
58 'shoppingweakness_set-TOTAL_FORMS': 1, |
|
59 'shoppingweakness_set-INITIAL_FORMS': 0, |
|
60 'shoppingweakness_set-MAX_NUM_FORMS': 0, |
|
61 '_save': u'Save', |
|
62 'person': person.id, |
|
63 'max_weight': 0, |
|
64 'shoppingweakness_set-0-item': item.id, |
|
65 } |
|
66 response = self.client.post('/test_admin/admin/admin_inlines/fashionista/add/', data) |
|
67 self.assertEqual(response.status_code, 302) |
|
68 self.assertEqual(len(Fashionista.objects.filter(person__firstname='Imelda')), 1) |
|
69 |
|
70 class TestInlineMedia(TestCase): |
|
71 fixtures = ['admin-views-users.xml'] |
|
72 |
|
73 def setUp(self): |
|
74 |
|
75 result = self.client.login(username='super', password='secret') |
|
76 self.assertEqual(result, True) |
|
77 |
|
78 def tearDown(self): |
|
79 self.client.logout() |
|
80 |
|
81 def test_inline_media_only_base(self): |
|
82 holder = Holder(dummy=13) |
|
83 holder.save() |
|
84 Inner(dummy=42, holder=holder).save() |
|
85 change_url = '/test_admin/admin/admin_inlines/holder/%i/' % holder.id |
|
86 response = self.client.get(change_url) |
|
87 self.assertContains(response, 'my_awesome_admin_scripts.js') |
|
88 |
|
89 def test_inline_media_only_inline(self): |
|
90 holder = Holder3(dummy=13) |
|
91 holder.save() |
|
92 Inner3(dummy=42, holder=holder).save() |
|
93 change_url = '/test_admin/admin/admin_inlines/holder3/%i/' % holder.id |
|
94 response = self.client.get(change_url) |
|
95 self.assertContains(response, 'my_awesome_inline_scripts.js') |
|
96 |
|
97 def test_all_inline_media(self): |
|
98 holder = Holder2(dummy=13) |
|
99 holder.save() |
|
100 Inner2(dummy=42, holder=holder).save() |
|
101 change_url = '/test_admin/admin/admin_inlines/holder2/%i/' % holder.id |
|
102 response = self.client.get(change_url) |
|
103 self.assertContains(response, 'my_awesome_admin_scripts.js') |
|
104 self.assertContains(response, 'my_awesome_inline_scripts.js') |
|
105 |
|
106 class TestInlineAdminForm(TestCase): |
|
107 |
|
108 def test_immutable_content_type(self): |
|
109 """Regression for #9362 |
|
110 The problem depends only on InlineAdminForm and its "original" |
|
111 argument, so we can safely set the other arguments to None/{}. We just |
|
112 need to check that the content_type argument of Child isn't altered by |
|
113 the internals of the inline form.""" |
|
114 |
|
115 sally = Teacher.objects.create(name='Sally') |
|
116 john = Parent.objects.create(name='John') |
|
117 joe = Child.objects.create(name='Joe', teacher=sally, parent=john) |
|
118 |
|
119 iaf = InlineAdminForm(None, None, {}, {}, joe) |
|
120 parent_ct = ContentType.objects.get_for_model(Parent) |
|
121 self.assertEqual(iaf.original.content_type, parent_ct) |