def SCHEMA_ANNOTATIONS_DICT(cls):  # pylint: disable-msg=g-bad-name
        """Schema annotations are dynamic and include a list of courses."""

        # Make a list of courses user has the rights to.
        course_list = []
        for acourse in sites.get_all_courses():
            if not roles.Roles.is_course_admin(acourse):
                continue
            if acourse == sites.get_course_for_current_request():
                continue
            course_list.append({
                'value': acourse.raw,
                'label': cgi.escape(acourse.get_title())})

        if not course_list:
            return None

        # Format annotations.
        return [
            (['title'], 'Import Course'),
            (
                ['properties', 'course', '_inputex'],
                {
                    'label': 'Available Courses',
                    '_type': 'select',
                    'choices': course_list})]
Example #2
0
    def SCHEMA_ANNOTATIONS_DICT(cls):  # pylint: disable-msg=g-bad-name
        """Schema annotations are dynamic and include a list of courses."""

        # Make a list of courses user has the rights to.
        course_list = []
        for acourse in sites.get_all_courses():
            if not roles.Roles.is_course_admin(acourse):
                continue
            if acourse == sites.get_course_for_current_request():
                continue
            course_list.append({
                'value': acourse.raw,
                'label': acourse.get_title()
            })

        if not course_list:
            return None

        # Format annotations.
        return [(['title'], 'Import Course'),
                (['properties', 'course', '_inputex'], {
                    'label': 'Available Courses',
                    '_type': 'select',
                    'choices': course_list
                })]
 def can_add(cls):
     if roles.Roles.is_super_admin():
         return True
     for course_context in sites.get_all_courses():
         if roles.Roles.is_course_admin(course_context):
             return True
     return False
Example #4
0
def get_visible_courses():
    result = []
    for app_context in sorted(sites.get_all_courses()):
        with Namespace(app_context.namespace):
            if DashboardHandler.current_user_has_access(app_context):
                result.append(app_context)
    return result
    def test_old_assessment_availability(self):
        actions.login(ADMIN_EMAIL, is_admin=True)
        new_course_context = actions.simple_add_course(
            'new_course', ADMIN_EMAIL, 'My New Course')
        new_course = courses.Course(None, new_course_context)
        new_course.import_from(
            sites.get_all_courses(rules_text='course:/:/')[0])
        new_course.save()

        # Prove that there are at least some assessments in this course.
        assessments = new_course.get_units_of_type(verify.UNIT_TYPE_ASSESSMENT)
        self.assertIsNotNone(assessments[0])

        # Get the first Unit
        unit = new_course.get_units_of_type(verify.UNIT_TYPE_UNIT)[0]

        unit_rest_handler = unit_lesson_editor.UnitRESTHandler()
        schema = unit_rest_handler.get_schema(
            new_course, unit.unit_id).get_schema_dict()

        # Verify that there are 4 valid choices for pre- or post-asssments
        # for this unit
        choices = self._get_selection_choices(
            schema, ['properties', 'pre_assessment', '_inputex'])
        self.assertEquals(5, len(choices))
        self.assertEquals(-1, choices['-- None --'])

        choices = self._get_selection_choices(
            schema, ['properties', 'post_assessment', '_inputex'])
        self.assertEquals(5, len(choices))
        self.assertEquals(-1, choices['-- None --'])
Example #6
0
def update_course_config(name, settings):
    """Merge settings into the saved course.yaml configuration.

    Args:
      name: Name of the course.  E.g., 'my_test_course'.
      settings: A nested dict of name/value settings.  Names for items here
          can be found in modules/dashboard/course_settings.py in
          create_course_registry.  See below in simple_add_course()
          for an example.
    Returns:
      Context object for the modified course.
    """
    site_type = 'course'
    namespace = 'ns_%s' % name
    slug = '/%s' % name
    rule = '%s:%s::%s' % (site_type, slug, namespace)

    context = sites.get_all_courses(rule)[0]
    environ = courses.deep_dict_merge(settings,
                                      courses.Course.get_environ(context))
    course = courses.Course(handler=None, app_context=context)
    course.save_settings(environ)
    course_config = config.Registry.test_overrides.get(
        sites.GCB_COURSES_CONFIG.name, 'course:/:/')
    if rule not in course_config:
        course_config = '%s, %s' % (rule, course_config)
        sites.setup_courses(course_config)
    return context
    def test_old_assessment_assignment(self):
        new_course_context = actions.simple_add_course(
            'new_course', ADMIN_EMAIL, 'My New Course')
        new_course = courses.Course(None, new_course_context)
        new_course.import_from(
            sites.get_all_courses(rules_text='course:/:/')[0])
        new_course.save()

        unit_rest_handler = unit_lesson_editor.UnitRESTHandler()
        unit_rest_handler.app_context = new_course_context

        # Use REST handler function to save pre/post handlers on one unit.
        errors = []
        unit = new_course.get_units_of_type(verify.UNIT_TYPE_UNIT)[0]
        assessment = new_course.get_units_of_type(
            verify.UNIT_TYPE_ASSESSMENT)[0]
        unit_rest_handler.apply_updates(
            unit,
            {
                'title': unit.title,
                'now_available': unit.now_available,
                'label_groups': [],
                'pre_assessment': assessment.unit_id,
                'post_assessment': -1,
                'show_contents_on_one_page': False,
                'manual_progress': False,
                'description': None,
                'unit_header': None,
                'unit_footer': None,
            }, errors)
        assert not errors
Example #8
0
    def test_unicode_pages(self):
        # TODO(emichael): Remove try, except, else when the unicode issue
        # is fixed in dev_appserver.
        try:
            sites.setup_courses('course:/test::ns_test, course:/:/')
            course = courses.Course(None,
                                    app_context=sites.get_all_courses()[0])
            unit = course.add_unit()
            unit.now_available = True
            lesson_a = course.add_lesson(unit)
            lesson_a.notes = search_unit_test.UNICODE_PAGE_URL
            lesson_a.now_available = True
            course.update_unit(unit)
            course.save()

            self.index_test_course()

            self.swap(logging, 'error', self.error_report)
            response = self.get('/test/search?query=paradox')
            self.assertEqual('', self.logged_error)
            self.assertNotIn('unavailable', response.body)
            self.assertIn('gcb-search-result', response.body)
        except AssertionError:
            # Failing due to known unicode issue
            pass
        else:
            raise AssertionError('Unicode search test should have failed. The '
                                 'issue might now be fixed in dev_appserver.')
Example #9
0
    def test_get_entity_id_wrapper_in_progress_works(self):
        """Tests get_entity_id wrappers in progress.ProgressStats."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        progress_stats = ProgressStats(course)
        unit1 = course.add_unit()

        # pylint: disable-msg=protected-access
        assert_equals(
            progress_stats._get_unit_ids_of_type_unit(), [unit1.unit_id])
        assessment1 = course.add_assessment()
        assert_equals(
            progress_stats._get_assessment_ids(), [assessment1.unit_id])
        lesson11 = course.add_lesson(unit1)
        lesson12 = course.add_lesson(unit1)
        assert_equals(
            progress_stats._get_lesson_ids(unit1.unit_id),
            [lesson11.lesson_id, lesson12.lesson_id])
        lesson11.has_activity = True
        course.set_activity_content(lesson11, u'var activity=[]', [])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson11.lesson_id),
            [0])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson12.lesson_id),
            [])
    def put(self):
        """Handles REST PUT verb with JSON payload."""
        if not CourseOutlineRights.can_edit(self):
            transforms.send_json_response(self, 401, "Access denied.", {})
            return

        request = transforms.loads(self.request.get("request"))
        payload = request.get("payload")
        course_raw = transforms.json_to_dict(transforms.loads(payload), self.SCHEMA_DICT)["course"]

        source = None
        for acourse in sites.get_all_courses():
            if acourse.raw == course_raw:
                source = acourse
                break

        if not source:
            transforms.send_json_response(self, 404, "Object not found.", {"raw": course_raw})
            return

        course = courses.Course(self)
        errors = []
        try:
            course.import_from(source, errors)
        except Exception as e:  # pylint: disable-msg=broad-except
            logging.exception(e)
            errors.append("Import failed: %s" % e)

        if errors:
            transforms.send_json_response(self, 412, "\n".join(errors))
            return

        course.save()
        transforms.send_json_response(self, 200, "Imported.")
Example #11
0
    def test_get_entity_id_wrapper_in_progress_works(self):
        """Tests get_entity_id wrappers in progress.ProgressStats."""
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        progress_stats = ProgressStats(course)
        unit1 = course.add_unit()

        assert_equals(
            progress_stats._get_unit_ids_of_type_unit(), [unit1.unit_id])
        assessment1 = course.add_assessment()
        assert_equals(
            progress_stats._get_assessment_ids(), [assessment1.unit_id])
        lesson11 = course.add_lesson(unit1)
        lesson12 = course.add_lesson(unit1)
        assert_equals(
            progress_stats._get_lesson_ids(unit1.unit_id),
            [lesson11.lesson_id, lesson12.lesson_id])
        lesson11.has_activity = True
        course.set_activity_content(lesson11, u'var activity=[]', [])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson11.lesson_id),
            [0])
        assert_equals(
            progress_stats._get_activity_ids(unit1.unit_id, lesson12.lesson_id),
            [])
    def get(self):
        """Enforces rights to all GET operations."""
        action = self.request.get('action')

        if action in self.get_actions:
            destination = '/admin?action=%s' % action
        else:
            destination = '/admin'

        user = users.get_current_user()
        if not user:
            self.redirect(users.create_login_url(destination), normalize=False)
            return
        if not self.can_view():
            if appengine_config.PRODUCTION_MODE:
                self.error(403)
            else:
                self.redirect(
                    users.create_login_url(destination), normalize=False)
            return
        if not sites.get_all_courses() and not action:
            self.redirect('/admin?action=welcome', normalize=False)
            return

        # Force reload of properties. It's expensive, but admin deserves it!
        config.Registry.get_overrides(force_update=True)

        return super(AdminHandler, self).get()
Example #13
0
    def test_unicode_pages(self):
        # TODO(emichael): Remove try, except, else when the unicode issue
        # is fixed in dev_appserver.
        try:
            sites.setup_courses('course:/test::ns_test, course:/:/')
            course = courses.Course(None,
                                    app_context=sites.get_all_courses()[0])
            unit = course.add_unit()
            unit.now_available = True
            lesson_a = course.add_lesson(unit)
            lesson_a.notes = search_unit_test.UNICODE_PAGE_URL
            lesson_a.now_available = True
            course.update_unit(unit)
            course.save()

            self.index_test_course()

            self.swap(logging, 'error', self.error_report)
            response = self.get('/test/search?query=paradox')
            self.assertEqual('', self.logged_error)
            self.assertNotIn('unavailable', response.body)
            self.assertIn('gcb-search-result', response.body)
        except AssertionError:
            # Failing due to known unicode issue
            pass
        else:
            raise AssertionError('Unicode search test should have failed. The '
                                 'issue might now be fixed in dev_appserver.')
Example #14
0
 def test_compute_entity_dict_constructs_dict_correctly(self):
     sites.setup_courses('course:/test::ns_test, course:/:/')
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     progress_stats = ProgressStats(course)
     course_dict = progress_stats.compute_entity_dict('course', [])
     assert_equals(course_dict, {
         'label': 'UNTITLED COURSE', 'u': {}, 's': {}})
Example #15
0
 def test_compute_entity_dict_constructs_dict_correctly(self):
     sites.setup_courses('course:/test::ns_test, course:/:/')
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     progress_stats = ProgressStats(course)
     course_dict = progress_stats.compute_entity_dict('course', [])
     assert_equals(course_dict, {
         'label': 'UNTITLED COURSE', 'u': {}, 's': {}})
Example #16
0
 def can_add(cls):
     if roles.Roles.is_super_admin():
         return True
     for course_context in sites.get_all_courses():
         if roles.Roles.is_course_admin(course_context):
             return True
     return False
Example #17
0
 def get_all_courses(cls):
     all_courses = []
     for app_context in sites.get_all_courses():
         if cls._is_visible(app_context):
             all_courses.append(
                 Course(app_context=app_context, id=app_context.get_slug()))
     return all_courses
Example #18
0
    def get(self):
        """Start an index job for each course."""
        cron_logger = logging.getLogger('modules.search.cron')
        self.response.headers['Content-Type'] = 'text/plain'

        if CAN_INDEX_ALL_COURSES_IN_CRON.value:
            counter = 0
            for context in sites.get_all_courses():
                namespace = context.get_namespace_name()
                counter += 1
                try:
                    check_jobs_and_submit(IndexCourse(context), context)
                except db.TransactionFailedError as e:
                    cron_logger.info(
                        'Failed to submit job #%s in namespace %s: %s',
                        counter, namespace, e)
                else:
                    cron_logger.info(
                        'Index job #%s submitted for namespace %s.',
                        counter, namespace)
            cron_logger.info('All %s indexing jobs started; cron job complete.',
                             counter)
        else:
            cron_logger.info('Automatic indexing disabled. Cron job halting.')
        self.response.write('OK\n')
    def test_certificate_table_entry(self):
        user = actions.login('*****@*****.**')
        models.Student.add_new_student_for_current_user('Test User', None, self)
        student = models.Student.get_by_user(user)

        all_courses = sites.get_all_courses()
        app_context = all_courses[0]
        course = courses.Course(None, app_context=app_context)

        # If the student is qualified, a link is shown
        self.is_qualified = True
        mock_handler = MockHandler()
        table_entry = certificate.get_certificate_table_entry(
            mock_handler, student, course)
        self.assertEquals('Certificate', table_entry[0])
        link = str(table_entry[1])
        self.assertEquals(
            '<a href="certificate">Click for certificate</a> '
            '| <a href="certificate.pdf">Download PDF</a>', link)

        # If the student is not qualified, a message is shown
        self.is_qualified = False
        table_entry = certificate.get_certificate_table_entry(
            mock_handler, student, course)
        self.assertEquals('Certificate', table_entry[0])
        self.assertIn(
            'You have not yet met the course requirements', table_entry[1])
    def test_private_units_and_lessons(self):
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])

        unit1 = course.add_unit()
        lesson11 = course.add_lesson(unit1)
        lesson11.notes = search_unit_tests.VALID_PAGE_URL
        lesson11.objectives = search_unit_tests.VALID_PAGE
        lesson11.video = 'portal'
        unit2 = course.add_unit()
        lesson21 = course.add_lesson(unit2)
        lesson21.notes = search_unit_tests.VALID_PAGE_URL
        lesson21.objectives = search_unit_tests.VALID_PAGE
        lesson21.video = 'portal'

        unit1.availability = courses.AVAILABILITY_AVAILABLE
        lesson11.availability = courses.AVAILABILITY_UNAVAILABLE
        course.update_unit(unit1)

        unit2.availability = courses.AVAILABILITY_UNAVAILABLE
        lesson21.availability = courses.AVAILABILITY_AVAILABLE
        course.update_unit(unit2)

        course.save()
        self.index_test_course()

        response = self.get('/test/search?query=cogito%20ergo%20sum')
        self.assertNotIn('gcb-search-result', response.body)

        response = self.get('/test/search?query=apple')
        self.assertNotIn('gcb-search-result', response.body)
        self.assertNotIn('v=portal', response.body)
Example #21
0
def get_visible_courses():
    result = []
    for app_context in sorted(sites.get_all_courses()):
        with Namespace(app_context.namespace):
            if DashboardHandler.current_user_has_access(app_context):
                result.append(app_context)
    return result
Example #22
0
    def test_external_links(self):
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        unit = course.add_unit()
        unit.availability = courses.AVAILABILITY_AVAILABLE
        lesson_a = course.add_lesson(unit)
        lesson_a.notes = search_unit_tests.VALID_PAGE_URL
        objectives_link = 'http://objectiveslink.null/'
        lesson_a.objectives = '<a href="%s"></a><a href="%s"></a>' % (
            search_unit_tests.LINKED_PAGE_URL, objectives_link)
        lesson_a.availability = courses.AVAILABILITY_AVAILABLE
        course.update_unit(unit)
        course.save()

        self.index_test_course()

        response = self.get('/test/search?query=What%20hath%20God%20wrought')
        self.assertIn('gcb-search-result', response.body)

        response = self.get('/test/search?query=Cogito')
        self.assertIn('gcb-search-result', response.body)
        self.assertIn(search_unit_tests.VALID_PAGE_URL, response.body)
        self.assertIn(objectives_link, response.body)
        self.assertNotIn(search_unit_tests.PDF_URL, response.body)

        # If this test fails, indexing will crawl the entire web
        response = self.get('/test/search?query=ABORT')
        self.assertNotIn('gcb-search-result', response.body)
        self.assertNotIn(search_unit_tests.SECOND_LINK_PAGE_URL, response.body)
Example #23
0
    def get(self):
        """Enforces rights to all GET operations."""
        action = self.request.get('action')

        if action in self.get_actions:
            destination = '/admin?action=%s' % action
        else:
            destination = '/admin'

        user = users.get_current_user()
        if not user:
            self.redirect(users.create_login_url(destination), normalize=False)
            return
        if not self.can_view():
            if appengine_config.PRODUCTION_MODE:
                self.error(403)
            else:
                self.redirect(users.create_login_url(destination),
                              normalize=False)
            return
        if not sites.get_all_courses() and not action:
            self.redirect('/admin?action=welcome', normalize=False)
            return

        # Force reload of properties. It's expensive, but admin deserves it!
        config.Registry.get_overrides(force_update=True)

        return super(AdminHandler, self).get()
Example #24
0
    def get(self):
        """Start an index job for each course."""
        cron_logger = logging.getLogger('modules.search.cron')
        self.response.headers['Content-Type'] = 'text/plain'

        if CAN_INDEX_ALL_COURSES_IN_CRON.value:
            counter = 0
            for context in sites.get_all_courses():
                namespace = context.get_namespace_name()
                counter += 1
                try:
                    check_jobs_and_submit(IndexCourse(context), context)
                except db.TransactionFailedError as e:
                    cron_logger.info(
                        'Failed to submit job #%s in namespace %s: %s',
                        counter, namespace, e)
                else:
                    cron_logger.info(
                        'Index job #%s submitted for namespace %s.',
                        counter, namespace)
            cron_logger.info('All %s indexing jobs started; cron job complete.',
                             counter)
        else:
            cron_logger.info('Automatic indexing disabled. Cron job halting.')
        self.response.write('OK\n')
Example #25
0
 def get_all_courses(cls):
     all_courses = []
     for app_context in sites.get_all_courses():
         if cls._is_visible(app_context):
             all_courses.append(Course(
                 app_context=app_context, id=app_context.get_slug()))
     return all_courses
Example #26
0
    def test_private_units_and_lessons(self):
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])

        unit1 = course.add_unit()
        lesson11 = course.add_lesson(unit1)
        lesson11.notes = search_unit_tests.VALID_PAGE_URL
        lesson11.objectives = search_unit_tests.VALID_PAGE
        lesson11.video = 'portal'
        unit2 = course.add_unit()
        lesson21 = course.add_lesson(unit2)
        lesson21.notes = search_unit_tests.VALID_PAGE_URL
        lesson21.objectives = search_unit_tests.VALID_PAGE
        lesson21.video = 'portal'

        unit1.availability = courses.AVAILABILITY_AVAILABLE
        lesson11.availability = courses.AVAILABILITY_UNAVAILABLE
        course.update_unit(unit1)

        unit2.availability = courses.AVAILABILITY_UNAVAILABLE
        lesson21.availability = courses.AVAILABILITY_AVAILABLE
        course.update_unit(unit2)

        course.save()
        self.index_test_course()

        response = self.get('/test/search?query=cogito%20ergo%20sum')
        self.assertNotIn('gcb-search-result', response.body)

        response = self.get('/test/search?query=apple')
        self.assertNotIn('gcb-search-result', response.body)
        self.assertNotIn('v=portal', response.body)
    def test_external_links(self):
        sites.setup_courses('course:/test::ns_test, course:/:/')
        course = courses.Course(None, app_context=sites.get_all_courses()[0])
        unit = course.add_unit()
        unit.availability = courses.AVAILABILITY_AVAILABLE
        lesson_a = course.add_lesson(unit)
        lesson_a.notes = search_unit_tests.VALID_PAGE_URL
        objectives_link = 'http://objectiveslink.null/'
        lesson_a.objectives = '<a href="%s"></a><a href="%s"></a>' % (
            search_unit_tests.LINKED_PAGE_URL, objectives_link)
        lesson_a.availability = courses.AVAILABILITY_AVAILABLE
        course.update_unit(unit)
        course.save()

        self.index_test_course()

        response = self.get('/test/search?query=What%20hath%20God%20wrought')
        self.assertIn('gcb-search-result', response.body)

        response = self.get('/test/search?query=Cogito')
        self.assertIn('gcb-search-result', response.body)
        self.assertIn(search_unit_tests.VALID_PAGE_URL, response.body)
        self.assertIn(objectives_link, response.body)
        self.assertNotIn(search_unit_tests.PDF_URL, response.body)

        # If this test fails, indexing will crawl the entire web
        response = self.get('/test/search?query=ABORT')
        self.assertNotIn('gcb-search-result', response.body)
        self.assertNotIn(search_unit_tests.SECOND_LINK_PAGE_URL, response.body)
Example #28
0
    def test_certificate_table_entry(self):
        user = actions.login('*****@*****.**')
        models.Student.add_new_student_for_current_user(
            'Test User', None, self)
        student = models.Student.get_by_user(user)

        all_courses = sites.get_all_courses()
        app_context = all_courses[0]
        course = courses.Course(None, app_context=app_context)

        # If the student is qualified, a link is shown
        self.is_qualified = True
        mock_handler = MockHandler()
        table_entry = certificate.get_certificate_table_entry(
            mock_handler, student, course)
        self.assertEquals('Certificate', table_entry[0])
        link = str(table_entry[1])
        self.assertEquals(
            '<a href="certificate">Click for certificate</a> '
            '| <a href="certificate.pdf">Download PDF</a>', link)

        # If the student is not qualified, a message is shown
        self.is_qualified = False
        table_entry = certificate.get_certificate_table_entry(
            mock_handler, student, course)
        self.assertEquals('Certificate', table_entry[0])
        self.assertIn('You have not yet met the course requirements',
                      table_entry[1])
    def test_old_assessment_assignment(self):
        new_course_context = actions.simple_add_course('new_course',
                                                       ADMIN_EMAIL,
                                                       'My New Course')
        new_course = courses.Course(None, new_course_context)
        new_course.import_from(
            sites.get_all_courses(rules_text='course:/:/')[0])
        new_course.save()

        unit_rest_handler = unit_lesson_editor.UnitRESTHandler()
        unit_rest_handler.app_context = new_course_context

        # Use REST handler function to save pre/post handlers on one unit.
        errors = []
        unit = new_course.get_units_of_type(verify.UNIT_TYPE_UNIT)[0]
        assessment = new_course.get_units_of_type(
            verify.UNIT_TYPE_ASSESSMENT)[0]
        unit_rest_handler.apply_updates(
            unit, {
                'title': unit.title,
                'now_available': unit.now_available,
                'label_groups': [],
                'pre_assessment': assessment.unit_id,
                'post_assessment': -1,
                'show_contents_on_one_page': False,
                'manual_progress': False,
                'description': None,
                'unit_header': None,
                'unit_footer': None,
            }, errors)
        assert not errors
    def test_old_assessment_availability(self):
        new_course_context = actions.simple_add_course('new_course',
                                                       ADMIN_EMAIL,
                                                       'My New Course')
        new_course = courses.Course(None, new_course_context)
        new_course.import_from(
            sites.get_all_courses(rules_text='course:/:/')[0])
        new_course.save()

        # Prove that there are at least some assessments in this course.
        assessments = new_course.get_units_of_type(verify.UNIT_TYPE_ASSESSMENT)
        self.assertIsNotNone(assessments[0])

        # Get the first Unit
        unit = new_course.get_units_of_type(verify.UNIT_TYPE_UNIT)[0]

        unit_rest_handler = unit_lesson_editor.UnitRESTHandler()
        schema = unit_rest_handler.get_annotations_dict(
            new_course, unit.unit_id)

        # Verify that there are 4 valid choices for pre- or post-asssments
        # for this unit
        choices = self._get_selection_choices(
            schema, ['properties', 'pre_assessment', '_inputex'])
        self.assertEquals(5, len(choices))
        self.assertEquals(-1, choices['-- None --'])

        choices = self._get_selection_choices(
            schema, ['properties', 'post_assessment', '_inputex'])
        self.assertEquals(5, len(choices))
        self.assertEquals(-1, choices['-- None --'])
    def setUp(self):
        super(StudentTracksTest, self).setUp()

        # Add a course that will show up.
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        # Add labels
        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Foo',
                       'descripton': 'foo',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.bar_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Bar',
                       'descripton': 'bar',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.baz_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Baz',
                       'descripton': 'baz',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.quux_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Quux',
                       'descripton': 'quux',
                       'type': models.LabelDTO.LABEL_TYPE_GENERAL}))

        # Register a student for that course.
        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()

        # Add some units to the course.
        self._course = courses.Course(
            None, app_context=sites.get_all_courses()[0])
        self._unit_no_labels = self._course.add_unit()
        self._unit_no_labels.title = 'Unit No Labels'
        self._unit_no_labels.availability = courses.AVAILABILITY_AVAILABLE
        self._course.add_lesson(self._unit_no_labels)
        self._unit_labels_foo = self._course.add_unit()
        self._unit_labels_foo.title = 'Unit Labels: Foo'
        self._unit_labels_foo.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo.labels = str(self.foo_id)
        self._course.add_lesson(self._unit_labels_foo)
        self._unit_labels_foo_bar = self._course.add_unit()
        self._unit_labels_foo_bar.title = 'Unit Labels: Bar, Foo'
        self._unit_labels_foo_bar.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo_bar.labels = '%s %s' % (self.bar_id, self.foo_id)
        self._course.add_lesson(self._unit_labels_foo_bar)
        self._unit_labels_quux = self._course.add_unit()
        self._unit_labels_quux.title = 'Unit Labels: Quux'
        self._unit_labels_quux.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_quux.labels = str(self.quux_id)
        self._course.add_lesson(self._unit_labels_quux)
        self._unit_labels_foo_quux = self._course.add_unit()
        self._unit_labels_foo_quux.title = 'Unit Labels: Foo Quux'
        self._unit_labels_foo_quux.availability = courses.AVAILABILITY_AVAILABLE
        self._unit_labels_foo_quux.labels = '%s %s' % (str(self.foo_id),
                                                       str(self.quux_id))
        self._course.add_lesson(self._unit_labels_foo_quux)
        self._course.save()
Example #32
0
 def get_public_courses(self):
     """Get all the public courses."""
     public_courses = []
     for course in sites.get_all_courses():
         info = sites.ApplicationContext.get_environ(course)
         if info['course']['now_available']:
             public_courses.append(course)
     return public_courses
 def get_public_courses(self):
     """Get all the public courses."""
     public_courses = []
     for course in sites.get_all_courses():
         if ((course.now_available and Roles.is_user_whitelisted(course))
             or Roles.is_course_admin(course)):
             public_courses.append(course)
     return public_courses
Example #34
0
 def get_public_courses(self):
     """Get all the public courses."""
     public_courses = []
     for course in sites.get_all_courses():
         info = sites.ApplicationContext.get_environ(course)
         if info['course']['now_available']:
             public_courses.append(course)
     return public_courses
Example #35
0
 def get_public_courses(self):
     """Get all the public courses."""
     public_courses = []
     for course in sites.get_all_courses():
         if ((course.now_available and Roles.is_user_whitelisted(course))
                 or Roles.is_course_admin(course)):
             public_courses.append(course)
     return public_courses
Example #36
0
    def test_compute_question_stats_on_empty_course_returns_empty_dicts(self):

        sites.setup_courses('course:/test::ns_test, course:/:/')
        app_context = sites.get_all_courses()[0]

        question_stats_computer = analytics.ComputeQuestionStats(app_context)
        id_to_questions, id_to_assessments = question_stats_computer.run()
        assert_equals({}, id_to_questions)
        assert_equals({}, id_to_assessments)
Example #37
0
 def get(self):
     namespaces = self.request.get_all('namespace')
     for context in sites.get_all_courses():
         if (namespaces and len(namespaces) > 0
                 and context.get_namespace_name() not in namespaces):
             continue
         job = ReFormatProgrammingAssignments(context)
         job.submit()
     self.response.write('OK\n')
Example #38
0
    def get_courses(self):
        """Shows a list of all courses available on this site."""
        template_values = {}
        template_values['page_title'] = self.format_title('Courses')

        content = []
        content.append('<h3>All Courses</h3>')
        content.append('<table>')
        content.append("""
            <tr>
              <th>Course Title</th>
              <th>Context Path</th>
              <th>Content Location</th>
              <th>Datastore Namespace</th>
            </tr>
            """)
        courses = sites.get_all_courses()
        count = 0
        for course in courses:
            count += 1
            error = ''
            slug = course.get_slug()
            location = sites.abspath(course.get_home_folder(), '/')
            try:
                name = cgi.escape(course.get_environ()['course']['title'])
            except Exception as e:  # pylint: disable-msg=broad-except
                name = 'UNKNOWN COURSE'
                error = (
                    '<p>Error in <strong>course.yaml</strong> file:<br/>'
                    '<pre>\n%s\n%s\n</pre></p>' % (
                        e.__class__.__name__, cgi.escape(str(e))))

            if slug == '/':
                link = '/dashboard'
            else:
                link = '%s/dashboard' % slug
            link = '<a href="%s">%s</a>' % (link, name)

            content.append("""
                <tr>
                  <td>%s%s</td>
                  <td>%s</td>
                  <td>%s</td>
                  <td>%s</td>
                </tr>
                """ % (
                    link, error, slug, location, course.get_namespace_name()))

        content.append("""
            <tr><td colspan="4" align="right">Total: %s item(s)</td></tr>
            """ % count)
        content.append('</table>')

        template_values['main_content'] = ''.join(content)

        self.render_page(template_values)
    def setUp(self):
        super(StudentTracksTest, self).setUp()

        # Add a course that will show up.
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        # Add labels
        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Foo", "descripton": "foo", "type": models.LabelDTO.LABEL_TYPE_COURSE_TRACK}
                )
            )
            self.bar_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Bar", "descripton": "bar", "type": models.LabelDTO.LABEL_TYPE_COURSE_TRACK}
                )
            )
            self.baz_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Baz", "descripton": "baz", "type": models.LabelDTO.LABEL_TYPE_COURSE_TRACK}
                )
            )
            self.quux_id = models.LabelDAO.save(
                models.LabelDTO(
                    None, {"title": "Quux", "descripton": "quux", "type": models.LabelDTO.LABEL_TYPE_GENERAL}
                )
            )

        # Register a student for that course.
        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()

        # Add some units to the course.
        self._course = courses.Course(None, app_context=sites.get_all_courses()[0])
        self._unit_no_labels = self._course.add_unit()
        self._unit_no_labels.title = "Unit No Labels"
        self._unit_no_labels.now_available = True
        self._unit_labels_foo = self._course.add_unit()
        self._unit_labels_foo.title = "Unit Labels: Foo"
        self._unit_labels_foo.now_available = True
        self._unit_labels_foo.labels = str(self.foo_id)
        self._unit_labels_foo_bar = self._course.add_unit()
        self._unit_labels_foo_bar.title = "Unit Labels: Bar, Foo"
        self._unit_labels_foo_bar.now_available = True
        self._unit_labels_foo_bar.labels = "%s %s" % (self.bar_id, self.foo_id)
        self._unit_labels_quux = self._course.add_unit()
        self._unit_labels_quux.title = "Unit Labels: Quux"
        self._unit_labels_quux.now_available = True
        self._unit_labels_quux.labels = str(self.quux_id)
        self._unit_labels_foo_quux = self._course.add_unit()
        self._unit_labels_foo_quux.title = "Unit Labels: Foo Quux"
        self._unit_labels_foo_quux.now_available = True
        self._unit_labels_foo_quux.labels = "%s %s" % (str(self.foo_id), str(self.quux_id))
        self._course.save()
 def _submit_jobs(cls):
     for course_context in sites.get_all_courses():
         per_course_jobs = [
             students.StudentCounter(course_context),
             enrollment.StudentEnrollmentEventCounter(course_context),
         ]
         for job in per_course_jobs:
             if job.is_active():
                 job.cancel()
             job.submit()
 def get_welcome(self):
     template_values = {}
     template_values['version'] = os.environ['GCB_PRODUCT_VERSION']
     template_values['course_count'] = len(sites.get_all_courses())
     template_values['add_first_xsrf'] = self.create_xsrf_token(
         'add_first_course')
     template_values['explore_sample_xsrf'] = self.create_xsrf_token(
         'explore_sample')
     self.response.write(
         self.get_template('welcome.html', []).render(template_values))
    def test_compute_question_stats_on_empty_course_returns_empty_dicts(self):

        sites.setup_courses('course:/test::ns_test, course:/:/')
        app_context = sites.get_all_courses()[0]

        question_stats_computer = (
            synchronous_providers.QuestionStatsGenerator(app_context))
        id_to_questions, id_to_assessments = question_stats_computer.run()
        assert_equals({}, id_to_questions)
        assert_equals({}, id_to_assessments)
 def test_unsubscribe_request_with_no_email_prompts_for_login(self):
     actions.logout()
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     course.set_course_availability(courses.COURSE_AVAILABILITY_PUBLIC)
     response = self.get('modules/unsubscribe')
     self.assertEquals(302, response.status_int)
     self.assertEquals(
         'https://www.google.com/accounts/Login'
         '?continue=http%3A//localhost/a/modules/unsubscribe',
         response.headers['Location'])
Example #44
0
 def get_welcome(self):
     template_values = {}
     template_values['version'] = os.environ['GCB_PRODUCT_VERSION']
     template_values['course_count'] = len(sites.get_all_courses())
     template_values['add_first_xsrf'] = self.create_xsrf_token(
         'add_first_course')
     template_values['explore_sample_xsrf'] = self.create_xsrf_token(
         'explore_sample')
     self.response.write(
         self.get_template('welcome.html', []).render(template_values))
 def _submit_jobs(cls):
     for course_context in sites.get_all_courses():
         per_course_jobs = [
             students.StudentCounter(course_context),
             enrollment.StudentEnrollmentEventCounter(course_context),
         ]
         for job in per_course_jobs:
             if job.is_active():
                 job.cancel()
             job.submit()
Example #46
0
    def test_compute_question_stats_on_empty_course_returns_empty_dicts(self):

        sites.setup_courses('course:/test::ns_test, course:/:/')
        app_context = sites.get_all_courses()[0]

        question_stats_computer = (
            synchronous_providers.QuestionStatsGenerator(app_context))
        id_to_questions, id_to_assessments = question_stats_computer.run()
        assert_equals({}, id_to_questions)
        assert_equals({}, id_to_assessments)
 def test_unsubscribe_request_with_no_email_prompts_for_login(self):
     actions.logout()
     course = courses.Course(None, app_context=sites.get_all_courses()[0])
     course.set_course_availability(courses.COURSE_AVAILABILITY_PUBLIC)
     response = self.get('modules/unsubscribe')
     self.assertEquals(302, response.status_int)
     self.assertEquals(
         'https://www.google.com/accounts/Login'
         '?continue=http%3A//localhost/a/modules/unsubscribe',
         response.headers['Location'])
Example #48
0
def _upload(upload_type, archive_path, course_url_prefix):
    _LOG.info((
        'Processing course with URL prefix %s from archive path %s' % (
            course_url_prefix, archive_path)))
    context = _get_requested_context(sites.get_all_courses(), course_url_prefix)
    if not context:
        _die('No course found with course_url_prefix %s' % course_url_prefix)
    if upload_type == _TYPE_COURSE:
        _upload_course(context, archive_path, course_url_prefix)
    elif upload_type == _TYPE_DATASTORE:
        _upload_datastore()
    def setUp(self):
        super(StudentTracksTest, self).setUp()

        # Add a course that will show up.
        actions.simple_add_course(COURSE_NAME, ADMIN_EMAIL, COURSE_TITLE)

        # Add labels
        with common_utils.Namespace(NAMESPACE):
            self.foo_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Foo',
                       'descripton': 'foo',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.bar_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Bar',
                       'descripton': 'bar',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.baz_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Baz',
                       'descripton': 'baz',
                       'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
            self.quux_id = models.LabelDAO.save(models.LabelDTO(
                None, {'title': 'Quux',
                       'descripton': 'quux',
                       'type': models.LabelDTO.LABEL_TYPE_GENERAL}))

        # Register a student for that course.
        actions.login(REGISTERED_STUDENT_EMAIL)
        actions.register(self, REGISTERED_STUDENT_NAME, COURSE_NAME)
        actions.logout()

        # Add some units to the course.
        self._course = courses.Course(
            None, app_context=sites.get_all_courses()[0])
        self._unit_no_labels = self._course.add_unit()
        self._unit_no_labels.title = 'Unit No Labels'
        self._unit_no_labels.now_available = True
        self._unit_labels_foo = self._course.add_unit()
        self._unit_labels_foo.title = 'Unit Labels: Foo'
        self._unit_labels_foo.now_available = True
        self._unit_labels_foo.labels = str(self.foo_id)
        self._unit_labels_foo_bar = self._course.add_unit()
        self._unit_labels_foo_bar.title = 'Unit Labels: Bar, Foo'
        self._unit_labels_foo_bar.now_available = True
        self._unit_labels_foo_bar.labels = '%s %s' % (self.bar_id, self.foo_id)
        self._unit_labels_quux = self._course.add_unit()
        self._unit_labels_quux.title = 'Unit Labels: Quux'
        self._unit_labels_quux.now_available = True
        self._unit_labels_quux.labels = str(self.quux_id)
        self._unit_labels_foo_quux = self._course.add_unit()
        self._unit_labels_foo_quux.title = 'Unit Labels: Foo Quux'
        self._unit_labels_foo_quux.now_available = True
        self._unit_labels_foo_quux.labels = '%s %s' % (str(self.foo_id),
                                                       str(self.quux_id))
        self._course.save()
Example #50
0
def _upload(upload_type, archive_path, course_url_prefix):
    _LOG.info(('Processing course with URL prefix %s from archive path %s' %
               (course_url_prefix, archive_path)))
    context = _get_requested_context(sites.get_all_courses(),
                                     course_url_prefix)
    if not context:
        _die('No course found with course_url_prefix %s' % course_url_prefix)
    if upload_type == _TYPE_COURSE:
        _upload_course(context, archive_path, course_url_prefix)
    elif upload_type == _TYPE_DATASTORE:
        _upload_datastore()
Example #51
0
 def _make_new_course(self, uid, title):
     """Make a new course entry."""
     errors = []
     admin_email = users.get_current_user().email()
     entry = sites.add_new_course_entry(uid, title, admin_email, errors)
     if errors:
         raise Exception(errors)
     app_context = sites.get_all_courses(entry)[0]
     new_course = models.courses.Course(None, app_context=app_context)
     new_course.init_new_course_settings(title, admin_email)
     return app_context
 def _import_sample_course(self):
     dst_app_context = actions.simple_add_course(
         'webserv', '*****@*****.**',
         'Power Searching with Google')
     dst_course = courses.Course(None, dst_app_context)
     src_app_context = sites.get_all_courses('course:/:/:')[0]
     errors = []
     dst_course.import_from(src_app_context, errors)
     dst_course.save()
     self.base = ''
     self.assertEquals(0, len(errors))
     return dst_course
 def _copy_sample_course(self, uid):
     """Make a fresh copy of sample course."""
     src_app_context = sites.get_all_courses('course:/:/:')[0]
     dst_app_context = self._make_new_course(
         uid, src_app_context.get_title())
     errors = []
     dst_course = courses.Course(None, dst_app_context)
     dst_course.import_from(src_app_context, errors)
     dst_course.save()
     if errors:
         raise Exception(errors)
     return dst_app_context
 def _get_course_list(cls):
     # Make a list of courses user has the rights to.
     course_list = []
     for acourse in sites.get_all_courses():
         if not roles.Roles.is_course_admin(acourse):
             continue
         if acourse == sites.get_course_for_current_request():
             continue
         course_list.append({
             'value': acourse.raw,
             'label': cgi.escape(acourse.get_title())})
     return course_list
Example #55
0
 def _import_sample_course(self, ns='guide', availability=None):
     dst_app_context = actions.simple_add_course(
         ns, '*****@*****.**' % ns,
         'Power Searching with Google [%s]' % ns)
     dst_course = courses.Course(None, dst_app_context)
     all_courses = sites.get_all_courses('course:/:/:')
     src_app_context = all_courses[len(all_courses) - 1]
     errors = []
     dst_course.import_from(src_app_context, errors)
     dst_course.save()
     dst_course.set_course_availability(availability)
     self.assertEquals(0, len(errors))
Example #56
0
 def _copy_sample_course(self, uid):
     """Make a fresh copy of sample course."""
     src_app_context = sites.get_all_courses('course:/:/:')[0]
     dst_app_context = self._make_new_course(uid,
                                             src_app_context.get_title())
     errors = []
     dst_course = courses.Course(None, dst_app_context)
     dst_course.import_from(src_app_context, errors)
     dst_course.save()
     if errors:
         raise Exception(errors)
     return dst_app_context
Example #57
0
 def _import_sample_course(self):
     dst_app_context = actions.simple_add_course(
         'webserv', '*****@*****.**',
         'Power Searching with Google')
     dst_course = courses.Course(None, dst_app_context)
     src_app_context = sites.get_all_courses('course:/:/:')[0]
     errors = []
     dst_course.import_from(src_app_context, errors)
     dst_course.save()
     self.base = ''
     self.assertEquals(0, len(errors))
     return dst_course
Example #58
0
 def _make_new_course(self, uid, title):
     """Make a new course entry."""
     errors = []
     admin_email = users.get_current_user().email()
     entry = sites.add_new_course_entry(
         uid, title, admin_email, errors)
     if errors:
         raise Exception(errors)
     app_context = sites.get_all_courses(entry)[0]
     new_course = models.courses.Course(None, app_context=app_context)
     new_course.init_new_course_settings(title, admin_email)
     return app_context