diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 89e8c6d719..9613d2e2d2 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -849,7 +849,7 @@ class ProjectOptionsSerializer(BaseSerializer): if scm_type: attrs.pop('local_path', None) if 'local_path' in attrs and attrs['local_path'] not in valid_local_paths: - errors['local_path'] = 'Invalid path choice' + errors['local_path'] = 'Invalid path choice.' if errors: raise serializers.ValidationError(errors) @@ -1305,14 +1305,14 @@ class InventorySourceOptionsSerializer(BaseSerializer): source_script = attrs.get('source_script', self.instance and self.instance.source_script or '') if source == 'custom': if source_script is None or source_script == '': - errors['source_script'] = 'source_script must be provided' + errors['source_script'] = "If 'source' is 'custom', 'source_script' must be provided." else: try: if source_script.organization != self.instance.inventory.organization: - errors['source_script'] = 'source_script does not belong to the same organization as the inventory.' + errors['source_script'] = "The 'source_script' does not belong to the same organization as the inventory." except Exception: # TODO: Log - errors['source_script'] = 'source_script doesn\'t exist.' + errors['source_script'] = "'source_script' doesn't exist." if errors: raise serializers.ValidationError(errors) @@ -1813,7 +1813,7 @@ class JobTemplateSerializer(UnifiedJobTemplateSerializer, JobOptionsSerializer): return value except yaml.YAMLError: pass - raise serializers.ValidationError('Must be valid JSON or YAML') + raise serializers.ValidationError('Must be valid JSON or YAML.') class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer): @@ -1860,7 +1860,7 @@ class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer): try: job_template = JobTemplate.objects.get(pk=data['job_template']) except JobTemplate.DoesNotExist: - self._errors = {'job_template': 'Invalid job template'} + self._errors = {'job_template': 'Invalid job template.'} return data.setdefault('name', job_template.name) data.setdefault('description', job_template.description) @@ -2278,7 +2278,7 @@ class JobLaunchSerializer(BaseSerializer): extra_vars = yaml.safe_load(extra_vars) assert isinstance(extra_vars, dict) except (yaml.YAMLError, TypeError, AttributeError, AssertionError): - errors['extra_vars'] = 'Must be a valid JSON or YAML dictionary' + errors['extra_vars'] = 'Must be a valid JSON or YAML dictionary.' if not isinstance(extra_vars, dict): extra_vars = {} @@ -2385,11 +2385,11 @@ class NotificationTemplateSerializer(BaseSerializer): attrs['notification_configuration'][field] = object_actual.notification_configuration[field] error_list = [] if missing_fields: - error_list.append("Missing required fields for Notification Configuration: {}".format(missing_fields)) + error_list.append("Missing required fields for Notification Configuration: {}.".format(missing_fields)) if incorrect_type_fields: for type_field_error in incorrect_type_fields: - error_list.append("Configuration field '{}' incorrect type, expected {}".format(type_field_error[0], - type_field_error[1])) + error_list.append("Configuration field '{}' incorrect type, expected {}.".format(type_field_error[0], + type_field_error[1])) if error_list: raise serializers.ValidationError(error_list) return attrs @@ -2509,9 +2509,11 @@ class ActivityStreamSerializer(BaseSerializer): if key == 'changes': field.help_text = 'A summary of the new and changed values when an object is created, updated, or deleted' if key == 'object1': - field.help_text = 'For create, update, and delete events this is the object type that was affected. For associate and disassociate events this is the object type associated or disassociated with object2' + field.help_text = ('For create, update, and delete events this is the object type that was affected. ' + 'For associate and disassociate events this is the object type associated or disassociated with object2.') if key == 'object2': - field.help_text = 'Unpopulated for create, update, and delete events. For associate and disassociate events this is the object type that object1 is being associated with' + field.help_text = ('Unpopulated for create, update, and delete events. For associate and disassociate ' + 'events this is the object type that object1 is being associated with.') if key == 'operation': field.help_text = 'The action taken with respect to the given object(s).' return ret @@ -2617,7 +2619,7 @@ class TowerSettingsSerializer(BaseSerializer): def to_internal_value(self, data): if data['key'] not in settings.TOWER_SETTINGS_MANIFEST: - self._errors = {'key': 'Key {0} is not a valid settings key'.format(data['key'])} + self._errors = {'key': 'Key {0} is not a valid settings key.'.format(data['key'])} return ret = super(TowerSettingsSerializer, self).to_internal_value(data) manifest_val = settings.TOWER_SETTINGS_MANIFEST[data['key']] diff --git a/awx/api/views.py b/awx/api/views.py index 5ba7b5e56e..fc3cf39521 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -856,7 +856,7 @@ class TeamRolesList(SubListCreateAttachDetachAPIView): # Forbid implicit role creation here sub_id = request.data.get('id', None) if not sub_id: - data = dict(msg='Role "id" field is missing') + data = dict(msg="Role 'id' field is missing.") return Response(data, status=status.HTTP_400_BAD_REQUEST) return super(TeamRolesList, self).post(request, *args, **kwargs) @@ -1138,7 +1138,7 @@ class UserRolesList(SubListCreateAttachDetachAPIView): # Forbid implicit role creation here sub_id = request.data.get('id', None) if not sub_id: - data = dict(msg='Role "id" field is missing') + data = dict(msg="Role 'id' field is missing.") return Response(data, status=status.HTTP_400_BAD_REQUEST) if sub_id == self.request.user.admin_role.pk: @@ -1269,10 +1269,10 @@ class CredentialList(ListCreateAPIView): kwargs.pop(field, None) if not any([x in request.data for x in ['user', 'team', 'organization']]): - return Response({'detail': 'Missing user, team, or organization'}, status=status.HTTP_400_BAD_REQUEST) + return Response({"detail": "Missing 'user', 'team', or 'organization'."}, status=status.HTTP_400_BAD_REQUEST) if sum([1 if x in request.data else 0 for x in ['user', 'team', 'organization']]) != 1: - return Response({'detail': 'Expecting exactly one of user, team, or organization'}, status=status.HTTP_400_BAD_REQUEST) + return Response({"detail": "Expecting exactly one of 'user', 'team', or 'organization'."}, status=status.HTTP_400_BAD_REQUEST) if 'user' in request.data: user = User.objects.get(pk=request.data['user']) @@ -1651,7 +1651,7 @@ class HostFactCompareView(SubDetailAPIView, SystemTrackingEnforcementMixin): fact_entry = Fact.get_host_fact(host_obj.id, module_spec, datetime_actual) if not fact_entry: - return Response({'detail': 'Fact not found'}, status=status.HTTP_404_NOT_FOUND) + return Response({'detail': 'Fact not found.'}, status=status.HTTP_404_NOT_FOUND) return Response(self.serializer_class(instance=fact_entry).data) class GroupList(ListCreateAPIView): @@ -1694,7 +1694,7 @@ class GroupChildrenList(SubListCreateAttachDetachAPIView): ''' sub_id = request.data.get('id', None) if not sub_id: - data = dict(msg='"id" is required to disassociate') + data = dict(msg="'id' is required to disassociate.") return Response(data, status=status.HTTP_400_BAD_REQUEST) parent = self.get_parent_object() @@ -2070,7 +2070,7 @@ class InventorySourceNotificationTemplatesAnyList(SubListCreateAttachDetachAPIVi def post(self, request, *args, **kwargs): parent = self.get_parent_object() if parent.source not in CLOUD_INVENTORY_SOURCES: - return Response(dict(msg="Notification Templates can only be assigned when source is one of {}" + return Response(dict(msg="Notification Templates can only be assigned when source is one of {}." .format(CLOUD_INVENTORY_SOURCES, parent.source)), status=status.HTTP_400_BAD_REQUEST) return super(InventorySourceNotificationTemplatesAnyList, self).post(request, *args, **kwargs) @@ -2288,34 +2288,34 @@ class JobTemplateSurveySpec(GenericAPIView): obj.survey_spec = json.dumps(request.data) except ValueError: # TODO: Log - return Response(dict(error="Invalid JSON when parsing survey spec"), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="Invalid JSON when parsing survey spec."), status=status.HTTP_400_BAD_REQUEST) if "name" not in obj.survey_spec: - return Response(dict(error="'name' missing from survey spec"), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'name' missing from survey spec."), status=status.HTTP_400_BAD_REQUEST) if "description" not in obj.survey_spec: - return Response(dict(error="'description' missing from survey spec"), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'description' missing from survey spec."), status=status.HTTP_400_BAD_REQUEST) if "spec" not in obj.survey_spec: - return Response(dict(error="'spec' missing from survey spec"), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'spec' missing from survey spec."), status=status.HTTP_400_BAD_REQUEST) if not isinstance(obj.survey_spec["spec"], list): - return Response(dict(error="'spec' must be a list of items"), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'spec' must be a list of items."), status=status.HTTP_400_BAD_REQUEST) if len(obj.survey_spec["spec"]) < 1: - return Response(dict(error="'spec' doesn't contain any items"), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'spec' doesn't contain any items."), status=status.HTTP_400_BAD_REQUEST) idx = 0 variable_set = set() for survey_item in obj.survey_spec["spec"]: if not isinstance(survey_item, dict): - return Response(dict(error="survey element %s is not a json object" % str(idx)), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="Survey question %s is not a json object." % str(idx)), status=status.HTTP_400_BAD_REQUEST) if "type" not in survey_item: - return Response(dict(error="'type' missing from survey element %s" % str(idx)), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'type' missing from survey question %s." % str(idx)), status=status.HTTP_400_BAD_REQUEST) if "question_name" not in survey_item: - return Response(dict(error="'question_name' missing from survey element %s" % str(idx)), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'question_name' missing from survey question %s." % str(idx)), status=status.HTTP_400_BAD_REQUEST) if "variable" not in survey_item: - return Response(dict(error="'variable' missing from survey element %s" % str(idx)), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'variable' missing from survey question %s." % str(idx)), status=status.HTTP_400_BAD_REQUEST) if survey_item['variable'] in variable_set: - return Response(dict(error="'variable' name '%s' duplicated in survey element %s" % (survey_item['variable'], str(idx))), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'variable' '%s' duplicated in survey question %s." % (survey_item['variable'], str(idx))), status=status.HTTP_400_BAD_REQUEST) else: variable_set.add(survey_item['variable']) if "required" not in survey_item: - return Response(dict(error="'required' missing from survey element %s" % str(idx)), status=status.HTTP_400_BAD_REQUEST) + return Response(dict(error="'required' missing from survey question %s." % str(idx)), status=status.HTTP_400_BAD_REQUEST) idx += 1 obj.save() return Response() @@ -2516,7 +2516,7 @@ class JobTemplateCallback(GenericAPIView): # NOTE: We limit this to one job waiting per host per callblack to keep them from stacking crazily if Job.objects.filter(status__in=['pending', 'waiting', 'running'], job_template=job_template, limit=limit).count() > 0: - data = dict(msg='Host callback job already pending') + data = dict(msg='Host callback job already pending.') return Response(data, status=status.HTTP_400_BAD_REQUEST) # Everything is fine; actually create the job. @@ -2861,7 +2861,7 @@ class JobJobPlaysList(BaseJobEventsList): all_plays = [] job = Job.objects.filter(pk=self.kwargs['pk']) if not job.exists(): - return ({'detail': 'job not found'}, -1, status.HTTP_404_NOT_FOUND) + return ({'detail': 'Job not found.'}, -1, status.HTTP_404_NOT_FOUND) job = job[0] # Put together a queryset for relevant job events. @@ -2943,15 +2943,15 @@ class JobJobTasksList(BaseJobEventsList): # If there's no event ID specified, this will return a 404. job = Job.objects.filter(pk=self.kwargs['pk']) if not job.exists(): - return ({'detail': 'job not found'}, -1, status.HTTP_404_NOT_FOUND) + return ({'detail': 'Job not found.'}, -1, status.HTTP_404_NOT_FOUND) job = job[0] if 'event_id' not in request.query_params: - return ({'detail': '"event_id" not provided'}, -1, status.HTTP_400_BAD_REQUEST) + return ({"detail": "'event_id' not provided."}, -1, status.HTTP_400_BAD_REQUEST) parent_task = job.job_events.filter(pk=int(request.query_params.get('event_id', -1))) if not parent_task.exists(): - return ({'detail': 'parent event not found'}, -1, status.HTTP_404_NOT_FOUND) + return ({'detail': 'Parent event not found.'}, -1, status.HTTP_404_NOT_FOUND) parent_task = parent_task[0] # Some events correspond to a playbook or task starting up, @@ -3624,7 +3624,7 @@ class RoleUsersList(SubListCreateAttachDetachAPIView): # Forbid implicit role creation here sub_id = request.data.get('id', None) if not sub_id: - data = dict(msg='Role "id" field is missing') + data = dict(msg="Role 'id' field is missing.") return Response(data, status=status.HTTP_400_BAD_REQUEST) return super(RoleUsersList, self).post(request, *args, **kwargs) @@ -3647,7 +3647,7 @@ class RoleTeamsList(ListAPIView): # Forbid implicit role creation here sub_id = request.data.get('id', None) if not sub_id: - data = dict(msg='Role "id" field is missing') + data = dict(msg="Role 'id' field is missing.") return Response(data, status=status.HTTP_400_BAD_REQUEST) # XXX: Need to pull in can_attach and can_unattach kinda code from SubListCreateAttachDetachAPIView role = Role.objects.get(pk=self.kwargs['pk']) diff --git a/awx/main/models/credential.py b/awx/main/models/credential.py index 71ee9a75ef..d1e6e91d93 100644 --- a/awx/main/models/credential.py +++ b/awx/main/models/credential.py @@ -329,12 +329,12 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin): def clean_ssh_key_unlock(self): if self.has_encrypted_ssh_key_data and not self.ssh_key_unlock: raise ValidationError('SSH key unlock must be set when SSH key ' - 'is encrypted') + 'is encrypted.') return self.ssh_key_unlock def clean(self): if self.deprecated_user and self.deprecated_team: - raise ValidationError('Credential cannot be assigned to both a user and team') + raise ValidationError('Credential cannot be assigned to both a user and team.') def _password_field_allows_ask(self, field): return bool(self.kind == 'ssh' and field != 'ssh_key_data') @@ -394,7 +394,7 @@ def validate_ssh_private_key(data): 'cert_bin': '', # Cert data as binary. } data = data.strip() - validation_error = ValidationError('Invalid private key') + validation_error = ValidationError('Invalid private key.') # Sanity check: We may potentially receive a full PEM certificate, # and we want to accept these. diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index b9bb57be99..18033d11ce 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -994,7 +994,7 @@ class InventorySourceOptions(BaseModel): # an EC2 instance with an IAM Role assigned, boto will use credentials # from the instance metadata instead of those explicitly provided. elif self.source in CLOUD_PROVIDERS and self.source != 'ec2': - raise ValidationError('Credential is required for a cloud source') + raise ValidationError('Credential is required for a cloud source.') return cred def clean_source_regions(self): diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index e7a97755f3..c945dc9b3c 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -244,11 +244,11 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): def clean(self): if self.job_type == 'scan' and (self.inventory is None or self.ask_inventory_on_launch): - raise ValidationError('Scan jobs must be assigned a fixed inventory') + raise ValidationError({"inventory": ["Scan jobs must be assigned a fixed inventory.",]}) if (not self.ask_inventory_on_launch) and self.inventory is None: - raise ValidationError('Job Template must either have an inventory or allow prompting for inventory') + raise ValidationError({"inventory": ["Job Template must provide 'inventory' or allow prompting for it.",]}) if (not self.ask_credential_on_launch) and self.credential is None: - raise ValidationError('Job Template must either have a credential or allow prompting for credential') + raise ValidationError({"credential": ["Job Template must provide 'credential' or allow prompting for it.",]}) return super(JobTemplate, self).clean() def create_job(self, **kwargs): @@ -292,9 +292,9 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): if not self.survey_enabled: return errors if 'name' not in self.survey_spec: - errors.append("'name' missing from survey spec") + errors.append("'name' missing from survey spec.") if 'description' not in self.survey_spec: - errors.append("'description' missing from survey spec") + errors.append("'description' missing from survey spec.") for survey_element in self.survey_spec.get("spec", []): if survey_element['variable'] not in data and \ survey_element['required']: @@ -302,50 +302,50 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): elif survey_element['type'] in ["textarea", "text", "password"]: if survey_element['variable'] in data: if 'min' in survey_element and survey_element['min'] not in ["", None] and len(data[survey_element['variable']]) < survey_element['min']: - errors.append("'%s' value %s is too small (must be at least %s)" % + errors.append("'%s' value %s is too small (must be at least %s)." % (survey_element['variable'], data[survey_element['variable']], survey_element['min'])) if 'max' in survey_element and survey_element['max'] not in ["", None] and len(data[survey_element['variable']]) > survey_element['max']: - errors.append("'%s' value %s is too large (must be no more than %s)" % + errors.append("'%s' value %s is too large (must be no more than %s)." % (survey_element['variable'], data[survey_element['variable']], survey_element['max'])) elif survey_element['type'] == 'integer': if survey_element['variable'] in data: if 'min' in survey_element and survey_element['min'] not in ["", None] and survey_element['variable'] in data and \ data[survey_element['variable']] < survey_element['min']: - errors.append("'%s' value %s is too small (must be at least %s)" % + errors.append("'%s' value %s is too small (must be at least %s)." % (survey_element['variable'], data[survey_element['variable']], survey_element['min'])) if 'max' in survey_element and survey_element['max'] not in ["", None] and survey_element['variable'] in data and \ data[survey_element['variable']] > survey_element['max']: - errors.append("'%s' value %s is too large (must be no more than %s)" % + errors.append("'%s' value %s is too large (must be no more than %s)." % (survey_element['variable'], data[survey_element['variable']], survey_element['max'])) if type(data[survey_element['variable']]) != int: - errors.append("Value %s for %s expected to be an integer" % (data[survey_element['variable']], - survey_element['variable'])) + errors.append("Value %s for '%s' expected to be an integer." % (data[survey_element['variable']], + survey_element['variable'])) elif survey_element['type'] == 'float': if survey_element['variable'] in data: if 'min' in survey_element and survey_element['min'] not in ["", None] and data[survey_element['variable']] < survey_element['min']: - errors.append("'%s' value %s is too small (must be at least %s)" % + errors.append("'%s' value %s is too small (must be at least %s)." % (survey_element['variable'], data[survey_element['variable']], survey_element['min'])) if 'max' in survey_element and survey_element['max'] not in ["", None] and data[survey_element['variable']] > survey_element['max']: - errors.append("'%s' value %s is too large (must be no more than %s)" % + errors.append("'%s' value %s is too large (must be no more than %s)." % (survey_element['variable'], data[survey_element['variable']], survey_element['max'])) if type(data[survey_element['variable']]) not in (float, int): - errors.append("Value %s for %s expected to be a numeric type" % (data[survey_element['variable']], - survey_element['variable'])) + errors.append("Value %s for '%s' expected to be a numeric type." % (data[survey_element['variable']], + survey_element['variable'])) elif survey_element['type'] == 'multiselect': if survey_element['variable'] in data: if type(data[survey_element['variable']]) != list: - errors.append("'%s' value is expected to be a list" % survey_element['variable']) + errors.append("'%s' value is expected to be a list." % survey_element['variable']) else: for val in data[survey_element['variable']]: if val not in survey_element['choices']: - errors.append("Value %s for %s expected to be one of %s" % (val, survey_element['variable'], - survey_element['choices'])) + errors.append("Value %s for '%s' expected to be one of %s." % (val, survey_element['variable'], + survey_element['choices'])) elif survey_element['type'] == 'multiplechoice': if survey_element['variable'] in data: if data[survey_element['variable']] not in survey_element['choices']: - errors.append("Value %s for %s expected to be one of %s" % (data[survey_element['variable']], - survey_element['variable'], - survey_element['choices'])) + errors.append("Value %s for '%s' expected to be one of %s." % (data[survey_element['variable']], + survey_element['variable'], + survey_element['choices'])) return errors def _update_unified_job_kwargs(self, **kwargs): diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index f421bb7fa3..0e74feb1bc 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -116,10 +116,10 @@ class ProjectOptions(models.Model): scm_url = update_scm_url(self.scm_type, scm_url, check_special_cases=False) except ValueError, e: - raise ValidationError((e.args or ('Invalid SCM URL',))[0]) + raise ValidationError((e.args or ('Invalid SCM URL.',))[0]) scm_url_parts = urlparse.urlsplit(scm_url) if self.scm_type and not any(scm_url_parts): - raise ValidationError('SCM URL is required') + raise ValidationError('SCM URL is required.') return unicode(self.scm_url or '') def clean_credential(self): @@ -128,7 +128,7 @@ class ProjectOptions(models.Model): cred = self.credential if cred: if cred.kind != 'scm': - raise ValidationError('Credential kind must be "scm"') + raise ValidationError("Credential kind must be 'scm'.") try: scm_url = update_scm_url(self.scm_type, self.scm_url, check_special_cases=False) @@ -143,7 +143,7 @@ class ProjectOptions(models.Model): update_scm_url(self.scm_type, self.scm_url, scm_username, scm_password) except ValueError, e: - raise ValidationError((e.args or ('Invalid credential',))[0]) + raise ValidationError((e.args or ('Invalid credential.',))[0]) except ValueError: pass return cred diff --git a/awx/main/tests/functional/api/test_fact_view.py b/awx/main/tests/functional/api/test_fact_view.py index f06801fa79..be5367ba52 100644 --- a/awx/main/tests/functional/api/test_fact_view.py +++ b/awx/main/tests/functional/api/test_fact_view.py @@ -61,7 +61,7 @@ def test_no_fact_found(hosts, get, user): response = get(url, user('admin', True)) expected_response = { - "detail": "Fact not found" + "detail": "Fact not found." } assert 404 == response.status_code assert expected_response == response.data diff --git a/awx/main/tests/functional/api/test_job_runtime_params.py b/awx/main/tests/functional/api/test_job_runtime_params.py index 6f76fdf1b6..37e7b68f9e 100644 --- a/awx/main/tests/functional/api/test_job_runtime_params.py +++ b/awx/main/tests/functional/api/test_job_runtime_params.py @@ -159,7 +159,7 @@ def test_job_reject_invalid_prompted_extra_vars(runtime_data, job_template_promp dict(extra_vars='{"unbalanced brackets":'), user('admin', True)) assert response.status_code == 400 - assert response.data['extra_vars'] == ['Must be a valid JSON or YAML dictionary'] + assert response.data['extra_vars'] == ['Must be a valid JSON or YAML dictionary.'] @pytest.mark.django_db @pytest.mark.job_runtime_vars diff --git a/awx/main/tests/functional/api/test_survey_spec_view.py b/awx/main/tests/functional/api/test_survey_spec_view.py index f881603c87..b45c88f495 100644 --- a/awx/main/tests/functional/api/test_survey_spec_view.py +++ b/awx/main/tests/functional/api/test_survey_spec_view.py @@ -12,7 +12,7 @@ def mock_feature_disabled(feature, bypass_database=None): return False def mock_check_license(self, add_host=False, feature=None, check_expiration=True): - raise LicenseForbids("Feature %s is not enabled in the active license" % feature) + raise LicenseForbids("Feature %s is not enabled in the active license." % feature) @pytest.fixture def survey_jobtemplate(project, inventory, credential): @@ -42,7 +42,7 @@ def test_deny_enabling_survey(deploy_jobtemplate, patch, user): JT_url = reverse('api:job_template_detail', args=(deploy_jobtemplate.id,)) response = patch(url=JT_url, data=dict(survey_enabled=True), user=user('admin', True)) assert response.status_code == 402 - assert response.data['detail'] == 'Feature surveys is not enabled in the active license' + assert response.data['detail'] == 'Feature surveys is not enabled in the active license.' @mock.patch('awx.main.access.BaseAccess.check_license', mock_check_license) @pytest.mark.django_db @@ -61,7 +61,7 @@ def test_deny_creating_with_survey(machine_credential, project, inventory, post, response = post(url=JT_url, data=JT_data, user=user('admin', True)) assert response.status_code == 402 - assert response.data['detail'] == 'Feature surveys is not enabled in the active license' + assert response.data['detail'] == 'Feature surveys is not enabled in the active license.' @mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled) @pytest.mark.django_db @@ -105,7 +105,7 @@ def test_survey_spec_non_dict_error(deploy_jobtemplate, post, user): user=user('admin', True)) assert response.status_code == 400 - assert response.data['error'] == "survey element 0 is not a json object" + assert response.data['error'] == "Survey question 0 is not a json object." @mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled) @pytest.mark.django_db @@ -132,4 +132,4 @@ def test_survey_spec_dual_names_error(deploy_jobtemplate, post, user): user=user('admin', True)) assert response.status_code == 400 - assert response.data['error'] == "'variable' name 'submitter_email' duplicated in survey element 1" + assert response.data['error'] == "'variable' 'submitter_email' duplicated in survey question 1."