test_views.py 11 KB

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