""" Python tests for the Survey models """ from collections import OrderedDict import ddt import pytest from django.core.exceptions import ValidationError from django.test import TestCase from django.test.client import Client from common.djangoapps.student.tests.factories import UserFactory 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 = 'Password1234' self.student = UserFactory.create( username='student', email='student@test.com', password=self.password, ) self.student2 = UserFactory.create( username='student2', email='student2@test.com', password=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