PageRenderTime 42ms CodeModel.GetById 2ms app.highlight 35ms RepoModel.GetById 1ms app.codeStats 0ms

/main/tests/test_form_show.py

https://github.com/zoulema/formhub
Python | 432 lines | 362 code | 44 blank | 26 comment | 10 complexity | dc8c0d76b6d90ce6613fd2fc711dcc1e MD5 | raw file
  1import os
  2from test_base import MainTestCase
  3from main.views import show, form_photos, update_xform, profile, enketo_preview
  4from django.core.urlresolvers import reverse
  5from odk_logger.models import XForm
  6from odk_logger.views import download_xlsform, download_jsonform,\
  7    download_xform, delete_xform
  8from odk_viewer.views import export_list, map_view
  9from utils.user_auth import http_auth_string
 10from odk_viewer.models import ParsedInstance
 11
 12
 13class TestFormShow(MainTestCase):
 14
 15    def setUp(self):
 16        MainTestCase.setUp(self)
 17        self._create_user_and_login()
 18        self._publish_transportation_form()
 19        self.url = reverse(show, kwargs={
 20            'username': self.user.username,
 21            'id_string': self.xform.id_string
 22        })
 23
 24    def test_show_form_name(self):
 25        response = self.client.get(self.url)
 26        self.assertEqual(response.status_code, 200)
 27        self.assertContains(response, self.xform.id_string)
 28
 29    def test_hide_from_anon(self):
 30        response = self.anon.get(self.url)
 31        self.assertEqual(response.status_code, 302)
 32
 33    def test_hide_from_not_user(self):
 34        self._create_user_and_login("jo")
 35        response = self.client.get(self.url)
 36        self.assertEqual(response.status_code, 302)
 37
 38    def test_show_to_anon_if_public(self):
 39        self.xform.shared = True
 40        self.xform.save()
 41        response = self.anon.get(self.url)
 42        self.assertEqual(response.status_code, 200)
 43
 44    def test_dl_xlsx_xlsform(self):
 45        self._publish_xlsx_file()
 46        response = self.client.get(reverse(download_xlsform, kwargs={
 47            'username': self.user.username,
 48            'id_string': 'exp_one'
 49        }))
 50        self.assertEqual(response.status_code, 200)
 51        self.assertEqual(
 52            response['Content-Disposition'],
 53            "attachment; filename=exp_one.xlsx")
 54
 55    def test_dl_xls_to_anon_if_public(self):
 56        self.xform.shared = True
 57        self.xform.save()
 58        response = self.anon.get(reverse(download_xlsform, kwargs={
 59            'username': self.user.username,
 60            'id_string': self.xform.id_string
 61        }))
 62        self.assertEqual(response.status_code, 200)
 63
 64    def test_dl_xls_for_basic_auth(self):
 65        extra = {
 66            'HTTP_AUTHORIZATION':
 67            http_auth_string(self.login_username, self.login_password)
 68        }
 69        response = self.anon.get(reverse(download_xlsform, kwargs={
 70            'username': self.user.username,
 71            'id_string': self.xform.id_string
 72        }), **extra)
 73        self.assertEqual(response.status_code, 200)
 74
 75    def test_dl_json_to_anon_if_public(self):
 76        self.xform.shared = True
 77        self.xform.save()
 78        response = self.anon.get(reverse(download_jsonform, kwargs={
 79            'username': self.user.username,
 80            'id_string': self.xform.id_string
 81        }))
 82        self.assertEqual(response.status_code, 200)
 83
 84    def test_dl_jsonp_to_anon_if_public(self):
 85        self.xform.shared = True
 86        self.xform.save()
 87        callback = 'jsonpCallback'
 88        response = self.anon.get(reverse(download_jsonform, kwargs={
 89            'username': self.user.username,
 90            'id_string': self.xform.id_string
 91        }), {'callback': callback})
 92        self.assertEqual(response.status_code, 200)
 93        self.assertEqual(response.content.startswith(callback + '('), True)
 94        self.assertEqual(response.content.endswith(')'), True)
 95
 96    def test_dl_json_for_basic_auth(self):
 97        extra = {
 98            'HTTP_AUTHORIZATION':
 99            http_auth_string(self.login_username, self.login_password)
100        }
101        response = self.anon.get(reverse(download_jsonform, kwargs={
102            'username': self.user.username,
103            'id_string': self.xform.id_string
104        }), **extra)
105        self.assertEqual(response.status_code, 200)
106
107    def test_dl_json_for_cors_options(self):
108        response = self.anon.options(reverse(download_jsonform, kwargs={
109            'username': self.user.username,
110            'id_string': self.xform.id_string
111        }))
112        allowed_headers = ['Accept', 'Origin', 'X-Requested-With',
113                           'Authorization']
114        control_headers = response['Access-Control-Allow-Headers']
115        provided_headers = [h.strip() for h in control_headers.split(',')]
116        self.assertListEqual(allowed_headers, provided_headers)
117        self.assertEqual(response['Access-Control-Allow-Methods'], 'GET')
118        self.assertEqual(response['Access-Control-Allow-Origin'], '*')
119
120    def test_dl_xform_to_anon_if_public(self):
121        self.xform.shared = True
122        self.xform.save()
123        response = self.anon.get(reverse(download_xform, kwargs={
124            'username': self.user.username,
125            'id_string': self.xform.id_string
126        }))
127        self.assertEqual(response.status_code, 200)
128
129    def test_dl_xform_for_basic_auth(self):
130        extra = {
131            'HTTP_AUTHORIZATION':
132            http_auth_string(self.login_username, self.login_password)
133        }
134        response = self.anon.get(reverse(download_xform, kwargs={
135            'username': self.user.username,
136            'id_string': self.xform.id_string
137        }), **extra)
138        self.assertEqual(response.status_code, 200)
139
140    def test_show_private_if_shared_but_not_data(self):
141        self.xform.shared = True
142        self.xform.save()
143        response = self.anon.get(self.url)
144        self.assertContains(response, 'PRIVATE')
145
146    def test_show_link_if_shared_and_data(self):
147        self.xform.shared = True
148        self.xform.shared_data = True
149        self.xform.save()
150        self._submit_transport_instance()
151        response = self.anon.get(self.url)
152        self.assertContains(response, reverse(export_list, kwargs={
153            'username': self.user.username,
154            'id_string': self.xform.id_string,
155            'export_type': 'csv'
156        }))
157
158    def test_show_link_if_owner(self):
159        self._submit_transport_instance()
160        response = self.client.get(self.url)
161        self.assertContains(response, reverse(export_list, kwargs={
162            'username': self.user.username,
163            'id_string': self.xform.id_string,
164            'export_type': 'csv'
165        }))
166        self.assertContains(response, reverse(export_list, kwargs={
167            'username': self.user.username,
168            'id_string': self.xform.id_string,
169            'export_type': 'xls'
170        }))
171        self.assertNotContains(response, reverse(map_view, kwargs={
172            'username': self.user.username,
173            'id_string': self.xform.id_string
174        }))
175
176        # check that a form with geopoints has the map url
177        response = self._publish_xls_file(
178            os.path.join(
179                os.path.dirname(__file__), "fixtures", "gps", "gps.xls"))
180        self.assertEqual(response.status_code, 200)
181        self.xform = XForm.objects.latest('date_created')
182
183        show_url = reverse(show, kwargs={
184            'username': self.user.username,
185            'id_string': self.xform.id_string
186        })
187        map_url = reverse(map_view, kwargs={
188            'username': self.user.username,
189            'id_string': self.xform.id_string
190        })
191        response = self.client.get(show_url)
192        # check that map url doesnt show before we have submissions
193        self.assertNotContains(response, map_url)
194
195        # make a submission
196        self._make_submission(
197            os.path.join(
198                os.path.dirname(__file__), "fixtures", "gps", "instances",
199                "gps_1980-01-23_20-52-08.xml")
200        )
201        self.assertEqual(self.response.status_code, 201)
202        # get new show view
203        response = self.client.get(show_url)
204        self.assertContains(response, map_url)
205
206    def test_user_sees_edit_btn(self):
207        response = self.client.get(self.url)
208        self.assertContains(response, 'edit</a>')
209
210    def test_user_sees_settings(self):
211        response = self.client.get(self.url)
212        self.assertContains(response, 'Settings')
213
214    def test_anon_no_edit_btn(self):
215        self.xform.shared = True
216        self.xform.save()
217        response = self.anon.get(self.url)
218        self.assertNotContains(response, 'edit</a>')
219
220    def test_anon_no_toggle_data_share_btn(self):
221        self.xform.shared = True
222        self.xform.save()
223        response = self.anon.get(self.url)
224        self.assertNotContains(response, 'PUBLIC</a>')
225        self.assertNotContains(response, 'PRIVATE</a>')
226
227    def test_show_add_sourc_doc_if_owner(self):
228        response = self.client.get(self.url)
229        self.assertContains(response, 'Source document:')
230
231    def test_show_add_supporting_docs_if_owner(self):
232        response = self.client.get(self.url)
233        self.assertContains(response, 'Supporting document:')
234
235    def test_show_add_supporting_media_if_owner(self):
236        response = self.client.get(self.url)
237        self.assertContains(response, 'Media upload:')
238
239    def test_show_add_mapbox_layer_if_owner(self):
240        response = self.client.get(self.url)
241        self.assertContains(response, 'JSONP url:')
242
243    def test_hide_add_supporting_docs_if_not_owner(self):
244        self.xform.shared = True
245        self.xform.save()
246        response = self.anon.get(self.url)
247        self.assertNotContains(response, 'Upload')
248
249    def test_load_photo_page(self):
250        response = self.client.get(reverse(form_photos, kwargs={
251            'username': self.user.username,
252            'id_string': self.xform.id_string}))
253        self.assertEqual(response.status_code, 200)
254
255    def test_load_from_uuid(self):
256        self.xform = XForm.objects.get(pk=self.xform.id)
257        response = self.client.get(reverse(show, kwargs={
258            'uuid': self.xform.uuid}))
259        self.assertEqual(response.status_code, 302)
260        self.assertEqual(response['Location'],
261                         '%s%s' % (self.base_url, self.url))
262
263    def test_xls_replace_markup(self):
264        """
265        Check that update form is only shown when there are no submissions
266        and the user is the owner
267        """
268        # when we have 0 submissions, update markup exists
269        self.xform.shared = True
270        self.xform.save()
271        dashboard_url = reverse(profile, kwargs={
272            'username': 'bob'
273        })
274        response = self.client.get(dashboard_url)
275        self.assertContains(
276            response, 'href="#replace-transportation_2011_07_25"')
277        # a non owner can't see the markup
278        response = self.anon.get(self.url)
279        self.assertNotContains(
280            response, 'href="#replace-transportation_2011_07_25"')
281        # when we have a submission, we cant update the xls form
282        self._submit_transport_instance()
283        response = self.client.get(dashboard_url)
284        self.assertNotContains(
285            response, 'href="#replace-transportation_2011_07_25"')
286
287    def test_non_owner_cannot_replace_form(self):
288        """
289        Test that a non owner cannot replace a shared xls form
290        """
291        xform_update_url = reverse(update_xform, kwargs={
292            'username': self.user.username,
293            'id_string': self.xform.id_string
294        })
295        self.xform.shared = True
296        self.xform.save()
297        # create and login another user
298        self._create_user_and_login('peter', 'peter')
299        response = self.client.post(xform_update_url)
300        # since we are logged in, we'll be re-directed to our profile page
301        self.assertRedirects(response, self.base_url,
302                             status_code=302, target_status_code=302)
303
304    def test_replace_xform(self):
305        xform_update_url = reverse(update_xform, kwargs={
306            'username': self.user.username,
307            'id_string': self.xform.id_string
308        })
309        count = XForm.objects.count()
310        xls_path = os.path.join(self.this_directory, "fixtures",
311                                "transportation", "transportation_updated.xls")
312        with open(xls_path, "r") as xls_file:
313            post_data = {'xls_file': xls_file}
314            self.client.post(xform_update_url, post_data)
315        self.assertEqual(XForm.objects.count(), count)
316        self.xform = XForm.objects.order_by('id').reverse()[0]
317        data_dictionary = self.xform.data_dictionary()
318        # look for the preferred_means question
319        # which is only in the updated xls
320        is_updated_form = len([e.name for e in data_dictionary.survey_elements
321                               if e.name == u'preferred_means']) > 0
322        self.assertTrue(is_updated_form)
323
324    def test_update_form_doesnt_truncate_to_50_chars(self):
325        count = XForm.objects.count()
326        xls_path = os.path.join(
327            self.this_directory,
328            "fixtures",
329            "transportation",
330            "transportation_with_long_id_string.xls")
331        self._publish_xls_file_and_set_xform(xls_path)
332
333        # Update the form
334        xform_update_url = reverse(update_xform, kwargs={
335            'username': self.user.username,
336            'id_string': self.xform.id_string
337        })
338        updated_xls_path = os.path.join(
339            self.this_directory,
340            "fixtures",
341            "transportation",
342            "transportation_with_long_id_string_updated.xls")
343        with open(updated_xls_path, "r") as xls_file:
344            post_data = {'xls_file': xls_file}
345            self.client.post(xform_update_url, post_data)
346        # Count should stay the same
347        self.assertEqual(XForm.objects.count(), count + 1)
348        self.xform = XForm.objects.order_by('id').reverse()[0]
349        data_dictionary = self.xform.data_dictionary()
350        # look for the preferred_means question
351        # which is only in the updated xls
352        is_updated_form = len([e.name for e in data_dictionary.survey_elements
353                               if e.name == u'preferred_means']) > 0
354        self.assertTrue(is_updated_form)
355
356    def test_xform_delete(self):
357        id_string = self.xform.id_string
358        form_exists = XForm.objects.filter(
359            user=self.user, id_string=id_string).count() == 1
360        self.assertTrue(form_exists)
361        xform_delete_url = reverse(delete_xform, kwargs={
362            'username': self.user.username,
363            'id_string': id_string
364        })
365        self.client.post(xform_delete_url)
366        form_deleted = XForm.objects.filter(
367            user=self.user, id_string=id_string).count() == 0
368        self.assertTrue(form_deleted)
369
370    def test_non_owner_cant_delete_xform(self):
371        id_string = self.xform.id_string
372        form_exists = XForm.objects.filter(
373            user=self.user, id_string=id_string).count() == 1
374        self.assertTrue(form_exists)
375        xform_delete_url = reverse(delete_xform, kwargs={
376            'username': self.user.username,
377            'id_string': id_string
378        })
379        # save current user before we re-assign
380        bob = self.user
381        self._create_user_and_login('alice', 'alice')
382        self.client.post(xform_delete_url)
383        form_deleted = XForm.objects.filter(
384            user=bob, id_string=id_string).count() == 0
385        self.assertFalse(form_deleted)
386
387    def test_xform_delete_cascades_mongo_instances(self):
388        initial_mongo_count = ParsedInstance.query_mongo(
389            self.user.username, self.xform.id_string, '{}', '[]', '{}',
390            count=True)[0]["count"]
391        # submit instance
392        for i in range(len(self.surveys)):
393            self._submit_transport_instance(i)
394        # check mongo record exists
395        mongo_count = ParsedInstance.query_mongo(
396            self.user.username, self.xform.id_string, '{}', '[]', '{}',
397            count=True)[0]["count"]
398        self.assertEqual(mongo_count, initial_mongo_count + len(self.surveys))
399        # delete form
400        xform_delete_url = reverse(delete_xform, kwargs={
401            'username': self.user.username,
402            'id_string': self.xform.id_string
403        })
404        self.client.post(xform_delete_url)
405        mongo_count = ParsedInstance.query_mongo(
406            self.user.username, self.xform.id_string, '{}', '[]', '{}',
407            count=True)[0]["count"]
408        self.assertEqual(mongo_count, initial_mongo_count)
409
410    def test_enketo_preview(self):
411        url = reverse(
412            enketo_preview, kwargs={'username': self.user.username,
413                                    'id_string': self.xform.id_string})
414        response = self.client.get(url)
415        self.assertEqual(response.status_code, 302)
416
417    def test_enketo_preview_works_on_shared_forms(self):
418        self.xform.shared = True
419        self.xform.save()
420        url = reverse(
421            enketo_preview, kwargs={'username': self.user.username,
422                                    'id_string': self.xform.id_string})
423        response = self.anon.get(url)
424        self.assertEqual(response.status_code, 302)
425
426    def test_form_urls_case_insensitive(self):
427        url = reverse(show, kwargs={
428            'username': self.user.username.upper(),
429            'id_string': self.xform.id_string.upper()
430        })
431        response = self.client.get(url)
432        self.assertEqual(response.status_code, 200)