utils.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import json
  2. import logging
  3. import re
  4. from contextlib import contextmanager
  5. from django.contrib.auth import get_user_model
  6. from django.contrib.auth.models import Permission
  7. from django.contrib.contenttypes.models import ContentType
  8. from django.utils.text import slugify
  9. from dcim.models import Device, DeviceRole, DeviceType, Manufacturer, Site
  10. from extras.choices import CustomFieldTypeChoices
  11. from extras.models import CustomField, Tag
  12. from virtualization.models import Cluster, ClusterType, VirtualMachine
  13. def post_data(data):
  14. """
  15. Take a dictionary of test data (suitable for comparison to an instance) and return a dict suitable for POSTing.
  16. """
  17. ret = {}
  18. for key, value in data.items():
  19. if value is None:
  20. ret[key] = ''
  21. elif type(value) in (list, tuple):
  22. if value and hasattr(value[0], 'pk'):
  23. # Value is a list of instances
  24. ret[key] = [v.pk for v in value]
  25. else:
  26. ret[key] = value
  27. elif hasattr(value, 'pk'):
  28. # Value is an instance
  29. ret[key] = value.pk
  30. else:
  31. ret[key] = str(value)
  32. return ret
  33. def create_test_device(name, site=None, **attrs):
  34. """
  35. Convenience method for creating a Device (e.g. for component testing).
  36. """
  37. if site is None:
  38. site, _ = Site.objects.get_or_create(name='Site 1', slug='site-1')
  39. manufacturer, _ = Manufacturer.objects.get_or_create(name='Manufacturer 1', slug='manufacturer-1')
  40. devicetype, _ = DeviceType.objects.get_or_create(model='Device Type 1', manufacturer=manufacturer)
  41. devicerole, _ = DeviceRole.objects.get_or_create(name='Device Role 1', slug='device-role-1')
  42. device = Device.objects.create(name=name, site=site, device_type=devicetype, role=devicerole, **attrs)
  43. return device
  44. def create_test_virtualmachine(name):
  45. """
  46. Convenience method for creating a VirtualMachine.
  47. """
  48. cluster_type, _ = ClusterType.objects.get_or_create(name='Cluster Type 1', slug='cluster-type-1')
  49. cluster, _ = Cluster.objects.get_or_create(name='Cluster 1', type=cluster_type)
  50. virtual_machine = VirtualMachine.objects.create(name=name, cluster=cluster)
  51. return virtual_machine
  52. def create_test_user(username='testuser', permissions=None):
  53. """
  54. Create a User with the given permissions.
  55. """
  56. user = get_user_model().objects.create_user(username=username)
  57. if permissions is None:
  58. permissions = ()
  59. for perm_name in permissions:
  60. app, codename = perm_name.split('.')
  61. perm = Permission.objects.get(content_type__app_label=app, codename=codename)
  62. user.user_permissions.add(perm)
  63. return user
  64. def create_tags(*names):
  65. """
  66. Create and return a Tag instance for each name given.
  67. """
  68. tags = [Tag(name=name, slug=slugify(name)) for name in names]
  69. Tag.objects.bulk_create(tags)
  70. return tags
  71. def extract_form_failures(content):
  72. """
  73. Given raw HTML content from an HTTP response, return a list of form errors.
  74. """
  75. FORM_ERROR_REGEX = r'<!-- FORM-ERROR (.*) -->'
  76. return re.findall(FORM_ERROR_REGEX, str(content))
  77. @contextmanager
  78. def disable_warnings(logger_name):
  79. """
  80. Temporarily suppress expected warning messages to keep the test output clean.
  81. """
  82. logger = logging.getLogger(logger_name)
  83. current_level = logger.level
  84. logger.setLevel(logging.ERROR)
  85. yield
  86. logger.setLevel(current_level)
  87. #
  88. # Custom field testing
  89. #
  90. DUMMY_CF_DATA = {
  91. 'text_field': 'foo123',
  92. 'integer_field': 456,
  93. 'decimal_field': 456.12,
  94. 'boolean_field': True,
  95. 'json_field': {'abc': 123},
  96. }
  97. def add_custom_field_data(form_data, model):
  98. """
  99. Create some custom fields for the model and add a value for each to the form data.
  100. Args:
  101. form_data: The dictionary of form data to be updated
  102. model: The model of the object the form seeks to create or modify
  103. """
  104. content_type = ContentType.objects.get_for_model(model)
  105. custom_fields = (
  106. CustomField(type=CustomFieldTypeChoices.TYPE_TEXT, name='text_field', default='foo'),
  107. CustomField(type=CustomFieldTypeChoices.TYPE_INTEGER, name='integer_field', default=123),
  108. CustomField(type=CustomFieldTypeChoices.TYPE_DECIMAL, name='decimal_field', default=123.45),
  109. CustomField(type=CustomFieldTypeChoices.TYPE_BOOLEAN, name='boolean_field', default=False),
  110. CustomField(type=CustomFieldTypeChoices.TYPE_JSON, name='json_field', default='{"x": "y"}'),
  111. )
  112. CustomField.objects.bulk_create(custom_fields)
  113. for cf in custom_fields:
  114. cf.content_types.set([content_type])
  115. form_data.update({
  116. f'cf_{k}': v if type(v) is str else json.dumps(v)
  117. for k, v in DUMMY_CF_DATA.items()
  118. })