def test_news_label_filtering(self):
        actions.login(self.STUDENT_EMAIL)
        actions.register(self, 'John Smith')

        label_foo = models.LabelDAO.save(models.LabelDTO(
            None, {'title': 'Foo',
                   'descripton': 'foo',
                   'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))
        label_bar = models.LabelDAO.save(models.LabelDTO(
            None, {'title': 'Bar',
                   'descripton': 'bar',
                   'type': models.LabelDTO.LABEL_TYPE_COURSE_TRACK}))

        now_ts = utc.now_as_timestamp() + 3  # Avoid filtering in-past items
        news.CourseNewsDao.add_news_item(news.NewsItem(
            'test:no_labels', 'url_no_labels',
            when=utc.timestamp_to_datetime(now_ts)))
        news.CourseNewsDao.add_news_item(news.NewsItem(
            'test:with_labels', 'url_with_labels',
            labels=common_utils.list_to_text([label_foo]),
            when=utc.timestamp_to_datetime(now_ts - 1)))

        # Student starts life with no labels, so should match both items.
        response = self.get('course')
        soup = self.parse_html_string_to_soup(response.body)
        self.assertEquals(
            [news_tests_lib.NewsItem(
                'Test Item no_labels', 'url_no_labels', True),
             news_tests_lib.NewsItem(
                 'Test Item with_labels', 'url_with_labels', True)],
            news_tests_lib.extract_news_items_from_soup(soup))

        # Apply non-matching label to Student; should not see labeled news.
        models.Student.set_labels_for_current(
            common_utils.list_to_text([label_bar]))
        response = self.get('course')
        soup = self.parse_html_string_to_soup(response.body)
        self.assertEquals(
            [news_tests_lib.NewsItem(
                'Test Item no_labels', 'url_no_labels', True)],
            news_tests_lib.extract_news_items_from_soup(soup))

        # Apply matching label to Student; should again see labeled news.
        models.Student.set_labels_for_current(
            common_utils.list_to_text([label_foo, label_bar]))
        response = self.get('course')
        soup = self.parse_html_string_to_soup(response.body)
        self.assertEquals(
            [news_tests_lib.NewsItem(
                'Test Item no_labels', 'url_no_labels', True),
             news_tests_lib.NewsItem(
                 'Test Item with_labels', 'url_with_labels', True)],
            news_tests_lib.extract_news_items_from_soup(soup))
    def test_get_news_some_old_some_new(self):
        user = actions.login(self.STUDENT_EMAIL)
        actions.register(self, 'John Smith')

        # Newsworthy thing happened beyond newsworthy time limit,
        then_ts = utc.now_as_timestamp() - news.NEWSWORTHINESS_SECONDS - 1
        then = utc.timestamp_to_datetime(then_ts)
        self._set_student_enroll_date(user, then)
        news_item = news.NewsItem('test:one', 'url_one', then)
        news.CourseNewsDao.add_news_item(news_item)
        news_item = news.NewsItem('test:two', 'url_two', then)
        news.CourseNewsDao.add_news_item(news_item)
        # But student has seen the thing, so it's marked as non-new.
        news.StudentNewsDao.mark_item_seen('test:one')

        response = self.get('course')
        soup = self.parse_html_string_to_soup(response.body)
        self.assertEquals(['has_new_news'],
                          self._get_news_title_styles(soup))
        self.assertEquals(
            [
                news_tests_lib.NewsItem('Test Item two', 'url_two', True),
                news_tests_lib.NewsItem('Test Item one', 'url_one', False),
            ],
            news_tests_lib.extract_news_items_from_soup(soup))
 def should_start_jobs():
     now_timestamp = utc.hour_start(utc.now_as_timestamp())
     status = StartAvailabilityJobsStatus.get_singleton()
     last_run = utc.hour_start(
         utc.datetime_to_timestamp(status.last_run))
     if now_timestamp > last_run:
         status.last_run = utc.timestamp_to_datetime(now_timestamp)
         StartAvailabilityJobsStatus.update_singleton(status)
         return True
     return False
Exemple #4
0
 def should_start_jobs():
     now_timestamp = utc.hour_start(utc.now_as_timestamp())
     status = StartAvailabilityJobsStatus.get_singleton()
     last_run = utc.hour_start(
         utc.datetime_to_timestamp(status.last_run))
     if now_timestamp > last_run:
         status.last_run = utc.timestamp_to_datetime(now_timestamp)
         StartAvailabilityJobsStatus.update_singleton(status)
         return True
     return False
def get_course_enrolled(enrolled_dto, course_name):
    if enrolled_dto.is_empty:
        # 'count' property is not present, so exit early.
        return CourseEnrolled(0, NONE_ENROLLED,
                              _NONE_RECENT_FMT.format(course_name))

    count = enrolled_dto.get()
    lm_dt = utc.timestamp_to_datetime(enrolled_dto.last_modified)
    lm_text = utc.to_text(dt=lm_dt, fmt=utc.ISO_8601_UTC_HUMAN_FMT)
    most_recent_enroll = _MOST_RECENT_FMT.format(lm_text, course_name)
    return CourseEnrolled(count, count, most_recent_enroll)
def get_course_enrolled(enrolled_dto, course_name):
    if enrolled_dto.is_empty:
        # 'count' property is not present, so exit early.
        return CourseEnrolled(
            0, NONE_ENROLLED, _NONE_RECENT_FMT.format(course_name))

    count = enrolled_dto.get()
    lm_dt = utc.timestamp_to_datetime(enrolled_dto.last_modified)
    lm_text = utc.to_text(dt=lm_dt, fmt=utc.ISO_8601_UTC_HUMAN_FMT)
    most_recent_enroll = _MOST_RECENT_FMT.format(lm_text, course_name)
    return CourseEnrolled(count, count, most_recent_enroll)
    def _test_add_newer_and_older_news_item(self, dao_class):
        now_ts = utc.now_as_timestamp()

        older = news.NewsItem('test:key', 'test:url',
                              when=utc.timestamp_to_datetime(now_ts))
        newer = news.NewsItem('test:key', 'test:url',
                              when=utc.timestamp_to_datetime(now_ts + 1))

        dao_class.add_news_item(older)
        self.assertEquals([older], dao_class.get_news_items())

        # Newer items added with no-overwrite flag do not displace older item.
        dao_class.add_news_item(newer, overwrite_existing=False)
        self.assertEquals([older], dao_class.get_news_items())

        # Newer items displace older items with the same key.
        dao_class.add_news_item(newer)
        self.assertEquals([newer], dao_class.get_news_items())

        # But older items w/ same key do not displace newer ones.
        dao_class.add_news_item(older)
        self.assertEquals([newer], dao_class.get_news_items())
    def reduce(cls, key, values):
        total = sum(int(value) for value in values)
        ns_name = namespace_manager.get_namespace()

        if key == TotalEnrollmentEntity.COUNTING:
            TotalEnrollmentDAO.set(ns_name, total)
            yield key, total
        else:
            # key is actually a daily 'adds' counter bin seconds since epoch.
            bin_seconds_since_epoch = long(key)
            today = utc.day_start(utc.now_as_timestamp())
            # Avoid race conditions by not updating today's daily bin (which
            # is being updated by student lifecycle events).
            if bin_seconds_since_epoch != today:
                date_time = utc.timestamp_to_datetime(bin_seconds_since_epoch)
                EnrollmentsAddedDAO.set(ns_name, date_time, total)
    def reduce(cls, key, values):
        total = sum(int(value) for value in values)
        ns_name = namespace_manager.get_namespace()

        if key == TotalEnrollmentEntity.COUNTING:
            TotalEnrollmentDAO.set(ns_name, total)
            yield key, total
        else:
            # key is actually a daily 'adds' counter bin seconds since epoch.
            bin_seconds_since_epoch = long(key)
            today = utc.day_start(utc.now_as_timestamp())
            # Avoid race conditions by not updating today's daily bin (which
            # is being updated by student lifecycle events).
            if bin_seconds_since_epoch != today:
                date_time = utc.timestamp_to_datetime(bin_seconds_since_epoch)
                EnrollmentsAddedDAO.set(ns_name, date_time, total)
    def test_get_news_unseen(self):
        user = actions.login(self.STUDENT_EMAIL)
        actions.register(self, 'John Smith')

        # Added item is older than newsworthiness cutoff, but student has
        # not been marked as having seen it, so it's new news.
        then_ts = utc.now_as_timestamp() - news.NEWSWORTHINESS_SECONDS - 1
        then = utc.timestamp_to_datetime(then_ts)
        self._set_student_enroll_date(user, then)
        news_item = news.NewsItem('test:key', 'test:url', then)
        news.CourseNewsDao.add_news_item(news_item)

        response = self.get('course')
        soup = self.parse_html_string_to_soup(response.body)
        self.assertEquals(['has_new_news'],
                          self._get_news_title_styles(soup))
        self.assertEquals(
            [news_tests_lib.NewsItem('Test Item key', 'test:url', True)],
            news_tests_lib.extract_news_items_from_soup(soup))
    def test_student_and_course_news(self):
        user = actions.login(self.STUDENT_EMAIL)
        actions.register(self, 'John Smith')

        then_ts = utc.now_as_timestamp() - news.NEWSWORTHINESS_SECONDS - 1
        then = utc.timestamp_to_datetime(then_ts)
        self._set_student_enroll_date(user, then)
        news_item = news.NewsItem('test:one', 'url_one', then)
        news.CourseNewsDao.add_news_item(news_item)
        news_item = news.NewsItem('test:two', 'url_two', then)
        news.StudentNewsDao.add_news_item(news_item)

        response = self.get('course')
        soup = self.parse_html_string_to_soup(response.body)
        self.assertEquals(['has_new_news'],
                          self._get_news_title_styles(soup))
        self.assertEquals(
            [
                news_tests_lib.NewsItem('Test Item two', 'url_two', True),
                news_tests_lib.NewsItem('Test Item one', 'url_one', True),
            ],
            news_tests_lib.extract_news_items_from_soup(soup))
    def test_old_news_excluded_by_new_news(self):
        NUM_OLD_ITEMS = news.MIN_NEWS_ITEMS_TO_DISPLAY * 2
        NUM_NEW_ITEMS = news.MIN_NEWS_ITEMS_TO_DISPLAY * 2

        user = actions.login(self.STUDENT_EMAIL)
        actions.register(self, 'John Smith')
        then_ts = (
            utc.now_as_timestamp() - news.NEWSWORTHINESS_SECONDS -
            NUM_OLD_ITEMS - 1)
        self._set_student_enroll_date(user, utc.timestamp_to_datetime(then_ts))

        # Add many old items - twice as many as we're willing to show.
        expected_old_items = []
        for i in xrange(NUM_OLD_ITEMS):
            expected_old_items.append(news_tests_lib.NewsItem(
                'Test Item %i' % i, 'u%i' % i, False))

            then = utc.timestamp_to_datetime(then_ts + i)
            item = news.NewsItem('test:%d' % i, 'u%d' % i, then)
            news.CourseNewsDao.add_news_item(item)
            news.StudentNewsDao.mark_item_seen('test:%d' % i)

        # Force everything we just did to be old news.
        try:
            save_newsworthiness_seconds = news.NEWSWORTHINESS_SECONDS
            news.NEWSWORTHINESS_SECONDS = 1
            time.sleep(2)

            # Expect that we see old items in newest-first order.
            expected_old_items.reverse()

            # Verify that we are only shown half of the old-news items before
            # we add any new ones.
            response = self.get('course')
            soup = self.parse_html_string_to_soup(response.body)
            self.assertEquals(
                expected_old_items[0:NUM_OLD_ITEMS / 2],
                news_tests_lib.extract_news_items_from_soup(soup))

            # Start adding new news items, one at a time.
            expected_new_items = []
            for i in xrange(NUM_NEW_ITEMS):
                j = NUM_OLD_ITEMS + i
                expected_new_items.append(news_tests_lib.NewsItem(
                    'Test Item %i' % j, 'u%i' % j, True))
                then = utc.timestamp_to_datetime(then_ts + j)
                item = news.NewsItem('test:%d' % j, 'u%d' % j, then)
                news.CourseNewsDao.add_news_item(item)

                # Expect to see all new items, and maybe some old items,
                # as long as the new ones are not crowding them out.
                # New items should appear strictly first.
                expected_items = list(reversed(expected_new_items))
                if i < news.MIN_NEWS_ITEMS_TO_DISPLAY:
                    expected_items += expected_old_items[
                        :news.MIN_NEWS_ITEMS_TO_DISPLAY - i - 1]

                response = self.get('course')
                soup = self.parse_html_string_to_soup(response.body)
                actual_items = news_tests_lib.extract_news_items_from_soup(soup)
                self.assertEquals(expected_items, actual_items)

        finally:
            news.NEWSWORTHINESS_SECONDS = save_newsworthiness_seconds
 def get(self):
     eta_timestamp = utc.hour_end(utc.now_as_timestamp()) + 1
     eta = utc.timestamp_to_datetime(eta_timestamp)
     deferred.defer(self.maybe_start_jobs, _eta=eta)
     logging.info(
         'StartAvailabilityJobs - scheduling deferred task at %s', eta)
Exemple #14
0
 def get(self):
     eta_timestamp = utc.hour_end(utc.now_as_timestamp()) + 1
     eta = utc.timestamp_to_datetime(eta_timestamp)
     deferred.defer(self.maybe_start_jobs, _eta=eta)
     logging.info('StartAvailabilityJobs - scheduling deferred task at %s',
                  eta)