예제 #1
0
    def setUp(self):
        """
        Set up the for the course outline tests.
        """

        super(TestCourseReIndex, self).setUp()

        self.course.start = datetime.datetime(2014, 1, 1, tzinfo=pytz.utc)
        modulestore().update_item(self.course, self.user.id)

        self.chapter = ItemFactory.create(
            parent_location=self.course.location, category='chapter', display_name="Week 1"
        )
        self.sequential = ItemFactory.create(
            parent_location=self.chapter.location, category='sequential', display_name="Lesson 1"
        )
        self.vertical = ItemFactory.create(
            parent_location=self.sequential.location, category='vertical', display_name='Subsection 1'
        )
        self.video = ItemFactory.create(
            parent_location=self.vertical.location, category="video", display_name="My Video"
        )

        self.html = ItemFactory.create(
            parent_location=self.vertical.location, category="html", display_name="My HTML",
            data="<div>This is my unique HTML content</div>",

        )
    def setUpClass(cls):
        # Nose runs setUpClass methods even if a class decorator says to skip
        # the class: https://github.com/nose-devs/nose/issues/946
        # So, skip the test class here if we are not in the LMS.
        if settings.ROOT_URLCONF != 'lms.urls':
            raise unittest.SkipTest('Test only valid in lms')

        super(TestCrowdsourceHinter, cls).setUpClass()
        cls.course = CourseFactory.create(
            display_name='CrowdsourceHinter_Test_Course'
        )
        with cls.store.bulk_operations(cls.course.id, emit_signals=False):
            cls.chapter = ItemFactory.create(
                parent=cls.course, display_name='Overview'
            )
            cls.section = ItemFactory.create(
                parent=cls.chapter, display_name='Welcome'
            )
            cls.unit = ItemFactory.create(
                parent=cls.section, display_name='New Unit'
            )
            cls.xblock = ItemFactory.create(
                parent=cls.unit,
                category='crowdsourcehinter',
                display_name='crowdsourcehinter'
            )

        cls.course_url = reverse(
            'courseware_section',
            kwargs={
                'course_id': cls.course.id.to_deprecated_string(),
                'chapter': 'Overview',
                'section': 'Welcome',
            }
        )
    def setUp(self):

        self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course')
        self.overview_chapter = ItemFactory.create(display_name='Overview')
        self.courseware_chapter = ItemFactory.create(display_name='courseware')

        self.test_course = CourseFactory.create(number='666', display_name='Robot_Sub_Course')
        self.other_org_course = CourseFactory.create(org='Other_Org_Course')
        self.sub_courseware_chapter = ItemFactory.create(
            parent_location=self.test_course.location, display_name='courseware'
        )
        self.sub_overview_chapter = ItemFactory.create(
            parent_location=self.sub_courseware_chapter.location,
            display_name='Overview'
        )
        self.welcome_section = ItemFactory.create(
            parent_location=self.overview_chapter.location,
            display_name='Welcome'
        )

        self.global_staff_user = GlobalStaffFactory()
        self.unenrolled_user = UserFactory(last_name="Unenrolled")

        self.enrolled_user = UserFactory(last_name="Enrolled")
        CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.course.id)
        CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.test_course.id)

        self.staff_user = StaffFactory(course=self.course.location)
        self.instructor_user = InstructorFactory(
            course=self.course.location)
        self.org_staff_user = OrgStaffFactory(course=self.course.location)
        self.org_instructor_user = OrgInstructorFactory(
            course=self.course.location)
예제 #4
0
 def setUpClass(cls):
     super(TestGetProblemGradeDistribution, cls).setUpClass()
     cls.course = CourseFactory.create(
         display_name=u"test course omega \u03a9",
     )
     with cls.store.bulk_operations(cls.course.id, emit_signals=False):
         section = ItemFactory.create(
             parent_location=cls.course.location,
             category="chapter",
             display_name=u"test factory section omega \u03a9",
         )
         cls.sub_section = ItemFactory.create(
             parent_location=section.location,
             category="sequential",
             display_name=u"test subsection omega \u03a9",
         )
         cls.unit = ItemFactory.create(
             parent_location=cls.sub_section.location,
             category="vertical",
             metadata={'graded': True, 'format': 'Homework'},
             display_name=u"test unit omega \u03a9",
         )
         cls.items = []
         for i in xrange(USER_COUNT - 1):
             item = ItemFactory.create(
                 parent_location=cls.unit.location,
                 category="problem",
                 data=StringResponseXMLFactory().build_xml(answer='foo'),
                 metadata={'rerandomize': 'always'},
                 display_name=u"test problem omega \u03a9 " + str(i)
             )
             cls.items.append(item)
             cls.item = item
예제 #5
0
    def set_up_course(self, enable_subsection_grades=True):
        """
        Configures the course for this test.
        """
        # pylint: disable=attribute-defined-outside-init,no-member
        self.course = CourseFactory.create(
            org='edx',
            name='course',
            run='run',
        )
        if not enable_subsection_grades:
            PersistentGradesEnabledFlag.objects.create(enabled=False)

        self.chapter = ItemFactory.create(parent=self.course, category="chapter", display_name="Chapter")
        self.sequential = ItemFactory.create(parent=self.chapter, category='sequential', display_name="Open Sequential")
        self.problem = ItemFactory.create(parent=self.sequential, category='problem', display_name='problem')

        self.score_changed_kwargs = {
            'points_possible': 10,
            'points_earned': 5,
            'user': self.user,
            'course_id': unicode(self.course.id),
            'usage_id': unicode(self.problem.location),
        }

        # this call caches the anonymous id on the user object, saving 4 queries in all happy path tests
        _ = anonymous_id_for_user(self.user, self.course.id)
예제 #6
0
    def setUp(self):
        self.partition = UserPartition(
            0,
            'first_partition',
            'First Partition',
            [
                Group(0, 'alpha'),
                Group(1, 'beta')
            ]
        )

        self.course = CourseFactory.create(
            number=self.COURSE_NUMBER,
            user_partitions=[self.partition]
        )

        self.chapter = ItemFactory.create(
            parent_location=self.course.location,
            category="chapter",
            display_name="test chapter",
        )
        self.sequential = ItemFactory.create(
            parent_location=self.chapter.location,
            category="sequential",
            display_name="Split Test Tests",
        )

        self.student = UserFactory.create()
        CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
        self.client.login(username=self.student.username, password='******')
예제 #7
0
 def setUpClass(cls):
     super(GradesEventIntegrationTest, cls).setUpClass()
     cls.store = modulestore()
     with cls.store.default_store(ModuleStoreEnum.Type.split):
         cls.course = CourseFactory.create()
         cls.chapter = ItemFactory.create(
             parent=cls.course,
             category="chapter",
             display_name="Test Chapter"
         )
         cls.sequence = ItemFactory.create(
             parent=cls.chapter,
             category='sequential',
             display_name="Test Sequential 1",
             graded=True,
             format="Homework"
         )
         cls.vertical = ItemFactory.create(
             parent=cls.sequence,
             category='vertical',
             display_name='Test Vertical 1'
         )
         problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
             question_text='The correct answer is Choice 2',
             choices=[False, False, True, False],
             choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3']
         )
         cls.problem = ItemFactory.create(
             parent=cls.vertical,
             category="problem",
             display_name="p1",
             data=problem_xml,
             metadata={'weight': 2}
         )
예제 #8
0
    def setup_course(self):
        self.course = CourseFactory.create(data=self.COURSE_DATA)

        # Turn off cache.
        modulestore().request_cache = None
        modulestore().metadata_inheritance_cache_subsystem = None

        chapter = ItemFactory.create(
            parent_location=self.course.location,
            category="sequential",
        )
        self.section = ItemFactory.create(
            parent_location=chapter.location,
            category="sequential"
        )

        # username = robot{0}, password = '******'
        self.users = [
            UserFactory.create()
            for i in range(self.USER_COUNT)
        ]

        for user in self.users:
            CourseEnrollmentFactory.create(user=user, course_id=self.course.id)

        # login all users for acces to Xmodule
        self.clients = {user.username: Client() for user in self.users}
        self.login_statuses = [
            self.clients[user.username].login(
                username=user.username, password='******')
            for user in self.users
        ]

        self.assertTrue(all(self.login_statuses))
예제 #9
0
    def setUp(self):
        """
        Creates a basic course structure for our course
        """
        super(CourseStatusAPITestCase, self).setUp()

        self.section = ItemFactory.create(
            parent=self.course,
            category='chapter',
        )
        self.sub_section = ItemFactory.create(
            parent=self.section,
            category='sequential',
        )
        self.unit = ItemFactory.create(
            parent=self.sub_section,
            category='vertical',
        )
        self.other_sub_section = ItemFactory.create(
            parent=self.section,
            category='sequential',
        )
        self.other_unit = ItemFactory.create(
            parent=self.other_sub_section,
            category='vertical',
        )
예제 #10
0
    def setUpClass(cls):
        super(SplitTestBase, cls).setUpClass()
        cls.partition = UserPartition(
            0,
            'first_partition',
            'First Partition',
            [
                Group(0, 'alpha'),
                Group(1, 'beta')
            ]
        )

        cls.course = CourseFactory.create(
            number=cls.COURSE_NUMBER,
            user_partitions=[cls.partition]
        )

        cls.chapter = ItemFactory.create(
            parent_location=cls.course.location,
            category="chapter",
            display_name="test chapter",
        )
        cls.sequential = ItemFactory.create(
            parent_location=cls.chapter.location,
            category="sequential",
            display_name="Split Test Tests",
        )
예제 #11
0
    def setUp(self):
        super(TestTaskExecution, self).setUp()

        self.course = CourseFactory.create(start=datetime(2015, 3, 1))
        self.section = ItemFactory.create(parent=self.course, category='chapter', display_name='Test Section')
        self.subsection = ItemFactory.create(parent=self.section, category='sequential', display_name='Test Subsection')
        self.vertical = ItemFactory.create(parent=self.subsection, category='vertical', display_name='Test Unit')
예제 #12
0
    def _add_entrance_exam(self):
        """ Sets up entrance exam """
        with self.store.bulk_operations(self.course.id):
            self.course.entrance_exam_enabled = True

            self.entrance_exam = ItemFactory.create(
                parent=self.course,
                category="chapter",
                display_name="Entrance Exam Chapter",
                is_entrance_exam=True,
                in_entrance_exam=True,
            )
            self.subsection_1 = ItemFactory.create(
                parent=self.entrance_exam,
                category='sequential',
                display_name="The Only Exam Sequential",
                graded=True,
                in_entrance_exam=True,
            )
            self.problem_1 = ItemFactory.create(
                parent=self.subsection_1,
                category='problem',
                display_name="The Only Exam Problem",
                graded=True,
                in_entrance_exam=True,
            )

            add_entrance_exam_milestone(self.course, self.entrance_exam)

            self.course.entrance_exam_minimum_score_pct = 0.50
            self.course.entrance_exam_id = unicode(self.entrance_exam.location)
            self.store.update_item(self.course, self.user.id)
    def setUpClass(cls):
        super(TestGradebook, cls).setUpClass()

        # Create a course with the desired grading policy (from our class attribute)
        kwargs = {}
        if cls.grading_policy is not None:
            kwargs['grading_policy'] = cls.grading_policy
        cls.course = CourseFactory.create(**kwargs)

        # Now give it some content
        with cls.store.bulk_operations(cls.course.id, emit_signals=False):
            chapter = ItemFactory.create(
                parent_location=cls.course.location,
                category="sequential",
            )
            section = ItemFactory.create(
                parent_location=chapter.location,
                category="sequential",
                metadata={'graded': True, 'format': 'Homework'}
            )
            cls.items = [
                ItemFactory.create(
                    parent_location=section.location,
                    category="problem",
                    data=StringResponseXMLFactory().build_xml(answer='foo'),
                    metadata={'rerandomize': 'always'}
                )
                for __ in xrange(USER_COUNT - 1)
            ]
예제 #14
0
    def test_resume_course_visibility(self):
        SelfPacedConfiguration(enable_course_home_improvements=True).save()
        chapter = ItemFactory.create(
            category="chapter", parent_location=self.course.location
        )
        section = ItemFactory.create(
            category='section', parent_location=chapter.location
        )
        section_url = reverse(
            'courseware_section',
            kwargs={
                'section': section.url_name,
                'chapter': chapter.url_name,
                'course_id': self.course.id
            }
        )
        self.client.get(section_url)
        info_url = reverse('info', args=(unicode(self.course.id),))

        # Assuring a non-authenticated user cannot see the resume course button.
        resume_course_url = self.get_resume_course_url(info_url)
        self.assertEqual(resume_course_url, None)

        # Assuring an unenrolled user cannot see the resume course button.
        self.setup_user()
        resume_course_url = self.get_resume_course_url(info_url)
        self.assertEqual(resume_course_url, None)

        # Assuring an enrolled user can see the resume course button.
        self.enroll(self.course)
        resume_course_url = self.get_resume_course_url(info_url)
        self.assertEqual(resume_course_url, section_url)
예제 #15
0
 def setUpClass(cls):
     super(TestStudentModuleGrading, cls).setUpClass()
     cls.course = CourseFactory.create()
     cls.chapter = ItemFactory.create(
         parent=cls.course,
         category="chapter",
         display_name="Test Chapter"
     )
     cls.sequence = ItemFactory.create(
         parent=cls.chapter,
         category='sequential',
         display_name="Test Sequential 1",
         graded=True
     )
     cls.vertical = ItemFactory.create(
         parent=cls.sequence,
         category='vertical',
         display_name='Test Vertical 1'
     )
     problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
         question_text='The correct answer is Choice 3',
         choices=[False, False, True, False],
         choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3']
     )
     cls.problem = ItemFactory.create(
         parent=cls.vertical,
         category="problem",
         display_name="Test Problem",
         data=problem_xml
     )
     cls.request = get_mock_request(UserFactory())
     cls.user = cls.request.user
     cls.instructor = UserFactory(username='******', is_staff=True)
예제 #16
0
    def setUpClass(cls):
        super(TestSites, cls).setUpClass()
        cls.course = CourseFactory.create(
            display_name='Robot_Super_Course',
            org='TestSiteX',
            emit_signals=True,
        )
        cls.chapter0 = ItemFactory.create(parent_location=cls.course.location, display_name='Overview')
        cls.chapter9 = ItemFactory.create(parent_location=cls.course.location, display_name='factory_chapter')
        cls.section0 = ItemFactory.create(parent_location=cls.chapter0.location, display_name='Welcome')
        cls.section9 = ItemFactory.create(parent_location=cls.chapter9.location, display_name='factory_section')

        cls.course_outside_site = CourseFactory.create(
            display_name='Robot_Course_Outside_Site',
            org='FooX',
            emit_signals=True,
        )

        # have a course which explicitly sets visibility in catalog to False
        cls.course_hidden_visibility = CourseFactory.create(
            display_name='Hidden_course',
            org='TestSiteX',
            catalog_visibility=CATALOG_VISIBILITY_NONE,
            emit_signals=True,
        )

        # have a course which explicitly sets visibility in catalog and about to true
        cls.course_with_visibility = CourseFactory.create(
            display_name='visible_course',
            org='TestSiteX',
            course="foo",
            catalog_visibility=CATALOG_VISIBILITY_CATALOG_AND_ABOUT,
            emit_signals=True,
        )
예제 #17
0
    def setUpClass(cls):
        super(TestCCXGrades, cls).setUpClass()
        cls._course = course = CourseFactory.create(enable_ccx=True)

        # Create a course outline
        cls.mooc_start = start = datetime.datetime(
            2010, 5, 12, 2, 42, tzinfo=pytz.UTC
        )
        chapter = ItemFactory.create(
            start=start, parent=course, category='sequential'
        )
        cls.sections = sections = [
            ItemFactory.create(
                parent=chapter,
                category="sequential",
                metadata={'graded': True, 'format': 'Homework'})
            for _ in xrange(4)
        ]
        # making problems available at class level for possible future use in tests
        cls.problems = [
            [
                ItemFactory.create(
                    parent=section,
                    category="problem",
                    data=StringResponseXMLFactory().build_xml(answer='foo'),
                    metadata={'rerandomize': 'always'}
                ) for _ in xrange(4)
            ] for section in sections
        ]
예제 #18
0
    def _test_course_location_null(self, store):
        """ Test that course location information is added to index """
        sequential2 = ItemFactory.create(
            parent_location=self.chapter.location,
            category='sequential',
            display_name=None,
            modulestore=store,
            publish_item=True,
            start=datetime(2015, 3, 1, tzinfo=UTC),
        )
        # add a new vertical
        vertical2 = ItemFactory.create(
            parent_location=sequential2.location,
            category='vertical',
            display_name='Subsection 2',
            modulestore=store,
            publish_item=True,
        )
        ItemFactory.create(
            parent_location=vertical2.location,
            category="html",
            display_name="Find Me",
            publish_item=True,
            modulestore=store,
        )
        self.reindex_course(store)
        response = self.search(query_string="Find Me")
        self.assertEqual(response["total"], 1)

        result = response["results"][0]["data"]
        self.assertEqual(result["course_name"], "Search Index Test Course")
        self.assertEqual(result["location"], ["Week 1", CoursewareSearchIndexer.UNNAMED_MODULE_NAME, "Subsection 2"])
예제 #19
0
 def setUpClass(cls):
     super(GradeTestBase, cls).setUpClass()
     cls.course = CourseFactory.create()
     cls.chapter = ItemFactory.create(
         parent=cls.course,
         category="chapter",
         display_name="Test Chapter"
     )
     cls.sequence = ItemFactory.create(
         parent=cls.chapter,
         category='sequential',
         display_name="Test Sequential 1",
         graded=True
     )
     cls.vertical = ItemFactory.create(
         parent=cls.sequence,
         category='vertical',
         display_name='Test Vertical 1'
     )
     problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
         question_text='The correct answer is Choice 3',
         choices=[False, False, True, False],
         choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3']
     )
     cls.problem = ItemFactory.create(
         parent=cls.vertical,
         category="problem",
         display_name="Test Problem",
         data=problem_xml
     )
예제 #20
0
    def _test_not_indexing_unpublished_content(self, store):
        """ add a new one, only appers in index once added """
        # Publish the vertical to start with
        self.publish_item(store, self.vertical.location)
        self.reindex_course(store)
        response = self.search()
        self.assertEqual(response["total"], 4)

        # Now add a new unit to the existing vertical
        ItemFactory.create(
            parent_location=self.vertical.location,
            category="html",
            display_name="Some other content",
            publish_item=False,
            modulestore=store,
        )
        self.reindex_course(store)
        response = self.search()
        self.assertEqual(response["total"], 4)

        # Now publish it and we should find it
        # Publish the vertical as is, and everything should be available
        self.publish_item(store, self.vertical.location)
        self.reindex_course(store)
        response = self.search()
        self.assertEqual(response["total"], 5)
예제 #21
0
    def _test_not_indexable(self, store):
        """ test not indexable items """
        # Publish the vertical to start with
        self.publish_item(store, self.vertical.location)
        self.reindex_course(store)
        response = self.search()
        self.assertEqual(response["total"], 4)

        # Add a non-indexable item
        ItemFactory.create(
            parent_location=self.vertical.location,
            category="openassessment",
            display_name="Some other content",
            publish_item=False,
            modulestore=store,
        )
        self.reindex_course(store)
        response = self.search()
        self.assertEqual(response["total"], 4)

        # even after publishing, we should not find the non-indexable item
        self.publish_item(store, self.vertical.location)
        self.reindex_course(store)
        response = self.search()
        self.assertEqual(response["total"], 4)
예제 #22
0
 def setUp(self):
     """
     Create a simple course with a video component.
     """
     super(AuthoringMixinTestCase, self).setUp()
     self.course = CourseFactory.create()
     chapter = ItemFactory.create(
         category='chapter',
         parent_location=self.course.location,
         display_name='Test Chapter'
     )
     sequential = ItemFactory.create(
         category='sequential',
         parent_location=chapter.location,
         display_name='Test Sequential'
     )
     vertical = ItemFactory.create(
         category='vertical',
         parent_location=sequential.location,
         display_name='Test Vertical'
     )
     video = ItemFactory.create(
         category='video',
         parent_location=vertical.location,
         display_name='Test Vertical'
     )
     self.vertical_location = vertical.location
     self.video_location = video.location
     self.pet_groups = [Group(1, 'Cat Lovers'), Group(2, 'Dog Lovers')]
예제 #23
0
 def setUpClass(cls):
     super(MasqueradeTestCase, cls).setUpClass()
     cls.course = CourseFactory.create(number="masquerade-test", metadata={"start": datetime.now(UTC())})
     cls.info_page = ItemFactory.create(
         category="course_info", parent_location=cls.course.location, data="OOGIE BLOOGIE", display_name="updates"
     )
     cls.chapter = ItemFactory.create(
         parent_location=cls.course.location, category="chapter", display_name="Test Section"
     )
     cls.sequential_display_name = "Test Masquerade Subsection"
     cls.sequential = ItemFactory.create(
         parent_location=cls.chapter.location, category="sequential", display_name=cls.sequential_display_name
     )
     cls.vertical = ItemFactory.create(
         parent_location=cls.sequential.location, category="vertical", display_name="Test Unit"
     )
     problem_xml = OptionResponseXMLFactory().build_xml(
         question_text="The correct answer is Correct",
         num_inputs=2,
         weight=2,
         options=["Correct", "Incorrect"],
         correct_option="Correct",
     )
     cls.problem_display_name = "TestMasqueradeProblem"
     cls.problem = ItemFactory.create(
         parent_location=cls.vertical.location,
         category="problem",
         data=problem_xml,
         display_name=cls.problem_display_name,
     )
예제 #24
0
    def setup_course(self, default_store=None):
        """
        Helper method to create the course.
        """
        if not default_store:
            default_store = self.store.default_modulestore.get_modulestore_type()
        with self.store.default_store(default_store):
            self.course = CourseFactory.create(**self.course_options())
            chapter = ItemFactory.create(parent=self.course, category='chapter')
            self.vertical_block = ItemFactory.create(
                parent_location=chapter.location,
                category='vertical',
                display_name="Vertical"
            )
            self.html_block = ItemFactory.create(
                parent=self.vertical_block,
                category='html',
                data="<p>Test HTML Content<p>"
            )

        # block_name_to_be_tested can be `html_block` or `vertical_block`.
        # These attributes help ensure the positive and negative tests are in sync.
        self.block_to_be_tested = getattr(self, self.block_name_to_be_tested)
        self.block_specific_chrome_html_elements = self.BLOCK_SPECIFIC_CHROME_HTML_ELEMENTS[
            self.block_name_to_be_tested
        ]
예제 #25
0
    def setUp(self):
        """
        Fixtures.
        """
        super(TestSetDueDateExtension, self).setUp()

        self.due = due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc)
        course = CourseFactory.create()
        week1 = ItemFactory.create(due=due, parent=course)
        week2 = ItemFactory.create(due=due, parent=course)
        week3 = ItemFactory.create(parent=course)
        homework = ItemFactory.create(parent=week1)
        assignment = ItemFactory.create(parent=homework, due=due)

        user = UserFactory.create()

        self.course = course
        self.week1 = week1
        self.homework = homework
        self.assignment = assignment
        self.week2 = week2
        self.week3 = week3
        self.user = user

        inject_field_overrides((course, week1, week2, week3, homework, assignment), course, user)
예제 #26
0
 def setUp(self):
     super(GradesServiceTests, self).setUp()
     self.service = GradesService()
     self.course = CourseFactory.create(org='edX', number='DemoX', display_name='Demo_Course', run='Spring2019')
     self.subsection = ItemFactory.create(parent=self.course, category="subsection", display_name="Subsection")
     self.subsection_without_grade = ItemFactory.create(
         parent=self.course,
         category="subsection",
         display_name="Subsection without grade"
     )
     self.user = UserFactory()
     self.grade = PersistentSubsectionGrade.update_or_create_grade(
         user_id=self.user.id,
         course_id=self.course.id,
         usage_key=self.subsection.location,
         first_attempted=None,
         visible_blocks=[],
         earned_all=6.0,
         possible_all=6.0,
         earned_graded=5.0,
         possible_graded=5.0
     )
     self.signal_patcher = patch('lms.djangoapps.grades.signals.signals.SUBSECTION_OVERRIDE_CHANGED.send')
     self.mock_signal = self.signal_patcher.start()
     self.id_patcher = patch('lms.djangoapps.grades.services.create_new_event_transaction_id')
     self.mock_create_id = self.id_patcher.start()
     self.mock_create_id.return_value = 1
     self.type_patcher = patch('lms.djangoapps.grades.services.set_event_transaction_type')
     self.mock_set_type = self.type_patcher.start()
     self.flag_patcher = patch('lms.djangoapps.grades.services.waffle_flags')
     self.mock_waffle_flags = self.flag_patcher.start()
     self.mock_waffle_flags.return_value = {
         REJECTED_EXAM_OVERRIDES_GRADE: MockWaffleFlag(True)
     }
예제 #27
0
    def setUp(self):
        """
        Fixtures.
        """
        super(TestDataDumps, self).setUp()

        due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=UTC)
        course = CourseFactory.create()
        week1 = ItemFactory.create(due=due, parent=course)
        week2 = ItemFactory.create(due=due, parent=course)

        homework = ItemFactory.create(
            parent=week1,
            due=due
        )

        user1 = UserFactory.create()
        user2 = UserFactory.create()
        self.course = course
        self.week1 = week1
        self.homework = homework
        self.week2 = week2
        self.user1 = user1
        self.user2 = user2
        signals.extract_dates(None, course.id)
예제 #28
0
    def setUp(self):
        """
        Initial data setup
        """
        super(TestHandleItemDeleted, self).setUp()

        self.course = CourseFactory.create()
        self.course.enable_subsection_gating = True
        self.course.save()
        self.chapter = ItemFactory.create(
            parent=self.course,
            category="chapter",
            display_name="Chapter"
        )
        self.open_seq = ItemFactory.create(
            parent=self.chapter,
            category='sequential',
            display_name="Open Sequential"
        )
        self.gated_seq = ItemFactory.create(
            parent=self.chapter,
            category='sequential',
            display_name="Gated Sequential"
        )
        gating_api.add_prerequisite(self.course.id, self.open_seq.location)
        gating_api.set_required_content(self.course.id, self.gated_seq.location, self.open_seq.location, 100)
예제 #29
0
    def test_xblock_studio_url(self):

        # Verify course URL
        course_url = u"/course/{}".format(unicode(self.course.id))
        self.assertEqual(xblock_studio_url(self.course), course_url)

        # Verify chapter URL
        chapter = ItemFactory.create(parent_location=self.course.location, category="chapter", display_name="Week 1")
        self.assertEqual(xblock_studio_url(chapter), u"{}?show={}".format(course_url, http.urlquote(chapter.location)))

        # Verify sequential URL
        sequential = ItemFactory.create(
            parent_location=chapter.location, category="sequential", display_name="Lesson 1"
        )
        self.assertEqual(
            xblock_studio_url(sequential), u"{}?show={}".format(course_url, http.urlquote(sequential.location))
        )

        # Verify unit URL
        vertical = ItemFactory.create(parent_location=sequential.location, category="vertical", display_name="Unit")
        self.assertEqual(xblock_studio_url(vertical), u"/container/{}".format(vertical.location))

        # Verify child vertical URL
        child_vertical = ItemFactory.create(
            parent_location=vertical.location, category="vertical", display_name="Child Vertical"
        )
        self.assertEqual(xblock_studio_url(child_vertical), u"/container/{}".format(child_vertical.location))

        # Verify video URL
        video = ItemFactory.create(parent_location=child_vertical.location, category="video", display_name="My Video")
        self.assertIsNone(xblock_studio_url(video))
예제 #30
0
    def setUp(self):
        super(TestGetProblemGradeDistribution, self).setUp()

        self.request_factory = RequestFactory()
        self.instructor = AdminFactory.create()
        self.client.login(username=self.instructor.username, password='******')
        self.attempts = 3
        self.course = CourseFactory.create(
            display_name=u"test course omega \u03a9",
        )

        section = ItemFactory.create(
            parent_location=self.course.location,
            category="chapter",
            display_name=u"test factory section omega \u03a9",
        )
        self.sub_section = ItemFactory.create(
            parent_location=section.location,
            category="sequential",
            display_name=u"test subsection omega \u03a9",
        )

        unit = ItemFactory.create(
            parent_location=self.sub_section.location,
            category="vertical",
            metadata={'graded': True, 'format': 'Homework'},
            display_name=u"test unit omega \u03a9",
        )

        self.users = [UserFactory.create(username="******" + str(__)) for __ in xrange(USER_COUNT)]

        for user in self.users:
            CourseEnrollmentFactory.create(user=user, course_id=self.course.id)

        for i in xrange(USER_COUNT - 1):
            category = "problem"
            self.item = ItemFactory.create(
                parent_location=unit.location,
                category=category,
                data=StringResponseXMLFactory().build_xml(answer='foo'),
                metadata={'rerandomize': 'always'},
                display_name=u"test problem omega \u03a9 " + str(i)
            )

            for j, user in enumerate(self.users):
                StudentModuleFactory.create(
                    grade=1 if i < j else 0,
                    max_grade=1 if i < j else 0.5,
                    student=user,
                    course_id=self.course.id,
                    module_state_key=self.item.location,
                    state=json.dumps({'attempts': self.attempts}),
                )

            for j, user in enumerate(self.users):
                StudentModuleFactory.create(
                    course_id=self.course.id,
                    module_type='sequential',
                    module_state_key=self.item.location,
                )
 def setUp(self):
     super(TestRebindModule, self).setUp()
     self.homework = self.add_graded_section_to_course('homework')
     self.lti = ItemFactory.create(category='lti', parent=self.homework)
     self.user = UserFactory.create()
     self.anon_user = AnonymousUser()
예제 #32
0
 def _add_simple_content_block(self):
     """ Adds simple HTML block to library """
     return ItemFactory.create(category="html",
                               parent_location=self.library.location,
                               user_id=self.user.id,
                               publish_item=False)
예제 #33
0
    def test_studio_user_permissions(self):
        """
        Test that user could attach to the problem only libraries that he has access (or which were created by him).
        This test was created on the basis of bug described in the pull requests on github:
        https://github.com/edx/edx-platform/pull/11331
        https://github.com/edx/edx-platform/pull/11611
        """
        self._create_library(org='admin_org_1',
                             library='lib_adm_1',
                             display_name='admin_lib_1')
        self._create_library(org='admin_org_2',
                             library='lib_adm_2',
                             display_name='admin_lib_2')

        self._login_as_non_staff_user()

        self._create_library(org='staff_org_1',
                             library='lib_staff_1',
                             display_name='staff_lib_1')
        self._create_library(org='staff_org_2',
                             library='lib_staff_2',
                             display_name='staff_lib_2')

        with modulestore().default_store(ModuleStoreEnum.Type.split):
            course = CourseFactory.create()

        instructor_role = CourseInstructorRole(course.id)
        auth.add_users(self.user, instructor_role, self.non_staff_user)

        lib_block = ItemFactory.create(category='library_content',
                                       parent_location=course.location,
                                       user_id=self.non_staff_user.id,
                                       publish_item=False)

        def _get_settings_html():
            """
            Helper function to get block settings HTML
            Used to check the available libraries.
            """
            edit_view_url = reverse_usage_url("xblock_view_handler",
                                              lib_block.location,
                                              {"view_name": STUDIO_VIEW})

            resp = self.client.get_json(edit_view_url)
            self.assertEqual(resp.status_code, 200)

            return parse_json(resp)['html']

        self._login_as_staff_user()
        staff_settings_html = _get_settings_html()
        self.assertIn('staff_lib_1', staff_settings_html)
        self.assertIn('staff_lib_2', staff_settings_html)
        self.assertIn('admin_lib_1', staff_settings_html)
        self.assertIn('admin_lib_2', staff_settings_html)

        self._login_as_non_staff_user()
        response = self.client.get_json(LIBRARY_REST_URL)
        staff_libs = parse_json(response)
        self.assertEqual(2, len(staff_libs))

        non_staff_settings_html = _get_settings_html()
        self.assertIn('staff_lib_1', non_staff_settings_html)
        self.assertIn('staff_lib_2', non_staff_settings_html)
        self.assertNotIn('admin_lib_1', non_staff_settings_html)
        self.assertNotIn('admin_lib_2', non_staff_settings_html)
    def test_spoc_gradebook_mongo_calls(self):
        """
        Test that the MongoDB cache is used in API to return grades
        """
        # prepare course structure
        course = ItemFactory.create(
            parent_location=self.course.location,
            category="course",
            display_name="Test course",
        )

        students = []
        for i in range(20):
            username = "******" % i
            student = UserFactory.create(username=username)
            CourseEnrollmentFactory.create(user=student, course_id=self.course.id)
            students.append(student)

        chapter = ItemFactory.create(
            parent=course,
            category='chapter',
            display_name="Chapter",
            publish_item=True,
            start=datetime.datetime(2015, 3, 1, tzinfo=UTC),
        )
        sequential = ItemFactory.create(
            parent=chapter,
            category='sequential',
            display_name="Lesson",
            publish_item=True,
            start=datetime.datetime(2015, 3, 1, tzinfo=UTC),
            metadata={'graded': True, 'format': 'Homework'},
        )
        vertical = ItemFactory.create(
            parent=sequential,
            category='vertical',
            display_name='Subsection',
            publish_item=True,
            start=datetime.datetime(2015, 4, 1, tzinfo=UTC),
        )
        for i in range(10):
            problem = ItemFactory.create(
                category="problem",
                parent=vertical,
                display_name=u"A Problem Block %d" % i,
                weight=1,
                publish_item=False,
                metadata={'rerandomize': 'always'},
            )
            for j in students:
                grade = i % 2
                StudentModuleFactory.create(
                    grade=grade,
                    max_grade=1,
                    student=j,
                    course_id=self.course.id,
                    module_state_key=problem.location
                )

        # check MongoDB calls count
        url = reverse('spoc_gradebook', kwargs={'course_id': self.course.id})
        with check_mongo_calls(9):
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)
예제 #35
0
    def setUpClass(cls):
        """
        Set up an array of various courses to be tested.
        """
        SelfPacedRelativeDatesConfig.objects.create(enabled=True)

        # setUpClassAndTestData() already calls setUpClass on SharedModuleStoreTestCase
        # pylint: disable=super-method-not-called
        with super(TestCourseOutlinePage, cls).setUpClassAndTestData():
            cls.courses = []
            course = CourseFactory.create(self_paced=True)
            with cls.store.bulk_operations(course.id):
                chapter = ItemFactory.create(category='chapter',
                                             parent_location=course.location)
                sequential = ItemFactory.create(
                    category='sequential',
                    parent_location=chapter.location,
                    graded=True,
                    format="Homework")
                vertical = ItemFactory.create(
                    category='vertical', parent_location=sequential.location)
                problem = ItemFactory.create(category='problem',
                                             parent_location=vertical.location)
            course.children = [chapter]
            chapter.children = [sequential]
            sequential.children = [vertical]
            vertical.children = [problem]
            cls.courses.append(course)

            course = CourseFactory.create()
            with cls.store.bulk_operations(course.id):
                chapter = ItemFactory.create(category='chapter',
                                             parent_location=course.location)
                sequential = ItemFactory.create(
                    category='sequential', parent_location=chapter.location)
                sequential2 = ItemFactory.create(
                    category='sequential', parent_location=chapter.location)
                vertical = ItemFactory.create(
                    category='vertical',
                    parent_location=sequential.location,
                    display_name="Vertical 1")
                vertical2 = ItemFactory.create(
                    category='vertical',
                    parent_location=sequential2.location,
                    display_name="Vertical 2")
            course.children = [chapter]
            chapter.children = [sequential, sequential2]
            sequential.children = [vertical]
            sequential2.children = [vertical2]
            cls.courses.append(course)

            course = CourseFactory.create()
            with cls.store.bulk_operations(course.id):
                chapter = ItemFactory.create(category='chapter',
                                             parent_location=course.location)
                sequential = ItemFactory.create(
                    category='sequential',
                    parent_location=chapter.location,
                    due=datetime.datetime.now(),
                    graded=True,
                    format='Homework',
                )
                vertical = ItemFactory.create(
                    category='vertical', parent_location=sequential.location)
            course.children = [chapter]
            chapter.children = [sequential]
            sequential.children = [vertical]
            cls.courses.append(course)
예제 #36
0
    def setUp(self):
        """
        Set up tests
        """
        super(TestCCXGrades, self).setUp()
        self.course = course = CourseFactory.create(enable_ccx=True)

        # Create instructor account
        self.coach = coach = AdminFactory.create()
        self.client.login(username=coach.username, password="******")

        # Create a course outline
        self.mooc_start = start = datetime.datetime(2010,
                                                    5,
                                                    12,
                                                    2,
                                                    42,
                                                    tzinfo=pytz.UTC)
        chapter = ItemFactory.create(start=start,
                                     parent=course,
                                     category='sequential')
        sections = [
            ItemFactory.create(parent=chapter,
                               category="sequential",
                               metadata={
                                   'graded': True,
                                   'format': 'Homework'
                               }) for _ in xrange(4)
        ]
        # pylint: disable=unused-variable
        problems = [[
            ItemFactory.create(
                parent=section,
                category="problem",
                data=StringResponseXMLFactory().build_xml(answer='foo'),
                metadata={'rerandomize': 'always'}) for _ in xrange(4)
        ] for section in sections]

        # Create CCX
        role = CourseCcxCoachRole(course.id)
        role.add_users(coach)
        ccx = CcxFactory(course_id=course.id, coach=self.coach)

        # override course grading policy and make last section invisible to students
        override_field_for_ccx(
            ccx, course, 'grading_policy', {
                'GRADER': [{
                    'drop_count': 0,
                    'min_count': 2,
                    'short_label': 'HW',
                    'type': 'Homework',
                    'weight': 1
                }],
                'GRADE_CUTOFFS': {
                    'Pass': 0.75
                },
            })
        override_field_for_ccx(ccx, sections[-1], 'visible_to_staff_only',
                               True)

        # create a ccx locator and retrieve the course structure using that key
        # which emulates how a student would get access.
        self.ccx_key = CCXLocator.from_course_locator(course.id, ccx.id)
        self.course = get_course_by_id(self.ccx_key)

        self.student = student = UserFactory.create()
        CourseEnrollmentFactory.create(user=student, course_id=self.course.id)
        CcxMembershipFactory(ccx=ccx, student=student, active=True)

        # create grades for self.student as if they'd submitted the ccx
        for chapter in self.course.get_children():
            for i, section in enumerate(chapter.get_children()):
                for j, problem in enumerate(section.get_children()):
                    # if not problem.visible_to_staff_only:
                    StudentModuleFactory.create(
                        grade=1 if i < j else 0,
                        max_grade=1,
                        student=self.student,
                        course_id=self.course.id,
                        module_state_key=problem.location)

        self.client.login(username=coach.username, password="******")

        self.addCleanup(RequestCache.clear_request_cache)
 def _create_chapter(self, **kwargs):
     ItemFactory.create(parent=self.course, category='chapter', **kwargs)
예제 #38
0
    def test_deprecated_blocks_list_updated_correctly(self, delete_vertical):
        """
        Verify that deprecated blocks list shown on banner is updated correctly.

        Here is the scenario:
            This list of deprecated blocks shown on banner contains published
            and un-published blocks. That list should be updated when we delete
            un-published block(s). This behavior should be same if we delete
            unpublished vertical or problem.
        """
        block_types = ['notes']
        course_module = modulestore().get_item(self.course.location)

        vertical1 = ItemFactory.create(
            parent_location=self.sequential.location,
            category='vertical',
            display_name='Vert1 Subsection1')
        problem1 = ItemFactory.create(parent_location=vertical1.location,
                                      category='notes',
                                      display_name='notes problem in vert1',
                                      publish_item=False)

        info = _deprecated_blocks_info(course_module, block_types)
        # info['blocks'] should be empty here because there is nothing
        # published or un-published present
        self.assertEqual(info['blocks'], [])

        vertical2 = ItemFactory.create(
            parent_location=self.sequential.location,
            category='vertical',
            display_name='Vert2 Subsection1')
        ItemFactory.create(parent_location=vertical2.location,
                           category='notes',
                           display_name='notes problem in vert2',
                           pubish_item=True)
        # At this point CourseStructure will contain both the above
        # published and un-published verticals

        info = _deprecated_blocks_info(course_module, block_types)
        self.assertItemsEqual(
            info['blocks'],
            [[
                reverse_usage_url('container_handler', vertical1.location),
                'notes problem in vert1'
            ],
             [
                 reverse_usage_url('container_handler', vertical2.location),
                 'notes problem in vert2'
             ]])

        # Delete the un-published vertical or problem so that CourseStructure updates its data
        if delete_vertical:
            self.store.delete_item(vertical1.location, self.user.id)
        else:
            self.store.delete_item(problem1.location, self.user.id)

        info = _deprecated_blocks_info(course_module, block_types)
        # info['blocks'] should only contain the info about vertical2 which is published.
        # There shouldn't be any info present about un-published vertical1
        self.assertEqual(info['blocks'], [[
            reverse_usage_url('container_handler', vertical2.location),
            'notes problem in vert2'
        ]])
예제 #39
0
    def setUpClass(cls):
        super(TestProblemTypeAccess, cls).setUpClass()
        cls.factory = RequestFactory()

        cls.courses = {}

        # default course is used for most tests, it includes an audit and verified track and all the problem types
        # defined in 'PROBLEM_TYPES' and 'GRADED_SCORE_WEIGHT_TEST_CASES'
        cls.courses['default'] = cls._create_course(
            run='testcourse1',
            display_name='Test Course Title',
            modes=['audit', 'verified'],
            component_types=cls.COMPONENT_TYPES
        )
        # because default course is used for most tests self.course and self.problem_dict are set for ease of reference
        cls.course = cls.courses['default']['course']
        cls.blocks_dict = cls.courses['default']['blocks']

        # Create components with the cartesian product of possible values of
        # graded/has_score/weight for the test_graded_score_weight_values test.
        cls.graded_score_weight_blocks = {}
        for graded, has_score, weight, gated in cls.GRADED_SCORE_WEIGHT_TEST_CASES:
            case_name = ' Graded: ' + str(graded) + ' Has Score: ' + str(has_score) + ' Weight: ' + str(weight)
            block = ItemFactory.create(
                parent=cls.blocks_dict['vertical'],
                # has_score is determined by XBlock type. It is not a value set on an instance of an XBlock.
                # Therefore, we create a problem component when has_score is True
                # and an html component when has_score is False.
                category='problem' if has_score else 'html',
                graded=graded,
                weight=weight,
                metadata=METADATA if (graded and has_score and weight) else {},
            )
            # Intersperse HTML so that the content-gating renders in all blocks
            ItemFactory.create(
                parent=cls.blocks_dict['vertical'],
                category='html',
                graded=False,
            )
            cls.graded_score_weight_blocks[(graded, has_score, weight)] = block

        host = os.environ.get('BOK_CHOY_HOSTNAME', '127.0.0.1')
        metadata_lti_xblock = {
            'lti_id': 'correct_lti_id',
            'launch_url': 'http://{}:{}/{}'.format(host, '8765', 'correct_lti_endpoint'),
            'open_in_a_new_page': False
        }

        scored_lti_metadata = {}
        scored_lti_metadata.update(metadata_lti_xblock)
        scored_lti_metadata.update(METADATA)

        # add LTI blocks to default course
        cls.blocks_dict['lti_block'] = ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='lti_consumer',
            has_score=True,
            graded=True,
            metadata=scored_lti_metadata,
        )
        # Intersperse HTML so that the content-gating renders in all blocks
        ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='html',
            graded=False,
        )
        cls.blocks_dict['lti_block_not_scored'] = ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='lti_consumer',
            has_score=False,
            metadata=metadata_lti_xblock,
        )

        # Intersperse HTML so that the content-gating renders in all blocks
        ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='html',
            graded=False,
        )

        # add ungraded problem for xblock_handler test
        cls.blocks_dict['graded_problem'] = ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='problem',
            graded=True,
            metadata=METADATA,
        )

        # Intersperse HTML so that the content-gating renders in all blocks
        ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='html',
            graded=False,
        )

        cls.blocks_dict['ungraded_problem'] = ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='problem',
            graded=False,
        )

        # Intersperse HTML so that the content-gating renders in all blocks
        ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='html',
            graded=False,
        )

        cls.blocks_dict['audit_visible_graded_problem'] = ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='problem',
            graded=True,
            group_access={
                CONTENT_GATING_PARTITION_ID: [
                    CONTENT_TYPE_GATE_GROUP_IDS['limited_access'],
                    CONTENT_TYPE_GATE_GROUP_IDS['full_access']
                ]
            },
        )

        # Intersperse HTML so that the content-gating renders in all blocks
        ItemFactory.create(
            parent=cls.blocks_dict['vertical'],
            category='html',
            graded=False,
        )

        # audit_only course only has an audit track available
        cls.courses['audit_only'] = cls._create_course(
            run='audit_only_course_run_1',
            display_name='Audit Only Test Course Title',
            modes=['audit'],
            component_types=['problem', 'html']
        )

        # all_track_types course has all track types defined in MODE_TYPES
        cls.courses['all_track_types'] = cls._create_course(
            run='all_track_types_run_1',
            display_name='All Track/Mode Types Test Course Title',
            modes=cls.MODE_TYPES,
            component_types=['problem', 'html']
        )

        cls.courses['expired_upgrade_deadline'] = cls._create_course(
            run='expired_upgrade_deadline_run_1',
            display_name='Expired Upgrade Deadline Course Title',
            modes=['audit'],
            component_types=['problem', 'html']
        )
        CourseModeFactory.create(
            course_id=cls.courses['expired_upgrade_deadline']['course'].scope_ids.usage_id.course_key,
            mode_slug='verified',
            expiration_datetime=datetime(2018, 1, 1)
        )
예제 #40
0
    def setUpClass(cls):
        """
        Set up an array of various courses to be tested.
        """
        # setUpClassAndTestData() already calls setUpClass on SharedModuleStoreTestCase
        with super(TestCourseOutlinePage, cls).setUpClassAndTestData():
            cls.courses = []
            course = CourseFactory.create()
            with cls.store.bulk_operations(course.id):
                chapter = ItemFactory.create(category='chapter', parent_location=course.location)
                sequential = ItemFactory.create(category='sequential', parent_location=chapter.location)
                vertical = ItemFactory.create(category='vertical', parent_location=sequential.location)
            course.children = [chapter]
            chapter.children = [sequential]
            sequential.children = [vertical]
            cls.courses.append(course)

            course = CourseFactory.create()
            with cls.store.bulk_operations(course.id):
                chapter = ItemFactory.create(category='chapter', parent_location=course.location)
                sequential = ItemFactory.create(category='sequential', parent_location=chapter.location)
                sequential2 = ItemFactory.create(category='sequential', parent_location=chapter.location)
                vertical = ItemFactory.create(category='vertical', parent_location=sequential.location)
                vertical2 = ItemFactory.create(category='vertical', parent_location=sequential2.location)
            course.children = [chapter]
            chapter.children = [sequential, sequential2]
            sequential.children = [vertical]
            sequential2.children = [vertical2]
            cls.courses.append(course)

            course = CourseFactory.create()
            with cls.store.bulk_operations(course.id):
                chapter = ItemFactory.create(category='chapter', parent_location=course.location)
                sequential = ItemFactory.create(
                    category='sequential',
                    parent_location=chapter.location,
                    due=datetime.datetime.now(),
                    graded=True,
                    format='Homework',
                )
                vertical = ItemFactory.create(category='vertical', parent_location=sequential.location)
            course.children = [chapter]
            chapter.children = [sequential]
            sequential.children = [vertical]
            cls.courses.append(course)
예제 #41
0
    def test_dashboard_with_resume_buttons_and_view_buttons(self):
        '''
        The Test creates a four-course-card dashboard. The user completes course
        blocks in the even-numbered course cards. The test checks that courses
        with completion data have course cards with "Resume Course" buttons;
        those without have "View Course" buttons.

        '''
        self.override_waffle_switch(True)

        isEven = lambda n: n % 2 == 0

        num_course_cards = 4

        html_for_view_buttons = []
        html_for_resume_buttons = []
        html_for_entitlement = []

        for i in range(num_course_cards):

            course = CourseFactory.create()
            course_enrollment = CourseEnrollmentFactory(user=self.user,
                                                        course_id=course.id)

            course_key = course_enrollment.course_id
            course_key_string = str(course_key)

            if i == 1:
                CourseEntitlementFactory.create(
                    user=self.user, enrollment_course_run=course_enrollment)

            else:
                last_completed_block_string = ''
                course_run_string = self._pull_course_run_from_course_key(
                    course_key_string)

            # Submit completed course blocks in even-numbered courses.
            if isEven(i):
                block_keys = [
                    ItemFactory.create(category='video',
                                       parent_location=course.location,
                                       display_name='Video {0}'.format(
                                           six.text_type(number))).location
                    for number in range(5)
                ]
                last_completed_block_string = str(block_keys[-1])

                submit_completions_for_testing(self.user, course_key,
                                               block_keys)

            html_for_view_buttons.append(
                self._get_html_for_view_course_button(course_key_string,
                                                      course_run_string))
            html_for_resume_buttons.append(
                self._get_html_for_resume_course_button(
                    course_key_string, last_completed_block_string,
                    course_run_string))
            html_for_entitlement.append(
                self._get_html_for_entitlement_button(course_key_string))

        response = self.client.get(reverse('dashboard'))

        html_for_view_buttons = [
            self._remove_whitespace_from_html_string(button)
            for button in html_for_view_buttons
        ]
        html_for_resume_buttons = [
            self._remove_whitespace_from_html_string(button)
            for button in html_for_resume_buttons
        ]
        html_for_entitlement = [
            self._remove_whitespace_from_html_string(button)
            for button in html_for_entitlement
        ]

        dashboard_html = self._remove_whitespace_from_response(response)

        for i in range(num_course_cards):
            expected_button = None
            unexpected_button = None

            if i == 1:
                expected_button = html_for_entitlement[i]
                unexpected_button = html_for_view_buttons[
                    i] + html_for_resume_buttons[i]

            elif isEven(i):
                expected_button = html_for_resume_buttons[i]
                unexpected_button = html_for_view_buttons[
                    i] + html_for_entitlement[i]
            else:
                expected_button = html_for_view_buttons[i]
                unexpected_button = html_for_resume_buttons[
                    i] + html_for_entitlement[i]

            self.assertIn(expected_button, dashboard_html)
            self.assertNotIn(unexpected_button, dashboard_html)
예제 #42
0
    def _create_course(cls, run, display_name, modes, component_types):
        """
        Helper method to create a course
        Arguments:
            run (str): name of course run
            display_name (str): display name of course
            modes (list of str): list of modes/tracks this course should have
            component_types (list of str): list of problem types this course should have
        Returns:
             (dict): {
                'course': (CourseDescriptorWithMixins): course definition
                'blocks': (dict) {
                    'block_category_1': XBlock representing that block,
                    'block_category_2': XBlock representing that block,
                    ....
             }
        """
        start_date = timezone.now() - timedelta(weeks=1)
        course = CourseFactory.create(run=run, display_name=display_name, start=start_date)

        for mode in modes:
            CourseModeFactory.create(course_id=course.id, mode_slug=mode)

        with cls.store.bulk_operations(course.id):
            blocks_dict = {}
            chapter = ItemFactory.create(
                parent=course,
                display_name='Overview',
            )
            blocks_dict['chapter'] = ItemFactory.create(
                parent=course,
                category='chapter',
                display_name='Week 1',
            )
            blocks_dict['sequential'] = ItemFactory.create(
                parent=chapter,
                category='sequential',
                display_name='Lesson 1',
            )
            blocks_dict['vertical'] = ItemFactory.create(
                parent=blocks_dict['sequential'],
                category='vertical',
                display_name='Lesson 1 Vertical - Unit 1',
            )

            for component_type in component_types:
                block = ItemFactory.create(
                    parent=blocks_dict['vertical'],
                    category=component_type,
                    graded=True,
                    metadata={} if (component_type == 'html' or len(modes) == 1) else METADATA
                )
                blocks_dict[component_type] = block
                # Intersperse HTML so that the content-gating renders in all blocks
                ItemFactory.create(
                    parent=blocks_dict['vertical'],
                    category='html',
                    graded=False,
                )

            return {
                'course': course,
                'blocks': blocks_dict,
            }
예제 #43
0
    def setUp(self):
        """
        Test case scaffolding
        """
        super(EntranceExamTestCases, self).setUp()
        self.course = CourseFactory.create(
            metadata={
                'entrance_exam_enabled': True,
            }
        )
        with self.store.bulk_operations(self.course.id):
            self.chapter = ItemFactory.create(
                parent=self.course,
                display_name='Overview'
            )
            self.welcome = ItemFactory.create(
                parent=self.chapter,
                display_name='Welcome'
            )
            ItemFactory.create(
                parent=self.course,
                category='chapter',
                display_name="Week 1"
            )
            self.chapter_subsection = ItemFactory.create(
                parent=self.chapter,
                category='sequential',
                display_name="Lesson 1"
            )
            chapter_vertical = ItemFactory.create(
                parent=self.chapter_subsection,
                category='vertical',
                display_name='Lesson 1 Vertical - Unit 1'
            )
            ItemFactory.create(
                parent=chapter_vertical,
                category="problem",
                display_name="Problem - Unit 1 Problem 1"
            )
            ItemFactory.create(
                parent=chapter_vertical,
                category="problem",
                display_name="Problem - Unit 1 Problem 2"
            )

            ItemFactory.create(
                category="instructor",
                parent=self.course,
                data="Instructor Tab",
                display_name="Instructor"
            )
            self.entrance_exam = ItemFactory.create(
                parent=self.course,
                category="chapter",
                display_name="Entrance Exam Section - Chapter 1",
                is_entrance_exam=True,
                in_entrance_exam=True
            )
            self.exam_1 = ItemFactory.create(
                parent=self.entrance_exam,
                category='sequential',
                display_name="Exam Sequential - Subsection 1",
                graded=True,
                in_entrance_exam=True
            )
            subsection = ItemFactory.create(
                parent=self.exam_1,
                category='vertical',
                display_name='Exam Vertical - Unit 1'
            )
            problem_xml = MultipleChoiceResponseXMLFactory().build_xml(
                question_text='The correct answer is Choice 3',
                choices=[False, False, True, False],
                choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3']
            )
            self.problem_1 = ItemFactory.create(
                parent=subsection,
                category="problem",
                display_name="Exam Problem - Problem 1",
                data=problem_xml
            )
            self.problem_2 = ItemFactory.create(
                parent=subsection,
                category="problem",
                display_name="Exam Problem - Problem 2"
            )

        add_entrance_exam_milestone(self.course, self.entrance_exam)

        self.course.entrance_exam_enabled = True
        self.course.entrance_exam_minimum_score_pct = 0.50
        self.course.entrance_exam_id = unicode(self.entrance_exam.scope_ids.usage_id)

        self.anonymous_user = AnonymousUserFactory()
        self.request = get_mock_request(UserFactory())
        modulestore().update_item(self.course, self.request.user.id)  # pylint: disable=no-member

        self.client.login(username=self.request.user.username, password="******")
        CourseEnrollment.enroll(self.request.user, self.course.id)

        self.expected_locked_toc = (
            [
                {
                    'active': True,
                    'sections': [
                        {
                            'url_name': u'Exam_Sequential_-_Subsection_1',
                            'display_name': u'Exam Sequential - Subsection 1',
                            'graded': True,
                            'format': '',
                            'due': None,
                            'active': True
                        }
                    ],
                    'url_name': u'Entrance_Exam_Section_-_Chapter_1',
                    'display_name': u'Entrance Exam Section - Chapter 1',
                    'display_id': u'entrance-exam-section-chapter-1',
                }
            ]
        )
        self.expected_unlocked_toc = (
            [
                {
                    'active': False,
                    'sections': [
                        {
                            'url_name': u'Welcome',
                            'display_name': u'Welcome',
                            'graded': False,
                            'format': '',
                            'due': None,
                            'active': False
                        },
                        {
                            'url_name': u'Lesson_1',
                            'display_name': u'Lesson 1',
                            'graded': False,
                            'format': '',
                            'due': None,
                            'active': False
                        }
                    ],
                    'url_name': u'Overview',
                    'display_name': u'Overview',
                    'display_id': u'overview'
                },
                {
                    'active': False,
                    'sections': [],
                    'url_name': u'Week_1',
                    'display_name': u'Week 1',
                    'display_id': u'week-1'
                },
                {
                    'active': False,
                    'sections': [],
                    'url_name': u'Instructor',
                    'display_name': u'Instructor',
                    'display_id': u'instructor'
                },
                {
                    'active': True,
                    'sections': [
                        {
                            'url_name': u'Exam_Sequential_-_Subsection_1',
                            'display_name': u'Exam Sequential - Subsection 1',
                            'graded': True,
                            'format': '',
                            'due': None,
                            'active': True
                        }
                    ],
                    'url_name': u'Entrance_Exam_Section_-_Chapter_1',
                    'display_name': u'Entrance Exam Section - Chapter 1',
                    'display_id': u'entrance-exam-section-chapter-1'
                }
            ]
        )
예제 #44
0
 def create_test_course(cls):
     """
     Creates a test course.
     """
     course = CourseFactory.create()
     with cls.store.bulk_operations(course.id):
         chapter = ItemFactory.create(category='chapter',
                                      parent_location=course.location)
         chapter2 = ItemFactory.create(category='chapter',
                                       parent_location=course.location)
         sequential = ItemFactory.create(category='sequential',
                                         parent_location=chapter.location)
         sequential2 = ItemFactory.create(category='sequential',
                                          parent_location=chapter.location)
         sequential3 = ItemFactory.create(category='sequential',
                                          parent_location=chapter2.location)
         sequential4 = ItemFactory.create(category='sequential',
                                          parent_location=chapter2.location)
         vertical = ItemFactory.create(category='vertical',
                                       parent_location=sequential.location)
         vertical2 = ItemFactory.create(
             category='vertical', parent_location=sequential2.location)
         vertical3 = ItemFactory.create(
             category='vertical', parent_location=sequential3.location)
         vertical4 = ItemFactory.create(
             category='vertical', parent_location=sequential4.location)
         problem = ItemFactory.create(category='problem',
                                      parent_location=vertical.location)
         problem2 = ItemFactory.create(category='problem',
                                       parent_location=vertical2.location)
         problem3 = ItemFactory.create(category='problem',
                                       parent_location=vertical3.location)
     course.children = [chapter, chapter2]
     chapter.children = [sequential, sequential2]
     chapter2.children = [sequential3, sequential4]
     sequential.children = [vertical]
     sequential2.children = [vertical2]
     sequential3.children = [vertical3]
     sequential4.children = [vertical4]
     vertical.children = [problem]
     vertical2.children = [problem2]
     vertical3.children = [problem3]
     if hasattr(cls, 'user'):
         CourseEnrollment.enroll(cls.user, course.id)
     return course
예제 #45
0
 def setUp(self):
     self.course = CourseFactory.create()
     self.page = ItemFactory.create(
         category="course_info", parent_location=self.course.location,
         data="OOGIE BLOOGIE", display_name="updates"
     )
 def setUpClass(cls):
     super(AboutWithInvitationOnly, cls).setUpClass()
     cls.course = CourseFactory.create(metadata={"invitation_only": True})
     cls.about = ItemFactory.create(category="about",
                                    parent_location=cls.course.location,
                                    display_name="overview")
예제 #47
0
    def initialize_course(cls, course):
        """
        Sets up the structure of the test course.
        """
        course.self_paced = True

        cls.section = ItemFactory.create(
            parent_location=course.location,
            category="chapter",
        )
        cls.subsection1 = ItemFactory.create(
            parent_location=cls.section.location,
            category="sequential",
        )
        unit1 = ItemFactory.create(
            parent_location=cls.subsection1.location,
            category="vertical",
        )
        ItemFactory.create(
            parent_location=unit1.location,
            category="video",
        )
        ItemFactory.create(
            parent_location=unit1.location,
            category="problem",
        )

        cls.subsection2 = ItemFactory.create(
            parent_location=cls.section.location,
            category="sequential",
        )
        unit2 = ItemFactory.create(
            parent_location=cls.subsection2.location,
            category="vertical",
        )
        unit3 = ItemFactory.create(
            parent_location=cls.subsection2.location,
            category="vertical",
        )
        ItemFactory.create(
            parent_location=unit3.location,
            category="video",
        )
        ItemFactory.create(
            parent_location=unit3.location,
            category="video",
        )
        cls.homework = ItemFactory.create(
            parent_location=cls.section.location,
            category="sequential",
            graded=True,
            format='Homework',
        )
        cls.midterm = ItemFactory.create(
            parent_location=cls.section.location,
            category="sequential",
            graded=True,
            format='Midterm Exam',
        )
예제 #48
0
    def set_up_course(self,
                      enable_persistent_grades=True,
                      create_multiple_subsections=False):
        """
        Configures the course for this test.
        """
        # pylint: disable=attribute-defined-outside-init,no-member
        self.course = CourseFactory.create(
            org='edx',
            name='course',
            run='run',
        )
        if not enable_persistent_grades:
            PersistentGradesEnabledFlag.objects.create(enabled=False)

        self.chapter = ItemFactory.create(parent=self.course,
                                          category="chapter",
                                          display_name="Chapter")
        self.sequential = ItemFactory.create(parent=self.chapter,
                                             category='sequential',
                                             display_name="Sequential1")
        self.problem = ItemFactory.create(parent=self.sequential,
                                          category='problem',
                                          display_name='Problem')

        if create_multiple_subsections:
            seq2 = ItemFactory.create(parent=self.chapter,
                                      category='sequential')
            ItemFactory.create(parent=seq2, category='problem')

        self.frozen_now_datetime = datetime.now().replace(tzinfo=pytz.UTC)
        self.frozen_now_timestamp = to_timestamp(self.frozen_now_datetime)

        self.problem_weighted_score_changed_kwargs = OrderedDict([
            ('weighted_earned', 1.0),
            ('weighted_possible', 2.0),
            ('user_id', self.user.id),
            ('anonymous_user_id', 5),
            ('course_id', unicode(self.course.id)),
            ('usage_id', unicode(self.problem.location)),
            ('only_if_higher', None),
            ('modified', self.frozen_now_datetime),
            ('score_db_table',
             ScoreDatabaseTableEnum.courseware_student_module),
        ])

        create_new_event_transaction_id()

        self.recalculate_subsection_grade_kwargs = OrderedDict([
            ('user_id', self.user.id),
            ('course_id', unicode(self.course.id)),
            ('usage_id', unicode(self.problem.location)),
            ('anonymous_user_id', 5),
            ('only_if_higher', None),
            ('expected_modified_time', self.frozen_now_timestamp),
            ('score_deleted', False),
            ('event_transaction_id', unicode(get_event_transaction_id())),
            ('event_transaction_type', u'edx.grades.problem.submitted'),
            ('score_db_table',
             ScoreDatabaseTableEnum.courseware_student_module),
        ])

        # this call caches the anonymous id on the user object, saving 4 queries in all happy path tests
        _ = anonymous_id_for_user(self.user, self.course.id)
예제 #49
0
 def setUpClass(cls):
     super().setUpClass()
     cls.course = CourseFactory.create()
     cls.block = ItemFactory.create(category='aside', parent=cls.course)
     cls.aside_v2 = AsideUsageKeyV2(cls.block.scope_ids.usage_id, "aside")
     cls.aside_v1 = AsideUsageKeyV1(cls.block.scope_ids.usage_id, "aside")
예제 #50
0
    def setUp(self):
        super(GroupAccessTestCase, self).setUp()

        UserPartition.scheme_extensions = ExtensionManager.make_test_instance(
            [
                Extension("memory", USER_PARTITION_SCHEME_NAMESPACE,
                          MemoryUserPartitionScheme(), None),
                Extension("random", USER_PARTITION_SCHEME_NAMESPACE,
                          MemoryUserPartitionScheme(), None)
            ],
            namespace=USER_PARTITION_SCHEME_NAMESPACE)

        self.cat_group = Group(10, 'cats')
        self.dog_group = Group(20, 'dogs')
        self.worm_group = Group(30, 'worms')
        self.animal_partition = UserPartition(
            0,
            'Pet Partition',
            'which animal are you?',
            [self.cat_group, self.dog_group, self.worm_group],
            scheme=UserPartition.get_scheme("memory"),
        )

        self.red_group = Group(1000, 'red')
        self.blue_group = Group(2000, 'blue')
        self.gray_group = Group(3000, 'gray')
        self.color_partition = UserPartition(
            100,
            'Color Partition',
            'what color are you?',
            [self.red_group, self.blue_group, self.gray_group],
            scheme=UserPartition.get_scheme("memory"),
        )

        self.course = CourseFactory.create(
            user_partitions=[self.animal_partition, self.color_partition], )
        with self.store.bulk_operations(self.course.id, emit_signals=False):
            chapter = ItemFactory.create(category='chapter',
                                         parent=self.course)
            section = ItemFactory.create(category='sequential', parent=chapter)
            vertical = ItemFactory.create(category='vertical', parent=section)
            component = ItemFactory.create(category='problem', parent=vertical)

            self.chapter_location = chapter.location
            self.section_location = section.location
            self.vertical_location = vertical.location
            self.component_location = component.location

        self.red_cat = UserFactory()  # student in red and cat groups
        self.set_user_group(self.red_cat, self.animal_partition,
                            self.cat_group)
        self.set_user_group(self.red_cat, self.color_partition, self.red_group)

        self.blue_dog = UserFactory()  # student in blue and dog groups
        self.set_user_group(self.blue_dog, self.animal_partition,
                            self.dog_group)
        self.set_user_group(self.blue_dog, self.color_partition,
                            self.blue_group)

        self.white_mouse = UserFactory()  # student in no group

        self.gray_worm = UserFactory()  # student in deleted group
        self.set_user_group(self.gray_worm, self.animal_partition,
                            self.worm_group)
        self.set_user_group(self.gray_worm, self.color_partition,
                            self.gray_group)
        # delete the gray/worm groups from the partitions now so we can test scenarios
        # for user whose group is missing.
        self.animal_partition.groups.pop()
        self.color_partition.groups.pop()

        # add a staff user, whose access will be unconditional in spite of group access.
        self.staff = StaffFactory.create(course_key=self.course.id)
예제 #51
0
 def setUp(self):
     self.course = CourseFactory.create()
     self.about = ItemFactory.create(
         category="about", parent_location=self.course.location,
         data="OOGIE BLOOGIE", display_name="overview"
     )
예제 #52
0
 def setUp(self):
     """
     Test case scaffolding
     """
     super(EntranceExamTestCases, self).setUp()
     self.course = CourseFactory.create(metadata={
         'entrance_exam_enabled': True,
     })
     chapter = ItemFactory.create(parent=self.course,
                                  display_name='Overview')
     ItemFactory.create(parent=chapter, display_name='Welcome')
     ItemFactory.create(parent=self.course,
                        category='chapter',
                        display_name="Week 1")
     ItemFactory.create(parent=chapter,
                        category='sequential',
                        display_name="Lesson 1")
     ItemFactory.create(category="instructor",
                        parent=self.course,
                        data="Instructor Tab",
                        display_name="Instructor")
     self.entrance_exam = ItemFactory.create(
         parent=self.course,
         category="chapter",
         display_name="Entrance Exam Section - Chapter 1")
     self.exam_1 = ItemFactory.create(
         parent=self.entrance_exam,
         category='sequential',
         display_name="Exam Sequential - Subsection 1",
         graded=True,
         metadata={'in_entrance_exam': True})
     subsection = ItemFactory.create(parent=self.exam_1,
                                     category='vertical',
                                     display_name='Exam Vertical - Unit 1')
     self.problem_1 = ItemFactory.create(
         parent=subsection,
         category="problem",
         display_name="Exam Problem - Problem 1")
     self.problem_2 = ItemFactory.create(
         parent=subsection,
         category="problem",
         display_name="Exam Problem - Problem 2")
     self.problem_3 = ItemFactory.create(
         parent=subsection,
         category="problem",
         display_name="Exam Problem - Problem 3")
     milestone_namespace = generate_milestone_namespace(
         NAMESPACE_CHOICES['ENTRANCE_EXAM'], self.course.id)
     self.milestone = {
         'name': 'Test Milestone',
         'namespace': milestone_namespace,
         'description': 'Testing Courseware Entrance Exam Chapter',
     }
     MilestoneRelationshipType.objects.create(name='requires', active=True)
     MilestoneRelationshipType.objects.create(name='fulfills', active=True)
     self.milestone_relationship_types = milestones_api.get_milestone_relationship_types(
     )
     self.milestone = milestones_api.add_milestone(self.milestone)
     milestones_api.add_course_milestone(
         unicode(self.course.id),
         self.milestone_relationship_types['REQUIRES'], self.milestone)
     milestones_api.add_course_content_milestone(
         unicode(self.course.id), unicode(self.entrance_exam.location),
         self.milestone_relationship_types['FULFILLS'], self.milestone)
     user = UserFactory()
     self.request = RequestFactory()
     self.request.user = user
     self.request.COOKIES = {}
     self.request.META = {}
     self.request.is_secure = lambda: True
     self.request.get_host = lambda: "edx.org"
     self.request.method = 'GET'
     self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
         self.course.id, user, self.entrance_exam)
     self.entrance_exam.is_entrance_exam = True
     self.entrance_exam.in_entrance_exam = True
     self.course.entrance_exam_enabled = True
     self.course.entrance_exam_minimum_score_pct = 0.50
     self.course.entrance_exam_id = unicode(
         self.entrance_exam.scope_ids.usage_id)
     modulestore().update_item(self.course, user.id)  # pylint: disable=no-member
예제 #53
0
 def setUp(self):
     super().setUp()
     self.course = CourseFactory.create(highlights_enabled_for_messaging=True)
     with self.store.bulk_operations(self.course.id):
         ItemFactory.create(parent=self.course, category='chapter', highlights=['good stuff'])
예제 #54
0
    def test_library_import(self):
        """
        Try importing a known good library archive, and verify that the
        contents of the library have completely replaced the old contents.
        """
        # Create some blocks to overwrite
        library = LibraryFactory.create(modulestore=self.store)
        lib_key = library.location.library_key
        test_block = ItemFactory.create(
            category="vertical",
            parent_location=library.location,
            user_id=self.user.id,
            publish_item=False,
        )
        test_block2 = ItemFactory.create(category="vertical",
                                         parent_location=library.location,
                                         user_id=self.user.id,
                                         publish_item=False)
        # Create a library and blocks that should remain unmolested.
        unchanged_lib = LibraryFactory.create()
        unchanged_key = unchanged_lib.location.library_key
        test_block3 = ItemFactory.create(
            category="vertical",
            parent_location=unchanged_lib.location,
            user_id=self.user.id,
            publish_item=False)
        test_block4 = ItemFactory.create(
            category="vertical",
            parent_location=unchanged_lib.location,
            user_id=self.user.id,
            publish_item=False)
        # Refresh library.
        library = self.store.get_library(lib_key)
        children = [
            self.store.get_item(child).url_name for child in library.children
        ]
        self.assertEqual(len(children), 2)
        self.assertIn(test_block.url_name, children)
        self.assertIn(test_block2.url_name, children)

        unchanged_lib = self.store.get_library(unchanged_key)
        children = [
            self.store.get_item(child).url_name
            for child in unchanged_lib.children
        ]
        self.assertEqual(len(children), 2)
        self.assertIn(test_block3.url_name, children)
        self.assertIn(test_block4.url_name, children)

        extract_dir = path(tempfile.mkdtemp(dir=settings.DATA_DIR))
        # the extract_dir needs to be passed as a relative dir to
        # import_library_from_xml
        extract_dir_relative = path.relpath(extract_dir, settings.DATA_DIR)

        try:
            with tarfile.open(
                    path(TEST_DATA_DIR) / 'imports' /
                    'library.HhJfPD.tar.gz') as tar:
                safetar_extractall(tar, extract_dir)
            library_items = import_library_from_xml(
                self.store,
                self.user.id,
                settings.GITHUB_REPO_ROOT, [extract_dir_relative / 'library'],
                load_error_modules=False,
                static_content_store=contentstore(),
                target_id=lib_key)
        finally:
            shutil.rmtree(extract_dir)

        self.assertEqual(lib_key, library_items[0].location.library_key)
        library = self.store.get_library(lib_key)
        children = [
            self.store.get_item(child).url_name for child in library.children
        ]
        self.assertEqual(len(children), 3)
        self.assertNotIn(test_block.url_name, children)
        self.assertNotIn(test_block2.url_name, children)

        unchanged_lib = self.store.get_library(unchanged_key)
        children = [
            self.store.get_item(child).url_name
            for child in unchanged_lib.children
        ]
        self.assertEqual(len(children), 2)
        self.assertIn(test_block3.url_name, children)
        self.assertIn(test_block4.url_name, children)
예제 #55
0
    def setUp(self):
        super(ContentGroupTestCase, self).setUp()

        self.course = CourseFactory.create(
            org='org',
            number='number',
            run='run',
            # This test needs to use a course that has already started --
            # discussion topics only show up if the course has already started,
            # and the default start date for courses is Jan 1, 2030.
            start=datetime(2012, 2, 3, tzinfo=UTC),
            user_partitions=[
                UserPartition(
                    0,
                    'Content Group Configuration',
                    '',
                    [Group(1, 'Alpha'), Group(2, 'Beta')],
                    scheme_id='cohort')
            ],
            grading_policy={
                "GRADER": [{
                    "type": "Homework",
                    "min_count": 1,
                    "drop_count": 0,
                    "short_label": "HW",
                    "weight": 1.0
                }]
            },
            cohort_config={'cohorted': True},
            discussion_topics={})

        seed_permissions_roles(self.course.id)

        self.staff_user = UserFactory.create(is_staff=True)
        self.alpha_user = UserFactory.create()
        self.beta_user = UserFactory.create()
        self.non_cohorted_user = UserFactory.create()
        self.community_ta = UserFactory.create(username="******")
        self.community_ta.roles.add(
            Role.objects.get(name="Community TA", course_id=self.course.id))
        for user in [
                self.staff_user, self.alpha_user, self.beta_user,
                self.non_cohorted_user, self.community_ta
        ]:
            CourseEnrollmentFactory.create(user=user, course_id=self.course.id)

        alpha_cohort = CohortFactory(
            course_id=self.course.id,
            name='Cohort Alpha',
            users=[self.alpha_user, self.community_ta, self.staff_user])
        beta_cohort = CohortFactory(course_id=self.course.id,
                                    name='Cohort Beta',
                                    users=[self.beta_user])
        CourseUserGroupPartitionGroup.objects.create(
            course_user_group=alpha_cohort,
            partition_id=self.course.user_partitions[0].id,
            group_id=self.course.user_partitions[0].groups[0].id)
        CourseUserGroupPartitionGroup.objects.create(
            course_user_group=beta_cohort,
            partition_id=self.course.user_partitions[0].id,
            group_id=self.course.user_partitions[0].groups[1].id)
        self.alpha_module = ItemFactory.create(
            parent_location=self.course.location,
            category='discussion',
            discussion_id='alpha_group_discussion',
            discussion_target='Visible to Alpha',
            group_access={
                self.course.user_partitions[0].id:
                [self.course.user_partitions[0].groups[0].id]
            })
        self.beta_module = ItemFactory.create(
            parent_location=self.course.location,
            category='discussion',
            discussion_id='beta_group_discussion',
            discussion_target='Visible to Beta',
            group_access={
                self.course.user_partitions[0].id:
                [self.course.user_partitions[0].groups[1].id]
            })
        self.global_module = ItemFactory.create(
            parent_location=self.course.location,
            category='discussion',
            discussion_id='global_group_discussion',
            discussion_target='Visible to Everyone')
        self.course = self.store.get_item(self.course.location)
    def add_split_test(self, groups=None):
        """
        Adds split test and two content groups to second course in courses list.
        """
        if groups is None:
            groups = self.groups

        self.split_test_user_partition = UserPartition(
            id=0,
            name='Partition 2',
            description='This is partition 2',
            groups=groups,
            scheme=RandomUserPartitionScheme)

        self.split_test_user_partition.scheme.name = "random"

        sequential = ItemFactory.create(
            parent_location=self.chapter.location,
            category='sequential',
            display_name="Lesson 2",
            publish_item=True,
        )

        vertical = ItemFactory.create(
            parent_location=sequential.location,
            category='vertical',
            display_name='Subsection 3',
            publish_item=True,
        )

        split_test_unit = ItemFactory.create(
            parent_location=vertical.location,
            category='split_test',
            user_partition_id=0,
            display_name="Test Content Experiment 1",
        )

        condition_1_vertical = ItemFactory.create(
            parent_location=split_test_unit.location,
            category="vertical",
            display_name="Group ID 1",
        )

        condition_2_vertical = ItemFactory.create(
            parent_location=split_test_unit.location,
            category="vertical",
            display_name="Group ID 2",
        )

        ItemFactory.create(
            parent_location=condition_1_vertical.location,
            category="html",
            display_name="Group A",
            publish_item=True,
        )

        ItemFactory.create(
            parent_location=condition_2_vertical.location,
            category="html",
            display_name="Group B",
            publish_item=True,
        )

        self.courses[1].user_partitions = [self.split_test_user_partition]
        self.courses[1].save()
        modulestore().update_item(self.courses[1], self.user.id)
예제 #57
0
    def setup_course_with_grading(self, start=None, end=None):
        grading_course = CourseFactory.create(
            start=start,
            end=end,
            org='gradeX',
            run='GRAD1',
            display_name="Test Grading Course",
            grading_policy={
                "GRADER": [
                    {
                        "type": "Homework",
                        "min_count": 1,
                        "drop_count": 0,
                        "short_label": "HW",
                        "weight": 0.5
                    },
                    {
                        "type": "Midterm Exam",
                        "min_count": 1,
                        "drop_count": 0,
                        "short_label": "ME",
                        "weight": 0.5
                    },
                ],
                "GRADE_CUTOFFS": {
                    'A': .9,
                    'B': .33
                }
            },
        )

        test_data = '<html>{}</html>'.format(str(uuid.uuid4()))
        chapter1 = ItemFactory.create(category="chapter",
                                      parent_location=grading_course.location,
                                      data=test_data,
                                      display_name="Chapter 1")
        chapter2 = ItemFactory.create(category="chapter",
                                      parent_location=grading_course.location,
                                      data=test_data,
                                      display_name="Chapter 2")
        ItemFactory.create(
            category="sequential",
            parent_location=chapter1.location,
            data=test_data,
            display_name="Sequence 1",
        )
        sequential2 = ItemFactory.create(category="sequential",
                                         parent_location=chapter2.location,
                                         data=test_data,
                                         display_name="Sequence 2",
                                         graded=True,
                                         metadata={
                                             'rerandomize': 'always',
                                             'graded': True,
                                             'format': "Homework"
                                         })
        vertical1 = ItemFactory.create(
            category="vertical",
            parent_location=sequential2.location,
            data=test_data,
            display_name="Vertical 1",
        )
        sequential3 = ItemFactory.create(category="sequential",
                                         parent_location=chapter2.location,
                                         data=test_data,
                                         display_name="Sequence 3",
                                         graded=True,
                                         metadata={
                                             'rerandomize': 'always',
                                             'graded': True,
                                             'format': "Midterm Exam"
                                         })
        vertical2 = ItemFactory.create(
            category="vertical",
            parent_location=sequential3.location,
            data=test_data,
            display_name="Vertical 2",
        )
        item = ItemFactory.create(
            parent_location=vertical1.location,
            category='mentoring',
            data=StringResponseXMLFactory().build_xml(answer='foo'),
            display_name=u"test mentoring homework",
        )
        item2 = ItemFactory.create(
            parent_location=vertical2.location,
            category='mentoring',
            data=StringResponseXMLFactory().build_xml(answer='bar'),
            display_name=u"test mentoring midterm",
        )

        grading_course = self.store.get_course(grading_course.id)
        setattr(grading_course, 'homework_assignment', item)
        setattr(grading_course, 'midterm_assignment', item2)
        return grading_course
예제 #58
0
    def test_has_access_in_preview_mode_with_group(self):
        """
        Test that a user masquerading as a member of a group sees appropriate content in preview mode.
        """
        # Note about UserPartition and UserPartition Group IDs: these must not conflict with IDs used
        # by dynamic user partitions.
        partition_id = MINIMUM_STATIC_PARTITION_ID
        group_0_id = MINIMUM_STATIC_PARTITION_ID + 1
        group_1_id = MINIMUM_STATIC_PARTITION_ID + 2
        user_partition = UserPartition(
            partition_id,
            'Test User Partition',
            '', [Group(group_0_id, 'Group 1'),
                 Group(group_1_id, 'Group 2')],
            scheme_id='cohort')
        self.course.user_partitions.append(user_partition)
        self.course.cohort_config = {'cohorted': True}

        chapter = ItemFactory.create(category="chapter",
                                     parent_location=self.course.location)
        chapter.group_access = {partition_id: [group_0_id]}

        modulestore().update_item(self.course, ModuleStoreEnum.UserID.test)

        # User should not be able to preview when masquerading as student (and not in the group above).
        with patch('courseware.access.get_user_role') as mock_user_role:
            mock_user_role.return_value = 'student'
            self.assertFalse(
                bool(
                    access.has_access(self.global_staff,
                                      'load',
                                      chapter,
                                      course_key=self.course.id)))

        # Should be able to preview when in staff or instructor role.
        for mocked_role in ['staff', 'instructor']:
            with patch('courseware.access.get_user_role') as mock_user_role:
                mock_user_role.return_value = mocked_role
                self.assertTrue(
                    bool(
                        access.has_access(self.global_staff,
                                          'load',
                                          chapter,
                                          course_key=self.course.id)))

        # Now install masquerade group and set staff as a member of that.
        self.assertEqual(
            200,
            masquerade_as_group_member(self.global_staff, self.course,
                                       partition_id, group_0_id))
        # Can load the chapter since user is in the group.
        self.assertTrue(
            bool(
                access.has_access(self.global_staff,
                                  'load',
                                  chapter,
                                  course_key=self.course.id)))

        # Move the user to be a part of the second group.
        self.assertEqual(
            200,
            masquerade_as_group_member(self.global_staff, self.course,
                                       partition_id, group_1_id))
        # Cannot load the chapter since user is in a different group.
        self.assertFalse(
            bool(
                access.has_access(self.global_staff,
                                  'load',
                                  chapter,
                                  course_key=self.course.id)))
예제 #59
0
 def setUp(self):
     super(TestCourseUpdateResolver, self).setUp()
     self.course = CourseFactory(highlights_enabled_for_messaging=True, self_paced=True)
     with self.store.bulk_operations(self.course.id):
         ItemFactory.create(parent=self.course, category='chapter', highlights=[u'good stuff'])
예제 #60
0
    def setUp(self):
        """
        Set up a course with graded problems within a split test.

        Course hierarchy is as follows (modeled after how split tests
        are created in studio):
        -> course
            -> chapter
                -> sequential (graded)
                    -> vertical
                        -> split_test
                            -> vertical (Group A)
                                -> problem
                            -> vertical (Group B)
                                -> problem
        """
        super(TestConditionalContent, self).setUp()

        # Create user partitions
        self.user_partition_group_a = 0
        self.user_partition_group_b = 1
        self.partition = UserPartition(
            0, 'first_partition', 'First Partition', [
                Group(self.user_partition_group_a, 'Group A'),
                Group(self.user_partition_group_b, 'Group B')
            ])

        # Create course with group configurations and grading policy
        self.course = CourseFactory.create(user_partitions=[self.partition],
                                           grading_policy={
                                               "GRADER": [{
                                                   "type": "Homework",
                                                   "min_count": 1,
                                                   "drop_count": 0,
                                                   "short_label": "HW",
                                                   "weight": 1.0
                                               }]
                                           })
        chapter = ItemFactory.create(parent_location=self.course.location,
                                     display_name='Chapter')

        # add a sequence to the course to which the problems can be added
        self.problem_section = ItemFactory.create(
            parent_location=chapter.location,
            category='sequential',
            metadata={
                'graded': True,
                'format': 'Homework'
            },
            display_name=self.TEST_SECTION_NAME)

        # Create users and partition them
        self.student_a = UserFactory.create(username='******',
                                            email='*****@*****.**')
        CourseEnrollmentFactory.create(user=self.student_a,
                                       course_id=self.course.id)
        self.student_b = UserFactory.create(username='******',
                                            email='*****@*****.**')
        CourseEnrollmentFactory.create(user=self.student_b,
                                       course_id=self.course.id)

        UserCourseTagFactory(
            user=self.student_a,
            course_id=self.course.id,
            key='xblock.partition_service.partition_{0}'.format(
                self.partition.id),
            value=str(self.user_partition_group_a))
        UserCourseTagFactory(
            user=self.student_b,
            course_id=self.course.id,
            key='xblock.partition_service.partition_{0}'.format(
                self.partition.id),
            value=str(self.user_partition_group_b))

        # Create a vertical to contain our split test
        problem_vertical = ItemFactory.create(
            parent_location=self.problem_section.location,
            category='vertical',
            display_name='Problem Unit')

        # Create the split test and child vertical containers
        vertical_a_url = self.course.id.make_usage_key(
            'vertical', 'split_test_vertical_a')
        vertical_b_url = self.course.id.make_usage_key(
            'vertical', 'split_test_vertical_b')
        self.split_test = ItemFactory.create(
            parent_location=problem_vertical.location,
            category='split_test',
            display_name='Split Test',
            user_partition_id=self.partition.id,
            group_id_to_child={
                str(index): url
                for index, url in enumerate([vertical_a_url, vertical_b_url])
            })
        self.vertical_a = ItemFactory.create(
            parent_location=self.split_test.location,
            category='vertical',
            display_name='Group A problem container',
            location=vertical_a_url)
        self.vertical_b = ItemFactory.create(
            parent_location=self.split_test.location,
            category='vertical',
            display_name='Group B problem container',
            location=vertical_b_url)