Files
edx-platform/lms/djangoapps/survey/tests/test_models.py
2023-10-12 10:31:13 -04:00

315 lines
10 KiB
Python

"""
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 = '<li><input name="field1" /></li><li><input name="field2" /></li><li><select name="ddl"><option>1</option></select></li>' # lint-amnesty, pylint: disable=line-too-long
self.test_form_update = '<input name="field1" />'
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', '<input name="oops" /><<<>')
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', '<p>no input fields here</p>')
with pytest.raises(ValidationError):
SurveyForm.create('badform', '<input id="input_without_name" />')
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