예제 #1
0
    def test_does_not_raise_error_when_valid_text_entry_payload_supplied(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        try:
            client._validate_question_payload(self.valid_text_entry_payload)
        except AssertionError:
            self.fail('_validate_question_payload() raised AssertionErrror text-entry payload unexpectedly')
예제 #2
0
    def test_does_not_raise_error_when_valid_payload_shape_supplied(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        try:
            client._validate_question_payload(self.valid_minimal_question_payload_shape)
        except AssertionError:
            self.fail('_validate_question_payload() raised AssertionErrror for minimal correctly shaped payload unexpectedly')
예제 #3
0
    def test_validate_question_payload_raises_assertion_error_if_keys_missing(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        self.valid_minimal_question_payload_shape.pop('QuestionText', {})

        with self.assertRaises(AssertionError):
            client._validate_question_payload(self.valid_minimal_question_payload_shape)
예제 #4
0
    def test_raises_error_when_sub_selector_is_incorrect(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        self.valid_multi_choice_payload['SubSelector'] = 'INVALID'

        with self.assertRaises(AssertionError):
            client._validate_question_payload(self.valid_multi_choice_payload)
예제 #5
0
def publish_survey(survey_id, survey_name):
    '''
    Activate and publish the specified survey so it's available to take online
    '''
    try:
        assert survey_id.strip()
        assert survey_name.strip()
    except (AssertionError, AttributeError):
        raise AssertionError(
            'You must provide string values for survey_id and survey_name')

    base_url, auth_token = get_details_for_client()
    api = QualtricsAPIClient(base_url, auth_token)

    survey_description = '{}_{}'.format(
        survey_name,
        datetime.now().strftime("%Y-%m-%d_%H.%M.%S%p"))

    try:
        api.update_survey(survey_id, True)

        version_id, version_number, creation_date = api.publish_survey(
            survey_id, survey_description)
    except (AssertionError, HTTPError) as ex:
        raise QualtricsAPIException(ex)

    survey_url = QUALTRICS_API_PUBLISHED_SURVEY_URL_PATTERN.format(survey_id)

    return survey_url, version_id, version_number, creation_date
예제 #6
0
    def test_raises_error_when_choice_order_but_no_choices(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        self.valid_multi_choice_payload.pop('Choices', {})

        with self.assertRaises(AssertionError):
            client._validate_question_payload(self.valid_multi_choice_payload)
예제 #7
0
 def setUp(self):
     self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                      'token-456')
     self.question_payload = {
         'QuestionText': 'What is love?',
         'DataExportTag': 'Q1',
         'QuestionType': 'MC',
         'Selector': 'SAVR',
         'SubSelector': 'TX',
         'Configuration': {
             'QuestionDescriptionOption': 'UseText'
         },
         'QuestionDescription': 'respondent_what_is_love_mc',
         'Choices': {
             '1': 'Baby don\'t hurt me',
             '2': 'Don\'t hurt me',
             '3': 'No more'
         },
         'ChoiceOrder': ['1', '2', '3'],
         'Validation': {
             'Settings': {
                 'ForceResponse': 'OFF',
                 'ForceResponseType': 'OFF',
                 'Type': 'None'
             }
         },
         'Language': []
     }
예제 #8
0
    def test_raises_error_when_sub_selector_missing_when_expected(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        self.valid_multi_choice_payload.pop('SubSelector', {})

        with self.assertRaises(AssertionError):
            client._validate_question_payload(self.valid_multi_choice_payload)
    def test_validate_survey_id_does_not_raise_error_when_survey_id_valid(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        try:
            client._validate_survey_id('SV_0123456789a')
        except AssertionError:
            self.fail("_validate_survey_id() raised AssertionErrror unexpectedly")
    def test_build_headers_applies_x_api_token_header(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        expected_header_value = 'token-456'

        actual_header_value = client._build_headers('GET')['X-API-TOKEN']

        self.assertEqual(expected_header_value, actual_header_value)
    def test_build_headers_applies_json_content_type_header_for_put_requests(
            self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        expected_header_value = 'application/json'

        actual_header_value = client._build_headers('PUT')['Content-Type']

        self.assertEqual(expected_header_value, actual_header_value)
class CreateResponseExportTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_create_response_export_asserts_survey_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_response_export(None)

    def test_create_response_export_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_response_export('invalid-format-survey-id')

    @responses.activate
    def test_makes_request_as_expected(self):
        response_export_json = {
            'result': {
                'progressId': 'SV_1234567890a',
                'percentComplete': 0.0,
                'status': 'inProgress'
            },
            'meta': {
                'requestId': 'e4c3138f-53bd-4de8-8784-95d23745a8a2',
                'httpStatus': '200 - OK'
            }
        }

        responses.add(
            responses.POST,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses',
            json=response_export_json)

        response, progress_id = self.client.create_response_export(
            'SV_1234567890a')

        self.assertEqual(response, response_export_json)
        self.assertEqual(progress_id,
                         response_export_json['result']['progressId'])

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(
            responses.POST,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses',
            json={},
            status=404)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_response_export('SV_1234567890a')

        responses.replace(
            responses.POST,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses',
            json={},
            status=500)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_response_export('SV_1234567890a')
    def setUp(self):
        self.example_survey_as_json = None

        example_survey_json_file_path = os.path.join(
            os.path.abspath(os.path.dirname(__file__)), '.',
            'example_survey.json')

        with open(example_survey_json_file_path) as survey_json_file:
            self.example_survey_as_json = json.loads(survey_json_file.read())

        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

        self.client.get_survey = MagicMock()
        self.client.get_survey.return_value = self.example_survey_as_json
예제 #14
0
class CreateSurveyTestCase(unittest.TestCase):

    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

    def test_create_survey_asserts_survey_name_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_survey(None)

        with self.assertRaises(AssertionError):
            _ = self.client.create_survey('')

        with self.assertRaises(AssertionError):
            _ = self.client.create_survey(1)

    def test_create_survey_asserts_language_code_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_survey('Survey Name', language_code='XX')

    def test_create_survey_asserts_project_category_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_survey('Survey Name', project_category='ZZ')

    @responses.activate
    def test_makes_request_as_expected(self):
        create_survey_json = {
            'result': {
                "SurveyID": "SV_sUrV3Y1d",
                "DefaultBlockID": "BL_d3FaUlT8L0cK1d",
            },
            'meta': {
                'requestId': '888a0f7d-1cf7-4eea-8b61-850edfcf409d',
                'httpStatus': '200 - OK'
            }
        }

        responses.add(
            responses.POST, 'http://qualtrics.com/api/survey-definitions', json=create_survey_json
        )

        survey_id, default_block_id = self.client.create_survey('My New Survey Name')

        self.assertEqual(survey_id, create_survey_json['result']['SurveyID'])
        self.assertEqual(default_block_id, create_survey_json['result']['DefaultBlockID'])

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(
            responses.POST, 'http://qualtrics.com/api/survey-definitions', json={}, status=404
        )
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_survey('400 Survey Name')

        responses.replace(
            responses.POST, 'http://qualtrics.com/api/survey-definitions', json={}, status=500
        )
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_survey('500 Survey Name')
예제 #15
0
def get_survey_and_response_data(survey_id,
                                 abs_path_to_data_dir,
                                 process_responses=False):
    base_url, auth_token = get_details_for_client()
    api = QualtricsAPIClient(base_url, auth_token)

    try:
        survey_file_name = save_survey_to_file(api, survey_id,
                                               abs_path_to_data_dir)
    except (QualtricsAPIException, QualtricsDataSerialisationException) as qex:
        raise qex

    try:
        response_file_name = save_responses_to_file(api, survey_id,
                                                    abs_path_to_data_dir)
    except QualtricsDataSerialisationException as qex:
        raise qex

    try:
        unzipped_response_file_name = _unzip_response_file(
            survey_id, abs_path_to_data_dir)
    except QualtricsDataSerialisationException as qex:
        raise qex

    processed_response_file_name = None
    if process_responses:
        try:
            processed_response_file_name = _process_response_data(
                survey_id, abs_path_to_data_dir)
        except QualtricsDataSerialisationException as qex:
            raise qex

    return survey_file_name, response_file_name, unzipped_response_file_name, processed_response_file_name
예제 #16
0
def get_survey_data(survey_id, abs_path_to_data_dir):
    base_url, auth_token = get_details_for_client()
    api = QualtricsAPIClient(base_url, auth_token)

    try:
        file_path_and_name = save_survey_to_file(api, survey_id,
                                                 abs_path_to_data_dir)
    except (QualtricsAPIException, QualtricsDataSerialisationException) as qex:
        raise qex

    return file_path_and_name
class GetResponseExportFileTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_get_response_export_file_asserts_survey_id_and_file_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_file(None, 'file_id')

        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_file('SV_1234567890a', None)

        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_file(None, None)

    def test_get_response_export_file_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_file(
                'invalid-format-survey-id', 'file_id')

    @responses.activate
    def test_makes_request_as_expected(self):
        file_bytes = bytes('Lorem ipsum dolor sit amet', 'utf-8')

        responses.add(
            responses.GET,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses/file-0987/file',
            body=file_bytes)

        response = self.client.get_response_export_file(
            'SV_1234567890a', 'file-0987')

        self.assertEqual(response, file_bytes)

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(
            responses.GET,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses/file-0987/file',
            body='',
            status=404,
            json={'error': 'oh noes!'})
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.get_response_export_file(
                'SV_1234567890a', 'file-0987')

        responses.replace(
            responses.GET,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses/file-0987/file',
            body='',
            status=500,
            json={'error': 'oh noes!'})
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.get_response_export_file(
                'SV_1234567890a', 'file-0987')
    def test_build_headers_does_not_support_methods_beyond_get_delete_post_and_put(
            self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        with self.assertRaises(QualtricsAPIException):
            _ = client._build_headers('OPTIONS')['Content-Type']

        with self.assertRaises(QualtricsAPIException):
            _ = client._build_headers('HEAD')['Content-Type']

        with self.assertRaises(QualtricsAPIException):
            _ = client._build_headers('CONNECT')['Content-Type']

        with self.assertRaises(QualtricsAPIException):
            _ = client._build_headers('TRACE')['Content-Type']

        with self.assertRaises(QualtricsAPIException):
            _ = client._build_headers('Random-Method-String')['Content-Type']

        with self.assertRaises(QualtricsAPIException):
            _ = client._build_headers(None)['Content-Type']

        with self.assertRaises(QualtricsAPIException):
            _ = client._build_headers(123)['Content-Type']
 def setUp(self):
     self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                      'token-456')
class GetBlockTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_get_block_asserts_survey_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_block(None, 'block_id')

    def test_get_block_asserts_block_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_block('survey_id', None)

    def test_get_block_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_block('invalid-format-survey-id',
                                      'BL_abcdefghijk')

    def test_get_block_validates_block_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_block('SV_abcdefghijk',
                                      'invalid-format-block-id')

    @responses.activate
    def test_makes_request_as_expected(self):
        block_json = {
            "meta": {
                "httpStatus": "200 - OK",
                "requestId": "54d71b59-615a-4a4e-bc34-45665ca3e122"
            },
            "result": {
                "Type": "Default",
                "Description": "NPS Block",
                "ID": "BL_8BOLx7IFtYLKJyB",
                "BlockElements": [],
                "Options": {
                    "BlockLocking": "false",
                    "RandomizeQuestions": "false",
                    "BlockVisibility": "Expanded"
                }
            }
        }

        responses.add(
            responses.GET,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghijk/blocks/BL_abcdefghijk',
            json=block_json)

        response = self.client.get_block('SV_abcdefghijk', 'BL_abcdefghijk')

        self.assertEqual(response, block_json)

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        # Set a not found response
        responses.add(
            responses.GET,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghi01/blocks/BL_abcdefghi01',
            json={},
            status=404)
        with self.assertRaises(requests.HTTPError):
            _ = self.client.get_block('SV_abcdefghi01', 'BL_abcdefghi01')

        # Replace response with a server error
        responses.add(
            responses.GET,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghi02/blocks/BL_abcdefghi02',
            json={},
            status=500)
        with self.assertRaises(requests.HTTPError):
            _ = self.client.get_block('SV_abcdefghi02', 'BL_abcdefghi02')
class FindQuestionInSurveyJsonTestCase(unittest.TestCase):
    def setUp(self):
        self.example_survey_as_json = None

        example_survey_json_file_path = os.path.join(
            os.path.abspath(os.path.dirname(__file__)), '.',
            'example_survey.json')

        with open(example_survey_json_file_path) as survey_json_file:
            self.example_survey_as_json = json.loads(survey_json_file.read())

        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

        self.client.get_survey = MagicMock()
        self.client.get_survey.return_value = self.example_survey_as_json

    def test_finds_question_in_survey_by_label_when_present(self):
        expected_id = 'QID1'
        expected_dict = {
            'questionType': {
                'type': 'MC',
                'selector': 'NPS',
                'subSelector': None
            },
            'questionText':
            'On a scale of 0-10, how likely are you to recommend [COMPANY] to a friend or family member, where 0 is not at all likely and 10 is extremely likely?',
            'questionLabel': 'nps_company_rating',
            'validation': {
                'doesForceResponse': False,
                'doesRequestResponse': True
            },
            'questionName': 'Q1',
            'choices': {
                '0': {},
                '1': {},
                '2': {},
                '3': {},
                '4': {},
                '5': {},
                '6': {},
                '7': {},
                '8': {},
                '9': {},
                '10': {}
            }
        }  # Note that 'choices' has been simplified for this test case, see json file for full shape of this data

        actual_id, actual_dict = self.client.find_question_in_survey_by_label(
            'SV_b9JZIZmEZ11t6D3', 'nps_company_rating')

        self.assertEqual(expected_id, actual_id)
        self.assertCountEqual(expected_dict['questionType'],
                              actual_dict['questionType'])
        self.assertCountEqual(expected_dict['questionText'],
                              actual_dict['questionText'])

    def test_returns_tuple_of_none_and_none_when_question_not_present(self):
        expected = (
            None,
            None,
        )

        actual = self.client.find_question_in_survey_by_label(
            'SV_b9JZIZmEZ11t6D3', 'non_existent_label')

        self.assertEqual(expected, actual)
class UpdateBlockTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_update_block_asserts_survey_id_parameter(self):
        with self.assertRaises(AssertionError):
            self.client.update_block(None, 'BL_1234567890a', 'description',
                                     'Standard')

        with self.assertRaises(AssertionError):
            self.client.update_block('', 'BL_1234567890a', 'description',
                                     'Standard')

        with self.assertRaises(AssertionError):
            self.client.update_block(1, 'BL_1234567890a', 'description',
                                     'Standard')

    def test_update_block_asserts_block_id_parameter(self):
        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', None, 'description',
                                     'Standard')

        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', [1, 2, 3],
                                     'description', 'Standard')

        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', 123.45, 'description',
                                     'Standard')

    def test_update_block_asserts_block_description_parameter(self):
        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', 'BL_1234567890a', '',
                                     'Standard')

        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', 'BL_1234567890a', None,
                                     'Standard')

    def test_update_block_asserts_block_type_parameter(self):
        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', 'BL_1234567890a',
                                     'description', None)

        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', 'BL_1234567890a',
                                     'description', 'Unsupported_Block_Type')

    def test_update_block_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            self.client.update_block('invalid_survey_id', 'BL_1234567890a',
                                     'description', 'Standard')

    def test_update_block_validates_block_id(self):
        with self.assertRaises(AssertionError):
            self.client.update_block('SV_1234567890a', 'invalid_block_id',
                                     'description', 'Standard')

    @responses.activate
    def test_makes_request_as_expected(self):
        responses.add(
            responses.PUT,
            'http://qualtrics.com/api/survey-definitions/SV_1234567890a/blocks/BL_1234567890a'
        )

        try:
            self.client.update_block('SV_1234567890a', 'BL_1234567890a',
                                     'Block Description', 'Standard')

        except AssertionError as ae:
            self.fail(
                "update_block() raised AssertionError unexpectedly: {}".format(
                    ae))

        except Exception as ex:  # pylint: disable=broad-except
            self.fail(
                "update_block() raised Exception unexpectedly: {}".format(ex))

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(
            responses.PUT,
            'http://qualtrics.com/api/survey-definitions/SV_1234567890a/blocks/BL_1234567890a',
            json={},
            status=404)
        with self.assertRaises(requests.HTTPError):
            self.client.update_block(
                'SV_1234567890a', 'BL_1234567890a',
                'I\'m still, i\'m still Jenny from the...', 'Standard')

        responses.replace(
            responses.PUT,
            'http://qualtrics.com/api/survey-definitions/SV_1234567890a/blocks/BL_1234567890a',
            json={},
            status=500)
        with self.assertRaises(requests.HTTPError):
            self.client.update_block(
                'SV_1234567890a', 'BL_1234567890a',
                'Back with another one of those... rocking beats', 'Standard')
예제 #23
0
def create_survey(name, blocks, questions, language_code='EN'):
    '''
    Create a new survey with the specified blocks and questions

    1. create survey
    2. update default block (depends on questions supplied)
    3. create additional blocks as required (again depends on questions supplied)
    4. create questions, per question: build payloads (inc. display logic), assign to blocks, call api
    5. return survey_id
    '''
    assert blocks and questions, "You must provide lists of blocks and questions for the survey"

    base_url, auth_token = get_details_for_client()
    api = QualtricsAPIClient(base_url, auth_token)

    survey_id = default_block_id = None

    try:
        survey_id, default_block_id = api.create_survey(name, language_code)
    except (QualtricsAPIException, AssertionError, HTTPError) as ex:
        raise QualtricsAPIException(ex)

    if not survey_id:
        raise QualtricsAPIException(
            'API call create_survey failed to return survey_id')

    if not default_block_id:
        raise QualtricsAPIException(
            'API call create_survey failed to return default_block_id')

    block_ids_dict = {1: default_block_id}

    blockBar = Bar('Creating Blocks', max=len(blocks))

    for index, block in enumerate(blocks):
        blockBar.next()

        if index == 0:
            try:
                api.update_block(survey_id, default_block_id,
                                 block['description'],
                                 QUALTRICS_API_BLOCK_TYPE_DEFAULT)
            except (AssertionError, HTTPError) as ex:
                raise QualtricsAPIException(ex)
        else:
            try:
                _, new_block_id = api.create_block(
                    survey_id, block['description'],
                    QUALTRICS_API_BLOCK_TYPE_STANDARD)

                block_ids_dict[index + 1] = new_block_id
            except (AssertionError, HTTPError) as ex:
                raise QualtricsAPIException(ex)

    blockBar.finish()

    questionBar = Bar('Creating Questions', max=len(questions))

    for question in questions:
        questionBar.next()

        question_payload = api.build_question_payload(
            question, survey_id, include_display_logic=True)

        try:
            block_id = block_ids_dict[question['block_number']]
        except KeyError:
            block_id = block_ids_dict[1]

        try:
            api.create_question(survey_id, question_payload, block_id)
        except (AssertionError, HTTPError) as ex:
            raise QualtricsAPIException(ex)

    questionBar.finish()

    return survey_id
    def test_build_headers_does_not_apply_json_content_type_header_for_delete_requests(
            self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        with self.assertRaises(KeyError):
            _ = client._build_headers('DELETE')['Content-Type']
class UpdateQuestionTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_update_survey_asserts_survey_id_parameter(self):
        with self.assertRaises(AssertionError):
            self.client.update_survey(None, True)

        with self.assertRaises(AssertionError):
            self.client.update_survey('', True)

        with self.assertRaises(AssertionError):
            self.client.update_survey(1, True)

    def test_update_survey_asserts_is_active_parameter(self):
        with self.assertRaises(AssertionError):
            self.client.update_survey('SV_1234567890a', None)

        with self.assertRaises(AssertionError):
            self.client.update_survey('SV_1234567890a', [1, 2, 3])

        with self.assertRaises(AssertionError):
            self.client.update_survey('SV_1234567890a', 123.45)

        with self.assertRaises(AssertionError):
            self.client.update_survey('SV_1234567890a', {})

    def test_update_survey_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            self.client.update_survey('invalid_survey_id', False)

    @responses.activate
    def test_makes_request_as_expected(self):
        update_survey_json = {
            'meta': {
                'requestId': '82997a4-9493-41e1-be49-6f02e5afbb42',
                'httpStatus': '200 - OK'
            }
        }

        responses.add(responses.PUT,
                      'http://qualtrics.com/api/surveys/SV_1234567890a',
                      json=update_survey_json)

        try:
            self.client.update_survey('SV_1234567890a', True)

        except AssertionError as ae:
            self.fail("update_survey() raised AssertionError unexpectedly: {}".
                      format(ae))

        except Exception as ex:  # pylint: disable=broad-except
            self.fail(
                "update_survey() raised Exception unexpectedly: {}".format(ex))

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(responses.PUT,
                      'http://qualtrics.com/api/surveys/SV_1234567890a',
                      json={},
                      status=404)
        with self.assertRaises(requests.HTTPError):
            self.client.update_survey('SV_1234567890a', False)

        responses.replace(responses.PUT,
                          'http://qualtrics.com/api/surveys/SV_1234567890a',
                          json={},
                          status=500)
        with self.assertRaises(requests.HTTPError):
            self.client.update_survey('SV_1234567890a', False)
class PublishSurveyTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_publish_survey_asserts_survey_id_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.publish_survey(None, 'description')

        with self.assertRaises(AssertionError):
            _ = self.client.publish_survey('', 'description')

        with self.assertRaises(AssertionError):
            _ = self.client.publish_survey(1.23, 'description')

    def test_publish_survey_asserts_description_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.publish_survey('SV_51PEzLvt33771Mp', '')

        with self.assertRaises(AssertionError):
            _ = self.client.publish_survey('SV_51PEzLvt33771Mp', {})

    def test_publish_survey_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.publish_survey('invalid-format-survey-id',
                                           'description')

    @responses.activate
    def test_makes_request_as_expected(self):
        publish_survey_json = {
            "meta": {
                "httpStatus": "200 - OK",
                "requestId": "7999edd9-a232-4735-ae70-1c8cc7e30e09"
            },
            "result": {
                "metadata": {
                    "surveyID":
                    "SV_51PEzLvt33771Mp",
                    "versionID":
                    "9223370492291465912",
                    "versionNumber":
                    2,
                    "description":
                    "2019 New Survey Version",
                    "userID":
                    "UR_3fIVFlGaWYcfVml",
                    "creationDate":
                    "2019-27-09T07:48:49Z",
                    "published":
                    True,
                    "wasPublished":
                    True,
                    "publishEvents": [{
                        "date": "2019-26-09T21:21:50Z",
                        "userID": "UR_3fIVFlGaWYcfVml"
                    }]
                }
            }
        }

        responses.add(
            responses.POST,
            'http://qualtrics.com/api/survey-definitions/SV_51PEzLvt33771Mp/versions',
            json=publish_survey_json)

        version_id, version_number, creation_date = self.client.publish_survey(
            'SV_51PEzLvt33771Mp', '2019 v2 of My Survey')

        self.assertEqual(
            version_id, publish_survey_json['result']['metadata']['versionID'])
        self.assertEqual(
            version_number,
            publish_survey_json['result']['metadata']['versionNumber'])
        self.assertEqual(
            creation_date,
            publish_survey_json['result']['metadata']['creationDate'])

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(responses.POST,
                      'http://qualtrics.com/api/survey-definitions',
                      json={},
                      status=404)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_survey('400 Survey Name')

        responses.replace(responses.POST,
                          'http://qualtrics.com/api/survey-definitions',
                          json={},
                          status=500)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_survey('500 Survey Name')
예제 #27
0
class CreateBlockTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_create_block_asserts_survey_id_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_block(None, 'description', 'Standard')

        with self.assertRaises(AssertionError):
            _ = self.client.create_block('', 'description', 'Standard')

        with self.assertRaises(AssertionError):
            _ = self.client.create_block(1, 'description', 'Standard')

    def test_create_block_asserts_description_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_block('SV_abcdefghijk',
                                         datetime(2019, 8, 16), 'Standard')

        with self.assertRaises(AssertionError):
            _ = self.client.create_block('SV_abcdefghijk', [], 'Standard')

        with self.assertRaises(AssertionError):
            _ = self.client.create_block('SV_abcdefghijk', {}, 'Standard')

    def test_create_block_asserts_block_type_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_block('SV_abcdefghijk', 'description',
                                         'unsupported-block-type-value')

    @responses.activate
    def test_makes_request_as_expected(self):
        create_block_json = {
            'result': {
                'BlockID': 'BL_abcdefghijk',
                'FlowID': 'FL_1'
            },
            'meta': {
                'requestId': '888a0f7d-1cf7-4eea-8b61-850edfcf409d',
                'httpStatus': '200 - OK'
            }
        }

        responses.add(
            responses.POST,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghijk/blocks',
            json=create_block_json)

        result, block_id = self.client.create_block('SV_abcdefghijk',
                                                    'My block description',
                                                    'Standard')

        self.assertEqual(result, create_block_json)
        self.assertEqual(block_id, create_block_json['result']['BlockID'])

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(
            responses.POST,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghijk/blocks',
            json={},
            status=404)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_block('SV_abcdefghijk',
                                            'My block description', 'Standard')

        responses.replace(
            responses.POST,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghijk/blocks',
            json={},
            status=500)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_block('SV_abcdefghijk',
                                            'My block description', 'Standard')
    def test_validate_survey_id_raises_assertion_error_if_survey_id_format_invalid(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        with self.assertRaises(AssertionError):
            client._validate_survey_id('invalid-format-survey-id')
예제 #29
0
class CreateBlockTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')
        self.question_payload = {
            'QuestionText': 'What is love?',
            'DataExportTag': 'Q1',
            'QuestionType': 'MC',
            'Selector': 'SAVR',
            'SubSelector': 'TX',
            'Configuration': {
                'QuestionDescriptionOption': 'UseText'
            },
            'QuestionDescription': 'respondent_what_is_love_mc',
            'Choices': {
                '1': 'Baby don\'t hurt me',
                '2': 'Don\'t hurt me',
                '3': 'No more'
            },
            'ChoiceOrder': ['1', '2', '3'],
            'Validation': {
                'Settings': {
                    'ForceResponse': 'OFF',
                    'ForceResponseType': 'OFF',
                    'Type': 'None'
                }
            },
            'Language': []
        }

    def test_create_question_asserts_survey_id_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_question(None, self.question_payload)

        with self.assertRaises(AssertionError):
            _ = self.client.create_question('', self.question_payload)

        with self.assertRaises(AssertionError):
            _ = self.client.create_question(1, self.question_payload)

    def test_create_question_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            self.client.create_question('invalid_survey_id',
                                        self.question_payload)

    def test_create_question_asserts_question_payload_parameter(self):
        with self.assertRaises(AssertionError):
            _ = self.client.create_question('SV_abcdefghijk', None)

        with self.assertRaises(AssertionError):
            _ = self.client.create_question('SV_abcdefghijk',
                                            datetime(2019, 8, 16))

        with self.assertRaises(AssertionError):
            _ = self.client.create_question('SV_abcdefghijk', ['a', 'b'])

    def test_create_question_validates_question_payload_parameter(self):
        payload_without_question_text_key = self.question_payload
        payload_without_question_text_key.pop('QuestionText')

        with self.assertRaises(AssertionError):
            _ = self.client.create_question('SV_abcdefghijk',
                                            payload_without_question_text_key)

        with self.assertRaises(AssertionError):
            _ = self.client.create_question('SV_abcdefghijk', {})

    def test_create_question_asserts_optional_block_id_is_string_if_supplied(
            self):
        with self.assertRaises(AssertionError):
            self.client.create_question('SV_1234567890a',
                                        self.question_payload,
                                        block_id=123)

    def test_create_question_validates_optional_block_id_if_supplied(self):
        with self.assertRaises(AssertionError):
            self.client.create_question('SV_1234567890a',
                                        self.question_payload,
                                        block_id='invalid_block_id')

    @responses.activate
    def test_makes_request_as_expected(self):
        create_question_json = {
            'result': {
                'QuestionID': 'QID1'
            },
            'meta': {
                'requestId': 'be14851c-7d92-4b1c-a541-a9e03228b15e',
                'httpStatus': '200 - OK'
            }
        }

        responses.add(
            responses.POST,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghijk/questions?blockId=BL_1234567890a',
            json=create_question_json)

        result, question_id = self.client.create_question(
            'SV_abcdefghijk', self.question_payload, block_id='BL_1234567890a')

        self.assertEqual(result, create_question_json)
        self.assertEqual(question_id,
                         create_question_json['result']['QuestionID'])

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(
            responses.POST,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghijk/questions',
            json={},
            status=404)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_question('SV_abcdefghijk',
                                               self.question_payload)

        responses.replace(
            responses.POST,
            'http://qualtrics.com/api/survey-definitions/SV_abcdefghijk/questions',
            json={},
            status=500)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.create_question('SV_abcdefghijk',
                                               self.question_payload)
class GetResponseExportProgressTestCase(unittest.TestCase):
    def setUp(self):
        self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                         'token-456')

    def test_get_response_export_progress_asserts_survey_id_and_progress_id(
            self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_progress(None, 'progress_id')

        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_progress(
                'SV_1234567890a', None)

        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_progress(None, None)

    def test_get_response_export_progress_validates_survey_id(self):
        with self.assertRaises(AssertionError):
            _ = self.client.get_response_export_file(
                'invalid-format-survey-id', 'file_id')

    @responses.activate
    def test_makes_request_as_expected(self):
        in_progress_json = {
            'result': {
                'fileId': None,
                'percentComplete': 50.0,
                'status': 'inProgress'
            },
            'meta': {
                'requestId': '0842cbb3-0a52-4080-aec2-5d831e167c27',
                'httpStatus': '200 - OK'
            }
        }

        responses.add(
            responses.GET,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses/ES_9yn5UfrKkuuhxA1',
            json=in_progress_json)

        response, _ = self.client.get_response_export_progress(
            'SV_1234567890a', 'ES_9yn5UfrKkuuhxA1')

        self.assertEqual(response, in_progress_json)
        self.assertIsNone(response['result']['fileId'])
        self.assertEqual(response['result']['status'], 'inProgress')

        complete_json = {
            'result': {
                'fileId': '0a52e70b-9dd7-4c88-b5d4-be21f8cc921b',
                'percentComplete': 100.0,
                'status': 'complete'
            },
            'meta': {
                'requestId': '0842cbb3-0a52-4080-aec2-5d831e167c27',
                'httpStatus': '200 - OK'
            }
        }

        responses.replace(
            responses.GET,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses/ES_9yn5UfrKkuuhxA1',
            json=complete_json)

        response, file_id = self.client.get_response_export_progress(
            'SV_1234567890a', 'ES_9yn5UfrKkuuhxA1')

        self.assertEqual(response, complete_json)
        self.assertEqual(response['result']['fileId'], file_id)
        self.assertEqual(response['result']['percentComplete'], 100.0)

    @responses.activate
    def test_raises_http_error_for_failed_requests(self):
        responses.add(
            responses.GET,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses/ES_9yn5UfrKkuuhxA1',
            json={},
            status=404)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.get_response_export_progress(
                'SV_1234567890a', 'ES_9yn5UfrKkuuhxA1')

        responses.replace(
            responses.GET,
            'http://qualtrics.com/api/surveys/SV_1234567890a/export-responses/ES_9yn5UfrKkuuhxA1',
            json={},
            status=500)
        with self.assertRaises(requests.HTTPError):
            _, _ = self.client.get_response_export_progress(
                'SV_1234567890a', 'ES_9yn5UfrKkuuhxA1')