From a85f5a6a63e282a4b213ac7283732f704e3f8d0b Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Wed, 4 May 2016 16:35:29 -0400 Subject: [PATCH 1/3] started tests for survey spec --- .../functional/api/test_survey_spec_view.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 awx/main/tests/functional/api/test_survey_spec_view.py diff --git a/awx/main/tests/functional/api/test_survey_spec_view.py b/awx/main/tests/functional/api/test_survey_spec_view.py new file mode 100644 index 0000000000..87d67e7b2e --- /dev/null +++ b/awx/main/tests/functional/api/test_survey_spec_view.py @@ -0,0 +1,45 @@ +import mock +import pytest +import json + +from awx.main.utils import timestamp_apiformat +from django.core.urlresolvers import reverse +from django.utils import timezone + +def mock_feature_enabled(feature, bypass_database=None): + return True + +def mock_feature_disabled(feature, bypass_database=None): + return False + +@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): + 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.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 + print response.data + + From 92efb2d3172d153ae0949eb078c24b4459056635 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Thu, 5 May 2016 15:53:35 -0400 Subject: [PATCH 2/3] exception for dual-name questions and more tests --- awx/api/views.py | 5 ++ .../functional/api/test_survey_spec_view.py | 65 +++++++++++++++++-- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/awx/api/views.py b/awx/api/views.py index aa476f18c6..29f9cea95d 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -2229,6 +2229,7 @@ class JobTemplateSurveySpec(GenericAPIView): if len(obj.survey_spec["spec"]) < 1: 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) @@ -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) if "variable" not in survey_item: 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: return Response(dict(error="'required' missing from survey element %s" % str(idx)), status=status.HTTP_400_BAD_REQUEST) idx += 1 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 87d67e7b2e..27e93a2a5b 100644 --- a/awx/main/tests/functional/api/test_survey_spec_view.py +++ b/awx/main/tests/functional/api/test_survey_spec_view.py @@ -1,10 +1,8 @@ import mock import pytest -import json -from awx.main.utils import timestamp_apiformat from django.core.urlresolvers import reverse -from django.utils import timezone +from awx.main.models.jobs import JobTemplate def mock_feature_enabled(feature, bypass_database=None): return True @@ -40,6 +38,65 @@ def test_survey_spec_view_allowed(deploy_jobtemplate, get, user): response = get(spec_url, user('admin', True)) assert response.status_code == 200 - print response.data +@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" From fe1a0e2aa811c862182a520092ed6908961a65ab Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 6 May 2016 11:40:10 -0400 Subject: [PATCH 3/3] JT survey license check test migrations --- .../functional/api/test_survey_spec_view.py | 33 +++++++++++++++++++ awx/main/tests/old/jobs/jobs_monolithic.py | 21 ------------ 2 files changed, 33 insertions(+), 21 deletions(-) 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 27e93a2a5b..f881603c87 100644 --- a/awx/main/tests/functional/api/test_survey_spec_view.py +++ b/awx/main/tests/functional/api/test_survey_spec_view.py @@ -3,6 +3,7 @@ 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 @@ -10,6 +11,9 @@ def mock_feature_enabled(feature, bypass_database=None): 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( @@ -24,12 +28,41 @@ def survey_jobtemplate(project, inventory, credential): @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 diff --git a/awx/main/tests/old/jobs/jobs_monolithic.py b/awx/main/tests/old/jobs/jobs_monolithic.py index aae061ff15..de308f52c5 100644 --- a/awx/main/tests/old/jobs/jobs_monolithic.py +++ b/awx/main/tests/old/jobs/jobs_monolithic.py @@ -1109,27 +1109,6 @@ class JobTemplateSurveyTest(BaseJobTestMixin, django.test.TransactionTestCase): def tearDown(self): 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): url = reverse('api:job_template_list') data = dict(