PageRenderTime 35ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/main/tests/test_form_show.py

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