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")
예제 #2
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
예제 #3
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
예제 #4
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)
예제 #5
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')
예제 #6
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')
예제 #7
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)
예제 #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)
예제 #9
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)
예제 #10
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': []
     }
    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)
예제 #13
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
    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_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']
예제 #16
0
    def test_validate_question_payload_raises_assertion_error_if_no_payload(self):
        client = QualtricsAPIClient('http://qualtrics.com/api', 'token-456')

        with self.assertRaises(AssertionError):
            client._validate_question_payload()
 def test_raises_exception_when_auth_token_is_none(self):
     with self.assertRaises(QualtricsAPIException):
         QualtricsAPIClient('http://qualtrics.com/api', None)
예제 #18
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']
 def test_raises_exception_when_base_api_url_is_none(self):
     with self.assertRaises(QualtricsAPIException):
         QualtricsAPIClient(None, 'token-456')
 def setUp(self):
     self.client = QualtricsAPIClient('http://qualtrics.com/api',
                                      'token-456')
    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')