1from django.test import TestCase
2from django.urls import reverse
3
4from wagtail.core.models import Collection
5from wagtail.documents.models import Document
6from wagtail.tests.utils import WagtailTestUtils
7
8
9class TestCollectionsIndexView(TestCase, WagtailTestUtils):
10    def setUp(self):
11        self.login()
12
13    def get(self, params={}):
14        return self.client.get(reverse('wagtailadmin_collections:index'), params)
15
16    def test_simple(self):
17        response = self.get()
18        self.assertEqual(response.status_code, 200)
19        self.assertTemplateUsed(response, 'wagtailadmin/collections/index.html')
20
21        # Initially there should be no collections listed
22        # (Root should not be shown)
23        self.assertContains(response, "No collections have been created.")
24
25        root_collection = Collection.get_first_root_node()
26        self.collection = root_collection.add_child(name="Holiday snaps")
27
28        # Now the listing should contain our collection
29        response = self.get()
30        self.assertEqual(response.status_code, 200)
31        self.assertTemplateUsed(response, 'wagtailadmin/collections/index.html')
32        self.assertNotContains(response, "No collections have been created.")
33        self.assertContains(response, "Holiday snaps")
34
35    def test_ordering(self):
36        root_collection = Collection.get_first_root_node()
37        root_collection.add_child(name="Milk")
38        root_collection.add_child(name="Bread")
39        root_collection.add_child(name="Avocado")
40        response = self.get()
41        # Note that the Collections have been automatically sorted by name.
42        self.assertEqual(
43            [collection.name for collection in response.context['object_list']],
44            ['Avocado', 'Bread', 'Milk'])
45
46    def test_nested_ordering(self):
47        root_collection = Collection.get_first_root_node()
48
49        vegetables = root_collection.add_child(name="Vegetable")
50        vegetables.add_child(name="Spinach")
51        vegetables.add_child(name="Cucumber")
52
53        animals = root_collection.add_child(name="Animal")
54        animals.add_child(name="Dog")
55        animals.add_child(name="Cat")
56
57        response = self.get()
58        # Note that while we added the collections at level 1 in reverse-alpha order, they come back out in alpha order.
59        # And we added the Collections at level 2 in reverse-alpha order as well, but they were also alphabetized
60        # within their respective trees. This is the result of setting Collection.node_order_by = ['name'].
61        self.assertEqual(
62            [collection.name for collection in response.context['object_list']],
63            ['Animal', 'Cat', 'Dog', 'Vegetable', 'Cucumber', 'Spinach'])
64
65
66class TestAddCollection(TestCase, WagtailTestUtils):
67    def setUp(self):
68        self.login()
69
70    def get(self, params={}):
71        return self.client.get(reverse('wagtailadmin_collections:add'), params)
72
73    def post(self, post_data={}):
74        return self.client.post(reverse('wagtailadmin_collections:add'), post_data)
75
76    def test_get(self):
77        response = self.get()
78        self.assertEqual(response.status_code, 200)
79
80    def test_post(self):
81        response = self.post({
82            'name': "Holiday snaps",
83        })
84
85        # Should redirect back to index
86        self.assertRedirects(response, reverse('wagtailadmin_collections:index'))
87
88        # Check that the collection was created and is a child of root
89        self.assertEqual(Collection.objects.filter(name="Holiday snaps").count(), 1)
90
91        root_collection = Collection.get_first_root_node()
92        self.assertEqual(
93            Collection.objects.get(name="Holiday snaps").get_parent(),
94            root_collection
95        )
96
97
98class TestEditCollection(TestCase, WagtailTestUtils):
99    def setUp(self):
100        self.login()
101        self.root_collection = Collection.get_first_root_node()
102        self.collection = self.root_collection.add_child(name="Holiday snaps")
103        self.l1 = self.root_collection.add_child(name="Level 1")
104        self.l2 = self.l1.add_child(name="Level 2")
105        self.l3 = self.l2.add_child(name="Level 3")
106
107    def get(self, params={}, collection_id=None):
108        return self.client.get(
109            reverse('wagtailadmin_collections:edit', args=(collection_id or self.collection.id,)),
110            params
111        )
112
113    def post(self, post_data={}, collection_id=None):
114        return self.client.post(
115            reverse('wagtailadmin_collections:edit', args=(collection_id or self.collection.id,)),
116            post_data
117        )
118
119    def test_get(self):
120        response = self.get()
121        self.assertEqual(response.status_code, 200)
122
123    def test_cannot_edit_root_collection(self):
124        response = self.get(collection_id=self.root_collection.id)
125        self.assertEqual(response.status_code, 404)
126
127    def test_get_nonexistent_collection(self):
128        response = self.get(collection_id=100000)
129        self.assertEqual(response.status_code, 404)
130
131    def test_move_collection(self):
132        self.post({'name': "Level 2", 'parent': self.root_collection.pk}, self.l2.pk)
133        self.assertEqual(
134            Collection.objects.get(pk=self.l2.pk).get_parent().pk,
135            self.root_collection.pk,
136        )
137
138    def test_cannot_move_parent_collection_to_descendant(self):
139        self.post({'name': "Level 2", 'parent': self.l3.pk}, self.l2.pk)
140        self.assertEqual(
141            Collection.objects.get(pk=self.l2.pk).get_parent().pk,
142            self.l1.pk
143        )
144
145    def test_post(self):
146        response = self.post({'name': "Skiing photos"}, self.collection.pk)
147
148        # Should redirect back to index
149        self.assertRedirects(response, reverse('wagtailadmin_collections:index'))
150
151        # Check that the collection was edited
152        self.assertEqual(
153            Collection.objects.get(id=self.collection.id).name,
154            "Skiing photos"
155        )
156
157
158class TestDeleteCollection(TestCase, WagtailTestUtils):
159    def setUp(self):
160        self.login()
161        self.root_collection = Collection.get_first_root_node()
162        self.collection = self.root_collection.add_child(name="Holiday snaps")
163
164    def get(self, params={}, collection_id=None):
165        return self.client.get(
166            reverse('wagtailadmin_collections:delete', args=(collection_id or self.collection.id,)),
167            params
168        )
169
170    def post(self, post_data={}, collection_id=None):
171        return self.client.post(
172            reverse('wagtailadmin_collections:delete', args=(collection_id or self.collection.id,)),
173            post_data
174        )
175
176    def test_get(self):
177        response = self.get()
178        self.assertEqual(response.status_code, 200)
179        self.assertTemplateUsed(response, 'wagtailadmin/generic/confirm_delete.html')
180
181    def test_cannot_delete_root_collection(self):
182        response = self.get(collection_id=self.root_collection.id)
183        self.assertEqual(response.status_code, 404)
184
185    def test_get_nonexistent_collection(self):
186        response = self.get(collection_id=100000)
187        self.assertEqual(response.status_code, 404)
188
189    def test_get_nonempty_collection(self):
190        Document.objects.create(
191            title="Test document", collection=self.collection
192        )
193
194        response = self.get()
195        self.assertEqual(response.status_code, 200)
196        self.assertTemplateUsed(response, 'wagtailadmin/collections/delete_not_empty.html')
197
198    def test_get_collection_with_descendent(self):
199        self.collection.add_child(instance=Collection(name='Test collection'))
200
201        response = self.get()
202        self.assertEqual(response.status_code, 200)
203        self.assertTemplateUsed(response, 'wagtailadmin/collections/delete_not_empty.html')
204
205    def test_post(self):
206        response = self.post()
207
208        # Should redirect back to index
209        self.assertRedirects(response, reverse('wagtailadmin_collections:index'))
210
211        # Check that the collection was deleted
212        with self.assertRaises(Collection.DoesNotExist):
213            Collection.objects.get(id=self.collection.id)
214
215    def test_post_nonempty_collection(self):
216        Document.objects.create(
217            title="Test document", collection=self.collection
218        )
219
220        response = self.post()
221        self.assertEqual(response.status_code, 403)
222
223        # Check that the collection was not deleted
224        self.assertTrue(Collection.objects.get(id=self.collection.id))
225
226    def test_post_collection_with_descendant(self):
227        self.collection.add_child(instance=Collection(name='Test collection'))
228
229        response = self.post()
230        self.assertEqual(response.status_code, 403)
231
232        # Check that the collection was not deleted
233        self.assertTrue(Collection.objects.get(id=self.collection.id))
234