class ConceptsTests(TestCase): def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit(course=self.course, unit=self.unit, order=0, addedBy=self.user) self.course_unit.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.concept = Concept.new_concept('bad', 'idea', self.unit, self.user) self.lesson = Lesson(title='New York Test Lesson', text='brr', addedBy=self.user) self.lesson.save_root(self.concept) self.unit_lesson = UnitLesson(unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id) self.unit_lesson.save() def test_unit_concepts_search(self): self.lesson.concept = self.concept self.lesson.save() response = self.client.get( reverse('ct:unit_concepts', kwargs={'course_id': self.course.id, 'unit_id': self.unit.id}), {'search': 'New York'}, follow=True ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'ct/concepts.html') self.assertIn('actionTarget', response.context) cset_dict = {i[0]: i[1] for i in response.context['cset']} self.assertIn('New York Test Lesson', cset_dict) self.assertIn('New York', cset_dict) self.assertIn('The New York Times Company', cset_dict)
def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.concept = Concept(title='test title', addedBy=self.user) self.concept.save() self.lesson = Lesson(title='ugh', text='brr', addedBy=self.user, kind=Lesson.ORCT_QUESTION) self.lesson.save_root() self.lesson.add_concept_link(self.concept, ConceptLink.TESTS, self.user) self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.unit_lesson = UnitLesson(unit=self.unit, addedBy=self.user, treeID=42, lesson=self.lesson) self.unit_lesson.save() self.response = Response(course=self.course, lesson=self.lesson, author=self.user, unitLesson=self.unit_lesson, confidence=Response.GUESS, title='test title', text='test text') self.response.save() self.context = { 'actionTarget': '/ct/courses/1/units/1/', 'ul': self.unit_lesson, 'test_text': 'This is a test text', 'r': self.response }
class LTITestCase(TestCase): def setUp(self): """ Preconditions. """ self.client = Client() self.user = User.objects.create_user('test', '*****@*****.**', 'test') mocked_nonce = u'135685044251684026041377608307' mocked_timestamp = u'1234567890' mocked_decoded_signature = u'my_signature=' self.headers = { u'user_id': 1, u'lis_person_name_full': u'Test Username', u'lis_person_name_given': u'First', u'lis_person_name_family': u'Second', u'lis_person_contact_email_primary': u'*****@*****.**', u'lis_person_sourcedid': u'Test_Username', u'oauth_callback': u'about:blank', u'launch_presentation_return_url': '', u'lti_message_type': u'basic-lti-launch-request', u'lti_version': 'LTI-1p0', u'roles': u'Student', u'context_id': 1, u'tool_consumer_info_product_family_code': u'moodle', u'context_title': u'Test title', u'tool_consumer_instance_guid': u'test.dot.com', u'resource_link_id': 'dfgsfhrybvrth', u'lis_result_sourcedid': 'wesgaegagrreg', u'oauth_nonce': mocked_nonce, u'oauth_timestamp': mocked_timestamp, u'oauth_consumer_key': u'', u'oauth_signature_method': u'HMAC-SHA1', u'oauth_version': u'1.0', u'oauth_signature': mocked_decoded_signature } self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.course_ref = CourseRef( course=self.course, context_id=self.headers.get('context_id'), tc_guid=self.headers.get('tool_consumer_instance_guid') ) self.course_ref.save() self.course_ref.instructors.add(self.user) self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user ) self.courseunit.save()
def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit(course=self.course, unit=self.unit, order=0, addedBy=self.user) self.course_unit.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.concept = Concept.new_concept('bad', 'idea', self.unit, self.user) self.lesson = Lesson(title='New York Test Lesson', text='brr', addedBy=self.user) self.lesson.save_root(self.concept) self.unit_lesson = UnitLesson(unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id) self.unit_lesson.save()
def setUp(self): self.user = User.objects.create_user( username='******', email='jacob@_', password='******' ) # have to login or Django self.client.session storage won't work self.client.login(username='******', password='******') self.course = Course( title='Great Course', description='the bestest', addedBy=self.user ) self.course.save() self.unit = Unit(title='My Courselet', addedBy=self.user) self.unit.save() self.lesson = Lesson( title='Big Deal', text='very interesting info', addedBy=self.user ) self.lesson.save_root() self.unitLesson = UnitLesson.create_from_lesson( self.lesson, self.unit, order='APPEND' ) self.ulQ = create_question_unit(self.user) self.ulQ2 = create_question_unit( self.user, 'Pretest', 'Scary Question', 'Tell me something.' ) self.json_mixin = JSONBlobMixin() self.fsmDict = dict(name='test', title='try this') self.nodeDict = dict( START=dict(title='start here', path='ct:home', funcName='fsm.fsm_plugin.testme.START'), MID=dict(title='in the middle', path='ct:about', doLogging=True), END=dict(title='end here', path='ct:home') ) self.edgeDict = ( dict(name='next', fromNode='START', toNode='END', title='go go go'), dict(name='select_Lesson', fromNode='MID', toNode='MID', title='go go go'), )
def setUp(self): self.username, self.password = '******', 'test' self.user = User.objects.create_user('test', '*****@*****.**', 'test') self.instructor = Instructor.objects.create(user=self.user, institution='institute', what_do_you_teach='something') self.user2 = User.objects.create_user('test1', '*****@*****.**', 'test') self.instructor2 = Instructor.objects.create(user=self.user2, institution='institution', what_do_you_teach='something') self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() self.lesson = Lesson(title='title', text='text', addedBy=self.user) self.lesson.save() self.unitlesson = UnitLesson( unit=self.unit, order=0, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id ) self.unitlesson.save() self.client.login(username=self.username, password=self.password) self.url = reverse('ctms:my_courses')
def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit( course=self.course, unit=self.unit, order=0, addedBy=self.user ) self.course_unit.releaseTime = timezone.now() - datetime.timedelta(days=1) self.course_unit.save() self.enroll = EnrollUnitCode(courseUnit=self.course_unit) self.enroll.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.student_role = Role(course=self.course, user=self.user, role=Role.ENROLLED) self.student_role.save() self.concept = Concept.new_concept('bad', 'idea', self.unit, self.user) self.lesson = Lesson( title='New York Test Lesson', text='brr', addedBy=self.user, kind=Lesson.ORCT_QUESTION ) self.lesson.save_root(self.concept) self.unit_lesson = UnitLesson( unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id, order=0 ) self.unit_lesson.save() self.unit_lesson_answer = UnitLesson( parent=self.unit_lesson, unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id, kind=UnitLesson.ANSWERS ) self.unit_lesson_answer.save() self.user = User.objects.create_user(username='******', password='******') call_command('fsm_deploy')
class LTITestCase(TestCase): def setUp(self): """ Preconditions. """ self.client = Client() self.user = User.objects.create_user('test', '*****@*****.**', 'test') mocked_nonce = u'135685044251684026041377608307' mocked_timestamp = u'1234567890' mocked_decoded_signature = u'my_signature=' self.headers = { u'user_id': 1, u'lis_person_name_full': u'Test Username', u'lis_person_name_given': u'First', u'lis_person_name_family': u'Second', u'lis_person_contact_email_primary': u'*****@*****.**', u'lis_person_sourcedid': u'Test_Username', u'oauth_callback': u'about:blank', u'launch_presentation_return_url': '', u'lti_message_type': u'basic-lti-launch-request', u'lti_version': 'LTI-1p0', u'roles': u'Student', u'context_id': 1, u'tool_consumer_info_product_family_code': u'moodle', u'context_title': u'Test title', u'tool_consumer_instance_guid': u'test.dot.com', u'resource_link_id': 'dfgsfhrybvrth', u'lis_result_sourcedid': 'wesgaegagrreg', u'oauth_nonce': mocked_nonce, u'oauth_timestamp': mocked_timestamp, u'oauth_consumer_key': u'', u'oauth_signature_method': u'HMAC-SHA1', u'oauth_version': u'1.0', u'oauth_signature': mocked_decoded_signature } self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.course_ref = CourseRef( course=self.course, context_id=self.headers.get('context_id'), tc_guid=self.headers.get('tool_consumer_instance_guid')) self.course_ref.save() self.course_ref.instructors.add(self.user) self.courseunit = CourseUnit(unit=self.unit, course=self.course, order=0, addedBy=self.user) self.courseunit.save()
class FunctionTests(OurTestCase): def setUp(self): self.user = User.objects.create_user(username='******', email='jacob@_', password='******') self.client.login(username='******', password='******') self.wikiUser = User.objects.create_user(username='******', email='wiki@_', password='******') self.unit = Unit(title='My Courselet', addedBy=self.user) self.unit.save() def test_sourceDB(self): """ Check wikipedia concept retrieval. """ c, lesson = Concept.get_from_sourceDB('New York City', self.user) self.assertEqual(c.title, 'New York City') self.assertEqual(c.addedBy, self.user) self.assertEqual(lesson.addedBy, self.wikiUser) self.assertEqual(lesson.concept, c) self.assertTrue(lesson.is_committed()) self.assertEqual(lesson.changeLog, 'initial text from wikipedia') self.assertEqual(lesson.sourceDB, 'wikipedia') self.assertEqual(lesson.sourceID, 'New York City') self.assertIn('City of New York', lesson.text) # check that subsequent retrieval uses stored db record c2, l2 = Concept.get_from_sourceDB('New York City', self.user) self.assertEqual(c2.pk, c.pk) self.assertEqual(l2.pk, lesson.pk) self.assertIn(c, list(Concept.search_text('new york'))) def test_sourceDB_temp(self): """ Check wikipedia temporary document retrieval. """ lesson = Lesson.get_from_sourceDB('New York City', self.user, doSave=False) self.assertIn('City of New York', lesson.text) # got the text? self.assertEqual(Lesson.objects.count(), 0) # nothing saved? def test_wikipedia_view(self): """ Check wikipedia view and concept addition method. """ url = '/ct/teach/courses/1/units/%d/concepts/wikipedia/%s/' % ( self.unit.pk, urllib.quote('New York City')) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, 'City of New York') self.check_post_get(url, dict(task='add'), '/', 'City of New York') ul = UnitLesson.objects.get(lesson__concept__title='New York City', unit=self.unit) # check UL & concept added self.assertTrue(ul in UnitLesson.search_sourceDB('New York City')[0]) self.assertTrue(ul in UnitLesson.search_sourceDB('New York City', unit=self.unit)[0])
class FunctionTests(OurTestCase): def setUp(self): self.user = User.objects.create_user( username='******', email='jacob@_', password='******' ) self.client.login(username='******', password='******') self.wikiUser = User.objects.create_user( username='******', email='wiki@_', password='******' ) self.unit = Unit(title='My Courselet', addedBy=self.user) self.unit.save() def test_sourceDB(self): """ Check wikipedia concept retrieval. """ c, lesson = Concept.get_from_sourceDB('New York City', self.user) self.assertEqual(c.title, 'New York City') self.assertEqual(c.addedBy, self.user) self.assertEqual(lesson.addedBy, self.wikiUser) self.assertEqual(lesson.concept, c) self.assertTrue(lesson.is_committed()) self.assertEqual(lesson.changeLog, 'initial text from wikipedia') self.assertEqual(lesson.sourceDB, 'wikipedia') self.assertEqual(lesson.sourceID, 'New York City') self.assertIn('City of New York', lesson.text) # check that subsequent retrieval uses stored db record c2, l2 = Concept.get_from_sourceDB('New York City', self.user) self.assertEqual(c2.pk, c.pk) self.assertEqual(l2.pk, lesson.pk) self.assertIn(c, list(Concept.search_text('new york'))) def test_sourceDB_temp(self): """ Check wikipedia temporary document retrieval. """ lesson = Lesson.get_from_sourceDB( 'New York City', self.user, doSave=False ) self.assertIn('City of New York', lesson.text) # got the text? self.assertEqual(Lesson.objects.count(), 0) # nothing saved? def test_wikipedia_view(self): """ Check wikipedia view and concept addition method. """ url = '/ct/teach/courses/1/units/%d/concepts/wikipedia/%s/' % (self.unit.pk, urllib.quote('New York City')) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, 'City of New York') self.check_post_get(url, dict(task='add'), '/', 'City of New York') ul = UnitLesson.objects.get( lesson__concept__title='New York City', unit=self.unit ) # check UL & concept added self.assertTrue(ul in UnitLesson.search_sourceDB('New York City')[0]) self.assertTrue(ul in UnitLesson.search_sourceDB('New York City', unit=self.unit)[0])
def setUp(self): self.user = User.objects.create_user( username='******', email='jacob@_', password='******' ) self.client.login(username='******', password='******') self.wikiUser = User.objects.create_user( username='******', email='wiki@_', password='******' ) self.unit = Unit(title='My Courselet', addedBy=self.user) self.unit.save()
def setUp(self): super(SharedCoursesListViewTests, self).setUp() self.unit2 = Unit(title='Test title2', addedBy=self.user) self.unit2.save() self.course2 = Course(title='Test title2', description='test description2', access='Public2', enrollCode='1112', lockout='1222', addedBy=self.user) self.course2.save() self.courseunit2 = CourseUnit( unit=self.unit2, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit2.save() self.courseunit3 = CourseUnit( unit=self.unit, course=self.course2, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit3.save() enroll_unit_code = EnrollUnitCode.get_code(self.courseunit, give_instance=True) enroll_unit_code2 = EnrollUnitCode.get_code(self.courseunit2, give_instance=True) enroll_unit_code3 = EnrollUnitCode.get_code(self.courseunit3, give_instance=True) self.tester_shared_course = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course, enroll_unit_code=enroll_unit_code ) self.tester_shared_course2 = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course, enroll_unit_code=enroll_unit_code2 ) self.tester_shared_course3 = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course2, enroll_unit_code=enroll_unit_code3 ) self.url = reverse('ctms:shared_courses')
def setUp(self): self.user = User.objects.create_user(username="******", password="******") self.course = Course(title="test_title", addedBy=self.user) self.course.save() self.concept = Concept(title="test title", addedBy=self.user) self.concept.save() self.lesson = Lesson(title="ugh", text="brr", addedBy=self.user, kind=Lesson.ORCT_QUESTION) self.lesson.save_root() self.lesson.add_concept_link(self.concept, ConceptLink.TESTS, self.user) self.unit = Unit(title="test unit title", addedBy=self.user) self.unit.save() self.unit_lesson = UnitLesson(unit=self.unit, addedBy=self.user, treeID=42, lesson=self.lesson) self.unit_lesson.save() self.response = Response( course=self.course, lesson=self.lesson, author=self.user, unitLesson=self.unit_lesson, confidence=Response.GUESS, title="test title", text="test text", ) self.response.save() self.context = { "actionTarget": "/ct/courses/1/units/1/", "ul": self.unit_lesson, "test_text": "This is a test text", "r": self.response, }
class SetUpMixin(object): """ Mixin to provide setUp method. """ def setUp(self): self.client = Client() self.user = User.objects.create_user('test', '*****@*****.**', 'test') get_specs()[0].save_graph(self.user.username) get_specs_additional()[0].save_graph(self.user.username) get_specs_resource()[0].save_graph(self.user.username) self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() self.concept = Concept.new_concept('bad', 'idea', self.unit, self.user) lesson = Lesson(title='title', text='text', addedBy=self.user) lesson.save() self.unitlesson = UnitLesson( unit=self.unit, order=0, lesson=lesson, addedBy=self.user, treeID=lesson.id ) self.unitlesson.save() resource_lesson = Lesson( title='title for resource', text='text for resource', addedBy=self.user ) resource_lesson.save() self.resource_unitlesson = UnitLesson( unit=self.unit, lesson=resource_lesson, addedBy=self.user, treeID=resource_lesson.id ) self.resource_unitlesson.save()
def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit(course=self.course, unit=self.unit, order=0, addedBy=self.user) self.course_unit.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.enroll = EnrollUnitCode.get_code_for_user_chat(self.course_unit, True, self.user) self.history_live_chat = Chat( user=self.user, is_live=True, enroll_code=self.enroll ) self.history_live_chat.save()
def setUp(self): self.user = User.objects.create_user(username="******", email="jacob@_", password="******") # have to login or Django self.client.session storage won't work self.client.login(username="******", password="******") self.course = Course(title="Great Course", description="the bestest", addedBy=self.user) self.course.save() self.unit = Unit(title="My Courselet", addedBy=self.user) self.unit.save() self.lesson = Lesson(title="Big Deal", text="very interesting info", addedBy=self.user) self.lesson.save_root() self.unitLesson = UnitLesson.create_from_lesson(self.lesson, self.unit, order="APPEND") self.ulQ = create_question_unit(self.user) self.ulQ2 = create_question_unit(self.user, "Pretest", "Scary Question", "Tell me something.") self.json_mixin = JSONBlobMixin() self.fsmDict = dict(name="test", title="try this") self.nodeDict = dict( START=dict(title="start here", path="ct:home", funcName="fsm.fsm_plugin.testme.START"), MID=dict(title="in the middle", path="ct:about", doLogging=True), END=dict(title="end here", path="ct:home"), ) self.edgeDict = ( dict(name="next", fromNode="START", toNode="END", title="go go go"), dict(name="select_Lesson", fromNode="MID", toNode="MID", title="go go go"), )
class TagsTest(TestCase): def setUp(self): self.user = User.objects.create_user(username="******", password="******") self.course = Course(title="test_title", addedBy=self.user) self.course.save() self.concept = Concept(title="test title", addedBy=self.user) self.concept.save() self.lesson = Lesson(title="ugh", text="brr", addedBy=self.user, kind=Lesson.ORCT_QUESTION) self.lesson.save_root() self.lesson.add_concept_link(self.concept, ConceptLink.TESTS, self.user) self.unit = Unit(title="test unit title", addedBy=self.user) self.unit.save() self.unit_lesson = UnitLesson(unit=self.unit, addedBy=self.user, treeID=42, lesson=self.lesson) self.unit_lesson.save() self.response = Response( course=self.course, lesson=self.lesson, author=self.user, unitLesson=self.unit_lesson, confidence=Response.GUESS, title="test title", text="test text", ) self.response.save() self.context = { "actionTarget": "/ct/courses/1/units/1/", "ul": self.unit_lesson, "test_text": "This is a test text", "r": self.response, } def render_template(self, string, context=None): context = context or {} context = Context(context) return Template(string).render(context) @unpack @data( ("{{ test_text | md2html }}", "<p>This is a test text</p>\n"), ("{{ actionTarget | get_object_url:ul }}", "/ct/courses/1/units/1/lessons/1/"), ("{{ actionTarget | get_home_url:ul }}", "/ct/courses/1/units/1/lessons/1/"), ("{{ actionTarget | get_thread_url:r }}", "/ct/courses/1/units/1/lessons/1/faq/1/"), ("{{ actionTarget | get_tasks_url:ul }}", "/ct/courses/1/units/1/lessons/1/tasks/"), ("{{ actionTarget | get_dummy_navbar }}", '<li><a href="/ct/courses/1/">Course</a></li>'), ) def test_all_filters(self, template_variable, expected_result): rendered = self.render_template("{% load ct_extras %}" + template_variable, context=self.context) self.assertEqual(rendered, expected_result) @patch("ct.templatetags.ct_extras.pypandoc") def test_md2html_pandoc_exception(self, pypandoc): pypandoc.convert.side_effect = StandardError rendered = self.render_template("{% load ct_extras %}" "{{ test_text | md2html }}", context=self.context) self.assertEqual(rendered, self.context["test_text"]) @data("get_base_url", "get_path_type") def test_get_base_url_exception(self, helper): with self.assertRaises(ValueError): getattr(inspect.getmodule(self), helper).__call__( "/ct/courses/1/units/1/lessons/1/", baseToken="non_existent_token" ) def test_get_object_url_exception(self): self.context["ul"] = self.unit # Unit object does not have get_url method rendered = self.render_template( "{% load ct_extras %}" "{{ actionTarget | get_object_url:ul }}", context=self.context ) self.assertEqual(rendered, "/ct/courses/1/units/1/unit/1/teach/") @patch("ct.templatetags.ct_extras.timezone") def test_display_datetime(self, timezone_patched): saved_time = timezone.now() timezone_patched.now.return_value = saved_time context = {"dt": saved_time - timedelta(1)} rendered = self.render_template("{% load ct_extras %}" "{{ dt|display_datetime }}", context=context) self.assertEqual(rendered, "1 day ago") def test_find_audio(self): result = find_audio("test tag head .. audio:: test tag tail \n", 4) self.assertEqual(result, (14, 39, "test tag tail")) def test_audio_html(self): """ Function should return string for embeding audio into html. """ result = audio_html("audio.mp3") self.assertEqual( result, """<audio controls><source src="audio.ogg" type="audio/ogg"><source src="audio.mp3" """ """type="audio/mpeg">no support for audio!</audio>""", ) def test_video_html(self): """ Function should return string for embeding youtube or vimeo link. """ result = video_html("youtube:test_video_path") self.assertIn("test_video_path", result) self.assertIn('src="https://www.youtube.com/embed/', result) result = video_html("vimeo:test_video_path") self.assertIn("test_video_path", result) self.assertIn('src="https://player.vimeo.com/video/', result) def test_video_html_with_exception(self): """ Test exception handling. """ result = video_html("youtube") self.assertEqual(result, "ERROR: bad video source: youtube") result = video_html("some_new_cdn:test_video_path") self.assertEqual(result, "ERROR: unknown video sourceDB: some_new_cdn") def test_add_replace_temporary_markers(self): """ Test add_temporary_markers and replace_temporary_markers in tandem. """ result = add_temporary_markers("test tag head .. audio:: test tag tail \n", find_audio) self.assertEqual(result, ("test tag head mArKeR:0:\n", [("mArKeR:0:", "test tag tail")])) result = replace_temporary_markers(result[0], audio_html, result[1]) self.assertEqual( result, """test tag head <audio controls><source src="test tag tail.ogg" type="audio/ogg">""" """<source src="test tag tail.mp3" type="audio/mpeg">no support for audio!</audio>\n""", )
class MyTestCase(TestCase): models_to_check = tuple() context_should_contain_keys = tuple() def setUp(self): self.username, self.password = '******', 'test' self.user = User.objects.create_user(self.username, '*****@*****.**', self.password) self.instructor = Instructor.objects.create(user=self.user, institution='institute', what_do_you_teach='something') self.username2, self.password2 = 'test1', 'test' self.user2 = User.objects.create_user(self.username2, '*****@*****.**', self.password2) self.instructor2 = Instructor.objects.create(user=self.user2, institution='institute', what_do_you_teach='something') self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() self.lesson = Lesson(title='title', text='text', addedBy=self.user) self.lesson.save() self.unitlesson = UnitLesson( unit=self.unit, order=0, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id ) self.unitlesson.save() self.resp1 = Response( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, text="Some text user may respond", author=self.user, status=NEED_HELP_STATUS, selfeval=Response.DIFFERENT ) self.resp1.save() self.resp2 = Response( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, text="Some text user may be responded 2", author=self.user, status=NEED_HELP_STATUS, selfeval=Response.DIFFERENT ) self.resp2.save() self.default_data = {} self.client.login(username=self.username, password=self.password) self.url = reverse('ctms:course_settings', kwargs={'pk': self.course.id}) def get_page(self): return self.client.get(self.url) def post_data(self, data={'name': 'some test name'}): response = self.client.post(self.url, data, follow=True) return response def get_client_method(self, method='post'): client_method = getattr(self.client, method) if not client_method: raise KeyError('self.client has no property {}'.format(method)) return client_method def post_valid_data(self, data={'name': 'some test name'}, method='post'): client_method = self.get_client_method(method) copied_data = {} if getattr(self, 'default_data', False): copied_data.update(self.default_data) copied_data.update(data) response = client_method(self.url, copied_data, follow=True) return response def post_invalid_data(self, data={'name': ''}, method='post'): client_method = self.get_client_method(method) copied_data = {} if getattr(self, 'default_data', False): copied_data.update(self.default_data) copied_data.update(data) response = client_method(self.url, copied_data, follow=True) return response def get_my_courses(self): return Course.objects.filter( models.Q(addedBy=self.user) | models.Q(role__role=Role.INSTRUCTOR, role__user=self.user) ) def get_test_course(self): return Course.objects.get(id=self.course.id) def get_test_unitlessons(self): return self.courseunit.unit.unitlesson_set.filter( kind=UnitLesson.COMPONENT, order__isnull=False ).order_by('order').annotate( responses_count=models.Count('response') ) def get_test_unitlesson(self): return self.courseunit.unit.unitlesson_set.filter( kind=UnitLesson.COMPONENT, order__isnull=False ).order_by('order').annotate( responses_count=models.Count('response') )[0] get_test_courslet = get_test_unitlesson get_test_response = lambda self: self.get_test_responses()[0] def get_test_courseunit(self): return CourseUnit.objects.get(id=self.courseunit.id) def get_test_responses(self): return Response.objects.filter( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, ) def get_model_counts(self, **kwargs): if isinstance(self.models_to_check, (list, tuple)): return {model: model.objects.filter().count() for model in self.models_to_check} return {self.models_to_check: self.models_to_check.objects.filter().count()} def validate_model_counts(self, first_counts, second_counts, must_equal=False): if isinstance(self.models_to_check, (list, tuple)): all_models = self.models_to_check else: all_models = [self.models_to_check] for model in all_models: if must_equal: self.assertEqual( first_counts[model], second_counts[model], "{} ({}) != {} ({}), with must_equal={}".format( model, first_counts[model], model, second_counts[model], must_equal ) ) else: self.assertNotEqual( first_counts[model], second_counts[model], "{} ({}) == {} ({}), with must_equal={}".format( model, first_counts[model], model, second_counts[model], must_equal ) ) def check_context_keys(self, response): for key in self.context_should_contain_keys: self.assertIn(key, response.context) def am_i_instructor(self, method='GET'): methods_map = {'GET', self.client.get, 'POST', self.client.post} client_method = methods_map.get(method) self.assertIsNotNone(client_method) if getattr(self, 'url'): if getattr(self, 'NEED_INSTRUCTOR'): response = client_method(self.url) if getattr(self, 'instructor'): self.assertEqual(response.status_code, 200) self.instructor.delete() response = client_method(self.url) self.assertEqual(response.status_code, 403) else: self.assertEqual(response.status_code, 403) else: response = client_method(self.url) self.assertEqual(response.status_code, 200)
class MyCoursesTests(MyTestCase): def setUp(self): self.username, self.password = '******', 'test' self.user = User.objects.create_user('test', '*****@*****.**', 'test') self.instructor = Instructor.objects.create(user=self.user, institution='institute', what_do_you_teach='something') self.user2 = User.objects.create_user('test1', '*****@*****.**', 'test') self.instructor2 = Instructor.objects.create(user=self.user2, institution='institution', what_do_you_teach='something') self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() self.lesson = Lesson(title='title', text='text', addedBy=self.user) self.lesson.save() self.unitlesson = UnitLesson( unit=self.unit, order=0, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id ) self.unitlesson.save() self.client.login(username=self.username, password=self.password) self.url = reverse('ctms:my_courses') def test_get_my_courses_page(self): response = self.client.get(self.url) # should contain 1 course self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'ctms/my_courses.html') self.assertIn('my_courses', response.context) self.assertIn(self.course, response.context['my_courses']) def test_get_my_courses_page_instructor_role(self): """ Ensure Role.INSTRUCTOR granted access to a Course. """ course = Course(title='Instructor2 Course', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user2) course.save() Role.objects.create(role=Role.INSTRUCTOR, course=course, user=self.user) response = self.client.get(self.url) # should contain 2 courses self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'ctms/my_courses.html') self.assertIn('my_courses', response.context) self.assertIn(self.course, response.context['my_courses']) self.assertIn(course, response.context['my_courses']) self.assertEqual(len(response.context['my_courses']), 2) @data(Role.TA, Role.SELFSTUDY, Role.ENROLLED) def test_get_my_courses_page_notinstructor_role(self, role): """ Ensure Role.INSTRUCTOR granted access to a Course. """ course = Course(title='Instructor2 Course', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user2) course.save() Role.objects.create(role=role, course=course, user=self.user) response = self.client.get(self.url) # should contain 1 courses self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'ctms/my_courses.html') self.assertIn('my_courses', response.context) self.assertIn(self.course, response.context['my_courses']) self.assertNotIn(course, response.context['my_courses']) self.assertEqual(len(response.context['my_courses']), 1) def test_my_courses_show_shared_courses(self): self.course.addedBy = self.user2 self.course.save() # create shared course enroll_unit_code = EnrollUnitCode.get_code(self.courseunit, give_instance=True) shared_course = Invite.create_new( True, self.course, self.instructor2, self.user.email, 'tester', enroll_unit_code) response = self.client.get(reverse('ctms:shared_courses')) # should return shared courses self.assertIn('shared_courses', response.context) self.assertNotEqual(len(response.context['shared_courses']), 0) self.assertTrue(shared_course.course.title in response.context['shared_courses']) def my_courses_show_create_course_form(self): self.course.delete() response = self.client.get(self.url) # should return Course form self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'ctms/my_courses.html') self.assertIn('my_courses', response.context) self.assertIn('shared_courses', response.context) self.assertIn('course_form', response.context) self.assertFalse(len(response.context['my_courses']) < 0) def post_valid_create_course_form(self): courses_cnt = Course.objects.filter(addedBy=self.user).count() course_ids = [ i['id'] for i in Course.objects.filter(addedBy=self.user).values('id') ] data = { 'name': 'some course' } response = self.client.post(self.url, data) new_courses = Course.objects.filter(addedBy=self.user) new_course = new_courses.exclude(id__in=course_ids).get() self.assertEqual(new_courses.count(), courses_cnt) self.assertRedirects(response, reverse('ctms:course_view', kwargs={'course_id': new_course.id})) return response def post_invalid_create_course_form(self): courses_cnt = Course.objects.filter(addedBy=self.user).count() course_ids = [ i['id'] for i in Course.obget_courslet_view_logged_out_user_testjects.filter(addedBy=self.user).values('id') ] data = { 'name': '' } response = self.client.post(self.url, data) new_courses = Course.objects.filter(addedBy=self.user) new_course = new_courses.exclude(id__in=course_ids) self.assertNotEqual(new_courses.count(), courses_cnt) # course was not created self.assertEqual(len(new_course) == 0) self.assertTemplateUsed(response, 'ctms/my_courses.html') return response def post_valid_create_course_form_to_create_course_view(self): self.url = reverse('ctms:create_course') self.post_valid_create_course_form() def post_invalid_create_course_form_to_create_course_view(self): self.url = reverse('ctms:create_course') self.post_invalid_create_course_form()
class TestCourseView(TestCase): def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit(course=self.course, unit=self.unit, order=0, addedBy=self.user) self.course_unit.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.enroll = EnrollUnitCode.get_code_for_user_chat(self.course_unit, True, self.user) self.history_live_chat = Chat( user=self.user, is_live=True, enroll_code=self.enroll ) self.history_live_chat.save() @patch('chat.serializers.ChatProgressSerializer') @patch('lms.views.get_object_or_404') @patch('lms.views.EnrollUnitCode.get_code') @patch('fsm.models.FSMState.find_live_sessions') @patch('chat.models.Chat.objects.filter') def test_course_view(self, chatFilterMock, find_live_sessions, get_code, get_obj_or_404, ChatProgressSerializer): """ This test tests that: - query FSMState.find_live_sessions(request.user).filter(activity__course=course).first() return live session and this live session is present in page's context """ filter_mock = Mock() filter_mock.filter = Mock() find_live_sessions.return_value = filter_mock first_mock = Mock() filter_mock.filter.return_value = first_mock first_mock.first = Mock() first_mock.first.return_value = Mock() first_mock.first.return_value.id = 1 unit = Mock() unit.unit.get_exercises.return_value=[Mock()] course_mock = Mock() course_units = Mock() course_mock.get_course_units = course_units course_units.return_value = [unit] get_obj_or_404.return_value = course_mock chatFilterMock = Mock() chatFilterMock.return_value = [Mock()] ChatProgressSerializer.data.get.return_value = 0 response = self.client.get(reverse('lms:course_view', kwargs={'course_id': 1})) self.assertEqual(response.status_code, 200) self.assertEqual(filter_mock.filter.call_count, 1) self.assertEqual(first_mock.first.call_count, 1) self.assertEqual(get_obj_or_404.call_count, 1) self.assertTemplateUsed(response, 'lms/course_page.html') # context should contain these keys: course, liveSession, courslets self.assertIn('course', response.context) self.assertIn('liveSession', response.context) self.assertIn('courslets', response.context) def test_course_view_negative(self): """ This test tests case when teacher not yet (opened) joined live session and student opens course page. Student should not see 'Join Live Session' button on the top of the page. """ response = self.client.get( reverse('lms:course_view', kwargs={'course_id': self.course.id}) ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'lms/course_page.html') self.assertIn('course', response.context) self.assertIn('liveSession', response.context) self.assertIn('courslets', response.context) self.assertEqual(response.context['liveSession'], None) self.assertFalse(response.context['liveSession']) #TODO: write test when teacher really creates Course and Courslets inside of the course and student open page. #TODO: user should see 'Join' button. @patch('chat.models.Chat.get_spent_time') def test_live_chat_history_time_spent(self, get_spent_time): get_spent_time.return_value = datetime.timedelta(days=1, hours=1) response = self.client.get(reverse('lms:course_view', kwargs={'course_id': self.course.id})) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'lms/course_page.html') self.assertIn('livesessions', response.context) self.assertNotEqual(response.context['livesessions'], []) self.assertEqual(response.context['livesessions'][0].get_formatted_time_spent(), '1 day, 1:00:00')
def setUp(self): self.username, self.password = '******', 'test' self.user = User.objects.create_user(self.username, '*****@*****.**', self.password) self.instructor = Instructor.objects.create(user=self.user, institution='institute', what_do_you_teach='something') self.username2, self.password2 = 'test1', 'test' self.user2 = User.objects.create_user(self.username2, '*****@*****.**', self.password2) self.instructor2 = Instructor.objects.create(user=self.user2, institution='institute', what_do_you_teach='something') self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() self.lesson = Lesson(title='title', text='text', addedBy=self.user) self.lesson.save() self.unitlesson = UnitLesson( unit=self.unit, order=0, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id ) self.unitlesson.save() self.resp1 = Response( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, text="Some text user may respond", author=self.user, status=NEED_HELP_STATUS, selfeval=Response.DIFFERENT ) self.resp1.save() self.resp2 = Response( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, text="Some text user may be responded 2", author=self.user, status=NEED_HELP_STATUS, selfeval=Response.DIFFERENT ) self.resp2.save() self.default_data = {} self.client.login(username=self.username, password=self.password) self.url = reverse('ctms:course_settings', kwargs={'pk': self.course.id})
class TestCourseletViewHistoryTab(TestCase): def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit( course=self.course, unit=self.unit, order=0, addedBy=self.user ) self.course_unit.releaseTime = timezone.now() - datetime.timedelta(days=1) self.course_unit.save() self.enroll = EnrollUnitCode(courseUnit=self.course_unit) self.enroll.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.student_role = Role(course=self.course, user=self.user, role=Role.ENROLLED) self.student_role.save() self.concept = Concept.new_concept('bad', 'idea', self.unit, self.user) self.lesson = Lesson( title='New York Test Lesson', text='brr', addedBy=self.user, kind=Lesson.ORCT_QUESTION ) self.lesson.save_root(self.concept) self.unit_lesson = UnitLesson( unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id, order=0 ) self.unit_lesson.save() self.unit_lesson_answer = UnitLesson( parent=self.unit_lesson, unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id, kind=UnitLesson.ANSWERS ) self.unit_lesson_answer.save() self.user = User.objects.create_user(username='******', password='******') call_command('fsm_deploy') def test_click_on_courslet_creates_new_chat(self): # test that there's no history yet response = self.client.get( reverse('lms:course_view', kwargs={'course_id': self.course.id}) ) self.assertEqual(response.status_code, 200) self.assertIsNotNone(list(response.context['courslets'])) self.assertEqual(response.status_code, 200) chats_count_1 = Chat.objects.all().count() # firstly call to chat:init_chat_api function with enroll_key and chat_id=0 response = self.client.get( reverse( 'chat:init_chat_api', kwargs={ 'enroll_key': self.enroll.enrollCode, 'chat_id': 0 } ), HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) json_content = json.loads(response.content) chat_id = json_content['id'] response = self.client.get( reverse('chat:chat_enroll', kwargs={'enroll_key': self.enroll.enrollCode, 'chat_id': chat_id}) ) self.assertEqual(response.context['chat'].id, Chat.objects.all().first().id) self.assertEqual(response.status_code, 200) chats_count_2 = Chat.objects.count() self.assertNotEqual(chats_count_2, chats_count_1) response = self.client.get( reverse('chat:chat_enroll', kwargs={'enroll_key': self.enroll.enrollCode, 'chat_id': chat_id}) ) chats_count_3 = Chat.objects.count() response = self.client.get( reverse('chat:chat_enroll', kwargs={'enroll_key': self.enroll.enrollCode, 'chat_id': chat_id}) ) chats_count_4 = Chat.objects.count() self.assertEqual(response.status_code, 200) self.assertEqual(chats_count_4, chats_count_2) self.assertEqual(chats_count_3, chats_count_2) self.assertEqual(response.context['chat'].id, Chat.objects.all().first().id) chat = Chat.objects.all().first() # get chat and set state to None it means that courslet finished. chat.state = None chat.save() response = self.client.get( reverse('lms:course_view', kwargs={'course_id': self.course.id}) ) self.assertEqual(response.status_code, 200) self.assertEqual(Chat.objects.count(), chats_count_2) self.assertEqual(len(list(response.context['courslets'])), 1) def test_courslet_history(self): enroll_code = EnrollUnitCode.get_code(self.course_unit) response = self.client.get( reverse( 'chat:init_chat_api', kwargs={ 'enroll_key': self.enroll.enrollCode, 'chat_id': 0 } ), HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) json_content = json.loads(response.content) chat_id = json_content['id'] response = self.client.get( reverse('chat:chat_enroll', args=(enroll_code, chat_id)), follow=True ) response = self.client.get( reverse('chat:history'), {'chat_id': chat_id}, follow=True ) json_content = json.loads(response.content) next_url = json_content['input']['url'] answer = 'My Answer' response = self.client.put( next_url, data=json.dumps({"text": answer, "chat_id": chat_id}), content_type='application/json', follow=True ) json_content = json.loads(response.content) next_url = json_content['input']['url'] response = self.client.get( next_url, {'chat_id': chat_id}, follow=True ) json_content = json.loads(response.content) next_url = json_content['input']['url'] self.assertIsNotNone(json_content['input']['options']) self.assertEqual(len(json_content['addMessages']), 2) # emulate chat finished - set state to None Chat.objects.filter(id=chat_id).update(state=None) response = self.client.get( reverse('chat:chat_enroll', args=(enroll_code, chat_id)), follow=True ) response = self.client.get( reverse('chat:history'), {'chat_id': chat_id}, follow=True ) json_content = json.loads(response.content) self.assertIsNone(json_content['input']['options']) self.assertEqual(len(json_content['addMessages']), 4)
class TestCourseView(TestCase): def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit(course=self.course, unit=self.unit, order=0, addedBy=self.user) self.course_unit.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.enroll = EnrollUnitCode.get_code_for_user_chat(self.course_unit, True, self.user) self.history_live_chat = Chat( user=self.user, is_live=True, enroll_code=self.enroll ) self.history_live_chat.save() @patch('chat.serializers.ChatProgressSerializer') @patch('lms.views.get_object_or_404') @patch('lms.views.EnrollUnitCode.get_code') @patch('fsm.models.FSMState.find_live_sessions') @patch('chat.models.Chat.objects.filter') def test_course_view(self, chatFilterMock, find_live_sessions, get_code, get_obj_or_404, ChatProgressSerializer): """ This test tests that: - query FSMState.find_live_sessions(request.user).filter(activity__course=course).first() return live session and this live session is present in page's context """ filter_mock = Mock() filter_mock.filter = Mock() find_live_sessions.return_value = filter_mock first_mock = Mock() filter_mock.filter.return_value = first_mock first_mock.first = Mock() first_mock.first.return_value = Mock() first_mock.first.return_value.id = 1 unit = Mock() unit.unit.get_exercises.return_value=[Mock()] course_mock = Mock() course_units = Mock() course_mock.get_course_units = course_units course_units.return_value = [unit] get_obj_or_404.return_value = course_mock chatFilterMock = Mock() chatFilterMock.return_value = [Mock()] ChatProgressSerializer.data.get.return_value = 0 response = self.client.get(reverse('lms:course_view', kwargs={'course_id': 1})) self.assertEqual(response.status_code, 200) self.assertEqual(filter_mock.filter.call_count, 1) self.assertEqual(first_mock.first.call_count, 1) self.assertEqual(get_obj_or_404.call_count, 1) self.assertTemplateUsed(response, 'lms/course_page.html') # context should contain these keys: course, liveSession, courslets self.assertIn('course', response.context) self.assertIn('liveSession', response.context) self.assertIn('courslets', response.context) def test_course_view_negative(self): """ This test tests case when teacher not yet (opened) joined live session and student opens course page. Student should not see 'Join Live Session' button on the top of the page. """ response = self.client.get( reverse('lms:course_view', kwargs={'course_id': self.course.id}) ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'lms/course_page.html') self.assertIn('course', response.context) self.assertIn('liveSession', response.context) self.assertIn('courslets', response.context) self.assertEqual(response.context['liveSession'], None) self.assertFalse(response.context['liveSession']) #TODO: write test when teacher really creates Course and Courslets inside of the course and student open page. #TODO: user should see 'Join' button. @patch('chat.models.Chat.get_spent_time') def test_live_chat_history_time_spent(self, get_spent_time): get_spent_time.return_value = datetime.timedelta(days=1, hours=1) response = self.client.get(reverse('lms:course_view', kwargs={'course_id': self.course.id})) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'lms/course_page.html') self.assertIn('livesessions', response.context) self.assertNotEquals(response.context['livesessions'], []) self.assertEqual(response.context['livesessions'][0].get_formatted_time_spent(), '1 day, 1:00:00')
class SharedCoursesListViewTests(MyTestCase): def setUp(self): super(SharedCoursesListViewTests, self).setUp() self.unit2 = Unit(title='Test title2', addedBy=self.user) self.unit2.save() self.course2 = Course(title='Test title2', description='test description2', access='Public2', enrollCode='1112', lockout='1222', addedBy=self.user) self.course2.save() self.courseunit2 = CourseUnit( unit=self.unit2, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit2.save() self.courseunit3 = CourseUnit( unit=self.unit, course=self.course2, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit3.save() enroll_unit_code = EnrollUnitCode.get_code(self.courseunit, give_instance=True) enroll_unit_code2 = EnrollUnitCode.get_code(self.courseunit2, give_instance=True) enroll_unit_code3 = EnrollUnitCode.get_code(self.courseunit3, give_instance=True) self.tester_shared_course = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course, enroll_unit_code=enroll_unit_code ) self.tester_shared_course2 = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course, enroll_unit_code=enroll_unit_code2 ) self.tester_shared_course3 = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course2, enroll_unit_code=enroll_unit_code3 ) self.url = reverse('ctms:shared_courses') def get_invite_by_id(self, id): return Invite.objects.get(id=id) def test_shared_courses_list(self): response = self.client.get(self.url) self.assertEqual( reverse('ctms:shared_courses'), response.context['shared_courses'][self.course.title]['link'] ) self.assertEqual( reverse('ctms:tester_join_course', kwargs={'code': self.tester_shared_course3.code}), response.context['shared_courses'][self.course2.title]['link'] ) def test_join_course(self): url = reverse('ctms:tester_join_course', kwargs={'code': self.tester_shared_course.code}) response = self.client.get(url) self.assertRedirects( response, reverse('chat:tester_chat_enroll', kwargs={'enroll_key': self.tester_shared_course.enroll_unit_code.enrollCode}) ) invite = self.get_invite_by_id(self.tester_shared_course.id) self.assertEqual(invite.status, 'joined') self.join_course_cases(url, self.tester_shared_course) def join_course_cases(self, url, invite): # if invited user is already registered but not logged in - login form must be shown self.client.logout() response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn('form', response.context) self.assertTrue(isinstance(response.context['form'], EmailLoginForm)) self.assertEqual(response.context['form'].initial['email'], invite.email) self.assertIn('u_hash', response.context['form'].initial) # if no such user invite.email = '*****@*****.**' invite.save() response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn('form', response.context) self.assertTrue(isinstance(response.context['form'], SignUpForm)) self.assertEqual(response.context['form'].initial['email'], invite.email) self.assertIn('u_hash', response.context['form'].initial) # if user registered after sending invitation - login form must be shown User.objects.create_user('asdasd', '*****@*****.**', '123') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn('form', response.context) self.assertTrue(isinstance(response.context['form'], EmailLoginForm)) self.assertEqual(response.context['form'].initial['email'], invite.email) self.assertIn('u_hash', response.context['form'].initial) def student_join_course(self): url = reverse('ctms:tester_join_course', kwargs={'code': self.student_shared_course.code}) response = self.client.get(url) self.assertRedirects( response, reverse('lms:course_view', kwargs={'course_id': self.student_shared_course.course.id}) ) invite = self.get_invite_by_id(self.tester_shared_course.id) self.assertEqual(invite.status, 'joined') self.join_course_cases(url, self.student_shared_course)
class TestCourseletViewHistoryTab(TestCase): def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.client.login(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.course_unit = CourseUnit( course=self.course, unit=self.unit, order=0, addedBy=self.user ) self.course_unit.releaseTime = timezone.now() - datetime.timedelta(days=1) self.course_unit.save() self.enroll = EnrollUnitCode(courseUnit=self.course_unit) self.enroll.save() self.role = Role(course=self.course, user=self.user, role=Role.INSTRUCTOR) self.role.save() self.student_role = Role(course=self.course, user=self.user, role=Role.ENROLLED) self.student_role.save() self.concept = Concept.new_concept('bad', 'idea', self.unit, self.user) self.lesson = Lesson( title='New York Test Lesson', text='brr', addedBy=self.user, kind=Lesson.ORCT_QUESTION ) self.lesson.save_root(self.concept) self.unit_lesson = UnitLesson( unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id, order=0 ) self.unit_lesson.save() self.unit_lesson_answer = UnitLesson( parent=self.unit_lesson, unit=self.unit, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id, kind=UnitLesson.ANSWERS ) self.unit_lesson_answer.save() self.user = User.objects.create_user(username='******', password='******') call_command('fsm_deploy') def test_click_on_courslet_creates_new_chat(self): # test that there's no history yet response = self.client.get( reverse('lms:course_view', kwargs={'course_id': self.course.id}) ) self.assertEqual(response.status_code, 200) self.assertIsNotNone(list(response.context['courslets'])) self.assertEqual(response.status_code, 200) chats_count_1 = Chat.objects.all().count() # firstly call to chat:init_chat_api function with enroll_key and chat_id=0 response = self.client.get( reverse( 'chat:init_chat_api', kwargs={ 'enroll_key': self.enroll.enrollCode, 'chat_id': 0 } ), HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) json_content = json.loads(response.content) chat_id = json_content['id'] response = self.client.get( reverse('chat:chat_enroll', kwargs={'enroll_key': self.enroll.enrollCode, 'chat_id': chat_id}) ) self.assertEqual(response.context['chat'].id, Chat.objects.all().first().id) self.assertEqual(response.status_code, 200) chats_count_2 = Chat.objects.count() self.assertNotEqual(chats_count_2, chats_count_1) response = self.client.get( reverse('chat:chat_enroll', kwargs={'enroll_key': self.enroll.enrollCode, 'chat_id': chat_id}) ) chats_count_3 = Chat.objects.count() response = self.client.get( reverse('chat:chat_enroll', kwargs={'enroll_key': self.enroll.enrollCode, 'chat_id': chat_id}) ) chats_count_4 = Chat.objects.count() self.assertEqual(response.status_code, 200) self.assertEqual(chats_count_4, chats_count_2) self.assertEqual(chats_count_3, chats_count_2) self.assertEqual(response.context['chat'].id, Chat.objects.all().first().id) chat = Chat.objects.all().first() # get chat and set state to None it means that courslet finished. chat.state = None chat.save() response = self.client.get( reverse('lms:course_view', kwargs={'course_id': self.course.id}) ) self.assertEqual(response.status_code, 200) self.assertEqual(Chat.objects.count(), chats_count_2) self.assertEqual(len(list(response.context['courslets'])), 1) def test_courslet_history(self): enroll_code = EnrollUnitCode.get_code(self.course_unit) response = self.client.get( reverse( 'chat:init_chat_api', kwargs={ 'enroll_key': self.enroll.enrollCode, 'chat_id': 0 } ), HTTP_X_REQUESTED_WITH='XMLHttpRequest' ) json_content = json.loads(response.content) chat_id = json_content['id'] response = self.client.get( reverse('chat:chat_enroll', args=(enroll_code, chat_id)), follow=True ) response = self.client.get( reverse('chat:history'), {'chat_id': chat_id}, follow=True ) json_content = json.loads(response.content) next_url = json_content['input']['url'] answer = 'My Answer' response = self.client.put( next_url, data=json.dumps({"text": answer, "chat_id": chat_id}), content_type='application/json', follow=True ) json_content = json.loads(response.content) next_url = json_content['input']['url'] response = self.client.get( next_url, {'chat_id': chat_id}, follow=True ) json_content = json.loads(response.content) next_url = json_content['input']['url'] self.assertIsNotNone(json_content['input']['options']) self.assertEquals(len(json_content['addMessages']), 2) # emulate chat finished - set state to None Chat.objects.filter(id=chat_id).update(state=None) response = self.client.get( reverse('chat:chat_enroll', args=(enroll_code, chat_id)), follow=True ) response = self.client.get( reverse('chat:history'), {'chat_id': chat_id}, follow=True ) json_content = json.loads(response.content) self.assertIsNone(json_content['input']['options']) self.assertEquals(len(json_content['addMessages']), 4)
class FSMTests(OurTestCase): """ Tests for FSM stack. """ def setUp(self): self.user = User.objects.create_user( username='******', email='jacob@_', password='******' ) # have to login or Django self.client.session storage won't work self.client.login(username='******', password='******') self.course = Course( title='Great Course', description='the bestest', addedBy=self.user ) self.course.save() self.unit = Unit(title='My Courselet', addedBy=self.user) self.unit.save() self.lesson = Lesson( title='Big Deal', text='very interesting info', addedBy=self.user ) self.lesson.save_root() self.unitLesson = UnitLesson.create_from_lesson( self.lesson, self.unit, order='APPEND' ) self.ulQ = create_question_unit(self.user) self.ulQ2 = create_question_unit( self.user, 'Pretest', 'Scary Question', 'Tell me something.' ) self.json_mixin = JSONBlobMixin() self.fsmDict = dict(name='test', title='try this') self.nodeDict = dict( START=dict(title='start here', path='ct:home', funcName='fsm.fsm_plugin.testme.START'), MID=dict(title='in the middle', path='ct:about', doLogging=True), END=dict(title='end here', path='ct:home') ) self.edgeDict = ( dict(name='next', fromNode='START', toNode='END', title='go go go'), dict(name='select_Lesson', fromNode='MID', toNode='MID', title='go go go'), ) def test_load(self): """ Check loading an FSM graph, and replacing it. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') self.assertEqual(f.fsmnode_set.count(), 3) self.assertEqual(f.startNode.name, 'START') self.assertEqual(f.startNode.outgoing.count(), 1) e = f.startNode.outgoing.all()[0] self.assertEqual(e.name, 'next') self.assertEqual(e.toNode.name, 'END') f2 = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') # replace self.assertEqual(FSM.objects.get(pk=f.pk).name, 'testOLD') # renamed self.assertNotEqual(f.startNode, f2.startNode) self.assertEqual(f.startNode.name, f2.startNode.name) def test_json_blob(self): """ Check roundtrip dump/load via json blob data. """ name, pk = self.json_mixin.dump_json_id(self.unit) label, obj = self.json_mixin.load_json_id(name, pk) self.assertEqual(self.unit, obj) self.assertEqual(label, 'Unit') def test_json_blob2(self): """ Check roundtrip dump/load via named json blob data. """ name, pk = self.json_mixin.dump_json_id(self.unit, 'fruity') self.assertEqual(name, 'fruity_Unit_id') label, obj = self.json_mixin.load_json_id(name, pk) self.assertEqual(self.unit, obj) self.assertEqual(label, 'fruity') def test_json_blob3(self): """ Check roundtrip dump/load via json blob string. """ s = self.json_mixin.dump_json_id_dict(dict(fruity=self.unit)) d = self.json_mixin.load_json_id_dict(s) self.assertEqual(list(d.items()), [('fruity', self.unit)]) def test_json_blob4(self): """ Check roundtrip dump/load via db storage. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') d = f.startNode.load_json_data() self.assertEqual(d, {}) d['fruity'] = self.unit d['anumber'] = 3 d['astring'] = 'jeff' f.startNode.save_json_data(d) node = FSMNode.objects.get(pk=f.startNode.pk) d2 = node.load_json_data() self.assertEqual(d2, {'fruity': self.unit, 'anumber': 3, 'astring': 'jeff'}) def test_start(self): """ Check basic startup of new FSM instance. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') self.do_start(f) def test_start2(self): """ Check basic startup of new FSM instance using FSMSpecification. """ from fsm.fsm_plugin.testme import get_specs spec = get_specs()[0] f = spec.save_graph('jacob') self.assertTrue(f.startNode.doLogging) self.assertFalse(f.get_node('MID').doLogging) fsmStack = self.do_start(f) # test filter_input() plugin functionality edge = fsmStack.state.fsmNode.outgoing.get(name='next') self.assertTrue(edge.filter_input('the right stuff')) self.assertFalse(edge.filter_input('the WRONG stuff')) # test get_help() plugin functionality request = FakeRequest(self.user, path='/ct/about/') msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, 'here here!') request = FakeRequest(self.user, path='/ct/courses/1/') msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, 'there there') request = FakeRequest(self.user) msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, None) def test_start3(self): """ Check that FSMState saves unitLesson, select_ data, and logging. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') fsmStack = self.do_start(f, unitLesson=self.unitLesson) self.assertEqual(fsmStack.state.unitLesson, self.unitLesson) request = FakeRequest(self.user, method='GET') # check logging on the MID node fsmStack.event(request, None) # send a render event to log self.assertEqual(fsmStack.state.activity.fsmName, 'test') ae = fsmStack.state.activityEvent self.assertEqual(ae.nodeName, 'MID') self.assertEqual(ae.unitLesson, self.unitLesson) self.assertIsNotNone(ae.startTime) self.assertIsNone(ae.endTime) request = FakeRequest(self.user) # now try a select_ event fsmStack.event(request, 'select_Lesson', lesson=self.lesson) self.assertEqual(fsmStack.state.get_data_attr('lesson'), self.lesson) # check that exit from MID node was logged self.assertIsNotNone(ae.endTime) self.assertTrue(ae.endTime > ae.startTime) self.assertEqual(ae.exitEvent, 'select_Lesson') self.assertIsNone(fsmStack.state.activityEvent) def do_start(self, f, **kwargs): """ Run tests of basic startup of new FSM instance. """ fsmData = dict(unit=self.unit, foo='bar') request = FakeRequest(self.user) fsmStack = FSMStack(request) self.assertIsNone(fsmStack.state) try: result = fsmStack.push(request, 'invalid', stateData=fsmData, **kwargs) except FSM.DoesNotExist: pass else: raise AssertionError('failed to catch bad FSM query') result = fsmStack.push(request, 'test', stateData=fsmData, **kwargs) self.assertEqual(request.session['fsmID'], fsmStack.state.pk) self.assertEqual(fsmStack.state.load_json_data(), fsmData) self.assertEqual(fsmStack.state.fsmNode.name, 'MID') self.assertEqual(fsmStack.state.fsmNode.path, 'ct:about') self.assertEqual(fsmStack.state.fsmNode.get_path( fsmStack.state, request ), '/ct/about/') self.assertEqual(result, '/ct/about/') return fsmStack def test_trivial_plugin(self): """ Check trivial plugin import and call. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') request = FakeRequest(self.user) fsmStack = FSMStack(request) fsmStack.state = FSMState(user=self.user, fsmNode=f.startNode) self.assertEqual(f.startNode.event(fsmStack, request, 'start'), '/ct/about/') self.assertEqual(f.startNode.get_path(fsmStack.state, request), '/ct/some/where/else/') def test_bad_funcName(self): """ Check that FSM.save_graph() catches bad plugin funcName. """ nodeDictBad = dict( START=dict(title='start here', path='ct:home', funcName='fsm.fsm_plugin.testme.invalid') ) try: FSM.save_graph(self.fsmDict, nodeDictBad, (), 'jacob') except AttributeError: pass else: raise AssertionError('FSM.save_graph() failed to catch bad plugin funcName') def test_bad_fsmID(self): """ Make sure FSMStack silently handles bad fsmID. """ request = FakeRequest(self.user, dict(fsmID=99)) fsmStack = FSMStack(request) self.assertEqual(request.session, {}) self.assertIsNone(fsmStack.state) def test_randomtrial(self): """ Basic randomized trial. """ self.assertEqual(self.ulQ.order, 0) from ct.fsm_plugin.lessonseq import get_specs f = get_specs()[0].save_graph(self.user.username) # load FSM spec from ct.fsm_plugin.randomtrial import get_specs f = get_specs()[0].save_graph(self.user.username) # load FSM spec self.assertEqual(ActivityLog.objects.count(), 0) fsmData = dict(testFSM='lessonseq', treatmentFSM='lessonseq', treatment1=self.ulQ.unit, treatment2=self.ulQ.unit, testUnit=self.ulQ2.unit, course=self.course) request, fsmStack, result = self.get_fsm_request( 'randomtrial', fsmData, dict(trialName='test') ) self.assertEqual(self.client.session['fsmID'], fsmStack.state.pk) self.assertEqual(result, '/fsm/nodes/%d/' % f.startNode.pk) self.assertEqual(ActivityLog.objects.count(), 1) # rt FSM start page response = self.client.get(result) self.assertEqual(response.status_code, 200) self.assertContains(response, 'answer a few preliminary questions') url = '/ct/courses/%d/units/%d/lessons/%d/ask/' \ % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk) self.check_post_get(result, dict(fsmtask='next'), url, 'Scary Question') # pretest Q postdata = dict(text='i dunno', confidence=Response.GUESS) url = self.check_post_get(url, postdata, '/assess/', 'write an answer') # pretest assess assessPOST = dict(selfeval=Response.CORRECT, status=DONE_STATUS, liked='') url2 = '/ct/courses/%d/units/%d/lessons/%d/ask/' \ % (self.course.pk, self.ulQ.unit.pk, self.ulQ.pk) self.check_post_get(url, assessPOST, url2, 'your quest') # treatment Q postdata = dict(text='i like rats', confidence=Response.GUESS) url = self.check_post_get(url2, postdata, '/assess/', 'write an answer') # treatment assess url2 = '/ct/courses/%d/units/%d/lessons/%d/ask/' \ % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk) self.check_post_get(url, assessPOST, url2, 'Scary Question') # posttest Q postdata = dict(text='i still dunno', confidence=Response.GUESS) url = self.check_post_get(url2, postdata, '/assess/', 'write an answer') # posttest assess url2 = '/ct/courses/%d/units/%d/tasks/' \ % (self.course.pk, self.ulQ.unit.pk) self.check_post_get(url, assessPOST, url2, 'Next Step to work on') self.assertEqual(Response.objects.filter(activity__isnull=False, confidence=Response.GUESS). count(), 3) # check responses logged to RT activity def test_slideshow(self): """ Basic slide show FSM. """ from ct.fsm_plugin.slideshow import get_specs get_specs()[0].save_graph(self.user.username) # load FSM spec fsmData = dict(unit=self.ulQ2.unit, course=self.course) request, fsmStack, result = self.get_fsm_request('slideshow', fsmData) self.assertEqual(result, '/ct/courses/%d/units/%d/lessons/%d/read/' % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk)) # start page = question response = self.client.get(result) self.assertEqual(response.status_code, 200) self.assertContains(response, 'Scary Question') # answer page answer = self.ulQ2.get_answers()[0] url = '/ct/courses/%d/units/%d/lessons/%d/read/' \ % (self.course.pk, self.ulQ2.unit.pk, answer.pk) self.check_post_get(result, dict(fsmtask='next'), url, 'an answer') # end of slide show should dump us on concepts page url2 = '/ct/courses/%d/units/%d/concepts/' % (self.course.pk, self.ulQ2.unit.pk) self.check_post_get(url, dict(fsmtask='next'), url2, 'Pretest') def get_fsm_request(self, fsmName, stateData, startArgs=None, **kwargs): """ Create request, fsmStack and start specified FSM. """ startArgs = startArgs or {} request = FakeRequest(self.user) request.session = self.client.session fsmStack = FSMStack(request) result = fsmStack.push(request, fsmName, stateData, startArgs, **kwargs) request.session.save() return request, fsmStack, result
class FSMTests(OurTestCase): """ Tests for FSM stack. """ def setUp(self): self.user = User.objects.create_user( username='******', email='jacob@_', password='******' ) # have to login or Django self.client.session storage won't work self.client.login(username='******', password='******') self.course = Course( title='Great Course', description='the bestest', addedBy=self.user ) self.course.save() self.unit = Unit(title='My Courselet', addedBy=self.user) self.unit.save() self.lesson = Lesson( title='Big Deal', text='very interesting info', addedBy=self.user ) self.lesson.save_root() self.unitLesson = UnitLesson.create_from_lesson( self.lesson, self.unit, order='APPEND' ) self.ulQ = create_question_unit(self.user) self.ulQ2 = create_question_unit( self.user, 'Pretest', 'Scary Question', 'Tell me something.' ) self.json_mixin = JSONBlobMixin() self.fsmDict = dict(name='test', title='try this') self.nodeDict = dict( START=dict(title='start here', path='ct:home', funcName='fsm.fsm_plugin.testme.START'), MID=dict(title='in the middle', path='ct:about', doLogging=True), END=dict(title='end here', path='ct:home') ) self.edgeDict = ( dict(name='next', fromNode='START', toNode='END', title='go go go'), dict(name='select_Lesson', fromNode='MID', toNode='MID', title='go go go'), ) def test_load(self): """ Check loading an FSM graph, and replacing it. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') self.assertEqual(f.fsmnode_set.count(), 3) self.assertEqual(f.startNode.name, 'START') self.assertEqual(f.startNode.outgoing.count(), 1) e = f.startNode.outgoing.all()[0] self.assertEqual(e.name, 'next') self.assertEqual(e.toNode.name, 'END') f2 = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') # replace self.assertEqual(FSM.objects.get(pk=f.pk).name, 'testOLD') # renamed self.assertNotEqual(f.startNode, f2.startNode) self.assertEqual(f.startNode.name, f2.startNode.name) def test_json_blob(self): """ Check roundtrip dump/load via json blob data. """ name, pk = self.json_mixin.dump_json_id(self.unit) label, obj = self.json_mixin.load_json_id(name, pk) self.assertEqual(self.unit, obj) self.assertEqual(label, 'Unit') def test_json_blob2(self): """ Check roundtrip dump/load via named json blob data. """ name, pk = self.json_mixin.dump_json_id(self.unit, 'fruity') self.assertEqual(name, 'fruity_Unit_id') label, obj = self.json_mixin.load_json_id(name, pk) self.assertEqual(self.unit, obj) self.assertEqual(label, 'fruity') def test_json_blob3(self): """ Check roundtrip dump/load via json blob string. """ s = self.json_mixin.dump_json_id_dict(dict(fruity=self.unit)) d = self.json_mixin.load_json_id_dict(s) self.assertEqual(d.items(), [('fruity', self.unit)]) def test_json_blob4(self): """ Check roundtrip dump/load via db storage. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') d = f.startNode.load_json_data() self.assertEqual(d, {}) d['fruity'] = self.unit d['anumber'] = 3 d['astring'] = 'jeff' f.startNode.save_json_data(d) node = FSMNode.objects.get(pk=f.startNode.pk) d2 = node.load_json_data() self.assertEqual(d2, {'fruity': self.unit, 'anumber': 3, 'astring': 'jeff'}) def test_start(self): """ Check basic startup of new FSM instance. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') self.do_start(f) def test_start2(self): """ Check basic startup of new FSM instance using FSMSpecification. """ from fsm.fsm_plugin.testme import get_specs spec = get_specs()[0] f = spec.save_graph('jacob') self.assertTrue(f.startNode.doLogging) self.assertFalse(f.get_node('MID').doLogging) fsmStack = self.do_start(f) # test filter_input() plugin functionality edge = fsmStack.state.fsmNode.outgoing.get(name='next') self.assertTrue(edge.filter_input('the right stuff')) self.assertFalse(edge.filter_input('the WRONG stuff')) # test get_help() plugin functionality request = FakeRequest(self.user, path='/ct/about/') msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, 'here here!') request = FakeRequest(self.user, path='/ct/courses/1/') msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, 'there there') request = FakeRequest(self.user) msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, None) def test_start3(self): """ Check that FSMState saves unitLesson, select_ data, and logging. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') fsmStack = self.do_start(f, unitLesson=self.unitLesson) self.assertEqual(fsmStack.state.unitLesson, self.unitLesson) request = FakeRequest(self.user, method='GET') # check logging on the MID node fsmStack.event(request, None) # send a render event to log self.assertEqual(fsmStack.state.activity.fsmName, 'test') ae = fsmStack.state.activityEvent self.assertEqual(ae.nodeName, 'MID') self.assertEqual(ae.unitLesson, self.unitLesson) self.assertIsNotNone(ae.startTime) self.assertIsNone(ae.endTime) request = FakeRequest(self.user) # now try a select_ event fsmStack.event(request, 'select_Lesson', lesson=self.lesson) self.assertEqual(fsmStack.state.get_data_attr('lesson'), self.lesson) # check that exit from MID node was logged self.assertIsNotNone(ae.endTime) self.assertTrue(ae.endTime > ae.startTime) self.assertEqual(ae.exitEvent, 'select_Lesson') self.assertIsNone(fsmStack.state.activityEvent) def do_start(self, f, **kwargs): """ Run tests of basic startup of new FSM instance. """ fsmData = dict(unit=self.unit, foo='bar') request = FakeRequest(self.user) fsmStack = FSMStack(request) self.assertIsNone(fsmStack.state) try: result = fsmStack.push(request, 'invalid', stateData=fsmData, **kwargs) except FSM.DoesNotExist: pass else: raise AssertionError('failed to catch bad FSM query') result = fsmStack.push(request, 'test', stateData=fsmData, **kwargs) self.assertEqual(request.session['fsmID'], fsmStack.state.pk) self.assertEqual(fsmStack.state.load_json_data(), fsmData) self.assertEqual(fsmStack.state.fsmNode.name, 'MID') self.assertEqual(fsmStack.state.fsmNode.path, 'ct:about') self.assertEqual(fsmStack.state.fsmNode.get_path( fsmStack.state, request ), '/ct/about/') self.assertEqual(result, '/ct/about/') return fsmStack def test_trivial_plugin(self): """ Check trivial plugin import and call. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, 'jacob') request = FakeRequest(self.user) fsmStack = FSMStack(request) fsmStack.state = FSMState(user=self.user, fsmNode=f.startNode) self.assertEqual(f.startNode.event(fsmStack, request, 'start'), '/ct/about/') self.assertEqual(f.startNode.get_path(fsmStack.state, request), '/ct/some/where/else/') def test_bad_funcName(self): """ Check that FSM.save_graph() catches bad plugin funcName. """ nodeDictBad = dict( START=dict(title='start here', path='ct:home', funcName='fsm.fsm_plugin.testme.invalid') ) try: FSM.save_graph(self.fsmDict, nodeDictBad, (), 'jacob') except AttributeError: pass else: raise AssertionError('FSM.save_graph() failed to catch bad plugin funcName') def test_bad_fsmID(self): """ Make sure FSMStack silently handles bad fsmID. """ request = FakeRequest(self.user, dict(fsmID=99)) fsmStack = FSMStack(request) self.assertEqual(request.session, {}) self.assertIsNone(fsmStack.state) def test_randomtrial(self): """ Basic randomized trial. """ self.assertEqual(self.ulQ.order, 0) from ct.fsm_plugin.lessonseq import get_specs f = get_specs()[0].save_graph(self.user.username) # load FSM spec from ct.fsm_plugin.randomtrial import get_specs f = get_specs()[0].save_graph(self.user.username) # load FSM spec self.assertEqual(ActivityLog.objects.count(), 0) fsmData = dict(testFSM='lessonseq', treatmentFSM='lessonseq', treatment1=self.ulQ.unit, treatment2=self.ulQ.unit, testUnit=self.ulQ2.unit, course=self.course) request, fsmStack, result = self.get_fsm_request( 'randomtrial', fsmData, dict(trialName='test') ) self.assertEqual(self.client.session['fsmID'], fsmStack.state.pk) self.assertEqual(result, '/fsm/nodes/%d/' % f.startNode.pk) self.assertEqual(ActivityLog.objects.count(), 1) # rt FSM start page response = self.client.get(result) self.assertEqual(response.status_code, 200) self.assertContains(response, 'answer a few preliminary questions') url = '/ct/courses/%d/units/%d/lessons/%d/ask/' \ % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk) self.check_post_get(result, dict(fsmtask='next'), url, 'Scary Question') # pretest Q postdata = dict(text='i dunno', confidence=Response.GUESS) url = self.check_post_get(url, postdata, '/assess/', 'write an answer') # pretest assess assessPOST = dict(selfeval=Response.CORRECT, status=DONE_STATUS, liked='') url2 = '/ct/courses/%d/units/%d/lessons/%d/ask/' \ % (self.course.pk, self.ulQ.unit.pk, self.ulQ.pk) self.check_post_get(url, assessPOST, url2, 'your quest') # treatment Q postdata = dict(text='i like rats', confidence=Response.GUESS) url = self.check_post_get(url2, postdata, '/assess/', 'write an answer') # treatment assess url2 = '/ct/courses/%d/units/%d/lessons/%d/ask/' \ % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk) self.check_post_get(url, assessPOST, url2, 'Scary Question') # posttest Q postdata = dict(text='i still dunno', confidence=Response.GUESS) url = self.check_post_get(url2, postdata, '/assess/', 'write an answer') # posttest assess url2 = '/ct/courses/%d/units/%d/tasks/' \ % (self.course.pk, self.ulQ.unit.pk) self.check_post_get(url, assessPOST, url2, 'Next Step to work on') self.assertEqual(Response.objects.filter(activity__isnull=False, confidence=Response.GUESS). count(), 3) # check responses logged to RT activity def test_slideshow(self): """ Basic slide show FSM. """ from ct.fsm_plugin.slideshow import get_specs get_specs()[0].save_graph(self.user.username) # load FSM spec fsmData = dict(unit=self.ulQ2.unit, course=self.course) request, fsmStack, result = self.get_fsm_request('slideshow', fsmData) self.assertEqual(result, '/ct/courses/%d/units/%d/lessons/%d/read/' % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk)) # start page = question response = self.client.get(result) self.assertEqual(response.status_code, 200) self.assertContains(response, 'Scary Question') # answer page answer = self.ulQ2.get_answers()[0] url = '/ct/courses/%d/units/%d/lessons/%d/read/' \ % (self.course.pk, self.ulQ2.unit.pk, answer.pk) self.check_post_get(result, dict(fsmtask='next'), url, 'an answer') # end of slide show should dump us on concepts page url2 = '/ct/courses/%d/units/%d/concepts/' % (self.course.pk, self.ulQ2.unit.pk) self.check_post_get(url, dict(fsmtask='next'), url2, 'Pretest') def get_fsm_request(self, fsmName, stateData, startArgs=None, **kwargs): """ Create request, fsmStack and start specified FSM. """ startArgs = startArgs or {} request = FakeRequest(self.user) request.session = self.client.session fsmStack = FSMStack(request) result = fsmStack.push(request, fsmName, stateData, startArgs, **kwargs) request.session.save() return request, fsmStack, result
class SharedCoursesListViewTests(MyTestCase): def setUp(self): super(SharedCoursesListViewTests, self).setUp() self.unit2 = Unit(title='Test title2', addedBy=self.user) self.unit2.save() self.course2 = Course(title='Test title2', description='test description2', access='Public2', enrollCode='1112', lockout='1222', addedBy=self.user) self.course2.save() self.courseunit2 = CourseUnit( unit=self.unit2, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit2.save() self.courseunit3 = CourseUnit( unit=self.unit, course=self.course2, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit3.save() enroll_unit_code = EnrollUnitCode.get_code(self.courseunit, give_instance=True) enroll_unit_code2 = EnrollUnitCode.get_code(self.courseunit2, give_instance=True) enroll_unit_code3 = EnrollUnitCode.get_code(self.courseunit3, give_instance=True) self.tester_shared_course = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course, enroll_unit_code=enroll_unit_code ) self.tester_shared_course2 = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course, enroll_unit_code=enroll_unit_code2 ) self.tester_shared_course3 = Invite.create_new( invite_type='tester', commit=True, instructor=self.instructor2, email=self.user.email, course=self.course2, enroll_unit_code=enroll_unit_code3 ) self.url = reverse('ctms:shared_courses') def get_invite_by_id(self, id): return Invite.objects.get(id=id) def test_shared_courses_list(self): response = self.client.get(self.url) self.assertEquals( reverse('ctms:shared_courses'), response.context['shared_courses'][self.course.title]['link'] ) self.assertEquals( reverse('ctms:tester_join_course', kwargs={'code': self.tester_shared_course3.code}), response.context['shared_courses'][self.course2.title]['link'] ) def test_join_course(self): url = reverse('ctms:tester_join_course', kwargs={'code': self.tester_shared_course.code}) response = self.client.get(url) self.assertRedirects( response, reverse('chat:tester_chat_enroll', kwargs={'enroll_key': self.tester_shared_course.enroll_unit_code.enrollCode}) ) invite = self.get_invite_by_id(self.tester_shared_course.id) self.assertEqual(invite.status, 'joined') self.join_course_cases(url, self.tester_shared_course) def join_course_cases(self, url, invite): # if invited user is already registered but not logged in - login form must be shown self.client.logout() response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn('form', response.context) self.assertTrue(isinstance(response.context['form'], EmailLoginForm)) self.assertEqual(response.context['form'].initial['email'], invite.email) self.assertIn('u_hash', response.context['form'].initial) # if no such user invite.email = '*****@*****.**' invite.save() response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn('form', response.context) self.assertTrue(isinstance(response.context['form'], SignUpForm)) self.assertEqual(response.context['form'].initial['email'], invite.email) self.assertIn('u_hash', response.context['form'].initial) # if user registered after sending invitation - login form must be shown User.objects.create_user('asdasd', '*****@*****.**', '123') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertIn('form', response.context) self.assertTrue(isinstance(response.context['form'], EmailLoginForm)) self.assertEqual(response.context['form'].initial['email'], invite.email) self.assertIn('u_hash', response.context['form'].initial) def student_join_course(self): url = reverse('ctms:tester_join_course', kwargs={'code': self.student_shared_course.code}) response = self.client.get(url) self.assertRedirects( response, reverse('lms:course_view', kwargs={'course_id': self.student_shared_course.course.id}) ) invite = self.get_invite_by_id(self.tester_shared_course.id) self.assertEqual(invite.status, 'joined') self.join_course_cases(url, self.student_shared_course)
class TagsTest(TestCase): def setUp(self): self.user = User.objects.create_user(username='******', password='******') self.course = Course(title='test_title', addedBy=self.user) self.course.save() self.concept = Concept(title='test title', addedBy=self.user) self.concept.save() self.lesson = Lesson(title='ugh', text='brr', addedBy=self.user, kind=Lesson.ORCT_QUESTION) self.lesson.save_root() self.lesson.add_concept_link(self.concept, ConceptLink.TESTS, self.user) self.unit = Unit(title='test unit title', addedBy=self.user) self.unit.save() self.unit_lesson = UnitLesson(unit=self.unit, addedBy=self.user, treeID=42, lesson=self.lesson) self.unit_lesson.save() self.response = Response(course=self.course, lesson=self.lesson, author=self.user, unitLesson=self.unit_lesson, confidence=Response.GUESS, title='test title', text='test text') self.response.save() self.context = { 'actionTarget': '/ct/courses/1/units/1/', 'ul': self.unit_lesson, 'test_text': 'This is a test text', 'r': self.response } def render_template(self, string, context=None): context = context or {} context = Context(context) return Template(string).render(context) @unpack @data( ('{{ test_text | md2html }}', '<p>This is a test text</p>\n'), ('{{ actionTarget | get_object_url:ul }}', '/ct/courses/1/units/1/lessons/1/'), ('{{ actionTarget | get_home_url:ul }}', '/ct/courses/1/units/1/lessons/1/'), ('{{ actionTarget | get_thread_url:r }}', '/ct/courses/1/units/1/lessons/1/faq/1/'), ('{{ actionTarget | get_tasks_url:ul }}', '/ct/courses/1/units/1/lessons/1/tasks/'), ('{{ actionTarget | get_dummy_navbar }}', '<li><a href="/ct/courses/1/">Course</a></li>'), ) def test_all_filters(self, template_variable, expected_result): rendered = self.render_template('{% load ct_extras %}' + template_variable, context=self.context) self.assertEqual(rendered, expected_result) @patch('ct.templatetags.ct_extras.pypandoc') def test_md2html_pandoc_exception(self, pypandoc): pypandoc.convert.side_effect = StandardError rendered = self.render_template( '{% load ct_extras %}' '{{ test_text | md2html }}', context=self.context) self.assertEqual(rendered, self.context['test_text']) @data('get_base_url', 'get_path_type') def test_get_base_url_exception(self, helper): with self.assertRaises(ValueError): getattr(inspect.getmodule(self), helper).__call__('/ct/courses/1/units/1/lessons/1/', baseToken='non_existent_token') def test_get_object_url_exception(self): self.context[ 'ul'] = self.unit # Unit object does not have get_url method rendered = self.render_template( '{% load ct_extras %}' '{{ actionTarget | get_object_url:ul }}', context=self.context) self.assertEqual(rendered, '/ct/courses/1/units/1/unit/1/teach/') @patch('ct.templatetags.ct_extras.timezone') def test_display_datetime(self, timezone_patched): saved_time = timezone.now() timezone_patched.now.return_value = saved_time context = {'dt': saved_time - timedelta(1)} rendered = self.render_template( '{% load ct_extras %}' '{{ dt|display_datetime }}', context=context) self.assertEqual(rendered, '1 day ago') def test_find_audio(self): result = find_audio('test tag head .. audio:: test tag tail \n', 4) self.assertEqual(result, (14, 39, 'test tag tail')) def test_audio_html(self): """ Function should return string for embeding audio into html. """ result = audio_html('audio.mp3') self.assertEqual( result, '''<audio controls><source src="audio.ogg" type="audio/ogg"><source src="audio.mp3" ''' '''type="audio/mpeg">no support for audio!</audio>''') def test_video_html(self): """ Function should return string for embeding youtube or vimeo link. """ result = video_html('youtube:test_video_path') self.assertIn('test_video_path', result) self.assertIn('src="https://www.youtube.com/embed/', result) result = video_html('vimeo:test_video_path') self.assertIn('test_video_path', result) self.assertIn('src="https://player.vimeo.com/video/', result) def test_video_html_with_exception(self): """ Test exception handling. """ result = video_html('youtube') self.assertEqual(result, 'ERROR: bad video source: youtube') result = video_html('some_new_cdn:test_video_path') self.assertEqual(result, 'ERROR: unknown video sourceDB: some_new_cdn') def test_add_replace_temporary_markers(self): """ Test add_temporary_markers and replace_temporary_markers in tandem. """ result = add_temporary_markers( 'test tag head .. audio:: test tag tail \n', find_audio) self.assertEqual( result, ('test tag head mArKeR:0:\n', [('mArKeR:0:', 'test tag tail')])) result = replace_temporary_markers(result[0], audio_html, result[1]) self.assertEqual( result, '''test tag head <audio controls><source src="test tag tail.ogg" type="audio/ogg">''' '''<source src="test tag tail.mp3" type="audio/mpeg">no support for audio!</audio>\n''' )
def setUp(self): """ Preconditions. """ from chat.fsm_plugin.chat import get_specs from chat.fsm_plugin.additional import get_specs as get_specs_additional self.client = Client() self.user = User.objects.create_user('test', '*****@*****.**', 'test') get_specs()[0].save_graph(self.user.username) get_specs_additional()[0].save_graph(self.user.username) mocked_nonce = u'135685044251684026041377608307' mocked_timestamp = u'1234567890' mocked_decoded_signature = u'my_signature=' self.headers = { u'user_id': 1, u'lis_person_name_full': u'Test Username', u'lis_person_name_given': u'First', u'lis_person_name_family': u'Second', u'lis_person_contact_email_primary': u'*****@*****.**', u'lis_person_sourcedid': u'Test_Username', u'oauth_callback': u'about:blank', u'launch_presentation_return_url': '', u'lti_message_type': u'basic-lti-launch-request', u'lti_version': 'LTI-1p0', u'roles': u'Student', u'context_id': 1, u'tool_consumer_info_product_family_code': u'moodle', u'context_title': u'Test title', u'tool_consumer_instance_guid': u'test.dot.com', u'resource_link_id': 'dfgsfhrybvrth', u'lis_result_sourcedid': 'wesgaegagrreg', u'oauth_nonce': mocked_nonce, u'oauth_timestamp': mocked_timestamp, u'oauth_consumer_key': u'consumer_key', u'oauth_signature_method': u'HMAC-SHA1', u'oauth_version': u'1.0', u'oauth_signature': mocked_decoded_signature } self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.course_ref = CourseRef( course=self.course, context_id=self.headers.get('context_id'), tc_guid=self.headers.get('tool_consumer_instance_guid') ) self.course_ref.save() self.course_ref.instructors.add(self.user) self.role1 = Role( role=Role.ENROLLED, user=self.user, course=self.course, ) self.role1.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() lesson = Lesson(title='title', text='text', addedBy=self.user) lesson.save() unitlesson = UnitLesson( unit=self.unit, order=0, lesson=lesson, addedBy=self.user, treeID=lesson.id ) unitlesson.save() self.lti_consumer = LtiConsumer( consumer_name='test', consumer_key='consumer_key', consumer_secret='test_key' ) self.lti_consumer.save()
def setUp(self): """ Preconditions. """ from chat.fsm_plugin.chat import get_specs from chat.fsm_plugin.additional import get_specs as get_specs_additional self.client = Client() self.user = User.objects.create_user('test', '*****@*****.**', 'test') get_specs()[0].save_graph(self.user.username) get_specs_additional()[0].save_graph(self.user.username) mocked_nonce = '135685044251684026041377608307' mocked_timestamp = '1234567890' mocked_decoded_signature = 'my_signature=' self.headers = { 'user_id': 1, 'lis_person_name_full': 'Test Username', 'lis_person_name_given': 'First', 'lis_person_name_family': 'Second', 'lis_person_contact_email_primary': '*****@*****.**', 'lis_person_sourcedid': 'Test_Username', 'oauth_callback': 'about:blank', 'launch_presentation_return_url': '', 'lti_message_type': 'basic-lti-launch-request', 'lti_version': 'LTI-1p0', 'roles': 'Student', 'context_id': 1, 'tool_consumer_info_product_family_code': 'moodle', 'context_title': 'Test title', 'tool_consumer_instance_guid': 'test.dot.com', 'resource_link_id': 'dfgsfhrybvrth', 'lis_result_sourcedid': 'wesgaegagrreg', 'oauth_nonce': mocked_nonce, 'oauth_timestamp': mocked_timestamp, 'oauth_consumer_key': 'consumer_key', 'oauth_signature_method': 'HMAC-SHA1', 'oauth_version': '1.0', 'oauth_signature': mocked_decoded_signature } self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.course_ref = CourseRef( course=self.course, context_id=self.headers.get('context_id'), tc_guid=self.headers.get('tool_consumer_instance_guid')) self.course_ref.save() self.course_ref.instructors.add(self.user) self.role1 = Role( role=Role.ENROLLED, user=self.user, course=self.course, ) self.role1.save() self.courseunit = CourseUnit(unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now()) self.courseunit.save() lesson = Lesson(title='title', text='text', addedBy=self.user) lesson.save() unitlesson = UnitLesson(unit=self.unit, order=0, lesson=lesson, addedBy=self.user, treeID=lesson.id) unitlesson.save() self.lti_consumer = LtiConsumer(consumer_name='test', consumer_key='consumer_key', consumer_secret='test_key') self.lti_consumer.save()
class MyCoursesTests(MyTestCase): def setUp(self): self.username, self.password = '******', 'test' self.user = User.objects.create_user('test', '*****@*****.**', 'test') self.instructor = Instructor.objects.create(user=self.user, institution='institute', what_do_you_teach='something') self.user2 = User.objects.create_user('test1', '*****@*****.**', 'test') self.instructor2 = Instructor.objects.create(user=self.user2, institution='institution', what_do_you_teach='something') self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() self.lesson = Lesson(title='title', text='text', addedBy=self.user) self.lesson.save() self.unitlesson = UnitLesson( unit=self.unit, order=0, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id ) self.unitlesson.save() self.client.login(username=self.username, password=self.password) self.url = reverse('ctms:my_courses') @mock.patch('ctms.views.get_onboarding_percentage') def test_get_my_courses_page(self, onboarding_percentage): onboarding_percentage.return_value = 100 response = self.client.get(self.url) # should contain 1 course self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'ctms/my_courses.html') self.assertIn('my_courses', response.context) self.assertIn(self.course, response.context['my_courses']) @mock.patch('ctms.views.get_onboarding_percentage') def test_my_courses_show_shared_courses(self, onboarding_percentage): onboarding_percentage.return_value = 100 self.course.addedBy = self.user2 self.course.save() # create shared course enroll_unit_code = EnrollUnitCode.get_code(self.courseunit, give_instance=True) shared_course = Invite.create_new(True, self.course, self.instructor2, self.user.email, 'tester', enroll_unit_code) response = self.client.get(reverse('ctms:shared_courses')) # should return shared courses self.assertIn('shared_courses', response.context) self.assertNotEqual(len(response.context['shared_courses']), 0) self.assertTrue(shared_course.course.title in response.context['shared_courses']) def my_courses_show_create_course_form(self): self.course.delete() response = self.client.get(self.url) # should return Course form self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'ctms/my_courses.html') self.assertIn('my_courses', response.context) self.assertIn('shared_courses', response.context) self.assertIn('course_form', response.context) self.assertFalse(len(response.context['my_courses']) < 0) def post_valid_create_course_form(self): courses_cnt = Course.objects.filter(addedBy=self.user).count() course_ids = [ i['id'] for i in Course.objects.filter(addedBy=self.user).values('id') ] data = { 'name': 'some course' } response = self.client.post(self.url, data) new_courses = Course.objects.filter(addedBy=self.user) new_course = new_courses.exclude(id__in=course_ids).get() self.assertEqual(new_courses.count(), courses_cnt) self.assertRedirects(response, reverse('ctms:course_view', kwargs={'course_id': new_course.id})) return response def post_invalid_create_course_form(self): courses_cnt = Course.objects.filter(addedBy=self.user).count() course_ids = [ i['id'] for i in Course.obget_courslet_view_logged_out_user_testjects.filter(addedBy=self.user).values('id') ] data = { 'name': '' } response = self.client.post(self.url, data) new_courses = Course.objects.filter(addedBy=self.user) new_course = new_courses.exclude(id__in=course_ids) self.assertNotEqual(new_courses.count(), courses_cnt) # course was not created self.assertEqual(len(new_course) == 0) self.assertTemplateUsed(response, 'ctms/my_courses.html') return response def post_valid_create_course_form_to_create_course_view(self): self.url = reverse('ctms:create_course') self.post_valid_create_course_form() def post_invalid_create_course_form_to_create_course_view(self): self.url = reverse('ctms:create_course') self.post_invalid_create_course_form()
class FSMTests(OurTestCase): """ Tests for FSM stack. """ def setUp(self): self.user = User.objects.create_user(username="******", email="jacob@_", password="******") # have to login or Django self.client.session storage won't work self.client.login(username="******", password="******") self.course = Course(title="Great Course", description="the bestest", addedBy=self.user) self.course.save() self.unit = Unit(title="My Courselet", addedBy=self.user) self.unit.save() self.lesson = Lesson(title="Big Deal", text="very interesting info", addedBy=self.user) self.lesson.save_root() self.unitLesson = UnitLesson.create_from_lesson(self.lesson, self.unit, order="APPEND") self.ulQ = create_question_unit(self.user) self.ulQ2 = create_question_unit(self.user, "Pretest", "Scary Question", "Tell me something.") self.json_mixin = JSONBlobMixin() self.fsmDict = dict(name="test", title="try this") self.nodeDict = dict( START=dict(title="start here", path="ct:home", funcName="fsm.fsm_plugin.testme.START"), MID=dict(title="in the middle", path="ct:about", doLogging=True), END=dict(title="end here", path="ct:home"), ) self.edgeDict = ( dict(name="next", fromNode="START", toNode="END", title="go go go"), dict(name="select_Lesson", fromNode="MID", toNode="MID", title="go go go"), ) def test_load(self): """ Check loading an FSM graph, and replacing it. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, "jacob") self.assertEqual(f.fsmnode_set.count(), 3) self.assertEqual(f.startNode.name, "START") self.assertEqual(f.startNode.outgoing.count(), 1) e = f.startNode.outgoing.all()[0] self.assertEqual(e.name, "next") self.assertEqual(e.toNode.name, "END") f2 = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, "jacob") # replace self.assertEqual(FSM.objects.get(pk=f.pk).name, "testOLD") # renamed self.assertNotEqual(f.startNode, f2.startNode) self.assertEqual(f.startNode.name, f2.startNode.name) def test_json_blob(self): """ Check roundtrip dump/load via json blob data. """ name, pk = self.json_mixin.dump_json_id(self.unit) label, obj = self.json_mixin.load_json_id(name, pk) self.assertEqual(self.unit, obj) self.assertEqual(label, "Unit") def test_json_blob2(self): """ Check roundtrip dump/load via named json blob data. """ name, pk = self.json_mixin.dump_json_id(self.unit, "fruity") self.assertEqual(name, "fruity_Unit_id") label, obj = self.json_mixin.load_json_id(name, pk) self.assertEqual(self.unit, obj) self.assertEqual(label, "fruity") def test_json_blob3(self): """ Check roundtrip dump/load via json blob string. """ s = self.json_mixin.dump_json_id_dict(dict(fruity=self.unit)) d = self.json_mixin.load_json_id_dict(s) self.assertEqual(d.items(), [("fruity", self.unit)]) def test_json_blob4(self): """ Check roundtrip dump/load via db storage. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, "jacob") d = f.startNode.load_json_data() self.assertEqual(d, {}) d["fruity"] = self.unit d["anumber"] = 3 d["astring"] = "jeff" f.startNode.save_json_data(d) node = FSMNode.objects.get(pk=f.startNode.pk) d2 = node.load_json_data() self.assertEqual(d2, {"fruity": self.unit, "anumber": 3, "astring": "jeff"}) def test_start(self): """ Check basic startup of new FSM instance. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, "jacob") self.do_start(f) def test_start2(self): """ Check basic startup of new FSM instance using FSMSpecification. """ from fsm.fsm_plugin.testme import get_specs spec = get_specs()[0] f = spec.save_graph("jacob") self.assertTrue(f.startNode.doLogging) self.assertFalse(f.get_node("MID").doLogging) fsmStack = self.do_start(f) # test filter_input() plugin functionality edge = fsmStack.state.fsmNode.outgoing.get(name="next") self.assertTrue(edge.filter_input("the right stuff")) self.assertFalse(edge.filter_input("the WRONG stuff")) # test get_help() plugin functionality request = FakeRequest(self.user, path="/ct/about/") msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, "here here!") request = FakeRequest(self.user, path="/ct/courses/1/") msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, "there there") request = FakeRequest(self.user) msg = fsmStack.state.fsmNode.get_help(fsmStack.state, request) self.assertEqual(msg, None) def test_start3(self): """ Check that FSMState saves unitLesson, select_ data, and logging. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, "jacob") fsmStack = self.do_start(f, unitLesson=self.unitLesson) self.assertEqual(fsmStack.state.unitLesson, self.unitLesson) request = FakeRequest(self.user, method="GET") # check logging on the MID node fsmStack.event(request, None) # send a render event to log self.assertEqual(fsmStack.state.activity.fsmName, "test") ae = fsmStack.state.activityEvent self.assertEqual(ae.nodeName, "MID") self.assertEqual(ae.unitLesson, self.unitLesson) self.assertIsNotNone(ae.startTime) self.assertIsNone(ae.endTime) request = FakeRequest(self.user) # now try a select_ event fsmStack.event(request, "select_Lesson", lesson=self.lesson) self.assertEqual(fsmStack.state.get_data_attr("lesson"), self.lesson) # check that exit from MID node was logged self.assertIsNotNone(ae.endTime) self.assertTrue(ae.endTime > ae.startTime) self.assertEqual(ae.exitEvent, "select_Lesson") self.assertIsNone(fsmStack.state.activityEvent) def do_start(self, f, **kwargs): """ Run tests of basic startup of new FSM instance. """ fsmData = dict(unit=self.unit, foo="bar") request = FakeRequest(self.user) fsmStack = FSMStack(request) self.assertIsNone(fsmStack.state) try: result = fsmStack.push(request, "invalid", stateData=fsmData, **kwargs) except FSM.DoesNotExist: pass else: raise AssertionError("failed to catch bad FSM query") result = fsmStack.push(request, "test", stateData=fsmData, **kwargs) self.assertEqual(request.session["fsmID"], fsmStack.state.pk) self.assertEqual(fsmStack.state.load_json_data(), fsmData) self.assertEqual(fsmStack.state.fsmNode.name, "MID") self.assertEqual(fsmStack.state.fsmNode.path, "ct:about") self.assertEqual(fsmStack.state.fsmNode.get_path(fsmStack.state, request), "/ct/about/") self.assertEqual(result, "/ct/about/") return fsmStack def test_trivial_plugin(self): """ Check trivial plugin import and call. """ f = FSM.save_graph(self.fsmDict, self.nodeDict, self.edgeDict, "jacob") request = FakeRequest(self.user) fsmStack = FSMStack(request) fsmStack.state = FSMState(user=self.user, fsmNode=f.startNode) self.assertEqual(f.startNode.event(fsmStack, request, "start"), "/ct/about/") self.assertEqual(f.startNode.get_path(fsmStack.state, request), "/ct/some/where/else/") def test_bad_funcName(self): """ Check that FSM.save_graph() catches bad plugin funcName. """ nodeDictBad = dict(START=dict(title="start here", path="ct:home", funcName="fsm.fsm_plugin.testme.invalid")) try: FSM.save_graph(self.fsmDict, nodeDictBad, (), "jacob") except AttributeError: pass else: raise AssertionError("FSM.save_graph() failed to catch bad plugin funcName") def test_bad_fsmID(self): """ Make sure FSMStack silently handles bad fsmID. """ request = FakeRequest(self.user, dict(fsmID=99)) fsmStack = FSMStack(request) self.assertEqual(request.session, {}) self.assertIsNone(fsmStack.state) def test_randomtrial(self): """ Basic randomized trial. """ self.assertEqual(self.ulQ.order, 0) from ct.fsm_plugin.lessonseq import get_specs f = get_specs()[0].save_graph(self.user.username) # load FSM spec from ct.fsm_plugin.randomtrial import get_specs f = get_specs()[0].save_graph(self.user.username) # load FSM spec self.assertEqual(ActivityLog.objects.count(), 0) fsmData = dict( testFSM="lessonseq", treatmentFSM="lessonseq", treatment1=self.ulQ.unit, treatment2=self.ulQ.unit, testUnit=self.ulQ2.unit, course=self.course, ) request, fsmStack, result = self.get_fsm_request("randomtrial", fsmData, dict(trialName="test")) self.assertEqual(self.client.session["fsmID"], fsmStack.state.pk) self.assertEqual(result, "/fsm/nodes/%d/" % f.startNode.pk) self.assertEqual(ActivityLog.objects.count(), 1) # rt FSM start page response = self.client.get(result) self.assertEqual(response.status_code, 200) self.assertContains(response, "answer a few preliminary questions") url = "/ct/courses/%d/units/%d/lessons/%d/ask/" % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk) self.check_post_get(result, dict(fsmtask="next"), url, "Scary Question") # pretest Q postdata = dict(text="i dunno", confidence=Response.GUESS) url = self.check_post_get(url, postdata, "/assess/", "write an answer") # pretest assess assessPOST = dict(selfeval=Response.CORRECT, status=DONE_STATUS, liked="") url2 = "/ct/courses/%d/units/%d/lessons/%d/ask/" % (self.course.pk, self.ulQ.unit.pk, self.ulQ.pk) self.check_post_get(url, assessPOST, url2, "your quest") # treatment Q postdata = dict(text="i like rats", confidence=Response.GUESS) url = self.check_post_get(url2, postdata, "/assess/", "write an answer") # treatment assess url2 = "/ct/courses/%d/units/%d/lessons/%d/ask/" % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk) self.check_post_get(url, assessPOST, url2, "Scary Question") # posttest Q postdata = dict(text="i still dunno", confidence=Response.GUESS) url = self.check_post_get(url2, postdata, "/assess/", "write an answer") # posttest assess url2 = "/ct/courses/%d/units/%d/tasks/" % (self.course.pk, self.ulQ.unit.pk) self.check_post_get(url, assessPOST, url2, "Next Step to work on") self.assertEqual( Response.objects.filter(activity__isnull=False, confidence=Response.GUESS).count(), 3 ) # check responses logged to RT activity def test_slideshow(self): """ Basic slide show FSM. """ from ct.fsm_plugin.slideshow import get_specs get_specs()[0].save_graph(self.user.username) # load FSM spec fsmData = dict(unit=self.ulQ2.unit, course=self.course) request, fsmStack, result = self.get_fsm_request("slideshow", fsmData) self.assertEqual( result, "/ct/courses/%d/units/%d/lessons/%d/read/" % (self.course.pk, self.ulQ2.unit.pk, self.ulQ2.pk) ) # start page = question response = self.client.get(result) self.assertEqual(response.status_code, 200) self.assertContains(response, "Scary Question") # answer page answer = self.ulQ2.get_answers()[0] url = "/ct/courses/%d/units/%d/lessons/%d/read/" % (self.course.pk, self.ulQ2.unit.pk, answer.pk) self.check_post_get(result, dict(fsmtask="next"), url, "an answer") # end of slide show should dump us on concepts page url2 = "/ct/courses/%d/units/%d/concepts/" % (self.course.pk, self.ulQ2.unit.pk) self.check_post_get(url, dict(fsmtask="next"), url2, "Pretest") def get_fsm_request(self, fsmName, stateData, startArgs=None, **kwargs): """ Create request, fsmStack and start specified FSM. """ startArgs = startArgs or {} request = FakeRequest(self.user) request.session = self.client.session fsmStack = FSMStack(request) result = fsmStack.push(request, fsmName, stateData, startArgs, **kwargs) request.session.save() return request, fsmStack, result
class MyTestCase(TestCase): models_to_check = tuple() context_should_contain_keys = tuple() def setUp(self): self.username, self.password = '******', 'test' self.user = User.objects.create_user(self.username, '*****@*****.**', self.password) self.instructor = Instructor.objects.create(user=self.user, institution='institute', what_do_you_teach='something') self.username2, self.password2 = 'test1', 'test' self.user2 = User.objects.create_user(self.username2, '*****@*****.**', self.password2) self.instructor2 = Instructor.objects.create(user=self.user2, institution='institute', what_do_you_teach='something') self.unit = Unit(title='Test title', addedBy=self.user) self.unit.save() self.course = Course(title='Test title', description='test description', access='Public', enrollCode='111', lockout='222', addedBy=self.user) self.course.save() self.courseunit = CourseUnit( unit=self.unit, course=self.course, order=0, addedBy=self.user, releaseTime=timezone.now() ) self.courseunit.save() self.lesson = Lesson(title='title', text='text', addedBy=self.user) self.lesson.save() self.unitlesson = UnitLesson( unit=self.unit, order=0, lesson=self.lesson, addedBy=self.user, treeID=self.lesson.id ) self.unitlesson.save() self.resp1 = Response( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, text="Some text user may respond", author=self.user, status=NEED_HELP_STATUS, selfeval=Response.DIFFERENT ) self.resp1.save() self.resp2 = Response( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, text="Some text user may be responded 2", author=self.user, status=NEED_HELP_STATUS, selfeval=Response.DIFFERENT ) self.resp2.save() self.default_data = {} self.client.login(username=self.username, password=self.password) self.url = reverse('ctms:course_settings', kwargs={'pk': self.course.id}) def get_page(self): return self.client.get(self.url) def post_data(self, data={'name': 'some test name'}): response = self.client.post(self.url, data, follow=True) return response def get_client_method(self, method='post'): client_method = getattr(self.client, method) if not client_method: raise KeyError('self.client has no property {}'.format(method)) return client_method def post_valid_data(self, data={'name': 'some test name'}, method='post'): client_method = self.get_client_method(method) copied_data = {} if getattr(self, 'default_data', False): copied_data.update(self.default_data) copied_data.update(data) response = client_method(self.url, copied_data, follow=True) return response def post_invalid_data(self, data={'name': ''}, method='post'): client_method = self.get_client_method(method) copied_data = {} if getattr(self, 'default_data', False): copied_data.update(self.default_data) copied_data.update(data) response = client_method(self.url, copied_data, follow=True) return response def get_my_courses(self): return Course.objects.filter(addedBy=self.user) def get_test_course(self): return Course.objects.get(id=self.course.id) def get_test_unitlessons(self): return self.courseunit.unit.unitlesson_set.filter( kind=UnitLesson.COMPONENT, order__isnull=False ).order_by('order').annotate( responses_count=models.Count('response') ) def get_test_unitlesson(self): return self.courseunit.unit.unitlesson_set.filter( kind=UnitLesson.COMPONENT, order__isnull=False ).order_by('order').annotate( responses_count=models.Count('response') )[0] get_test_courslet = get_test_unitlesson get_test_response = lambda self: self.get_test_responses()[0] def get_test_courseunit(self): return CourseUnit.objects.get(id=self.courseunit.id) def get_test_responses(self): return Response.objects.filter( unitLesson=self.unitlesson, kind=Response.ORCT_RESPONSE, lesson=self.lesson, course=self.course, ) def get_model_counts(self, **kwargs): if isinstance(self.models_to_check, (list, tuple)): return {model: model.objects.filter().count() for model in self.models_to_check} return {self.models_to_check: self.models_to_check.objects.filter().count()} def validate_model_counts(self, first_counts, second_counts, must_equal=False): if isinstance(self.models_to_check, (list, tuple)): all_models = self.models_to_check else: all_models = [self.models_to_check] for model in all_models: if must_equal: self.assertEqual( first_counts[model], second_counts[model], "{} ({}) != {} ({}), with must_equal={}".format( model, first_counts[model], model, second_counts[model], must_equal ) ) else: self.assertNotEqual( first_counts[model], second_counts[model], "{} ({}) == {} ({}), with must_equal={}".format( model, first_counts[model], model, second_counts[model], must_equal ) ) def check_context_keys(self, response): for key in self.context_should_contain_keys: self.assertIn(key, response.context) def am_i_instructor(self, method='GET'): methods_map = {'GET', self.client.get, 'POST', self.client.post} client_method = methods_map.get(method) self.assertIsNotNone(client_method) if getattr(self, 'url'): if getattr(self, 'NEED_INSTRUCTOR'): response = client_method(self.url) if getattr(self, 'instructor'): self.assertEqual(response.status_code, 200) self.instructor.delete() response = client_method(self.url) self.assertEqual(response.status_code, 403) else: self.assertEqual(response.status_code, 403) else: response = client_method(self.url) self.assertEqual(response.status_code, 200)