test_views.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. import urllib.parse
  2. import uuid
  3. from django.contrib.auth.models import User
  4. from django.contrib.contenttypes.models import ContentType
  5. from django.urls import reverse
  6. from dcim.models import Site
  7. from extras.choices import *
  8. from extras.models import *
  9. from utilities.testing import ViewTestCases, TestCase
  10. class CustomFieldTestCase(ViewTestCases.PrimaryObjectViewTestCase):
  11. model = CustomField
  12. @classmethod
  13. def setUpTestData(cls):
  14. site_ct = ContentType.objects.get_for_model(Site)
  15. custom_fields = (
  16. CustomField(name='field1', label='Field 1', type=CustomFieldTypeChoices.TYPE_TEXT),
  17. CustomField(name='field2', label='Field 2', type=CustomFieldTypeChoices.TYPE_TEXT),
  18. CustomField(name='field3', label='Field 3', type=CustomFieldTypeChoices.TYPE_TEXT),
  19. )
  20. for customfield in custom_fields:
  21. customfield.save()
  22. customfield.content_types.add(site_ct)
  23. cls.form_data = {
  24. 'name': 'field_x',
  25. 'label': 'Field X',
  26. 'type': 'text',
  27. 'content_types': [site_ct.pk],
  28. 'filter_logic': CustomFieldFilterLogicChoices.FILTER_EXACT,
  29. 'default': None,
  30. 'weight': 200,
  31. 'required': True,
  32. }
  33. cls.csv_data = (
  34. 'name,label,type,content_types,weight,filter_logic,choices,validation_minimum,validation_maximum,validation_regex',
  35. 'field4,Field 4,text,dcim.site,100,exact,,,,[a-z]{3}',
  36. 'field5,Field 5,integer,dcim.site,100,exact,,1,100,',
  37. 'field6,Field 6,select,dcim.site,100,exact,"A,B,C",,,',
  38. )
  39. cls.bulk_edit_data = {
  40. 'required': True,
  41. 'weight': 200,
  42. }
  43. class CustomLinkTestCase(ViewTestCases.PrimaryObjectViewTestCase):
  44. model = CustomLink
  45. @classmethod
  46. def setUpTestData(cls):
  47. site_ct = ContentType.objects.get_for_model(Site)
  48. CustomLink.objects.bulk_create((
  49. CustomLink(name='Custom Link 1', content_type=site_ct, enabled=True, link_text='Link 1', link_url='http://example.com/?1'),
  50. CustomLink(name='Custom Link 2', content_type=site_ct, enabled=True, link_text='Link 2', link_url='http://example.com/?2'),
  51. CustomLink(name='Custom Link 3', content_type=site_ct, enabled=False, link_text='Link 3', link_url='http://example.com/?3'),
  52. ))
  53. cls.form_data = {
  54. 'name': 'Custom Link X',
  55. 'content_type': site_ct.pk,
  56. 'enabled': False,
  57. 'weight': 100,
  58. 'button_class': CustomLinkButtonClassChoices.DEFAULT,
  59. 'link_text': 'Link X',
  60. 'link_url': 'http://example.com/?x'
  61. }
  62. cls.csv_data = (
  63. "name,content_type,enabled,weight,button_class,link_text,link_url",
  64. "Custom Link 4,dcim.site,True,100,blue,Link 4,http://exmaple.com/?4",
  65. "Custom Link 5,dcim.site,True,100,blue,Link 5,http://exmaple.com/?5",
  66. "Custom Link 6,dcim.site,False,100,blue,Link 6,http://exmaple.com/?6",
  67. )
  68. cls.bulk_edit_data = {
  69. 'button_class': CustomLinkButtonClassChoices.CYAN,
  70. 'enabled': False,
  71. 'weight': 200,
  72. }
  73. class ExportTemplateTestCase(ViewTestCases.PrimaryObjectViewTestCase):
  74. model = ExportTemplate
  75. @classmethod
  76. def setUpTestData(cls):
  77. site_ct = ContentType.objects.get_for_model(Site)
  78. TEMPLATE_CODE = """{% for object in queryset %}{{ object }}{% endfor %}"""
  79. ExportTemplate.objects.bulk_create((
  80. ExportTemplate(name='Export Template 1', content_type=site_ct, template_code=TEMPLATE_CODE),
  81. ExportTemplate(name='Export Template 2', content_type=site_ct, template_code=TEMPLATE_CODE),
  82. ExportTemplate(name='Export Template 3', content_type=site_ct, template_code=TEMPLATE_CODE),
  83. ))
  84. cls.form_data = {
  85. 'name': 'Export Template X',
  86. 'content_type': site_ct.pk,
  87. 'template_code': TEMPLATE_CODE,
  88. }
  89. cls.csv_data = (
  90. "name,content_type,template_code",
  91. f"Export Template 4,dcim.site,{TEMPLATE_CODE}",
  92. f"Export Template 5,dcim.site,{TEMPLATE_CODE}",
  93. f"Export Template 6,dcim.site,{TEMPLATE_CODE}",
  94. )
  95. cls.bulk_edit_data = {
  96. 'mime_type': 'text/html',
  97. 'file_extension': 'html',
  98. 'as_attachment': True,
  99. }
  100. class WebhookTestCase(ViewTestCases.PrimaryObjectViewTestCase):
  101. model = Webhook
  102. @classmethod
  103. def setUpTestData(cls):
  104. site_ct = ContentType.objects.get_for_model(Site)
  105. webhooks = (
  106. Webhook(name='Webhook 1', payload_url='http://example.com/?1', type_create=True, http_method='POST'),
  107. Webhook(name='Webhook 2', payload_url='http://example.com/?2', type_create=True, http_method='POST'),
  108. Webhook(name='Webhook 3', payload_url='http://example.com/?3', type_create=True, http_method='POST'),
  109. )
  110. for webhook in webhooks:
  111. webhook.save()
  112. webhook.content_types.add(site_ct)
  113. cls.form_data = {
  114. 'name': 'Webhook X',
  115. 'content_types': [site_ct.pk],
  116. 'type_create': False,
  117. 'type_update': True,
  118. 'type_delete': True,
  119. 'payload_url': 'http://example.com/?x',
  120. 'http_method': 'GET',
  121. 'http_content_type': 'application/foo',
  122. 'conditions': None,
  123. }
  124. cls.csv_data = (
  125. "name,content_types,type_create,payload_url,http_method,http_content_type",
  126. "Webhook 4,dcim.site,True,http://example.com/?4,GET,application/json",
  127. "Webhook 5,dcim.site,True,http://example.com/?5,GET,application/json",
  128. "Webhook 6,dcim.site,True,http://example.com/?6,GET,application/json",
  129. )
  130. cls.bulk_edit_data = {
  131. 'enabled': False,
  132. 'type_create': False,
  133. 'type_update': True,
  134. 'type_delete': True,
  135. 'http_method': 'GET',
  136. }
  137. class TagTestCase(ViewTestCases.OrganizationalObjectViewTestCase):
  138. model = Tag
  139. @classmethod
  140. def setUpTestData(cls):
  141. Tag.objects.bulk_create((
  142. Tag(name='Tag 1', slug='tag-1'),
  143. Tag(name='Tag 2', slug='tag-2'),
  144. Tag(name='Tag 3', slug='tag-3'),
  145. ))
  146. cls.form_data = {
  147. 'name': 'Tag X',
  148. 'slug': 'tag-x',
  149. 'color': 'c0c0c0',
  150. 'comments': 'Some comments',
  151. }
  152. cls.csv_data = (
  153. "name,slug,color,description",
  154. "Tag 4,tag-4,ff0000,Fourth tag",
  155. "Tag 5,tag-5,00ff00,Fifth tag",
  156. "Tag 6,tag-6,0000ff,Sixth tag",
  157. )
  158. cls.bulk_edit_data = {
  159. 'color': '00ff00',
  160. }
  161. # TODO: Change base class to PrimaryObjectViewTestCase
  162. # Blocked by absence of standard create/edit, bulk create views
  163. class ConfigContextTestCase(
  164. ViewTestCases.GetObjectViewTestCase,
  165. ViewTestCases.GetObjectChangelogViewTestCase,
  166. ViewTestCases.DeleteObjectViewTestCase,
  167. ViewTestCases.ListObjectsViewTestCase,
  168. ViewTestCases.BulkEditObjectsViewTestCase,
  169. ViewTestCases.BulkDeleteObjectsViewTestCase
  170. ):
  171. model = ConfigContext
  172. @classmethod
  173. def setUpTestData(cls):
  174. site = Site.objects.create(name='Site 1', slug='site-1')
  175. # Create three ConfigContexts
  176. for i in range(1, 4):
  177. configcontext = ConfigContext(
  178. name='Config Context {}'.format(i),
  179. data={'foo': i}
  180. )
  181. configcontext.save()
  182. configcontext.sites.add(site)
  183. cls.form_data = {
  184. 'name': 'Config Context X',
  185. 'weight': 200,
  186. 'description': 'A new config context',
  187. 'is_active': True,
  188. 'regions': [],
  189. 'sites': [site.pk],
  190. 'roles': [],
  191. 'platforms': [],
  192. 'tenant_groups': [],
  193. 'tenants': [],
  194. 'tags': [],
  195. 'data': '{"foo": 123}',
  196. }
  197. cls.bulk_edit_data = {
  198. 'weight': 300,
  199. 'is_active': False,
  200. 'description': 'New description',
  201. }
  202. # TODO: Convert to StandardTestCases.Views
  203. class ObjectChangeTestCase(TestCase):
  204. user_permissions = (
  205. 'extras.view_objectchange',
  206. )
  207. @classmethod
  208. def setUpTestData(cls):
  209. site = Site(name='Site 1', slug='site-1')
  210. site.save()
  211. # Create three ObjectChanges
  212. user = User.objects.create_user(username='testuser2')
  213. for i in range(1, 4):
  214. oc = site.to_objectchange(action=ObjectChangeActionChoices.ACTION_UPDATE)
  215. oc.user = user
  216. oc.request_id = uuid.uuid4()
  217. oc.save()
  218. def test_objectchange_list(self):
  219. url = reverse('extras:objectchange_list')
  220. params = {
  221. "user": User.objects.first().pk,
  222. }
  223. response = self.client.get('{}?{}'.format(url, urllib.parse.urlencode(params)))
  224. self.assertHttpStatus(response, 200)
  225. def test_objectchange(self):
  226. objectchange = ObjectChange.objects.first()
  227. response = self.client.get(objectchange.get_absolute_url())
  228. self.assertHttpStatus(response, 200)
  229. class JournalEntryTestCase(
  230. # ViewTestCases.GetObjectViewTestCase,
  231. ViewTestCases.CreateObjectViewTestCase,
  232. ViewTestCases.EditObjectViewTestCase,
  233. ViewTestCases.DeleteObjectViewTestCase,
  234. ViewTestCases.ListObjectsViewTestCase,
  235. ViewTestCases.BulkEditObjectsViewTestCase,
  236. ViewTestCases.BulkDeleteObjectsViewTestCase
  237. ):
  238. model = JournalEntry
  239. @classmethod
  240. def setUpTestData(cls):
  241. site_ct = ContentType.objects.get_for_model(Site)
  242. site = Site.objects.create(name='Site 1', slug='site-1')
  243. user = User.objects.create(username='User 1')
  244. JournalEntry.objects.bulk_create((
  245. JournalEntry(assigned_object=site, created_by=user, comments='First entry'),
  246. JournalEntry(assigned_object=site, created_by=user, comments='Second entry'),
  247. JournalEntry(assigned_object=site, created_by=user, comments='Third entry'),
  248. ))
  249. cls.form_data = {
  250. 'assigned_object_type': site_ct.pk,
  251. 'assigned_object_id': site.pk,
  252. 'kind': 'info',
  253. 'comments': 'A new entry',
  254. }
  255. cls.bulk_edit_data = {
  256. 'kind': 'success',
  257. 'comments': 'Overwritten',
  258. }
  259. class CustomLinkTest(TestCase):
  260. user_permissions = ['dcim.view_site']
  261. def test_view_object_with_custom_link(self):
  262. customlink = CustomLink(
  263. content_type=ContentType.objects.get_for_model(Site),
  264. name='Test',
  265. link_text='FOO {{ obj.name }} BAR',
  266. link_url='http://example.com/?site={{ obj.slug }}',
  267. new_window=False
  268. )
  269. customlink.save()
  270. site = Site(name='Test Site', slug='test-site')
  271. site.save()
  272. response = self.client.get(site.get_absolute_url(), follow=True)
  273. self.assertEqual(response.status_code, 200)
  274. self.assertIn(f'FOO {site.name} BAR', str(response.content))