properly handle JT launch POST for required survey fields w/ no default

see: ansible/ansible-tower#7805
This commit is contained in:
Ryan Petrello
2017-12-04 09:08:36 -05:00
parent 12380fe1b1
commit 112757e202
2 changed files with 52 additions and 7 deletions

View File

@@ -170,15 +170,18 @@ class SurveyJobTemplateMixin(models.Model):
def _survey_element_validation(self, survey_element, data):
# Don't apply validation to the `$encrypted$` placeholder; the decrypted
# default (if any) will be validated against instead
errors = []
if (survey_element['type'] == "password"):
password_value = data.get(survey_element['variable'])
if (
isinstance(password_value, basestring) and
password_value == '$encrypted$'
):
return []
if survey_element.get('default') is None and survey_element['required']:
errors.append("'%s' value missing" % survey_element['variable'])
return errors
errors = []
if survey_element['variable'] not in data and survey_element['required']:
errors.append("'%s' value missing" % survey_element['variable'])
elif survey_element['type'] in ["textarea", "text", "password"]:

View File

@@ -168,7 +168,6 @@ def test_survey_spec_passwords_with_empty_default(job_template_factory, post, ad
@mock.patch('awx.api.views.feature_enabled', lambda feature: True)
@pytest.mark.django_db
@pytest.mark.parametrize('required', [True, False])
@pytest.mark.parametrize('default, launch_value, expected_extra_vars, status', [
['', '$encrypted$', {'secret_value': ''}, 201],
['', 'y', {'secret_value': 'y'}, 201],
@@ -183,9 +182,9 @@ def test_survey_spec_passwords_with_empty_default(job_template_factory, post, ad
['x' * 100, 'y', {'secret_value': 'y'}, 201],
['x' * 100, 'y' * 100, {}, 400],
])
def test_survey_spec_passwords_with_default(job_template_factory, post, admin_user,
required, default, launch_value, expected_extra_vars,
status):
def test_survey_spec_passwords_with_default_optional(job_template_factory, post, admin_user,
default, launch_value,
expected_extra_vars, status):
objects = job_template_factory('jt', organization='org1', project='prj',
inventory='inv', credential='cred')
job_template = objects.job_template
@@ -196,7 +195,50 @@ def test_survey_spec_passwords_with_default(job_template_factory, post, admin_us
'spec': [{
'index': 0,
'question_name': 'What is your password?',
'required': required,
'required': False,
'variable': 'secret_value',
'type': 'password',
'max': 3
}],
'name': 'my survey'
}
if default is not None:
input_data['spec'][0]['default'] = default
post(url=reverse('api:job_template_survey_spec', kwargs={'pk': job_template.id}),
data=input_data, user=admin_user, expect=200)
resp = post(reverse('api:job_template_launch', kwargs={'pk': job_template.pk}),
data={'extra_vars': {'secret_value': launch_value}}, user=admin_user, expect=status)
if status == 201:
job = Job.objects.get(pk=resp.data['job'])
assert json.loads(job.decrypted_extra_vars()) == expected_extra_vars
if default:
assert default not in json.loads(job.extra_vars).values()
assert launch_value not in json.loads(job.extra_vars).values()
@mock.patch('awx.api.views.feature_enabled', lambda feature: True)
@pytest.mark.django_db
@pytest.mark.parametrize('default, launch_value, expected_extra_vars, status', [
['', '$encrypted$', {'secret_value': ''}, 201],
[None, '$encrypted$', {}, 400],
[None, 'y', {'secret_value': 'y'}, 201],
])
def test_survey_spec_passwords_with_default_required(job_template_factory, post, admin_user,
default, launch_value,
expected_extra_vars, status):
objects = job_template_factory('jt', organization='org1', project='prj',
inventory='inv', credential='cred')
job_template = objects.job_template
job_template.survey_enabled = True
job_template.save()
input_data = {
'description': 'A survey',
'spec': [{
'index': 0,
'question_name': 'What is your password?',
'required': True,
'variable': 'secret_value',
'type': 'password',
'max': 3