def test_can_generate_not_whitelisted(self):
     """
     Test handling when user is not whitelisted
     """
     u = UserFactory()
     cr = CourseFactory()
     key = cr.id  # pylint: disable=no-member
     CourseEnrollmentFactory(
         user=u,
         course_id=key,
         is_active=True,
         mode="verified",
     )
     assert not can_generate_allowlist_certificate(u, key)
Beispiel #2
0
    def setUp(self):
        super().setUp()

        self.global_staff = GlobalStaffFactory()
        self.user = UserFactory()
        self.course_run = CourseFactory()
        self.course_run_key = self.course_run.id  # pylint: disable=no-member

        CourseEnrollmentFactory(
            user=self.user,
            course_id=self.course_run_key,
            is_active=True,
            mode="verified",
        )
Beispiel #3
0
    def setUpClass(cls):
        super(CourseTeamTest, cls).setUpClass()
        cls.course_id = "edx/the-course/1"
        cls.course1 = create_course(CourseKey.from_string(cls.course_id), TEAMS_CONFIG_1)

        cls.audit_learner = UserFactory.create(username="******")
        CourseEnrollmentFactory.create(user=cls.audit_learner, course_id="edx/the-course/1", mode=CourseMode.AUDIT)
        cls.audit_team = CourseTeamFactory(
            course_id="edx/the-course/1",
            team_id="audit-team",
            topic_id=TEAMSET_1_ID,
            name="The Team"
        )

        cls.masters_learner = UserFactory.create(username="******")
        CourseEnrollmentFactory.create(user=cls.masters_learner, course_id="edx/the-course/1", mode=CourseMode.MASTERS)
        cls.masters_team = CourseTeamFactory(
            course_id="edx/the-course/1",
            team_id="masters-team",
            topic_id=TEAMSET_1_ID,
            name="The Team",
            organization_protected=True
        )
 def test_upgrade_deadline_instructor_paced(self):
     course = CourseFactory(self_paced=False)
     course_upgrade_deadline = datetime.datetime.now(
         pytz.UTC) + datetime.timedelta(days=1)
     CourseModeFactory(
         course_id=course.id,
         mode_slug=CourseMode.VERIFIED,
         # This must be in the future to ensure it is returned by downstream code.
         expiration_datetime=course_upgrade_deadline)
     enrollment = CourseEnrollmentFactory(course_id=course.id,
                                          mode=CourseMode.AUDIT)
     DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
     assert enrollment.schedule is not None
     assert enrollment.upgrade_deadline == course_upgrade_deadline
Beispiel #5
0
def test_get_course_info_for_application_review(courses, user_with_profile):
    """
    Tests that `get_course_info_for_application_review` returns expected data for application review.
    """
    course1 = courses['test_course1']
    course2 = courses['test_course2']
    course3 = CourseOverviewFactory()

    CourseEnrollmentFactory(user=user_with_profile, course=course2)
    PersistentCourseGradeFactory(
        user_id=user_with_profile.id, course_id=course2.id, percent_grade=1.0, letter_grade='A'
    )

    CourseEnrollmentFactory(user=user_with_profile, course=course3)

    actual_courses_info = get_course_info_for_application_review([course1, course2, course3], user_with_profile)

    expected_courses_info = {
        course1.display_name: NOT_STARTED,
        course2.display_name: '100%',
        course3.display_name: IN_PROGRESS,
    }
    assert actual_courses_info == expected_courses_info
    def setUp(self):
        super(TestCourseSockView, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
        self.user = UserFactory.create()

        # Enroll the user in the four courses
        CourseEnrollmentFactory.create(user=self.user, course_id=self.standard_course.id)
        CourseEnrollmentFactory.create(user=self.user, course_id=self.verified_course.id)
        CourseEnrollmentFactory.create(user=self.user, course_id=self.verified_course_update_expired.id)
        CourseEnrollmentFactory.create(
            user=self.user, course_id=self.verified_course_already_enrolled.id, mode=CourseMode.VERIFIED
        )

        CommerceConfiguration.objects.create(enabled=True, checkout_on_ecommerce_service=True)

        # Log the user in
        self.client.login(username=self.user.username, password=TEST_PASSWORD)
Beispiel #7
0
    def test_remove_from_team(self):
        # Given a user already in a course and on a team
        user = UserFactory.create(username='******')
        mode = 'audit'
        CourseEnrollmentFactory.create(user=user,
                                       course_id=self.course.id,
                                       mode=mode)
        team = CourseTeamFactory(course_id=self.course.id,
                                 name='team_1',
                                 topic_id='teamset_1')
        team.add_user(user)
        assert CourseTeamMembership.is_user_on_team(user, team)

        # When I try to remove them from the team
        csv_data = self._csv_reader_from_array([
            ['user', 'mode', 'teamset_1'],
            [user.username, mode, ''],
        ])
        result = self.import_manager.set_team_memberships(csv_data)  # lint-amnesty, pylint: disable=unused-variable

        # Then they are removed from the team and the correct events are issued
        assert not CourseTeamMembership.is_user_on_team(user, team)
        self.assert_learner_removed_emitted(team.team_id, user.id)
Beispiel #8
0
    def setUp(self):  # pylint: disable=arguments-differ
        super().setUp('lms.djangoapps.certificates.utils.tracker')

        # Create user, a course run, and an enrollment
        self.u = UserFactory()
        self.cr = CourseFactory()
        self.key = self.cr.id  # pylint: disable=no-member
        CourseEnrollmentFactory(
            user=self.u,
            course_id=self.key,
            is_active=True,
            mode='verified',
        )
        self.gen_mode = 'batch'
    def test_updated_when_new_start_in_past(self):
        course = _create_course_run(
            self_paced=True, start_day_offset=5)  # course starts in future
        enrollment = CourseEnrollmentFactory(course_id=course.id,
                                             mode=CourseMode.AUDIT)
        previous_start = enrollment.course.start
        self.assert_schedule_dates(enrollment.schedule, previous_start)

        course.start = course.start + datetime.timedelta(
            days=-10)  # new course start changes to a past date
        self.store.update_item(course, ModuleStoreEnum.UserID.test)
        enrollment = CourseEnrollment.objects.get(id=enrollment.id)
        self.assert_schedule_dates(
            enrollment.schedule, course.start)  # start set to new course start
Beispiel #10
0
    def test_chunked_queries_send_numerous_emails(self, email_mock):
        """
        Test sending a large number of emails, to test the chunked querying
        """
        mock_factory = MockCourseEmailResult()
        email_mock.side_effect = mock_factory.get_mock_update_subtask_status()
        added_users = []
        for _ in range(LARGE_NUM_EMAILS):
            user = UserFactory()
            added_users.append(user)
            CourseEnrollmentFactory.create(user=user, course_id=self.course.id)

        optouts = []
        for i in [1, 3, 9, 10, 18]:  # 5 random optouts
            user = added_users[i]
            optouts.append(user)
            optout = Optout(user=user, course_id=self.course.id)
            optout.save()

        test_email = {
            'action': 'Send email',
            'send_to': '["myself", "staff", "learners"]',
            'subject': 'test subject for all',
            'message': 'test message for all'
        }
        response = self.client.post(self.send_mail_url, test_email)
        assert json.loads(
            response.content.decode('utf-8')) == self.success_content

        assert mock_factory.emails_sent == \
               ((((1 + len(self.staff)) + len(self.students)) + LARGE_NUM_EMAILS) - len(optouts))
        outbox_contents = [e.to[0] for e in mail.outbox]
        should_send_contents = (
            [self.instructor.email] + [s.email for s in self.staff] +
            [s.email for s in self.students] +
            [s.email for s in added_users if s not in optouts])
        six.assertCountEqual(self, outbox_contents, should_send_contents)
    def test_with_two_verifications(self):
        # checking if a user has two verification and but most recent verification course deadline is expired

        self._setup_mode_and_enrollment(self.DATES[self.FUTURE], "verified")

        # The student has an approved verification
        attempt = SoftwareSecurePhotoVerification.objects.create(
            user=self.user)
        attempt.mark_ready()
        attempt.submit()
        attempt.approve()
        # Making created at to previous date to differentiate with 2nd attempt.
        attempt.created_at = datetime.now(UTC) - timedelta(days=1)
        attempt.save()

        # Expect that the successfully verified message is shown
        self._assert_course_verification_status(VERIFY_STATUS_APPROVED)

        # Check that the "verification good until" date is displayed
        response = self.client.get(self.dashboard_url)
        self.assertContains(response,
                            attempt.expiration_datetime.strftime("%m/%d/%Y"))

        # Adding another verification with different course.
        # Its created_at is greater than course deadline.
        course2 = CourseFactory.create()
        CourseModeFactory.create(course_id=course2.id,
                                 mode_slug="verified",
                                 expiration_datetime=self.DATES[self.PAST])
        CourseEnrollmentFactory(course_id=course2.id,
                                user=self.user,
                                mode="verified")

        # The student has an approved verification
        attempt2 = SoftwareSecurePhotoVerification.objects.create(
            user=self.user)
        attempt2.mark_ready()
        attempt2.submit()
        attempt2.approve()
        attempt2.save()

        # Mark the attemp2 as approved so its date will appear on dasboard.
        self._assert_course_verification_status(VERIFY_STATUS_APPROVED)
        response2 = self.client.get(self.dashboard_url)
        self.assertContains(response2,
                            attempt2.expiration_datetime.strftime("%m/%d/%Y"))
        self.assertContains(response2,
                            attempt2.expiration_datetime.strftime("%m/%d/%Y"),
                            count=2)
    def test_can_generate_audit(self):
        """
        Test handling when user is enrolled in audit mode
        """
        u = UserFactory()
        cr = CourseFactory()
        key = cr.id  # pylint: disable=no-member
        CourseEnrollmentFactory(
            user=u,
            course_id=key,
            is_active=True,
            mode="audit",
        )

        assert not _can_generate_v2_certificate(u, key)
    def test_cert_status_none(self):
        """
        Test cert status when the user has no cert
        """
        u = UserFactory()
        cr = CourseFactory()
        key = cr.id  # pylint: disable=no-member
        CourseEnrollmentFactory(
            user=u,
            course_id=key,
            is_active=True,
            mode="verified",
        )

        assert _set_v2_cert_status(u, key) == CertificateStatuses.notpassing
Beispiel #14
0
    def setUp(self):
        super().setUp()
        self.user = UserFactory.create()
        self.verified_course = CourseFactory.create(self_paced=True, )
        self.verified_course_key = self.verified_course.id  # pylint: disable=no-member
        self.verified_enrollment = CourseEnrollmentFactory(
            user=self.user,
            course_id=self.verified_course_key,
            is_active=True,
            mode='verified',
        )
        CertificateAllowlistFactory(user=self.user,
                                    course_id=self.verified_course_key)

        self.audit_course = CourseFactory.create(self_paced=False)
        self.audit_course_key = self.audit_course.id  # pylint: disable=no-member
        self.audit_enrollment = CourseEnrollmentFactory(
            user=self.user,
            course_id=self.audit_course_key,
            is_active=True,
            mode='audit',
        )
        CertificateAllowlistFactory(user=self.user,
                                    course_id=self.audit_course_key)
Beispiel #15
0
    def test_view_course_appears_on_dashboard(self):
        """
        When a course doesn't have completion data, its course card should
        display a "View Course" button.
        """
        self.override_waffle_switch(True)

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

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

        course_key_string = str(course.id)
        # No completion data means there's no block from which to resume.
        resume_block_key_string = ''
        course_run_string = self._pull_course_run_from_course_key(course_key_string)

        view_button_html = self._get_html_for_view_course_button(
            course_key_string,
            course_run_string
        )
        resume_button_html = self._get_html_for_resume_course_button(
            course_key_string,
            resume_block_key_string,
            course_run_string
        )

        view_button_html = self._remove_whitespace_from_html_string(view_button_html)
        resume_button_html = self._remove_whitespace_from_html_string(resume_button_html)
        dashboard_html = self._remove_whitespace_from_response(response)

        assert view_button_html in dashboard_html
        assert resume_button_html not in dashboard_html
    def make_valid_goal(self, **kwargs):
        """Creates a goal that will cause an email to be sent as the goal is valid but has been missed"""
        kwargs.setdefault('days_per_week', 6)
        kwargs.setdefault('subscribed_to_reminders', True)
        kwargs.setdefault('overview__start', datetime(2021, 1, 1, tzinfo=UTC))
        kwargs.setdefault('overview__end',
                          datetime(2021, 4, 1,
                                   tzinfo=UTC))  # Have it end in the future
        goal = CourseGoalFactory(**kwargs)

        with freeze_time(
                '2021-02-01 10:00:00'):  # Create enrollment before March
            CourseEnrollmentFactory(user=goal.user, course_id=goal.course_key)

        return goal
Beispiel #17
0
    def test_enroll_mb_create_external_id(self):
        course_run_key = self.program['courses'][0]['course_runs'][0]['key']

        # Enroll user
        enrollment = CourseEnrollmentFactory.create(
            course_id=course_run_key,
            user=self.user,
            mode=CourseMode.VERIFIED,
        )
        enrollment.save()
        external_id = ExternalId.objects.get(
            user=self.user
        )
        assert external_id is not None
        assert external_id.external_id_type.name == ExternalIdType.MICROBACHELORS_COACHING
Beispiel #18
0
 def setUp(self):
     super(PassingGradeCertsTest, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
     self.course = CourseFactory.create(
         self_paced=True,
     )
     self.user = UserFactory.create()
     self.enrollment = CourseEnrollmentFactory(
         user=self.user,
         course_id=self.course.id,
         is_active=True,
         mode="verified",
     )
     self.ip_course = CourseFactory.create(self_paced=False)
     self.ip_enrollment = CourseEnrollmentFactory(
         user=self.user,
         course_id=self.ip_course.id,
         is_active=True,
         mode="verified",
     )
     attempt = SoftwareSecurePhotoVerification.objects.create(
         user=self.user,
         status='submitted'
     )
     attempt.approve()
 def test_is_on_allowlist_false(self):
     """
     Test the absence of the user on the allowlist
     """
     u = UserFactory()
     CourseEnrollmentFactory(
         user=u,
         course_id=self.course_run_key,
         is_active=True,
         mode=GeneratedCertificate.MODES.verified,
     )
     CertificateAllowlistFactory.create(course_id=self.course_run_key,
                                        user=u,
                                        allowlist=False)
     assert not is_on_certificate_allowlist(u, self.course_run_key)
    def test_handle_audit_status(self):
        """
        Test handling of a user who is not passing and is enrolled in audit mode
        """
        different_user = UserFactory()
        CourseEnrollmentFactory(
            user=different_user,
            course_id=self.course_run_key,
            is_active=True,
            mode=GeneratedCertificate.MODES.audit,
        )

        assert _set_v2_cert_status(different_user, self.course_run_key) is None
        assert not generate_regular_certificate_task(different_user,
                                                     self.course_run_key)
 def test_can_generate_not_allowlisted(self):
     """
     Test handling when user is not on the certificate allowlist.
     """
     u = UserFactory()
     cr = CourseFactory()
     key = cr.id  # pylint: disable=no-member
     CourseEnrollmentFactory(
         user=u,
         course_id=key,
         is_active=True,
         mode=GeneratedCertificate.MODES.verified,
     )
     assert not _can_generate_allowlist_certificate(u, key)
     assert _set_allowlist_cert_status(u, key) is None
Beispiel #22
0
    def setup_partitions_and_course(self, active=True):
        """
        Setup course structure and create user for user partition
        transformer test.
        Args:
            active: boolean representing if the user partitions are
            active or not
        """
        # Set up user partitions and groups.
        self.setup_groups_partitions(active=active)
        self.user_partition = self.user_partitions[0]

        # Build course.
        self.course_hierarchy = self.get_course_hierarchy()
        self.blocks = self.build_course(self.course_hierarchy)
        self.course = self.blocks['course']

        # Enroll user in course.
        CourseEnrollmentFactory.create(
            user=self.user, course_id=self.course.id, is_active=True
        )

        # Set up cohorts.
        self.setup_cohorts(self.course)
Beispiel #23
0
    def setUp(self):
        super(TestGradebook, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments

        instructor = AdminFactory.create()
        self.client.login(username=instructor.username, password='******')
        self.users = [UserFactory.create() for _ in range(USER_COUNT)]

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

        for i, item in enumerate(self.items):
            for j, user in enumerate(self.users):
                StudentModuleFactory.create(grade=1 if i < j else 0,
                                            max_grade=1,
                                            student=user,
                                            course_id=self.course.id,
                                            module_state_key=item.location)
        task_compute_all_grades_for_course.apply_async(
            kwargs={'course_key': text_type(self.course.id)})

        self.response = self.client.get(
            reverse('spoc_gradebook', args=(text_type(self.course.id), )))

        self.assertEqual(self.response.status_code, 200)
Beispiel #24
0
    def setUp(self):
        super().setUp()

        # Configure course as a credit course
        CreditCourse.objects.create(course_key=self.course.id, enabled=True)

        # Configure credit requirements (passing grade and in-course reverification)
        credit_api.set_credit_requirements(
            self.course.id, [{
                "namespace": "grade",
                "name": "grade",
                "display_name": self.MIN_GRADE_REQ_DISPLAY,
                "criteria": {
                    "min_grade": 0.8
                }
            }, {
                "namespace": "reverification",
                "name": "midterm",
                "display_name": self.VERIFICATION_REQ_DISPLAY,
                "criteria": {}
            }])

        # Create a user and log in
        self.user = UserFactory.create(username=self.USERNAME,
                                       password=self.PASSWORD)
        self.user.profile.name = self.USER_FULL_NAME
        self.user.profile.save()

        result = self.client.login(username=self.USERNAME,
                                   password=self.PASSWORD)
        assert result, 'Could not log in'

        # Enroll the user in the course as "verified"
        self.enrollment = CourseEnrollmentFactory(user=self.user,
                                                  course_id=self.course.id,
                                                  mode="verified")
Beispiel #25
0
    def test_grade_not_appears_before_cert_available_date(self):
        """
        Verify that learners are able to see their final grade of the course in
        the learner dashboard after the course had ended
        """
        self.course_key = CourseKey.from_string('course-v1:edX+DemoX+Demo_Course')
        self.course = CourseOverviewFactory.create(id=self.course_key, end_date=self.THREE_YEARS_AGO,
                                                   certificate_available_date=self.TOMORROW,
                                                   lowest_passing_grade=0.3)
        self.course_enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user)
        GeneratedCertificateFactory(status='notpassing', course_id=self.course.id, user=self.user, grade=0.45)

        response = self.client.get(reverse('dashboard'))
        self.assertNotContains(response, 'Your final grade:')
        self.assertNotContains(response, '<span class="grade-value">45%</span>')
Beispiel #26
0
    def test_create_new_team_from_import(self):
        # Given a user in a course
        user = UserFactory.create(username='******')
        mode = 'audit'
        CourseEnrollmentFactory.create(user=user,
                                       course_id=self.course.id,
                                       mode=mode)

        # When I add them to a team that does not exist
        assert CourseTeam.objects.all().count() == 0
        csv_data = self._csv_reader_from_array([
            ['username', 'mode', 'teamset_1'],
            [user.username, mode, 'new_exciting_team'],
        ])
        result = self.import_manager.set_team_memberships(csv_data)  # lint-amnesty, pylint: disable=unused-variable

        # Then a new team is created
        assert CourseTeam.objects.all().count() == 1

        # ... and the user is assigned to the team
        new_team = CourseTeam.objects.get(topic_id='teamset_1',
                                          name='new_exciting_team')
        assert CourseTeamMembership.is_user_on_team(user, new_team)
        self.assert_learner_added_emitted(new_team.team_id, user.id)
    def _setup_mode_and_enrollment(self, deadline, enrollment_mode):
        """Create a course mode and enrollment.

        Arguments:
            deadline (datetime): The deadline for submitting your verification.
            enrollment_mode (str): The mode of the enrollment.

        """
        CourseModeFactory.create(course_id=self.course.id,
                                 mode_slug="verified",
                                 expiration_datetime=deadline)
        CourseEnrollmentFactory(course_id=self.course.id,
                                user=self.user,
                                mode=enrollment_mode)
        VerificationDeadline.set_deadline(self.course.id, deadline)
    def test_can_receive_discount_entitlement(self, entitlement_mode):
        """
        Ensure that only users who have not already purchased courses receive the discount.
        """
        CourseEnrollmentFactory(is_active=True,
                                course_id=self.course.id,
                                user=self.user)

        if entitlement_mode is not None:
            CourseEntitlementFactory.create(mode=entitlement_mode,
                                            user=self.user)

        applicability = can_receive_discount(user=self.user,
                                             course=self.course)
        assert applicability == (entitlement_mode is None)
    def create_resolver(self):
        """
        Creates a CourseUpdateResolver with an enrollment to schedule.
        """
        enrollment = CourseEnrollmentFactory(course_id=self.course.id,
                                             user=self.user,
                                             mode='audit')

        return CourseUpdateResolver(
            async_send_task=Mock(name='async_send_task'),
            site=self.site_config.site,
            target_datetime=enrollment.schedule.start_date,
            day_offset=-7,
            bin_num=CourseUpdateResolver.bin_num_for_user_id(self.user.id),
        )
Beispiel #30
0
    def test_send_to_track_other_enrollments(self):
        """
        Failing test for EDUCATOR-217: verifies that emails are only sent to
        users in a specific track if they're in that track in the course the
        email is being sent from.
        """
        # Create a mode and designate an enrolled user to be placed in that mode
        CourseMode.objects.create(mode_slug='test_mode', course_id=self.course.id)
        test_mode_student = self.students[0]
        update_enrollment(test_mode_student, str(self.course.id), 'test_mode')

        # Take another user already enrolled in the course, then enroll them in
        # another course but in that same test mode
        test_mode_student_other_course = self.students[1]
        other_course = CourseFactory.create()
        CourseMode.objects.create(mode_slug='test_mode', course_id=other_course.id)
        CourseEnrollmentFactory.create(
            user=test_mode_student_other_course,
            course_id=other_course.id
        )
        update_enrollment(test_mode_student_other_course, str(other_course.id), 'test_mode')

        # Send the emails...
        test_email = {
            'action': 'Send email',
            'send_to': '["track:test_mode"]',
            'subject': 'test subject for test_mode track',
            'message': 'test message for test_mode track',
        }
        response = self.client.post(self.send_mail_url, test_email)
        assert json.loads(response.content.decode('utf-8')) == self.success_content

        # Only the the student in the test mode in the course the email was
        # sent from should receive an email
        assert len(mail.outbox) == 1
        assert mail.outbox[0].to[0] == test_mode_student.email