Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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()
Ejemplo n.º 5
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])
Ejemplo n.º 6
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])
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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()
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
0
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""",
        )
Ejemplo n.º 15
0
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)
Ejemplo n.º 16
0
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')
Ejemplo n.º 17
0
class LTITestCase(TestCase):
    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()
Ejemplo n.º 18
0
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)
Ejemplo n.º 19
0
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')
Ejemplo n.º 20
0
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
Ejemplo n.º 21
0
class LTITestCase(TestCase):
    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()
Ejemplo n.º 22
0
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
Ejemplo n.º 23
0
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'''
        )
Ejemplo n.º 24
0
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)