""" Python tests for the Survey models """ from collections import OrderedDict import ddt import pytest from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user from django.core.exceptions import ValidationError from django.test import TestCase from django.test.client import Client from lms.djangoapps.survey.exceptions import SurveyFormNameAlreadyExists, SurveyFormNotFound from lms.djangoapps.survey.models import SurveyAnswer, SurveyForm @ddt.ddt class SurveyModelsTests(TestCase): """ All tests for the Survey models.py file """ def setUp(self): """ Set up the test data used in the specific tests """ super().setUp() self.client = Client() # Create two accounts self.password = 'abc' self.student = User.objects.create_user('student', 'student@test.com', self.password) self.student2 = User.objects.create_user('student2', 'student2@test.com', self.password) self.test_survey_name = 'TestForm' self.test_form = '
  • ' # lint-amnesty, pylint: disable=line-too-long self.test_form_update = '' self.course_id = 'foo/bar/baz' self.student_answers = OrderedDict({ 'field1': 'value1', 'field2': 'value2', }) self.student_answers_update = OrderedDict({ 'field1': 'value1-updated', 'field2': 'value2-updated', }) self.student_answers_update2 = OrderedDict({ 'field1': 'value1-updated2', }) self.student2_answers = OrderedDict({ 'field1': 'value3' }) def _create_test_survey(self): """ Helper method to set up test form """ return SurveyForm.create(self.test_survey_name, self.test_form) def test_form_not_found_raise_exception(self): """ Asserts that when looking up a form that does not exist """ with pytest.raises(SurveyFormNotFound): SurveyForm.get(self.test_survey_name) def test_form_not_found_none(self): """ Asserts that when looking up a form that does not exist """ assert SurveyForm.get(self.test_survey_name, throw_if_not_found=False) is None def test_create_new_form(self): """ Make sure we can create a new form a look it up """ survey = self._create_test_survey() assert survey is not None new_survey = SurveyForm.get(self.test_survey_name) assert new_survey is not None assert new_survey.form == self.test_form def test_unicode_rendering(self): """ See if the survey form returns the expected unicode string """ survey = self._create_test_survey() assert survey is not None assert str(survey) == self.test_survey_name def test_create_form_with_malformed_html(self): """ Make sure that if a SurveyForm is saved with unparseable html an exception is thrown """ with pytest.raises(ValidationError): SurveyForm.create('badform', '<<<>') def test_create_form_with_no_fields(self): """ Make sure that if a SurveyForm is saved without any named fields an exception is thrown """ with pytest.raises(ValidationError): SurveyForm.create('badform', '

    no input fields here

    ') with pytest.raises(ValidationError): SurveyForm.create('badform', '') def test_create_form_already_exists(self): """ Make sure we can't create two surveys of the same name """ self._create_test_survey() with pytest.raises(SurveyFormNameAlreadyExists): self._create_test_survey() def test_create_form_update_existing(self): """ Make sure we can update an existing form """ survey = self._create_test_survey() assert survey is not None survey = SurveyForm.create(self.test_survey_name, self.test_form_update, update_if_exists=True) assert survey is not None survey = SurveyForm.get(self.test_survey_name) assert survey is not None assert survey.form == self.test_form_update def test_survey_has_no_answers(self): """ Create a new survey and assert that there are no answers to that survey """ survey = self._create_test_survey() assert len(survey.get_answers()) == 0 def test_user_has_no_answers(self): """ Create a new survey with no answers in it and check that a user is determined to not have answered it """ survey = self._create_test_survey() assert not survey.has_user_answered_survey(self.student) assert len(survey.get_answers()) == 0 @ddt.data(None, 'foo/bar/baz') def test_single_user_answers(self, course_id): """ Create a new survey and add answers to it """ survey = self._create_test_survey() assert survey is not None survey.save_user_answers(self.student, self.student_answers, course_id) assert survey.has_user_answered_survey(self.student) all_answers = survey.get_answers() assert len(list(all_answers.keys())) == 1 assert self.student.id in all_answers assert all_answers[self.student.id] == self.student_answers answers = survey.get_answers(self.student) assert len(list(answers.keys())) == 1 assert self.student.id in answers assert all_answers[self.student.id] == self.student_answers # check that the course_id was set answer_objs = SurveyAnswer.objects.filter( user=self.student, form=survey ) for answer_obj in answer_objs: if course_id: assert str(answer_obj.course_key) == course_id else: assert answer_obj.course_key is None def test_multiple_user_answers(self): """ Create a new survey and add answers to it """ survey = self._create_test_survey() assert survey is not None survey.save_user_answers(self.student, self.student_answers, self.course_id) survey.save_user_answers(self.student2, self.student2_answers, self.course_id) assert survey.has_user_answered_survey(self.student) all_answers = survey.get_answers() assert len(list(all_answers.keys())) == 2 assert self.student.id in all_answers assert self.student2.id in all_answers assert all_answers[self.student.id] == self.student_answers assert all_answers[self.student2.id] == self.student2_answers answers = survey.get_answers(self.student) assert len(list(answers.keys())) == 1 assert self.student.id in answers assert answers[self.student.id] == self.student_answers answers = survey.get_answers(self.student2) assert len(list(answers.keys())) == 1 assert self.student2.id in answers assert answers[self.student2.id] == self.student2_answers def test_update_answers(self): """ Make sure the update case works """ survey = self._create_test_survey() assert survey is not None survey.save_user_answers(self.student, self.student_answers, self.course_id) answers = survey.get_answers(self.student) assert len(list(answers.keys())) == 1 assert self.student.id in answers assert answers[self.student.id] == self.student_answers # update survey.save_user_answers(self.student, self.student_answers_update, self.course_id) answers = survey.get_answers(self.student) assert len(list(answers.keys())) == 1 assert self.student.id in answers assert answers[self.student.id] == self.student_answers_update # update with just a subset of the origin dataset survey.save_user_answers(self.student, self.student_answers_update2, self.course_id) answers = survey.get_answers(self.student) assert len(list(answers.keys())) == 1 assert self.student.id in answers assert answers[self.student.id] == self.student_answers_update2 def test_limit_num_users(self): """ Verify that the limit_num_users parameter to get_answers() works as intended """ survey = self._create_test_survey() survey.save_user_answers(self.student, self.student_answers, self.course_id) survey.save_user_answers(self.student2, self.student2_answers, self.course_id) # even though we have 2 users submitted answers # limit the result set to just 1 all_answers = survey.get_answers(limit_num_users=1) assert len(list(all_answers.keys())) == 1 def test_get_field_names(self): """ Create a new survey and add answers to it """ survey = self._create_test_survey() assert survey is not None survey.save_user_answers(self.student, self.student_answers, self.course_id) survey.save_user_answers(self.student2, self.student2_answers, self.course_id) names = survey.get_field_names() assert sorted(names) == ['ddl', 'field1', 'field2'] def test_retire_user_successful(self): survey = self._create_test_survey() assert survey is not None survey.save_user_answers(self.student, self.student_answers, self.course_id) survey.save_user_answers(self.student2, self.student2_answers, self.course_id) retire_result = SurveyAnswer.retire_user(self.student.id) assert retire_result answers = survey.get_answers(self.student) blanked_out_student_answser = {key: '' for key in self.student_answers} assert answers[self.student.id] == blanked_out_student_answser assert survey.get_answers(self.student2)[self.student2.id] == self.student2_answers def test_retire_user_not_exist(self): survey = self._create_test_survey() assert survey is not None survey.save_user_answers(self.student, self.student_answers, self.course_id) retire_result = SurveyAnswer.retire_user(self.student2.id) assert not retire_result answers = survey.get_answers(self.student) assert answers[self.student.id] == self.student_answers