Enforce unified list field consistency

Discovered via bug: controller_node field present in
project update list but not in detail view

Added tests to assert that "unified" list serializer
produces same fields as the ordinary serializer,
for unified jobs & unified JTs

Added test to check that list serializers do differ
from detail serializer except for allowed differences

Added test to check that list serializers are applied
correctly - only on list views, and that detail views,
likewise, do not use list serializers

Fix the many many bugs discovered by these new
testing mechanisms
This commit is contained in:
AlanCoding
2018-06-27 16:04:31 -04:00
parent 3e951a5598
commit 8ae979908c
5 changed files with 139 additions and 50 deletions

View File

@@ -671,7 +671,7 @@ class UnifiedJobTemplateSerializer(BaseSerializer):
else:
return super(UnifiedJobTemplateSerializer, self).get_types()
def to_representation(self, obj):
def get_sub_serializer(self, obj):
serializer_class = None
if type(self) is UnifiedJobTemplateSerializer:
if isinstance(obj, Project):
@@ -684,6 +684,10 @@ class UnifiedJobTemplateSerializer(BaseSerializer):
serializer_class = SystemJobTemplateSerializer
elif isinstance(obj, WorkflowJobTemplate):
serializer_class = WorkflowJobTemplateSerializer
return serializer_class
def to_representation(self, obj):
serializer_class = self.get_sub_serializer(obj)
if serializer_class:
serializer = serializer_class(instance=obj, context=self.context)
# preserve links for list view
@@ -766,7 +770,7 @@ class UnifiedJobSerializer(BaseSerializer):
return summary_fields
def to_representation(self, obj):
def get_sub_serializer(self, obj):
serializer_class = None
if type(self) is UnifiedJobSerializer:
if isinstance(obj, ProjectUpdate):
@@ -781,6 +785,10 @@ class UnifiedJobSerializer(BaseSerializer):
serializer_class = SystemJobSerializer
elif isinstance(obj, WorkflowJob):
serializer_class = WorkflowJobSerializer
return serializer_class
def to_representation(self, obj):
serializer_class = self.get_sub_serializer(obj)
if serializer_class:
serializer = serializer_class(instance=obj, context=self.context)
# preserve links for list view
@@ -818,7 +826,7 @@ class UnifiedJobListSerializer(UnifiedJobSerializer):
else:
return super(UnifiedJobListSerializer, self).get_types()
def to_representation(self, obj):
def get_sub_serializer(self, obj):
serializer_class = None
if type(self) is UnifiedJobListSerializer:
if isinstance(obj, ProjectUpdate):
@@ -832,7 +840,11 @@ class UnifiedJobListSerializer(UnifiedJobSerializer):
elif isinstance(obj, SystemJob):
serializer_class = SystemJobListSerializer
elif isinstance(obj, WorkflowJob):
serializer_class = WorkflowJobSerializer
serializer_class = WorkflowJobListSerializer
return serializer_class
def to_representation(self, obj):
serializer_class = self.get_sub_serializer(obj)
if serializer_class:
serializer = serializer_class(instance=obj, context=self.context)
ret = serializer.to_representation(obj)
@@ -1480,7 +1492,9 @@ class ProjectUpdateDetailSerializer(ProjectUpdateSerializer):
class ProjectUpdateListSerializer(ProjectUpdateSerializer, UnifiedJobListSerializer):
pass
class Meta:
model = ProjectUpdate
fields = ('*', '-controller_node') # field removal undone by UJ serializer
class ProjectUpdateCancelSerializer(ProjectUpdateSerializer):
@@ -2200,7 +2214,9 @@ class InventoryUpdateSerializer(UnifiedJobSerializer, InventorySourceOptionsSeri
class InventoryUpdateListSerializer(InventoryUpdateSerializer, UnifiedJobListSerializer):
pass
class Meta:
model = InventoryUpdate
fields = ('*', '-controller_node') # field removal undone by UJ serializer
class InventoryUpdateCancelSerializer(InventoryUpdateSerializer):
@@ -3547,12 +3563,6 @@ class WorkflowJobTemplateSerializer(JobTemplateMixin, LabelsListMixin, UnifiedJo
return vars_validate_or_raise(value)
# TODO:
class WorkflowJobTemplateListSerializer(WorkflowJobTemplateSerializer):
pass
# TODO:
class WorkflowJobSerializer(LabelsListMixin, UnifiedJobSerializer):
class Meta:
@@ -3583,7 +3593,6 @@ class WorkflowJobSerializer(LabelsListMixin, UnifiedJobSerializer):
return ret
# TODO:
class WorkflowJobListSerializer(WorkflowJobSerializer, UnifiedJobListSerializer):
class Meta:
@@ -3866,7 +3875,10 @@ class AdHocCommandListSerializer(AdHocCommandSerializer, UnifiedJobListSerialize
class SystemJobListSerializer(SystemJobSerializer, UnifiedJobListSerializer):
pass
class Meta:
model = SystemJob
fields = ('*', '-controller_node') # field removal undone by UJ serializer
class JobHostSummarySerializer(BaseSerializer):

View File

@@ -642,7 +642,7 @@ class InstanceUnifiedJobsList(SubListAPIView):
view_name = _("Instance Jobs")
model = UnifiedJob
serializer_class = UnifiedJobSerializer
serializer_class = UnifiedJobListSerializer
parent_model = Instance
def get_queryset(self):
@@ -689,7 +689,7 @@ class InstanceGroupUnifiedJobsList(SubListAPIView):
view_name = _("Instance Group Running Jobs")
model = UnifiedJob
serializer_class = UnifiedJobSerializer
serializer_class = UnifiedJobListSerializer
parent_model = InstanceGroup
relationship = "unifiedjob_set"
@@ -800,7 +800,7 @@ class ScheduleCredentialsList(LaunchConfigCredentialsBase):
class ScheduleUnifiedJobsList(SubListAPIView):
model = UnifiedJob
serializer_class = UnifiedJobSerializer
serializer_class = UnifiedJobListSerializer
parent_model = Schedule
relationship = 'unifiedjob_set'
view_name = _('Schedule Jobs List')
@@ -1058,7 +1058,7 @@ class OrganizationProjectsList(SubListCreateAttachDetachAPIView):
class OrganizationWorkflowJobTemplatesList(SubListCreateAttachDetachAPIView):
model = WorkflowJobTemplate
serializer_class = WorkflowJobTemplateListSerializer
serializer_class = WorkflowJobTemplateSerializer
parent_model = Organization
relationship = 'workflows'
parent_key = 'organization'
@@ -1380,7 +1380,7 @@ class ProjectNotificationTemplatesSuccessList(SubListCreateAttachDetachAPIView):
class ProjectUpdatesList(SubListAPIView):
model = ProjectUpdate
serializer_class = ProjectUpdateSerializer
serializer_class = ProjectUpdateListSerializer
parent_model = Project
relationship = 'project_updates'
@@ -1491,7 +1491,7 @@ class ProjectUpdateScmInventoryUpdates(SubListCreateAPIView):
view_name = _("Project Update SCM Inventory Updates")
model = InventoryUpdate
serializer_class = InventoryUpdateSerializer
serializer_class = InventoryUpdateListSerializer
parent_model = ProjectUpdate
relationship = 'scm_inventory_updates'
parent_key = 'source_project_update'
@@ -2830,7 +2830,7 @@ class InventorySourceGroupsList(SubListDestroyAPIView):
class InventorySourceUpdatesList(SubListAPIView):
model = InventoryUpdate
serializer_class = InventoryUpdateSerializer
serializer_class = InventoryUpdateListSerializer
parent_model = InventorySource
relationship = 'inventory_updates'
@@ -3701,7 +3701,7 @@ class WorkflowJobNodeAlwaysNodesList(WorkflowJobNodeChildrenBaseList):
class WorkflowJobTemplateList(WorkflowsEnforcementMixin, ListCreateAPIView):
model = WorkflowJobTemplate
serializer_class = WorkflowJobTemplateListSerializer
serializer_class = WorkflowJobTemplateSerializer
always_allow_superuser = False