test_base_classes.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. from django.apps import apps
  2. from django.test import TestCase
  3. from django.utils.module_loading import import_string
  4. from netbox.api.serializers import (
  5. NestedGroupModelSerializer,
  6. NetBoxModelSerializer,
  7. OrganizationalModelSerializer,
  8. PrimaryModelSerializer,
  9. )
  10. from netbox.filtersets import (
  11. NestedGroupModelFilterSet,
  12. NetBoxModelFilterSet,
  13. OrganizationalModelFilterSet,
  14. PrimaryModelFilterSet,
  15. )
  16. from netbox.forms.bulk_edit import (
  17. NestedGroupModelBulkEditForm,
  18. NetBoxModelBulkEditForm,
  19. OrganizationalModelBulkEditForm,
  20. PrimaryModelBulkEditForm,
  21. )
  22. from netbox.forms.bulk_import import (
  23. NestedGroupModelImportForm,
  24. NetBoxModelImportForm,
  25. OrganizationalModelImportForm,
  26. PrimaryModelImportForm,
  27. )
  28. from netbox.forms.filtersets import (
  29. NestedGroupModelFilterSetForm,
  30. NetBoxModelFilterSetForm,
  31. OrganizationalModelFilterSetForm,
  32. PrimaryModelFilterSetForm,
  33. )
  34. from netbox.forms.model_forms import (
  35. NestedGroupModelForm,
  36. NetBoxModelForm,
  37. OrganizationalModelForm,
  38. PrimaryModelForm,
  39. )
  40. from netbox.graphql.types import (
  41. NestedGroupObjectType,
  42. NetBoxObjectType,
  43. OrganizationalObjectType,
  44. PrimaryObjectType,
  45. )
  46. from netbox.models import NestedGroupModel, NetBoxModel, OrganizationalModel, PrimaryModel
  47. from netbox.registry import registry
  48. from netbox.tables import (
  49. NestedGroupModelTable,
  50. NetBoxTable,
  51. OrganizationalModelTable,
  52. PrimaryModelTable,
  53. )
  54. class FormClassesTestCase(TestCase):
  55. @staticmethod
  56. def get_form_for_model(model, prefix=''):
  57. """
  58. Import and return the form class for a given model.
  59. """
  60. app_label = model._meta.app_label
  61. model_name = model.__name__
  62. return import_string(f'{app_label}.forms.{model_name}{prefix}Form')
  63. @staticmethod
  64. def get_model_form_base_class(model):
  65. """
  66. Return the base form class for creating/editing the given model.
  67. """
  68. if model._meta.app_label == 'dummy_plugin':
  69. return None
  70. if issubclass(model, PrimaryModel):
  71. return PrimaryModelForm
  72. if issubclass(model, OrganizationalModel):
  73. return OrganizationalModelForm
  74. if issubclass(model, NestedGroupModel):
  75. return NestedGroupModelForm
  76. if issubclass(model, NetBoxModel):
  77. return NetBoxModelForm
  78. return None
  79. @staticmethod
  80. def get_bulk_edit_form_base_class(model):
  81. """
  82. Return the base form class for bulk editing the given model.
  83. """
  84. if model._meta.app_label == 'dummy_plugin':
  85. return None
  86. if issubclass(model, PrimaryModel):
  87. return PrimaryModelBulkEditForm
  88. if issubclass(model, OrganizationalModel):
  89. return OrganizationalModelBulkEditForm
  90. if issubclass(model, NestedGroupModel):
  91. return NestedGroupModelBulkEditForm
  92. if issubclass(model, NetBoxModel):
  93. return NetBoxModelBulkEditForm
  94. return None
  95. @staticmethod
  96. def get_import_form_base_class(model):
  97. """
  98. Return the base form class for importing the given model.
  99. """
  100. if model._meta.app_label == 'dummy_plugin':
  101. return None
  102. if issubclass(model, PrimaryModel):
  103. return PrimaryModelImportForm
  104. if issubclass(model, OrganizationalModel):
  105. return OrganizationalModelImportForm
  106. if issubclass(model, NestedGroupModel):
  107. return NestedGroupModelImportForm
  108. if issubclass(model, NetBoxModel):
  109. return NetBoxModelImportForm
  110. return None
  111. @staticmethod
  112. def get_filterset_form_base_class(model):
  113. """
  114. Return the base form class for the given model's FilterSet.
  115. """
  116. if model._meta.app_label == 'dummy_plugin':
  117. return None
  118. if issubclass(model, PrimaryModel):
  119. return PrimaryModelFilterSetForm
  120. if issubclass(model, OrganizationalModel):
  121. return OrganizationalModelFilterSetForm
  122. if issubclass(model, NestedGroupModel):
  123. return NestedGroupModelFilterSetForm
  124. if issubclass(model, NetBoxModel):
  125. return NetBoxModelFilterSetForm
  126. return None
  127. def test_model_form_base_classes(self):
  128. """
  129. Check that each model form inherits from the appropriate base class.
  130. """
  131. for model in apps.get_models():
  132. if base_class := self.get_model_form_base_class(model):
  133. form_class = self.get_form_for_model(model)
  134. self.assertTrue(issubclass(form_class, base_class), f"{form_class} does not inherit from {base_class}")
  135. def test_bulk_edit_form_base_classes(self):
  136. """
  137. Check that each bulk edit form inherits from the appropriate base class.
  138. """
  139. for model in apps.get_models():
  140. if base_class := self.get_bulk_edit_form_base_class(model):
  141. form_class = self.get_form_for_model(model, prefix='BulkEdit')
  142. self.assertTrue(issubclass(form_class, base_class), f"{form_class} does not inherit from {base_class}")
  143. def test_import_form_base_classes(self):
  144. """
  145. Check that each bulk import form inherits from the appropriate base class.
  146. """
  147. for model in apps.get_models():
  148. if base_class := self.get_import_form_base_class(model):
  149. form_class = self.get_form_for_model(model, prefix='Import')
  150. self.assertTrue(issubclass(form_class, base_class), f"{form_class} does not inherit from {base_class}")
  151. def test_filterset_form_base_classes(self):
  152. """
  153. Check that each filterset form inherits from the appropriate base class.
  154. """
  155. for model in apps.get_models():
  156. if base_class := self.get_filterset_form_base_class(model):
  157. form_class = self.get_form_for_model(model, prefix='Filter')
  158. self.assertTrue(issubclass(form_class, base_class), f"{form_class} does not inherit from {base_class}")
  159. class FilterSetClassesTestCase(TestCase):
  160. @staticmethod
  161. def get_filterset_for_model(model):
  162. """
  163. Return the filterset class for a given model from the application registry.
  164. """
  165. label = f'{model._meta.app_label}.{model._meta.model_name}'
  166. return registry['filtersets'].get(label)
  167. @staticmethod
  168. def get_model_filterset_base_class(model):
  169. """
  170. Return the base FilterSet class for the given model.
  171. """
  172. if model._meta.app_label == 'dummy_plugin':
  173. return None
  174. if issubclass(model, PrimaryModel):
  175. return PrimaryModelFilterSet
  176. if issubclass(model, OrganizationalModel):
  177. return OrganizationalModelFilterSet
  178. if issubclass(model, NestedGroupModel):
  179. return NestedGroupModelFilterSet
  180. if issubclass(model, NetBoxModel):
  181. return NetBoxModelFilterSet
  182. return None
  183. def test_model_filterset_base_classes(self):
  184. """
  185. Check that each FilterSet inherits from the appropriate base class.
  186. """
  187. for model in apps.get_models():
  188. if base_class := self.get_model_filterset_base_class(model):
  189. filterset = self.get_filterset_for_model(model)
  190. self.assertIsNotNone(filterset, f"No registered filterset found for model {model}")
  191. self.assertTrue(
  192. issubclass(filterset, base_class),
  193. f"{filterset} does not inherit from {base_class}",
  194. )
  195. class TableClassesTestCase(TestCase):
  196. @staticmethod
  197. def get_table_for_model(model):
  198. """
  199. Import and return the table class for a given model.
  200. """
  201. app_label = model._meta.app_label
  202. model_name = model.__name__
  203. return import_string(f'{app_label}.tables.{model_name}Table')
  204. @staticmethod
  205. def get_model_table_base_class(model):
  206. """
  207. Return the base table class for the given model.
  208. """
  209. if model._meta.app_label == 'dummy_plugin':
  210. return None
  211. if issubclass(model, PrimaryModel):
  212. return PrimaryModelTable
  213. if issubclass(model, OrganizationalModel):
  214. return OrganizationalModelTable
  215. if issubclass(model, NestedGroupModel):
  216. return NestedGroupModelTable
  217. if issubclass(model, NetBoxModel):
  218. return NetBoxTable
  219. return None
  220. def test_model_table_base_classes(self):
  221. """
  222. Check that each table inherits from the appropriate base class.
  223. """
  224. for model in apps.get_models():
  225. if base_class := self.get_model_table_base_class(model):
  226. table = self.get_table_for_model(model)
  227. self.assertTrue(
  228. issubclass(table, base_class),
  229. f"{table} does not inherit from {base_class}",
  230. )
  231. self.assertTrue(
  232. issubclass(table.Meta, base_class.Meta),
  233. f"{table}.Meta does not inherit from {base_class}.Meta",
  234. )
  235. class SerializerClassesTestCase(TestCase):
  236. @staticmethod
  237. def get_serializer_for_model(model):
  238. """
  239. Import and return the REST API serializer class for a given model.
  240. """
  241. app_label = model._meta.app_label
  242. model_name = model.__name__
  243. return import_string(f'{app_label}.api.serializers.{model_name}Serializer')
  244. @staticmethod
  245. def get_model_serializer_base_class(model):
  246. """
  247. Return the base serializer class for the given model.
  248. """
  249. if model._meta.app_label == 'dummy_plugin':
  250. return None
  251. if issubclass(model, PrimaryModel):
  252. return PrimaryModelSerializer
  253. if issubclass(model, OrganizationalModel):
  254. return OrganizationalModelSerializer
  255. if issubclass(model, NestedGroupModel):
  256. return NestedGroupModelSerializer
  257. if issubclass(model, NetBoxModel):
  258. return NetBoxModelSerializer
  259. return None
  260. def test_model_serializer_base_classes(self):
  261. """
  262. Check that each model serializer inherits from the appropriate base class.
  263. """
  264. for model in apps.get_models():
  265. if base_class := self.get_model_serializer_base_class(model):
  266. serializer = self.get_serializer_for_model(model)
  267. self.assertTrue(
  268. issubclass(serializer, base_class),
  269. f"{serializer} does not inherit from {base_class}",
  270. )
  271. class GraphQLTypeClassesTestCase(TestCase):
  272. @staticmethod
  273. def get_type_for_model(model):
  274. """
  275. Import and return the GraphQL type for a given model.
  276. """
  277. app_label = model._meta.app_label
  278. model_name = model.__name__
  279. return import_string(f'{app_label}.graphql.types.{model_name}Type')
  280. @staticmethod
  281. def get_model_type_base_class(model):
  282. """
  283. Return the base GraphQL type for the given model.
  284. """
  285. if model._meta.app_label == 'dummy_plugin':
  286. return None
  287. if issubclass(model, PrimaryModel):
  288. return PrimaryObjectType
  289. if issubclass(model, OrganizationalModel):
  290. return OrganizationalObjectType
  291. if issubclass(model, NestedGroupModel):
  292. return NestedGroupObjectType
  293. if issubclass(model, NetBoxModel):
  294. return NetBoxObjectType
  295. return None
  296. def test_model_type_base_classes(self):
  297. """
  298. Check that each GraphQL type inherits from the appropriate base class.
  299. """
  300. for model in apps.get_models():
  301. if base_class := self.get_model_type_base_class(model):
  302. graphql_type = self.get_type_for_model(model)
  303. self.assertTrue(
  304. issubclass(graphql_type, base_class),
  305. f"{graphql_type} does not inherit from {base_class}",
  306. )