mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 08:21:15 +03:00
Merge pull request #1823 from AlanCoding/532_survey_validation
Block Duplicate Survey Variables
This commit is contained in:
commit
ac24fc75b8
@ -2229,6 +2229,7 @@ class JobTemplateSurveySpec(GenericAPIView):
|
|||||||
if len(obj.survey_spec["spec"]) < 1:
|
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
|
idx = 0
|
||||||
|
variable_set = set()
|
||||||
for survey_item in obj.survey_spec["spec"]:
|
for survey_item in obj.survey_spec["spec"]:
|
||||||
if not isinstance(survey_item, dict):
|
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 element %s is not a json object" % str(idx)), status=status.HTTP_400_BAD_REQUEST)
|
||||||
@ -2238,6 +2239,10 @@ class JobTemplateSurveySpec(GenericAPIView):
|
|||||||
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 element %s" % str(idx)), status=status.HTTP_400_BAD_REQUEST)
|
||||||
if "variable" not in survey_item:
|
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 element %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)
|
||||||
|
else:
|
||||||
|
variable_set.add(survey_item['variable'])
|
||||||
if "required" not in survey_item:
|
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 element %s" % str(idx)), status=status.HTTP_400_BAD_REQUEST)
|
||||||
idx += 1
|
idx += 1
|
||||||
|
135
awx/main/tests/functional/api/test_survey_spec_view.py
Normal file
135
awx/main/tests/functional/api/test_survey_spec_view.py
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import mock
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from awx.main.models.jobs import JobTemplate
|
||||||
|
from awx.api.license import LicenseForbids
|
||||||
|
|
||||||
|
def mock_feature_enabled(feature, bypass_database=None):
|
||||||
|
return True
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def survey_jobtemplate(project, inventory, credential):
|
||||||
|
return JobTemplate.objects.create(
|
||||||
|
job_type='run',
|
||||||
|
project=project,
|
||||||
|
inventory=inventory,
|
||||||
|
credential=credential,
|
||||||
|
name='deploy-job-template'
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch('awx.api.views.feature_enabled', new=mock_feature_disabled)
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.survey
|
||||||
|
def test_survey_spec_view_denied(deploy_jobtemplate, get, user):
|
||||||
|
# TODO: Test non-enterprise license
|
||||||
|
spec_url = reverse('api:job_template_survey_spec', args=(deploy_jobtemplate.id,))
|
||||||
|
response = get(spec_url, user('admin', True))
|
||||||
|
|
||||||
|
assert response.status_code == 402
|
||||||
|
assert response.data['detail'] == 'Your license does not allow adding surveys.'
|
||||||
|
|
||||||
|
@mock.patch('awx.main.access.BaseAccess.check_license', mock_check_license)
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.survey
|
||||||
|
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'
|
||||||
|
|
||||||
|
@mock.patch('awx.main.access.BaseAccess.check_license', mock_check_license)
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.survey
|
||||||
|
def test_deny_creating_with_survey(machine_credential, project, inventory, post, user):
|
||||||
|
JT_url = reverse('api:job_template_list')
|
||||||
|
JT_data = dict(
|
||||||
|
name = 'JT with survey',
|
||||||
|
job_type = 'run',
|
||||||
|
inventory = inventory.pk,
|
||||||
|
project = project.pk,
|
||||||
|
playbook = 'hiworld.yml',
|
||||||
|
credential = machine_credential.pk,
|
||||||
|
survey_enabled = True,
|
||||||
|
)
|
||||||
|
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'
|
||||||
|
|
||||||
|
@mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled)
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.survey
|
||||||
|
def test_survey_spec_view_allowed(deploy_jobtemplate, get, user):
|
||||||
|
spec_url = reverse('api:job_template_survey_spec', args=(deploy_jobtemplate.id,))
|
||||||
|
response = get(spec_url, user('admin', True))
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
@mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled)
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.survey
|
||||||
|
def test_survey_spec_sucessful_creation(deploy_jobtemplate, post, user):
|
||||||
|
spec_url = reverse('api:job_template_survey_spec', args=(deploy_jobtemplate.id,))
|
||||||
|
response = post(
|
||||||
|
url=spec_url,
|
||||||
|
data={
|
||||||
|
"description": "Email of the submitter",
|
||||||
|
"spec": [{
|
||||||
|
"variable": "submitter_email",
|
||||||
|
"question_name": "Enter your email",
|
||||||
|
"type": "text",
|
||||||
|
"required": False
|
||||||
|
}],
|
||||||
|
"name": "Email survey"
|
||||||
|
},
|
||||||
|
user=user('admin', True))
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
@mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled)
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.survey
|
||||||
|
def test_survey_spec_non_dict_error(deploy_jobtemplate, post, user):
|
||||||
|
spec_url = reverse('api:job_template_survey_spec', args=(deploy_jobtemplate.id,))
|
||||||
|
response = post(
|
||||||
|
url=spec_url,
|
||||||
|
data={"description": "Email of the submitter",
|
||||||
|
"spec": ["What is your email?"], "name": "Email survey"},
|
||||||
|
user=user('admin', True))
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.data['error'] == "survey element 0 is not a json object"
|
||||||
|
|
||||||
|
@mock.patch('awx.api.views.feature_enabled', new=mock_feature_enabled)
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@pytest.mark.survey
|
||||||
|
def test_survey_spec_dual_names_error(deploy_jobtemplate, post, user):
|
||||||
|
spec_url = reverse('api:job_template_survey_spec', args=(deploy_jobtemplate.id,))
|
||||||
|
response = post(
|
||||||
|
url=spec_url,
|
||||||
|
data={
|
||||||
|
"description": "Email of the submitter",
|
||||||
|
"spec": [{
|
||||||
|
"variable": "submitter_email",
|
||||||
|
"question_name": "Enter your email",
|
||||||
|
"type": "text",
|
||||||
|
"required": False
|
||||||
|
}, {
|
||||||
|
"variable": "submitter_email",
|
||||||
|
"question_name": "Same variable as last question",
|
||||||
|
"type": "integer",
|
||||||
|
"required": False
|
||||||
|
}],
|
||||||
|
"name": "Email survey"
|
||||||
|
},
|
||||||
|
user=user('admin', True))
|
||||||
|
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.data['error'] == "'variable' name 'submitter_email' duplicated in survey element 1"
|
@ -1109,27 +1109,6 @@ class JobTemplateSurveyTest(BaseJobTestMixin, django.test.TransactionTestCase):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(JobTemplateSurveyTest, self).tearDown()
|
super(JobTemplateSurveyTest, self).tearDown()
|
||||||
|
|
||||||
def test_post_patch_job_template_survey_wrong_license(self):
|
|
||||||
url = reverse('api:job_template_list')
|
|
||||||
data = dict(
|
|
||||||
name = 'launched job template',
|
|
||||||
job_type = PERM_INVENTORY_DEPLOY,
|
|
||||||
inventory = self.inv_eng.pk,
|
|
||||||
project = self.proj_dev.pk,
|
|
||||||
playbook = self.proj_dev.playbooks[0],
|
|
||||||
credential = self.cred_sue.pk,
|
|
||||||
survey_enabled = True,
|
|
||||||
)
|
|
||||||
self.create_test_license_file(features=dict(surveys=False))
|
|
||||||
with self.current_user(self.user_sue):
|
|
||||||
self.post(url, data, expect=402)
|
|
||||||
data['survey_enabled'] = False
|
|
||||||
with self.current_user(self.user_sue):
|
|
||||||
response = self.post(url, data, expect=201)
|
|
||||||
jt_url = reverse('api:job_template_detail', args=(response['id'],))
|
|
||||||
with self.current_user(self.user_sue):
|
|
||||||
self.patch(jt_url, dict(survey_enabled=True), expect=402)
|
|
||||||
|
|
||||||
def test_post_job_template_survey(self):
|
def test_post_job_template_survey(self):
|
||||||
url = reverse('api:job_template_list')
|
url = reverse('api:job_template_list')
|
||||||
data = dict(
|
data = dict(
|
||||||
|
Loading…
Reference in New Issue
Block a user