tests.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import json
  2. from django.core import mail
  3. from django.contrib.auth.models import User
  4. from django.test import TestCase, Client, override_settings
  5. from contribmap.models import Contrib
  6. from contribmap.forms import PublicContribForm
  7. class APITestClient(Client):
  8. def json_get(self, *args, **kwargs):
  9. """ Annotate the response with a .data containing parsed JSON
  10. """
  11. response = super().get(*args, **kwargs)
  12. response.data = json.loads(response.content.decode('utf-8'))
  13. return response
  14. class APITestCase(TestCase):
  15. def setUp(self):
  16. super().setUp()
  17. self.client = APITestClient()
  18. class TestContrib(TestCase):
  19. def test_comma_separatedcharfield(self):
  20. co = Contrib(name='foo', orientations=['SO', 'NE'],
  21. contrib_type=Contrib.CONTRIB_CONNECT,
  22. latitude=0.5, longitude=0.5,
  23. )
  24. co.save()
  25. self.assertEqual(
  26. Contrib.objects.get(name='foo').orientations,
  27. ['SO', 'NE'])
  28. co.orientations = ['S']
  29. co.save()
  30. class TestContribPrivacy(TestCase):
  31. def test_always_private_field(self):
  32. c = Contrib.objects.create(
  33. name='John',
  34. phone='010101010101',
  35. contrib_type=Contrib.CONTRIB_CONNECT,
  36. latitude=0.5,
  37. longitude=0.5,
  38. )
  39. self.assertEqual(c.get_public_field('phone'), None)
  40. def test_public_field(self):
  41. c = Contrib.objects.create(
  42. name='John',
  43. phone='010101010101',
  44. contrib_type=Contrib.CONTRIB_CONNECT,
  45. privacy_name=True,
  46. latitude=0.5,
  47. longitude=0.5,
  48. )
  49. self.assertEqual(c.get_public_field('name'), 'John')
  50. def test_public_callable_field(self):
  51. c = Contrib.objects.create(
  52. name='John',
  53. phone='010101010101',
  54. orientations=['N'],
  55. contrib_type=Contrib.CONTRIB_CONNECT,
  56. privacy_name=True,
  57. latitude=0.5,
  58. longitude=0.5,
  59. )
  60. self.assertEqual(c.get_public_field('angles'), [[-23, 22]])
  61. def test_private_field(self):
  62. c = Contrib.objects.create(
  63. name='John',
  64. phone='010101010101',
  65. contrib_type=Contrib.CONTRIB_CONNECT,
  66. latitude=0.5,
  67. longitude=0.5,
  68. )
  69. self.assertEqual(c.privacy_name, False)
  70. self.assertEqual(c.get_public_field('name'), None)
  71. class TestViews(APITestCase):
  72. def mk_contrib_post_data(self, *args, **kwargs):
  73. post_data = {
  74. 'roof': True,
  75. 'privacy_place_details': True,
  76. 'privacy_coordinates': True,
  77. 'phone': '0202020202',
  78. 'orientations': ('N', 'NO', 'O', 'SO', 'S', 'SE', 'E', 'NE'),
  79. 'orientation': 'all',
  80. 'name': 'JohnCleese',
  81. 'longitude': -1.553621,
  82. 'latitude': 47.218371,
  83. 'floor_total': '2',
  84. 'floor': 1,
  85. 'email': 'coucou@example.com',
  86. 'contrib_type': 'connect',
  87. 'connect_local': 'on',
  88. }
  89. post_data.update(kwargs)
  90. return post_data
  91. def test_public_json(self):
  92. response = self.client.json_get('/map/public.json')
  93. self.assertEqual(response.status_code, 200)
  94. self.assertEqual(len(response.data['features']), 0)
  95. Contrib.objects.create(
  96. name='John',
  97. phone='010101010101',
  98. contrib_type=Contrib.CONTRIB_CONNECT,
  99. privacy_coordinates=True,
  100. latitude=0.5,
  101. longitude=0.5,
  102. )
  103. response = self.client.json_get('/map/public.json')
  104. self.assertEqual(response.status_code, 200)
  105. self.assertEqual(len(response.data['features']), 1)
  106. def test_private_json(self):
  107. self.client.force_login(
  108. User.objects.create(username='foo', is_staff=False))
  109. response = self.client.get('/map/private.json')
  110. self.assertEqual(response.status_code, 403)
  111. def test_private_json_staff(self):
  112. self.client.force_login(
  113. User.objects.create(username='foo', is_staff=True))
  114. response = self.client.get('/map/private.json')
  115. self.assertEqual(response.status_code, 200)
  116. @override_settings(NOTIFICATION_EMAILS=['foo@example.com'])
  117. def test_add_contrib_sends_moderator_email(self):
  118. post_data = self.mk_contrib_post_data({'name': 'JohnCleese'})
  119. del post_data['email']
  120. response = self.client.post('/map/contribute', post_data)
  121. self.assertEqual(response.status_code, 302)
  122. self.assertEqual(len(mail.outbox), 1)
  123. self.assertIn('JohnCleese', mail.outbox[0].subject)
  124. self.assertIn('JohnCleese', mail.outbox[0].body)
  125. class TestForms(TestCase):
  126. valid_data = {
  127. 'roof': True,
  128. 'privacy_place_details': True,
  129. 'privacy_coordinates': True,
  130. 'orientations': ['N'],
  131. 'orientation': 'all',
  132. 'name': 'JohnCleese',
  133. 'longitude': -1.553621,
  134. 'email': 'foo@example.com',
  135. 'phone': '0202020202',
  136. 'latitude': 47.218371,
  137. 'floor_total': '2',
  138. 'floor': 1,
  139. 'contrib_type': 'connect',
  140. 'connect_local': 'on',
  141. }
  142. def test_contact_validation(self):
  143. no_contact, phone_contact, email_contact, both_contact = [
  144. self.valid_data.copy() for i in range(4)]
  145. del phone_contact['email']
  146. del email_contact['phone']
  147. del no_contact['phone']
  148. del no_contact['email']
  149. both_contact.update(phone_contact)
  150. both_contact.update(email_contact)
  151. self.assertFalse(PublicContribForm(no_contact).is_valid())
  152. self.assertTrue(PublicContribForm(phone_contact).is_valid())
  153. self.assertTrue(PublicContribForm(email_contact).is_valid())
  154. self.assertTrue(PublicContribForm(both_contact).is_valid())
  155. def test_floors_validation(self):
  156. invalid_floors = self.valid_data.copy()
  157. invalid_floors['floor'] = 2
  158. invalid_floors['floor_total'] = 1
  159. self.assertFalse(PublicContribForm(invalid_floors).is_valid())
  160. self.assertTrue(PublicContribForm(self.valid_data).is_valid())
  161. invalid_floors['floor'] = None
  162. invalid_floors['floor_total'] = None
  163. self.assertTrue(PublicContribForm(invalid_floors).is_valid())
  164. def test_share_fields_validation(self):
  165. data = self.valid_data.copy()
  166. data['contrib_type'] = 'share'
  167. self.assertFalse(PublicContribForm(data).is_valid())
  168. data['access_type'] = 'cable'
  169. self.assertTrue(PublicContribForm(data).is_valid())
  170. @override_settings(NOTIFICATION_EMAILS=['foo@example.com'])
  171. def test_add_contrib_like_a_robot(self):
  172. response = self.client.post('/map/contribute', {
  173. 'roof': True,
  174. 'human_field': 'should not have no value',
  175. 'privacy_place_details': True,
  176. 'privacy_coordinates': True,
  177. 'phone': '0202020202',
  178. 'orientations': 'N',
  179. 'orientations': 'NO',
  180. 'orientations': 'O',
  181. 'orientations': 'SO',
  182. 'orientations': 'S',
  183. 'orientations': 'SE',
  184. 'orientations': 'E',
  185. 'orientations': 'NE',
  186. 'orientation': 'all',
  187. 'name': 'JohnCleese',
  188. 'longitude': -1.553621,
  189. 'latitude': 47.218371,
  190. 'floor_total': '2',
  191. 'floor': 1,
  192. 'email': 'coucou@example.com',
  193. 'contrib_type': 'connect',
  194. 'connect_local': 'on',
  195. })
  196. self.assertEqual(response.status_code, 403)
  197. self.assertEqual(len(mail.outbox), 0)
  198. class TestDataImport(TestCase):
  199. fixtures = ['bottle_data.yaml']
  200. def test_re_save(self):
  201. for contrib in Contrib.objects.all():
  202. contrib.full_clean()
  203. contrib.save()