Esempio n. 1
0
class SMClientTestCase(TestCase):
    @classmethod
    def setUpTestData(self):
        # Read SurveyMonkey API Token & Key
        SURVEYMONKEY_API_TOKEN = os.environ.get('SURVEYMONKEY_API_TOKEN')
        SURVEYMONKEY_API_KEY = os.environ.get('SURVEYMONKEY_API_KEY')
        self.api_client = SurveyMonkeyClient(SURVEYMONKEY_API_TOKEN, SURVEYMONKEY_API_KEY)
        # Create a survey and connect to SurveyMonkey via client
        self.survey_name = "Mike Test - DO NOT USE"

    def tearDown(self):
        # Add a second wait in between each test
        # To prevent running over API quota
        time.sleep(1)

    def test_get_survey_list(self):
        '''
        Test that the client will return a list of dict
        containing survey IDs matching Mike Test - DO NOT USE
        '''
        survey_list = self.api_client.get_survey_list(self.survey_name)
        expected = [{u'survey_id': u'72140246'}]
        self.assertEqual(survey_list, expected)

    def test_get_survey_id(self):
        '''
        The client should return only one single ID
        for Mike Test - DO NOT USE
        '''
        survey_id = self.api_client.get_survey_id(self.survey_name)
        self.assertEqual(survey_id, u'72140246')

    def test_get_survey_details(self):
        survey_pages = self.api_client.get_survey_details(self.survey_name)
        # survey_pages is a list
        self.assertTrue(isinstance(survey_pages, list))
        # There is only 1 element/page
        self.assertEqual(len(survey_pages), 1)
        # Check each element of pages to make sure they contain the correct keys
        expected_page_keys = [u'position', u'sub_heading', u'page_id', u'heading', u'questions']
        for p in survey_pages:
            self.assertEqual(p.keys(), expected_page_keys)

    def test_get_respondent_list(self):
        respondent_ids = self.api_client.get_respondent_list(self.survey_name)
        expected = [u'4352787778', u'4352787305', u'4352786821', u'4352786417', u'4352785923']
        self.assertEqual(respondent_ids, expected)

    def test_get_responses(self):
        responses = self.api_client.get_responses(self.survey_name)
        # Check Respondent IDs
        respondent_ids = [r['respondent_id'] for r in responses]
        expected_resp_ids = [u'4352787778', u'4352787305', u'4352786821', u'4352786417', u'4352785923']
        self.assertEqual(respondent_ids, expected_resp_ids)
Esempio n. 2
0
 def setUpTestData(self):
     # Read SurveyMonkey API Token & Key
     SURVEYMONKEY_API_TOKEN = os.environ.get('SURVEYMONKEY_API_TOKEN')
     SURVEYMONKEY_API_KEY = os.environ.get('SURVEYMONKEY_API_KEY')
     self.api_client = SurveyMonkeyClient(SURVEYMONKEY_API_TOKEN, SURVEYMONKEY_API_KEY)
     # Create a survey and connect to SurveyMonkey via client
     self.survey_name = "Mike Test - DO NOT USE"
Esempio n. 3
0
 def update_details(self):
     '''
     Connects to SurveyMonkey API using known credentials
     and create or update questions & choices in db based
     on details obtained from get_survey_details API call
     '''
     SURVEYMONKEY_API_TOKEN = os.environ.get('SURVEYMONKEY_API_TOKEN')
     SURVEYMONKEY_API_KEY = os.environ.get('SURVEYMONKEY_API_KEY')
     client = SurveyMonkeyClient(SURVEYMONKEY_API_TOKEN, SURVEYMONKEY_API_KEY)
     try:
         pages = client.get_survey_details(self.name)
     except IndexError:
         self.error_message = "Could not find survey in SurveyMonkey. Are you sure the survey name is correct?"
     else:
         # Clear error_message
         self.error_message = None
         for p in pages:
             for q in p["questions"]:
                 # Skip if it's descriptive text
                 if q["type"]["subtype"] != "descriptive_text":
                     qid = q["question_id"]
                     question, created = Question.objects.get_or_create(sm_id=qid, survey_id=self.id)
                     question.text = q["heading"]
                     question.survey_id = self.id
                     if q["type"]["family"] == u'open_ended':
                         question.open_ended = True
                     question.save()
                     # Update question choices as well
                     for a in q['answers']:
                         # Skip if no content in text
                         if a["text"]:
                             cid = a["answer_id"]
                             text = a["text"]
                             weight = a.get("weight")
                             # TODO Allow change of choice text without
                             # creating a new choice when 
                             choice, created = Choice.objects.get_or_create(
                                 sm_id=cid,
                                 text=text,
                                 weight=weight,
                                 question_id=question.id
                                 )
Esempio n. 4
0
    def download_responses(self):
        '''
        Use get_responses() method in SurveyMonkeyClient to
        retrieve a list of response dicts, then get_or_create
        Respondent and Answer associated with the survey

        You should always call update_details() before download_responses()
        to avoid having non-existent Questions for survey that has never
        been updated previously
        '''
        SURVEYMONKEY_API_TOKEN = os.environ.get('SURVEYMONKEY_API_TOKEN')
        SURVEYMONKEY_API_KEY = os.environ.get('SURVEYMONKEY_API_KEY')
        client = SurveyMonkeyClient(SURVEYMONKEY_API_TOKEN, SURVEYMONKEY_API_KEY)
        try:
            data = client.get_responses(self.name)
        except IndexError:
            self.error_message = "Could not find survey in SurveyMonkey. Are you sure the survey name is correct?"
        else:
            self.error_message = None
            for r in data:
                rid = r["respondent_id"]
                respondent, created = Respondent.objects.get_or_create(sm_id=rid, survey_id=self.id)
                # Only update Answer/Comment/Rating if it's a new respondent
                # TODO This means that if a respondent somehow update
                # their answers after submission, the updated value will not be reflected
                # unless we create a manual override here
                if created:
                    for q in r["questions"]:
                        # In each dict q there are 2 keys: "answers", and "question_id"
                        # First, use "question_id" to locate the question text
                        qid = q["question_id"]
                        question = self.question_set.get(sm_id=qid, survey_id=self.id)
                        # Associate the question with the respondent if
                        # the question is not in the set yet
                        if not respondent.questions.filter(id=question.id).exists():
                            respondent.questions.add(question)
                        # Next, find the response for this question
                        # q["answers"] is a list of dicts
                        for raw_answer in q["answers"]:
                            # Here's the tricky part, in the raw_answer dict
                            # Sometimes results come with "col", "row", or "text"
                            # If "text" exists, that's a dead giveaway that it's an open-ended question
                            # We can save that as comment
                            if "text" in raw_answer.keys():
                                comment, created = Answer.objects.get_or_create(
                                    question_id=question.id,
                                    respondent_id=respondent.id,
                                    text=raw_answer["text"]
                                    )
                            else:
                                # A quant response
                                # There will be "row" and "col"
                                # Use these to look up for responses
                                row_id = raw_answer.get("row")
                                col_id = raw_answer.get("col")
                                # If col_ans exists, it's a horizontal question
                                if col_id:
                                    choice = question.choice_set.get(sm_id=col_id)
                                else:
                                    # Try looking up with row_id
                                    choice = question.choice_set.get(sm_id=row_id)
                                rating, created = Answer.objects.get_or_create(
                                    question_id=question.id,
                                    choice_id=choice.id,
                                    respondent_id=respondent.id,
                                    )