def test_for_featured_explorations(self): """Note that both EXP_ID_1 and EXP_ID_2 are public. However, only EXP_ID_2 is featured, so the call to get_featured_explorations() should only return [EXP_ID_2]. """ activity_services.update_featured_activity_references([ activity_domain.ActivityReference( constants.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID_2) ]) featured_activity_summaries = ( summary_services.get_featured_activity_summary_dicts([ constants.DEFAULT_LANGUAGE_CODE])) self.assertEqual(len(featured_activity_summaries), 1) self.assertDictContainsSubset({ 'status': 'public', 'thumbnail_bg_color': '#a33f40', 'community_owned': False, 'tags': [], 'thumbnail_icon_url': '/subjects/Lightbulb.svg', 'language_code': constants.DEFAULT_LANGUAGE_CODE, 'id': self.EXP_ID_2, 'category': 'A category', 'ratings': feconf.get_empty_ratings(), 'title': 'A title', 'num_views': 0, 'objective': 'An objective' }, featured_activity_summaries[0])
def test_get_displayable_exp_summary_dicts_matching_ids(self): # A list of exp_id's are passed in: # EXP_ID_1 -- private exploration owned by Albert. # EXP_ID_2 -- pubished exploration owned by Albert. # EXP_ID_3 -- deleted exploration. # EXP_ID_5 -- private exploration owned by Bob. # Should only return [EXP_ID_2]. displayable_summaries = ( summary_services.get_displayable_exp_summary_dicts_matching_ids( [self.EXP_ID_1, self.EXP_ID_2, self.EXP_ID_3, self.EXP_ID_5])) expected_summary = { 'category': u'A category', 'community_owned': False, 'id': self.EXP_ID_2, 'language_code': constants.DEFAULT_LANGUAGE_CODE, 'num_views': 0, 'objective': u'An objective', 'ratings': feconf.get_empty_ratings(), 'status': 'public', 'tags': [], 'thumbnail_bg_color': '#a33f40', 'thumbnail_icon_url': '/subjects/Lightbulb.svg', 'title': u'Exploration 2 Albert title', } self.assertIn('last_updated_msec', displayable_summaries[0]) self.assertDictContainsSubset( expected_summary, displayable_summaries[0])
def test_get_library_groups(self): """The exploration with id '2' is an exploration in the Mathematics category. The call to get_library_groups() should return the exploration as part of the Mathematics & Statistics group. """ library_groups = summary_services.get_library_groups([]) expected_exploration_summary_dict = { 'category': u'Algorithms', 'community_owned': True, 'id': '2', 'language_code': constants.DEFAULT_LANGUAGE_CODE, 'num_views': 0, 'objective': u'discover the binary search algorithm', 'ratings': feconf.get_empty_ratings(), 'status': u'public', 'tags': [], 'title': u'The Lazy Magician', 'thumbnail_bg_color': '#d0982a', 'thumbnail_icon_url': '/subjects/Algorithms.svg', } expected_group = { 'categories': ['Algorithms', 'Computing', 'Programming'], 'header_i18n_id': 'I18N_LIBRARY_GROUPS_COMPUTING', } self.assertEqual(len(library_groups), 1) self.assertDictContainsSubset(expected_group, library_groups[0]) self.assertEqual( len(library_groups[0]['activity_summary_dicts']), 1) actual_exploration_summary_dict = ( library_groups[0]['activity_summary_dicts'][0]) self.assertDictContainsSubset(expected_exploration_summary_dict, ( actual_exploration_summary_dict))
def test_for_recently_published_explorations(self): """Tests for recently published explorations.""" self.process_and_flush_pending_tasks() recently_published_exploration_summaries = ( summary_services.get_recently_published_exp_summary_dicts( feconf.RECENTLY_PUBLISHED_QUERY_LIMIT_FOR_LIBRARY_PAGE)) test_summary_1 = { 'status': 'public', 'thumbnail_bg_color': '#a33f40', 'community_owned': False, 'tags': [], 'thumbnail_icon_url': '/subjects/Lightbulb.svg', 'language_code': constants.DEFAULT_LANGUAGE_CODE, 'id': self.EXP_ID_1, 'category': u'A category', 'ratings': feconf.get_empty_ratings(), 'title': u'A title', 'num_views': 0, 'objective': u'An objective' } test_summary_2 = { 'status': 'public', 'thumbnail_bg_color': '#a33f40', 'community_owned': False, 'tags': [], 'thumbnail_icon_url': '/subjects/Lightbulb.svg', 'language_code': constants.DEFAULT_LANGUAGE_CODE, 'id': self.EXP_ID_2, 'category': u'A category', 'ratings': feconf.get_empty_ratings(), 'title': u'A title', 'num_views': 0, 'objective': u'An objective' } test_summary_3 = { 'status': 'public', 'thumbnail_bg_color': '#a33f40', 'community_owned': False, 'tags': [], 'thumbnail_icon_url': '/subjects/Lightbulb.svg', 'language_code': constants.DEFAULT_LANGUAGE_CODE, 'id': self.EXP_ID_3, 'category': u'A category', 'ratings': feconf.get_empty_ratings(), 'title': u'A title', 'num_views': 0, 'objective': u'An objective' } self.assertDictContainsSubset( test_summary_3, recently_published_exploration_summaries[0]) self.assertDictContainsSubset( test_summary_1, recently_published_exploration_summaries[1]) self.assertDictContainsSubset( test_summary_2, recently_published_exploration_summaries[2]) # Test that editing an exploration does not change its # 'recently-published' status. exp_services.update_exploration( self.albert_id, self.EXP_ID_1, [exp_domain.ExplorationChange({ 'cmd': 'edit_exploration_property', 'property_name': 'title', 'new_value': 'New title' })], 'Changed title.') self.process_and_flush_pending_tasks() recently_published_exploration_summaries = ( summary_services.get_recently_published_exp_summary_dicts( feconf.RECENTLY_PUBLISHED_QUERY_LIMIT_FOR_LIBRARY_PAGE)) self.assertEqual( recently_published_exploration_summaries[1]['title'], 'New title') self.assertDictContainsSubset( test_summary_3, recently_published_exploration_summaries[0])
def assign_rating_to_exploration(user_id, exploration_id, new_rating): """Records the rating awarded by the user to the exploration in both the user-specific data and exploration summary. This function validates the exploration id but not the user id. Args: user_id: str. The id of the user assigning the rating. exploration_id: str. The id of the exploration that is assigned a rating. new_rating: int. Value of assigned rating, should be between 1 and 5 inclusive. """ if not isinstance(new_rating, int): raise ValueError('Expected the rating to be an integer, received %s' % new_rating) if new_rating not in ALLOWED_RATINGS: raise ValueError('Expected a rating 1-5, received %s.' % new_rating) exploration = exp_fetchers.get_exploration_by_id(exploration_id, strict=False) if exploration is None: raise ValueError('Invalid exploration id %s' % exploration_id) @transaction_services.run_in_transaction_wrapper def _update_user_rating_transactional(): """Updates the user rating of the exploration. Returns the old rating before updation. """ exp_user_data_model = user_models.ExplorationUserDataModel.get( user_id, exploration_id) if exp_user_data_model: old_rating = exp_user_data_model.rating else: old_rating = None exp_user_data_model = user_models.ExplorationUserDataModel.create( user_id, exploration_id) exp_user_data_model.rating = new_rating exp_user_data_model.rated_on = datetime.datetime.utcnow() exp_user_data_model.update_timestamps() exp_user_data_model.put() return old_rating old_rating = _update_user_rating_transactional() exploration_summary = exp_fetchers.get_exploration_summary_by_id( exploration_id) if not exploration_summary.ratings: exploration_summary.ratings = feconf.get_empty_ratings() exploration_summary.ratings[python_utils.UNICODE(new_rating)] += 1 if old_rating: exploration_summary.ratings[python_utils.UNICODE(old_rating)] -= 1 event_services.RateExplorationEventHandler.record(exploration_id, user_id, new_rating, old_rating) exploration_summary.scaled_average_rating = ( exp_services.get_scaled_average_rating(exploration_summary.ratings)) exp_services.save_exploration_summary(exploration_summary)