def test_recommendations_after_changes_in_rights(self): with self.swap( jobs_registry, 'ALL_CONTINUOUS_COMPUTATION_MANAGERS', self.ALL_CONTINUOUS_COMPUTATION_MANAGERS_FOR_TESTS): ModifiedExplorationRecommendationsAggregator.start_computation() self.assertEqual( self.count_jobs_in_taskqueue( queue_name=taskqueue_services.QUEUE_NAME_DEFAULT), 1) self.process_and_flush_pending_tasks() recommendations = ( recommendations_services.get_exploration_recommendations( 'exp_id_1')) self.assertEqual( recommendations, ['exp_id_4', 'exp_id_2', 'exp_id_3']) rights_manager.unpublish_exploration(self.ADMIN_ID, 'exp_id_4') ModifiedExplorationRecommendationsAggregator.stop_computation( self.ADMIN_ID) ModifiedExplorationRecommendationsAggregator.start_computation() self.assertEqual( self.count_jobs_in_taskqueue( queue_name=taskqueue_services.QUEUE_NAME_DEFAULT), 1) self.process_and_flush_pending_tasks() recommendations = ( recommendations_services.get_exploration_recommendations( 'exp_id_1')) self.assertEqual(recommendations, ['exp_id_2', 'exp_id_3'])
def test_get_item_similarity(self): exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual(recommendations_services.get_item_similarity( exp_summaries['exp_id_1'].category, exp_summaries['exp_id_1'].language_code, exp_summaries['exp_id_1'].owner_ids, exp_summaries['exp_id_2'].category, exp_summaries['exp_id_2'].language_code, exp_summaries['exp_id_2'].exploration_model_last_updated, exp_summaries['exp_id_2'].owner_ids, exp_summaries['exp_id_2'].status), 4.5) self.assertEqual(recommendations_services.get_item_similarity( exp_summaries['exp_id_4'].category, exp_summaries['exp_id_4'].language_code, exp_summaries['exp_id_4'].owner_ids, exp_summaries['exp_id_4'].category, exp_summaries['exp_id_4'].language_code, exp_summaries['exp_id_4'].exploration_model_last_updated, exp_summaries['exp_id_4'].owner_ids, exp_summaries['exp_id_4'].status), 9.0) rights_manager.unpublish_exploration(self.admin, 'exp_id_2') exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual(recommendations_services.get_item_similarity( exp_summaries['exp_id_1'].category, exp_summaries['exp_id_1'].language_code, exp_summaries['exp_id_1'].owner_ids, exp_summaries['exp_id_2'].category, exp_summaries['exp_id_2'].language_code, exp_summaries['exp_id_2'].exploration_model_last_updated, exp_summaries['exp_id_2'].owner_ids, exp_summaries['exp_id_2'].status), 0.0)
def test_contribution_msec_does_not_update_on_unpublished_explorations( self): self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.set_admins([self.ADMIN_EMAIL]) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) exploration = self.save_new_valid_exploration(self.EXP_ID, self.owner_id, end_state_name='End') self.init_state_name = exploration.init_state_name exp_services.publish_exploration_and_update_user_profiles( self.owner_id, self.EXP_ID) # We now manually reset the user's first_contribution_msec to None. # This is to test that the one off job skips over the unpublished # exploration and does not reset the user's first_contribution_msec. user_services._update_first_contribution_msec(self.owner_id, None) rights_manager.unpublish_exploration(self.admin_id, self.EXP_ID) # Test that first contribution time is not set for unpublished # explorations. job_id = user_jobs_one_off.UserFirstContributionMsecOneOffJob.create_new( ) user_jobs_one_off.UserFirstContributionMsecOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() self.assertIsNone( user_services.get_user_settings( self.owner_id).first_contribution_msec)
def test_unpublished_activity_is_removed_from_featured_list(self): rights_manager.publish_exploration(self.owner_id, self.EXP_ID_0) rights_manager.publish_exploration(self.owner_id, self.EXP_ID_1) rights_manager.publish_collection(self.owner_id, self.COL_ID_2) activity_services.update_featured_activity_references([ self._create_exploration_reference(self.EXP_ID_0), self._create_collection_reference(self.COL_ID_2)]) self._compare_lists( activity_services.get_featured_activity_references(), [ self._create_exploration_reference(self.EXP_ID_0), self._create_collection_reference(self.COL_ID_2)]) # Unpublishing an unfeatured activity does not affect the featured # list. rights_manager.unpublish_exploration(self.moderator_id, self.EXP_ID_1) self._compare_lists( activity_services.get_featured_activity_references(), [ self._create_exploration_reference(self.EXP_ID_0), self._create_collection_reference(self.COL_ID_2)]) # Unpublishing a featured activity removes it from the featured list. rights_manager.unpublish_collection(self.moderator_id, self.COL_ID_2) self._compare_lists( activity_services.get_featured_activity_references(), [ self._create_exploration_reference(self.EXP_ID_0)]) rights_manager.unpublish_exploration(self.moderator_id, self.EXP_ID_0) self._compare_lists( activity_services.get_featured_activity_references(), [])
def test_publishing_and_unpublishing_exploration(self): exp = exp_domain.Exploration.create_default_exploration( self.EXP_ID, title='A title', category='A category') exp_services.save_new_exploration(self.user_id_a, exp) exp_rights = rights_manager.get_exploration_rights(self.EXP_ID) self.assertFalse( rights_manager.check_can_access_activity(self.user_b, exp_rights)) rights_manager.publish_exploration(self.user_a, self.EXP_ID) exp_rights = rights_manager.get_exploration_rights(self.EXP_ID) self.assertTrue( rights_manager.check_can_access_activity(self.user_b, exp_rights)) self.assertFalse( rights_manager.check_can_unpublish_activity( self.user_a, exp_rights)) rights_manager.unpublish_exploration(self.user_admin, self.EXP_ID) exp_rights = rights_manager.get_exploration_rights(self.EXP_ID) self.assertTrue( rights_manager.check_can_access_activity(self.user_a, exp_rights)) self.assertFalse( rights_manager.check_can_access_activity(self.user_b, exp_rights))
def test_recommendations_after_changes_in_rights(self): with self.swap( jobs_registry, 'ONE_OFF_JOB_MANAGERS', self.ONE_OFF_JOB_MANAGERS_FOR_TESTS ): self.job_class.enqueue(self.job_class.create_new()) self.assertEqual( self.count_jobs_in_taskqueue( queue_name=taskqueue_services.QUEUE_NAME_DEFAULT), 1) self.process_and_flush_pending_tasks() recommendations = ( recommendations_services.get_exploration_recommendations( 'exp_id_1')) self.assertEqual( recommendations, ['exp_id_4', 'exp_id_2', 'exp_id_3']) rights_manager.unpublish_exploration(self.admin_id, 'exp_id_4') self.job_class.enqueue(self.job_class.create_new()) self.assertEqual( self.count_jobs_in_taskqueue( queue_name=taskqueue_services.QUEUE_NAME_DEFAULT), 1) self.process_and_flush_pending_tasks() recommendations = ( recommendations_services.get_exploration_recommendations( 'exp_id_1')) self.assertEqual(recommendations, ['exp_id_2', 'exp_id_3'])
def test_recommendations_after_changes_in_rights(self): with self.swap(jobs_registry, 'ALL_CONTINUOUS_COMPUTATION_MANAGERS', self.ALL_CONTINUOUS_COMPUTATION_MANAGERS_FOR_TESTS): ModifiedExplorationRecommendationsAggregator.start_computation() self.assertEqual( self.count_jobs_in_taskqueue( queue_name=taskqueue_services.QUEUE_NAME_DEFAULT), 1) self.process_and_flush_pending_tasks() recommendations = (recommendations_services. get_exploration_recommendations('exp_id_1')) self.assertEqual(recommendations, ['exp_id_4', 'exp_id_2', 'exp_id_3']) rights_manager.unpublish_exploration(self.ADMIN_ID, 'exp_id_4') ModifiedExplorationRecommendationsAggregator.stop_computation( self.ADMIN_ID) ModifiedExplorationRecommendationsAggregator.start_computation() self.assertEqual( self.count_jobs_in_taskqueue( queue_name=taskqueue_services.QUEUE_NAME_DEFAULT), 1) self.process_and_flush_pending_tasks() recommendations = (recommendations_services. get_exploration_recommendations('exp_id_1')) self.assertEqual(recommendations, ['exp_id_2', 'exp_id_3'])
def test_recommendations_after_changes_in_rights(self): with self.swap(jobs_registry, 'ONE_OFF_JOB_MANAGERS', self.ONE_OFF_JOB_MANAGERS_FOR_TESTS): self.job_class.enqueue(self.job_class.create_new()) self.assertEqual( self.count_jobs_in_mapreduce_taskqueue( taskqueue_services.QUEUE_NAME_ONE_OFF_JOBS), 1) self.process_and_flush_pending_mapreduce_tasks() recommendations = (recommendations_services. get_exploration_recommendations('exp_id_1')) self.assertEqual(recommendations, ['exp_id_4', 'exp_id_2', 'exp_id_3']) system_user = user_services.get_system_user() rights_manager.unpublish_exploration(system_user, 'exp_id_4') self.job_class.enqueue(self.job_class.create_new()) self.assertEqual( self.count_jobs_in_mapreduce_taskqueue( taskqueue_services.QUEUE_NAME_ONE_OFF_JOBS), 1) self.process_and_flush_pending_mapreduce_tasks() recommendations = (recommendations_services. get_exploration_recommendations('exp_id_1')) self.assertEqual(recommendations, ['exp_id_2', 'exp_id_3'])
def test_contribution_msec_does_not_update_on_unpublished_explorations(self): self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.set_admins([self.ADMIN_EMAIL]) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) exploration = self.save_new_valid_exploration( self.EXP_ID, self.owner_id, end_state_name='End') self.init_state_name = exploration.init_state_name exp_services.publish_exploration_and_update_user_profiles( self.owner_id, self.EXP_ID) # We now manually reset the user's first_contribution_msec to None. # This is to test that the one off job skips over the unpublished # exploration and does not reset the user's first_contribution_msec. user_services._update_first_contribution_msec( self.owner_id, None) rights_manager.unpublish_exploration(self.admin_id, self.EXP_ID) # Test that first contribution time is not set for unpublished # explorations. job_id = user_jobs_one_off.UserFirstContributionMsecOneOffJob.create_new() user_jobs_one_off.UserFirstContributionMsecOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() self.assertIsNone(user_services.get_user_settings( self.owner_id).first_contribution_msec)
def put(self, exploration_id): """Unpublishes the given exploration, and sends an email to all its owners. """ exploration = exp_services.get_exploration_by_id(exploration_id) email_body = self.payload.get('email_body') version = self.payload.get('version') _require_valid_version(version, exploration.version) # If moderator emails can be sent, check that all the prerequisites are # satisfied, otherwise do nothing. if feconf.REQUIRE_EMAIL_ON_MODERATOR_ACTION: if not email_body: raise self.InvalidInputException( 'Moderator actions should include an email to the ' 'recipient.') email_manager.require_moderator_email_prereqs_are_satisfied() # Unpublish exploration. rights_manager.unpublish_exploration(self.user, exploration_id) search_services.delete_explorations_from_search_index([exploration_id]) exp_rights = rights_manager.get_exploration_rights(exploration_id) # If moderator emails can be sent, send an email to the all owners of # the exploration notifying them of the change. if feconf.REQUIRE_EMAIL_ON_MODERATOR_ACTION: for owner_id in exp_rights.owner_ids: email_manager.send_moderator_action_email( self.user_id, owner_id, 'unpublish_exploration', exploration.title, email_body) self.render_json({ 'rights': exp_rights.to_dict(), })
def test_changing_viewability_of_exploration(self): exp = exp_domain.Exploration.create_default_exploration( self.EXP_ID, 'A title', 'A category') exp_services.save_new_exploration(self.user_id_a, exp) self.assertFalse( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue(rights_manager.Actor( self.user_id_a).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse(rights_manager.Actor( self.user_id_b).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue(rights_manager.Actor( self.user_id_admin).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) with self.assertRaisesRegexp(Exception, 'already the current value'): rights_manager.set_private_viewability_of_exploration( self.user_id_a, self.EXP_ID, False) with self.assertRaisesRegexp(Exception, 'cannot be changed'): rights_manager.set_private_viewability_of_exploration( self.user_id_b, self.EXP_ID, True) rights_manager.set_private_viewability_of_exploration( self.user_id_a, self.EXP_ID, True) self.assertTrue( rights_manager.Actor(self.user_id_a).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.set_private_viewability_of_exploration( self.user_id_a, self.EXP_ID, False) self.assertTrue( rights_manager.Actor(self.user_id_a).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.publish_exploration(self.user_id_a, self.EXP_ID) self.assertFalse(rights_manager.Actor( self.user_id_a).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID) self.assertTrue(rights_manager.Actor( self.user_id_a).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse(rights_manager.Actor( self.user_id_b).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue(rights_manager.Actor( self.user_id_admin).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
def test_changing_viewability_of_exploration(self): exp = exp_domain.Exploration.create_default_exploration( self.EXP_ID, title='A title', category='A category') exp_services.save_new_exploration(self.user_id_a, exp) self.assertFalse( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue(rights_manager.Actor( self.user_id_a).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse(rights_manager.Actor( self.user_id_b).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue(rights_manager.Actor( self.user_id_admin).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) with self.assertRaisesRegexp(Exception, 'already the current value'): rights_manager.set_private_viewability_of_exploration( self.user_id_a, self.EXP_ID, False) with self.assertRaisesRegexp(Exception, 'cannot be changed'): rights_manager.set_private_viewability_of_exploration( self.user_id_b, self.EXP_ID, True) rights_manager.set_private_viewability_of_exploration( self.user_id_a, self.EXP_ID, True) self.assertTrue( rights_manager.Actor(self.user_id_a).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.set_private_viewability_of_exploration( self.user_id_a, self.EXP_ID, False) self.assertTrue( rights_manager.Actor(self.user_id_a).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.publish_exploration(self.user_id_a, self.EXP_ID) self.assertFalse(rights_manager.Actor( self.user_id_a).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID) self.assertTrue(rights_manager.Actor( self.user_id_a).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse(rights_manager.Actor( self.user_id_b).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue(rights_manager.Actor( self.user_id_admin).can_change_private_viewability( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
def test_can_unpublish_and_delete_published_exploration(self): exp = exp_domain.Exploration.create_default_exploration( self.EXP_ID, 'A title', 'A category') exp_services.save_new_exploration(self.user_id_a, exp) rights_manager.publish_exploration(self.user_id_a, self.EXP_ID) rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID) self.assertTrue( rights_manager.Actor(self.user_id_a).can_delete(self.EXP_ID))
def put(self, exploration_id): """Updates the publication status of the given exploration, and sends an email to all its owners. """ exploration = exp_services.get_exploration_by_id(exploration_id) action = self.payload.get('action') email_body = self.payload.get('email_body') version = self.payload.get('version') _require_valid_version(version, exploration.version) if action not in feconf.VALID_MODERATOR_ACTIONS: raise self.InvalidInputException('Invalid moderator action.') # If moderator emails can be sent, check that all the prerequisites are # satisfied, otherwise do nothing. if feconf.REQUIRE_EMAIL_ON_MODERATOR_ACTION: if not email_body: raise self.InvalidInputException( 'Moderator actions should include an email to the ' 'recipient.') email_manager.require_moderator_email_prereqs_are_satisfied() # Perform the moderator action. if action == 'unpublish_exploration': rights_manager.unpublish_exploration( self.user_id, exploration_id) exp_services.delete_documents_from_search_index([ exploration_id]) elif action == 'publicize_exploration': try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration( self.user_id, exploration_id) else: raise self.InvalidInputException( 'No change was made to this exploration.') exp_rights = rights_manager.get_exploration_rights(exploration_id) # If moderator emails can be sent, send an email to the all owners of # the exploration notifying them of the change. if feconf.REQUIRE_EMAIL_ON_MODERATOR_ACTION: for owner_id in exp_rights.owner_ids: email_manager.send_moderator_action_email( self.user_id, owner_id, feconf.VALID_MODERATOR_ACTIONS[action]['email_intent'], exploration.title, email_body) self.render_json({ 'rights': exp_rights.to_dict(), })
def test_publishing_exploration(self): exp = exp_domain.Exploration.create_default_exploration( self.EXP_ID, 'A title', 'A category') exp_services.save_new_exploration(self.user_id_a, exp) rights_manager.publish_exploration(self.user_id_a, self.EXP_ID) self.assertTrue( rights_manager.Actor(self.user_id_b).can_view(self.EXP_ID)) rights_manager.unpublish_exploration(self.user_id_a, self.EXP_ID) self.assertFalse( rights_manager.Actor(self.user_id_b).can_view(self.EXP_ID))
def test_contribution_msec_does_not_change_if_exp_unpublished(self): self.save_new_valid_exploration( self.EXP_ID, self.owner_id, end_state_name='End') exp_services.publish_exploration_and_update_user_profiles( self.owner_id, self.EXP_ID) rights_manager.unpublish_exploration(self.admin_id, self.EXP_ID) # Test that contribution time is not eliminated if exploration is # unpublished. self.assertIsNotNone(user_services.get_user_settings( self.owner_id).first_contribution_msec)
def test_get_item_similarity(self): exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual( recommendations_services.get_item_similarity( exp_summaries['exp_id_1'], exp_summaries['exp_id_2']), 4.5) self.assertEqual( recommendations_services.get_item_similarity( exp_summaries['exp_id_4'], exp_summaries['exp_id_4']), 9.0) system_user = user_services.get_system_user() rights_manager.unpublish_exploration(system_user, 'exp_id_2') exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual( recommendations_services.get_item_similarity( exp_summaries['exp_id_1'], exp_summaries['exp_id_2']), 0.0)
def test_get_item_similarity(self): exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual(recommendations_services.get_item_similarity( exp_summaries['exp_id_1'].category, exp_summaries['exp_id_1'].language_code, exp_summaries['exp_id_1'].owner_ids, exp_summaries['exp_id_2'].category, exp_summaries['exp_id_2'].language_code, exp_summaries['exp_id_2'].exploration_model_last_updated, exp_summaries['exp_id_2'].owner_ids, exp_summaries['exp_id_2'].status), 4.5) self.assertEqual(recommendations_services.get_item_similarity( exp_summaries['exp_id_4'].category, exp_summaries['exp_id_4'].language_code, exp_summaries['exp_id_4'].owner_ids, exp_summaries['exp_id_4'].category, exp_summaries['exp_id_4'].language_code, exp_summaries['exp_id_4'].exploration_model_last_updated, exp_summaries['exp_id_4'].owner_ids, exp_summaries['exp_id_4'].status), 9.0) rights_manager.publicize_exploration(self.admin_id, 'exp_id_4') exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual(recommendations_services.get_item_similarity( exp_summaries['exp_id_4'].category, exp_summaries['exp_id_4'].language_code, exp_summaries['exp_id_4'].owner_ids, exp_summaries['exp_id_4'].category, exp_summaries['exp_id_4'].language_code, exp_summaries['exp_id_4'].exploration_model_last_updated, exp_summaries['exp_id_4'].owner_ids, exp_summaries['exp_id_4'].status), 10.0) rights_manager.unpublish_exploration(self.admin_id, 'exp_id_2') exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual(recommendations_services.get_item_similarity( exp_summaries['exp_id_1'].category, exp_summaries['exp_id_1'].language_code, exp_summaries['exp_id_1'].owner_ids, exp_summaries['exp_id_2'].category, exp_summaries['exp_id_2'].language_code, exp_summaries['exp_id_2'].exploration_model_last_updated, exp_summaries['exp_id_2'].owner_ids, exp_summaries['exp_id_2'].status), 0.0)
def test_get_item_similarity(self): with self.assertRaisesRegexp( Exception, 'Invalid reference_exp_id fake_exp_id'): recommendations_services.get_item_similarity( 'fake_exp_id', 'fake_exp_id_2') self.assertEqual(recommendations_services.get_item_similarity( 'exp_id_1', 'exp_id_2'), 4.5) self.assertEqual(recommendations_services.get_item_similarity( 'exp_id_4', 'exp_id_4'), 9.0) rights_manager.publicize_exploration(self.ADMIN_ID, 'exp_id_4') self.assertEqual(recommendations_services.get_item_similarity( 'exp_id_4', 'exp_id_4'), 10.0) rights_manager.unpublish_exploration(self.ADMIN_ID, 'exp_id_2') self.assertEqual(recommendations_services.get_item_similarity( 'exp_id_1', 'exp_id_2'), 0.0)
def test_contribution_msec_does_not_change_if_exploration_unpublished(self): self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.set_admins([self.ADMIN_EMAIL]) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) exploration = self.save_new_valid_exploration( self.EXP_ID, self.owner_id, end_state_name='End') self.init_state_name = exploration.init_state_name exp_services.publish_exploration_and_update_user_profiles( self.owner_id, self.EXP_ID) rights_manager.unpublish_exploration(self.admin_id, self.EXP_ID) # Test that contribution time is not eliminated if exploration is # unpublished. self.assertIsNotNone(user_services.get_user_settings( self.owner_id).first_contribution_msec)
def test_can_only_delete_unpublished_explorations(self): exp = exp_domain.Exploration.create_default_exploration(self.EXP_ID, "A title", "A category") exp_services.save_new_exploration(self.user_id_a, exp) self.assertTrue( rights_manager.Actor(self.user_id_a).can_delete(rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID) ) rights_manager.publish_exploration(self.user_id_a, self.EXP_ID) self.assertFalse( rights_manager.Actor(self.user_id_a).can_delete(rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID) ) rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID) self.assertTrue( rights_manager.Actor(self.user_id_a).can_delete(rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID) )
def test_contribution_msec_does_not_update_on_unpublished_explorations(self): self.save_new_valid_exploration( self.EXP_ID, self.owner_id, end_state_name='End') exp_services.publish_exploration_and_update_user_profiles( self.owner_id, self.EXP_ID) # We now manually reset the user's first_contribution_msec to None. # This is to test that the one off job skips over the unpublished # exploration and does not reset the user's first_contribution_msec. user_services._update_first_contribution_msec( # pylint: disable=protected-access self.owner_id, None) rights_manager.unpublish_exploration(self.admin_id, self.EXP_ID) # Test that first contribution time is not set for unpublished # explorations. job_id = user_jobs_one_off.UserFirstContributionMsecOneOffJob.create_new() user_jobs_one_off.UserFirstContributionMsecOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() self.assertIsNone(user_services.get_user_settings( self.owner_id).first_contribution_msec)
def test_first_published_time_of_exploration_that_is_unpublished(self): """This tests that, if an exploration is published, unpublished, and then published again, the job uses the first publication time as the value for first_published_msec. """ self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.set_admins([self.ADMIN_USERNAME]) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) owner = user_services.UserActionsInfo(owner_id) admin = user_services.UserActionsInfo(admin_id) self.save_new_valid_exploration(self.EXP_ID, owner_id, end_state_name='End') rights_manager.publish_exploration(owner, self.EXP_ID) job_class = exp_jobs_one_off.ExplorationFirstPublishedOneOffJob job_id = job_class.create_new() exp_jobs_one_off.ExplorationFirstPublishedOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() exploration_rights = rights_manager.get_exploration_rights(self.EXP_ID) # Test to see whether first_published_msec was correctly updated. exp_first_published = exploration_rights.first_published_msec exp_rights_model = exp_models.ExplorationRightsModel.get(self.EXP_ID) last_updated_time_msec = utils.get_time_in_millisecs( exp_rights_model.last_updated) self.assertLess(exp_first_published, last_updated_time_msec) rights_manager.unpublish_exploration(admin, self.EXP_ID) rights_manager.publish_exploration(owner, self.EXP_ID) job_id = job_class.create_new() exp_jobs_one_off.ExplorationFirstPublishedOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() # Test to see whether first_published_msec remains the same despite the # republication. exploration_rights = rights_manager.get_exploration_rights(self.EXP_ID) self.assertEqual(exp_first_published, exploration_rights.first_published_msec)
def test_can_only_delete_unpublished_explorations(self): exp = exp_domain.Exploration.create_default_exploration( self.EXP_ID, 'A title', 'A category') exp_services.save_new_exploration(self.user_id_a, exp) self.assertTrue( rights_manager.Actor(self.user_id_a).can_delete( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.publish_exploration(self.user_id_a, self.EXP_ID) self.assertFalse( rights_manager.Actor(self.user_id_a).can_delete( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID) self.assertTrue( rights_manager.Actor(self.user_id_a).can_delete( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
def test_get_item_similarity(self) -> None: exp_summaries = exp_services.get_all_exploration_summaries( ) # type: ignore[no-untyped-call] self.assertEqual( recommendations_services.get_item_similarity( exp_summaries['exp_id_1'], exp_summaries['exp_id_2']), 4.5) self.assertEqual( recommendations_services.get_item_similarity( exp_summaries['exp_id_4'], exp_summaries['exp_id_4']), 9.0) system_user = user_services.get_system_user( ) # type: ignore[no-untyped-call] rights_manager.unpublish_exploration( system_user, 'exp_id_2') # type: ignore[no-untyped-call] exp_summaries = exp_services.get_all_exploration_summaries( ) # type: ignore[no-untyped-call] self.assertEqual( recommendations_services.get_item_similarity( exp_summaries['exp_id_1'], exp_summaries['exp_id_2']), 0.0)
def test_contribution_msec_does_not_update_on_unpublished_explorations( self): self.save_new_valid_exploration( self.EXP_ID, self.owner_id, end_state_name='End') exp_services.publish_exploration_and_update_user_profiles( self.owner, self.EXP_ID) # We now manually reset the user's first_contribution_msec to None. # This is to test that the one off job skips over the unpublished # exploration and does not reset the user's first_contribution_msec. user_services._update_first_contribution_msec( # pylint: disable=protected-access self.owner_id, None) rights_manager.unpublish_exploration(self.admin, self.EXP_ID) # Test that first contribution time is not set for unpublished # explorations. job_id = ( user_jobs_one_off.UserFirstContributionMsecOneOffJob.create_new()) user_jobs_one_off.UserFirstContributionMsecOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() self.assertIsNone(user_services.get_user_settings( self.owner_id).first_contribution_msec)
def test_first_published_time_of_exploration_that_is_unpublished(self): """This tests that, if an exploration is published, unpublished, and then published again, the job uses the first publication time as the value for first_published_msec. """ self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.set_admins([self.ADMIN_USERNAME]) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) self.save_new_valid_exploration( self.EXP_ID, owner_id, end_state_name='End') rights_manager.publish_exploration(owner_id, self.EXP_ID) job_class = exp_jobs_one_off.ExplorationFirstPublishedOneOffJob job_id = job_class.create_new() exp_jobs_one_off.ExplorationFirstPublishedOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() exploration_rights = rights_manager.get_exploration_rights(self.EXP_ID) # Test to see whether first_published_msec was correctly updated. exp_first_published = exploration_rights.first_published_msec exp_rights_model = exp_models.ExplorationRightsModel.get(self.EXP_ID) last_updated_time_msec = utils.get_time_in_millisecs( exp_rights_model.last_updated) self.assertLess( exp_first_published, last_updated_time_msec) rights_manager.unpublish_exploration(admin_id, self.EXP_ID) rights_manager.publish_exploration(owner_id, self.EXP_ID) job_id = job_class.create_new() exp_jobs_one_off.ExplorationFirstPublishedOneOffJob.enqueue(job_id) self.process_and_flush_pending_tasks() # Test to see whether first_published_msec remains the same despite the # republication. exploration_rights = rights_manager.get_exploration_rights(self.EXP_ID) self.assertEqual( exp_first_published, exploration_rights.first_published_msec)
def test_contribution_msec_does_not_change_if_exploration_unpublished( self): self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.set_admins([self.ADMIN_EMAIL]) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) exploration = self.save_new_valid_exploration(self.EXP_ID, self.owner_id, end_state_name='End') self.init_state_name = exploration.init_state_name exp_services.publish_exploration_and_update_user_profiles( self.owner_id, self.EXP_ID) rights_manager.unpublish_exploration(self.admin_id, self.EXP_ID) # Test that contribution time is not eliminated if exploration is # unpublished. self.assertIsNotNone( user_services.get_user_settings( self.owner_id).first_contribution_msec)
def test_publishing_and_unpublishing_exploration(self): exp = exp_domain.Exploration.create_default_exploration( self.EXP_ID, title='A title', category='A category') exp_services.save_new_exploration(self.user_id_a, exp) self.assertFalse( rights_manager.Actor(self.user_id_b).can_play( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.publish_exploration(self.user_id_a, self.EXP_ID) self.assertTrue( rights_manager.Actor(self.user_id_b).can_play( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse( rights_manager.Actor(self.user_id_a).can_unpublish( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) rights_manager.unpublish_exploration(self.user_id_admin, self.EXP_ID) self.assertTrue( rights_manager.Actor(self.user_id_a).can_play( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertTrue( rights_manager.Actor(self.user_id_a).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse( rights_manager.Actor(self.user_id_b).can_play( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID)) self.assertFalse( rights_manager.Actor(self.user_id_b).can_view( rights_manager.ACTIVITY_TYPE_EXPLORATION, self.EXP_ID))
def put(self, exploration_id): """Updates the editing rights for the given exploration.""" exploration = exp_services.get_exploration_by_id(exploration_id) version = self.payload.get('version') _require_valid_version(version, exploration.version) is_public = self.payload.get('is_public') is_publicized = self.payload.get('is_publicized') is_community_owned = self.payload.get('is_community_owned') new_member_username = self.payload.get('new_member_username') new_member_role = self.payload.get('new_member_role') viewable_if_private = self.payload.get('viewable_if_private') if new_member_username: if not rights_manager.Actor(self.user_id).can_modify_roles( rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id): raise self.UnauthorizedUserException( 'Only an owner of this exploration can add or change ' 'roles.') new_member_id = user_services.get_user_id_from_username( new_member_username) if new_member_id is None: raise Exception('Sorry, we could not find the specified user.') rights_manager.assign_role_for_exploration(self.user_id, exploration_id, new_member_id, new_member_role) elif is_public is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_public: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) exp_services.publish_exploration_and_update_user_profiles( self.user_id, exploration_id) exp_services.index_explorations_given_ids([exploration_id]) else: rights_manager.unpublish_exploration(self.user_id, exploration_id) exp_services.delete_documents_from_search_index( [exploration_id]) elif is_publicized is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_publicized: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration(self.user_id, exploration_id) else: rights_manager.unpublicize_exploration(self.user_id, exploration_id) elif is_community_owned: exploration = exp_services.get_exploration_by_id(exploration_id) try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.release_ownership_of_exploration( self.user_id, exploration_id) elif viewable_if_private is not None: rights_manager.set_private_viewability_of_exploration( self.user_id, exploration_id, viewable_if_private) else: raise self.InvalidInputException( 'No change was made to this exploration.') self.render_json({ 'rights': rights_manager.get_exploration_rights(exploration_id).to_dict() })
def put(self, exploration_id): """Updates the editing rights for the given exploration.""" exploration = exp_services.get_exploration_by_id(exploration_id) version = self.payload.get('version') _require_valid_version(version, exploration.version) is_public = self.payload.get('is_public') is_publicized = self.payload.get('is_publicized') is_community_owned = self.payload.get('is_community_owned') new_member_email = self.payload.get('new_member_email') new_member_role = self.payload.get('new_member_role') if new_member_email: if not rights_manager.Actor(self.user_id).can_modify_roles( exploration_id): raise self.UnauthorizedUserException( 'Only an owner of this exploration can add or change ' 'roles.') new_member_id = user_services.get_user_id_from_email( new_member_email) if new_member_id is None: raise Exception( 'Sorry, we could not find a user with this email address.') user_services.get_or_create_user(new_member_id, new_member_email) rights_manager.assign_role( self.user_id, exploration_id, new_member_id, new_member_role) elif is_public is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_public: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publish_exploration( self.user_id, exploration_id) else: rights_manager.unpublish_exploration( self.user_id, exploration_id) elif is_publicized is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_publicized: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration( self.user_id, exploration_id) else: rights_manager.unpublicize_exploration( self.user_id, exploration_id) elif is_community_owned: exploration = exp_services.get_exploration_by_id(exploration_id) try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.release_ownership(self.user_id, exploration_id) else: raise self.InvalidInputException( 'No change was made to this exploration.') self.render_json({ 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict() })
def test_get_item_similarity(self): exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual( recommendations_services.get_item_similarity( exp_summaries["exp_id_1"].category, exp_summaries["exp_id_1"].language_code, exp_summaries["exp_id_1"].owner_ids, exp_summaries["exp_id_2"].category, exp_summaries["exp_id_2"].language_code, exp_summaries["exp_id_2"].exploration_model_last_updated, exp_summaries["exp_id_2"].owner_ids, exp_summaries["exp_id_2"].status, ), 4.5, ) self.assertEqual( recommendations_services.get_item_similarity( exp_summaries["exp_id_4"].category, exp_summaries["exp_id_4"].language_code, exp_summaries["exp_id_4"].owner_ids, exp_summaries["exp_id_4"].category, exp_summaries["exp_id_4"].language_code, exp_summaries["exp_id_4"].exploration_model_last_updated, exp_summaries["exp_id_4"].owner_ids, exp_summaries["exp_id_4"].status, ), 9.0, ) rights_manager.publicize_exploration(self.ADMIN_ID, "exp_id_4") exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual( recommendations_services.get_item_similarity( exp_summaries["exp_id_4"].category, exp_summaries["exp_id_4"].language_code, exp_summaries["exp_id_4"].owner_ids, exp_summaries["exp_id_4"].category, exp_summaries["exp_id_4"].language_code, exp_summaries["exp_id_4"].exploration_model_last_updated, exp_summaries["exp_id_4"].owner_ids, exp_summaries["exp_id_4"].status, ), 10.0, ) rights_manager.unpublish_exploration(self.ADMIN_ID, "exp_id_2") exp_summaries = exp_services.get_all_exploration_summaries() self.assertEqual( recommendations_services.get_item_similarity( exp_summaries["exp_id_1"].category, exp_summaries["exp_id_1"].language_code, exp_summaries["exp_id_1"].owner_ids, exp_summaries["exp_id_2"].category, exp_summaries["exp_id_2"].language_code, exp_summaries["exp_id_2"].exploration_model_last_updated, exp_summaries["exp_id_2"].owner_ids, exp_summaries["exp_id_2"].status, ), 0.0, )
def test_exp_state_pairs_are_produced_only_for_desired_interactions(self): """Checks output pairs are produced only for desired interactions. """ owner = user_services.UserActionsInfo(self.albert_id) exploration = exp_domain.Exploration.create_default_exploration( self.VALID_EXP_ID, title='title', category='category') exploration.add_states(['State1', 'State2']) state1 = exploration.states['State1'] state2 = exploration.states['State2'] customization_args_dict1 = { 'choices': { 'value': [{ 'html': '<p>This is value1 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_0' }, { 'html': '<p>This is value2 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_1' }] }, 'allowMultipleItemsInSamePosition': { 'value': True } } answer_group_list1 = [{ 'rule_input_translations': {}, 'rule_types_to_inputs': { 'IsEqualToOrdering': [{ 'x': [['a'], ['b']] }] }, 'outcome': { 'dest': 'Introduction', 'feedback': { 'content_id': 'feedback1', 'html': '<p>Outcome for state1</p>' }, 'param_changes': [], 'labelled_as_correct': False, 'refresher_exploration_id': None, 'missing_prerequisite_skill_id': None }, 'training_data': [], 'tagged_skill_misconception_id': None }] customization_args_dict2 = { 'choices': { 'value': [{ 'html': '<p>This is value1 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_0' }, { 'html': '<p>This is value2 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_1' }] }, 'allowMultipleItemsInSamePosition': { 'value': True } } answer_group_list2 = [{ 'rule_input_translations': {}, 'rule_types_to_inputs': { 'HasElementXBeforeElementY': [{ 'x': '', 'y': '' }], 'IsEqualToOrdering': [{ 'x': [['a']] }, { 'x': [] }], 'IsEqualToOrderingWithOneItemAtIncorrectPosition': [{ 'x': [] }] }, 'outcome': { 'dest': 'State1', 'feedback': { 'content_id': 'feedback', 'html': '<p>Outcome for state2</p>' }, 'param_changes': [], 'labelled_as_correct': False, 'refresher_exploration_id': None, 'missing_prerequisite_skill_id': None }, 'training_data': [], 'tagged_skill_misconception_id': None }, { 'rule_input_translations': {}, 'rule_types_to_inputs': { 'HasElementXAtPositionY': [{ 'x': '', 'y': 1 }, { 'x': 'a', 'y': 2 }] }, 'outcome': { 'dest': 'Introduction', 'feedback': { 'content_id': 'feedback2', 'html': '<p>Outcome for state1</p>' }, 'param_changes': [], 'labelled_as_correct': False, 'refresher_exploration_id': None, 'missing_prerequisite_skill_id': None }, 'training_data': [], 'tagged_skill_misconception_id': None }] state1.update_interaction_id('DragAndDropSortInput') state1.update_interaction_customization_args(customization_args_dict1) state1.update_next_content_id_index(2) state1.update_interaction_answer_groups(answer_group_list1) exp_services.save_new_exploration(self.albert_id, exploration) rights_manager.publish_exploration(owner, self.VALID_EXP_ID) # Start DragAndDropSortInputInteractionOneOffJob on sample exploration. job_id = (interaction_jobs_one_off. DragAndDropSortInputInteractionOneOffJob.create_new()) (interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob. enqueue(job_id)) self.process_and_flush_pending_tasks() actual_output = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob. get_output(job_id)) self.assertEqual(actual_output, []) state2.update_interaction_id('DragAndDropSortInput') state2.update_interaction_customization_args(customization_args_dict2) state2.update_next_content_id_index(2) state2.update_interaction_answer_groups(answer_group_list2) exp_services.save_new_exploration(self.albert_id, exploration) rights_manager.publish_exploration(owner, self.VALID_EXP_ID) # Start DragAndDropSortInputInteractionOneOffJob on sample exploration. job_id = (interaction_jobs_one_off. DragAndDropSortInputInteractionOneOffJob.create_new()) (interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob. enqueue(job_id)) self.process_and_flush_pending_tasks() actual_output = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob. get_output(job_id)) expected_output = [( u'[u\'exp_id0\', [u"[u\'State name: State2, AnswerGroup: 0, Rule in' 'put x in rule with rule type IsEqualToOrderingWithOneItemAtIncorre' 'ctPosition and rule input index 0 is empty. \', u\'State name: Sta' 'te2, AnswerGroup: 0, Rule input y in rule with rule type HasElemen' 'tXBeforeElementY and rule input index 0 is empty. \', u\'State nam' 'e: State2, AnswerGroup: 0, Rule input x in rule with rule type Has' 'ElementXBeforeElementY and rule input index 0 is empty. \', u\'Sta' 'te name: State2, AnswerGroup: 0, Rule input x in rule with rule ty' 'pe IsEqualToOrdering and rule input index 1 is empty. \', u\'State' ' name: State2, AnswerGroup: 1, Rule input x in rule with rule type' ' HasElementXAtPositionY and rule input index 0 is empty. \']"]]')] self.assertEqual(actual_output, expected_output) rights_manager.unpublish_exploration(self.admin, self.VALID_EXP_ID) # Start DragAndDropSortInputInteractionOneOffJob on private # exploration. job_id = (interaction_jobs_one_off. DragAndDropSortInputInteractionOneOffJob.create_new()) (interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob. enqueue(job_id)) self.process_and_flush_pending_tasks() actual_output = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob. get_output(job_id)) self.assertEqual(actual_output, [])
def test_exp_state_pairs_are_produced_only_for_desired_interactions(self): """Checks output pairs are produced only for desired interactions. """ owner = user_services.get_user_actions_info(self.albert_id) exploration = exp_domain.Exploration.create_default_exploration( self.VALID_EXP_ID, title='title', category='category') exploration.add_states(['State1', 'State2']) state1 = exploration.states['State1'] state2 = exploration.states['State2'] customization_args_dict1 = { 'choices': {'value': [{ 'html': '<p>This is value1 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_0' }, { 'html': '<p>This is value2 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_1' }]}, 'allowMultipleItemsInSamePosition': {'value': True} } state_answer_group_list1 = [state_domain.AnswerGroup( state_domain.Outcome( 'Introduction', state_domain.SubtitledHtml( 'feedback1', '<p>Outcome for state1</p>'), False, [], None, None), [ state_domain.RuleSpec( 'IsEqualToOrdering', { 'x': [['a'], ['b']] }) ], [], None )] customization_args_dict2 = { 'choices': {'value': [{ 'html': '<p>This is value1 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_0' }, { 'html': '<p>This is value2 for DragAndDropSortInput</p>', 'content_id': 'ca_choices_1' }]}, 'allowMultipleItemsInSamePosition': {'value': True} } state_answer_group_list2 = [ state_domain.AnswerGroup( state_domain.Outcome( 'State1', state_domain.SubtitledHtml( 'feedback', '<p>Outcome for state2</p>'), False, [], None, None), [ state_domain.RuleSpec( 'IsEqualToOrderingWithOneItemAtIncorrectPosition', { 'x': [] }), state_domain.RuleSpec( 'IsEqualToOrdering', { 'x': [['a']] }), state_domain.RuleSpec( 'HasElementXBeforeElementY', { 'x': '', 'y': '' }), state_domain.RuleSpec( 'IsEqualToOrdering', { 'x': [] }) ], [], None ), state_domain.AnswerGroup( state_domain.Outcome( 'Introduction', state_domain.SubtitledHtml( 'feedback2', '<p>Outcome for state1</p>'), False, [], None, None), [ state_domain.RuleSpec( 'HasElementXAtPositionY', { 'x': '', 'y': 1 }), state_domain.RuleSpec( 'HasElementXAtPositionY', { 'x': 'a', 'y': 2 }) ], [], None ) ] state1.update_interaction_id('DragAndDropSortInput') state1.update_interaction_customization_args(customization_args_dict1) state1.update_next_content_id_index(2) state1.update_interaction_answer_groups(state_answer_group_list1) exp_services.save_new_exploration(self.albert_id, exploration) rights_manager.publish_exploration(owner, self.VALID_EXP_ID) # Start DragAndDropSortInputInteractionOneOffJob on sample exploration. job_id = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob .create_new()) ( interaction_jobs_one_off .DragAndDropSortInputInteractionOneOffJob.enqueue(job_id)) self.process_and_flush_pending_mapreduce_tasks() actual_output = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob .get_output(job_id)) self.assertEqual(actual_output, []) state2.update_interaction_id('DragAndDropSortInput') state2.update_interaction_customization_args(customization_args_dict2) state2.update_next_content_id_index(2) state2.update_interaction_answer_groups(state_answer_group_list2) exp_services.save_new_exploration(self.albert_id, exploration) rights_manager.publish_exploration(owner, self.VALID_EXP_ID) # Start DragAndDropSortInputInteractionOneOffJob on sample exploration. job_id = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob .create_new()) ( interaction_jobs_one_off .DragAndDropSortInputInteractionOneOffJob.enqueue(job_id)) self.process_and_flush_pending_mapreduce_tasks() actual_output = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob .get_output(job_id)) expected_output = [( u'[u\'exp_id0\', [u"[u\'State name: State2, AnswerGroup: 0, Rule ' 'input x in rule with index 0 is empty. \', u\'State name: State2,' ' AnswerGroup: 0, Rule input y in rule with index 2 is empty. \', ' 'u\'State name: State2, AnswerGroup: 0, Rule input x in rule with ' 'index 2 is empty. \', u\'State name: State2, AnswerGroup: 0, Rule' ' input x in rule with index 3 is empty. \', u\'State name: State2' ', AnswerGroup: 1, Rule input x in rule with index 0 is empty. \']' '"]]' )] self.assertEqual(actual_output, expected_output) rights_manager.unpublish_exploration(self.admin, self.VALID_EXP_ID) # Start DragAndDropSortInputInteractionOneOffJob on private # exploration. job_id = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob .create_new()) ( interaction_jobs_one_off .DragAndDropSortInputInteractionOneOffJob.enqueue(job_id)) self.process_and_flush_pending_mapreduce_tasks() actual_output = ( interaction_jobs_one_off.DragAndDropSortInputInteractionOneOffJob .get_output(job_id)) self.assertEqual(actual_output, [])
def put(self, exploration_id): """Updates the editing rights for the given exploration.""" exploration = exp_services.get_exploration_by_id(exploration_id) version = self.payload.get('version') _require_valid_version(version, exploration.version) is_public = self.payload.get('is_public') is_publicized = self.payload.get('is_publicized') is_community_owned = self.payload.get('is_community_owned') new_member_username = self.payload.get('new_member_username') new_member_role = self.payload.get('new_member_role') viewable_if_private = self.payload.get('viewable_if_private') if new_member_username: if not rights_manager.Actor( self.user_id).can_modify_roles( rights_manager.ACTIVITY_TYPE_EXPLORATION, exploration_id): raise self.UnauthorizedUserException( 'Only an owner of this exploration can add or change ' 'roles.') new_member_id = user_services.get_user_id_from_username( new_member_username) if new_member_id is None: raise Exception( 'Sorry, we could not find the specified user.') rights_manager.assign_role_for_exploration( self.user_id, exploration_id, new_member_id, new_member_role) elif is_public is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_public: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) exp_services.publish_exploration_and_update_user_profiles( self.user_id, exploration_id) exp_services.index_explorations_given_ids([exploration_id]) else: rights_manager.unpublish_exploration( self.user_id, exploration_id) exp_services.delete_documents_from_search_index([ exploration_id]) elif is_publicized is not None: exploration = exp_services.get_exploration_by_id(exploration_id) if is_publicized: try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.publicize_exploration( self.user_id, exploration_id) else: rights_manager.unpublicize_exploration( self.user_id, exploration_id) elif is_community_owned: exploration = exp_services.get_exploration_by_id(exploration_id) try: exploration.validate(strict=True) except utils.ValidationError as e: raise self.InvalidInputException(e) rights_manager.release_ownership_of_exploration( self.user_id, exploration_id) elif viewable_if_private is not None: rights_manager.set_private_viewability_of_exploration( self.user_id, exploration_id, viewable_if_private) else: raise self.InvalidInputException( 'No change was made to this exploration.') self.render_json({ 'rights': rights_manager.get_exploration_rights( exploration_id).to_dict() })
def test_exp_state_pairs_are_produced_for_drag_and_drop_sort_interactions( self): """Checks (exp, state) pairs are produced correctly for DragAndDropSort interactions. """ owner = user_services.get_user_actions_info(self.albert_id) exploration = exp_domain.Exploration.create_default_exploration( self.VALID_EXP_ID, title='title', category='category') exploration.add_states(['State1', 'اختبارات']) state1 = exploration.states['State1'] state2 = exploration.states['اختبارات'] customization_args_dict1 = { 'choices': {'value': [{ 'html': '<p>This is value1 for DragAndDropSort</p>', 'content_id': 'ca_choices_0' }, { 'html': '<p>This is value2 for DragAndDropSort</p>', 'content_id': 'ca_choices_1' }]}, 'allowMultipleItemsInSamePosition': {'value': True} } state_answer_group_list1 = [state_domain.AnswerGroup( state_domain.Outcome( 'Introduction', state_domain.SubtitledHtml( 'feedback', '<p>Outcome for state1</p>'), False, [], None, None), [ state_domain.RuleSpec( 'IsEqualToOrdering', { 'x': [['<p>This is value1 for DragAndDropSort</p>']] }), state_domain.RuleSpec( 'IsEqualToOrdering', { 'x': [['<p>This is value2 for DragAndDropSort</p>']] }) ], [], None )] solution1 = state_domain.Solution.from_dict('DragAndDropSortInput', { 'answer_is_exclusive': True, 'correct_answer': [['<p>This is value2 for DragAndDropSort</p>']], 'explanation': { 'content_id': 'solution', 'html': '' } }) hint_list1 = [state_domain.Hint.from_dict({ 'hint_content': { 'content_id': 'hint_0', 'html': '' } })] state1.update_interaction_id('DragAndDropSortInput') state1.update_interaction_customization_args(customization_args_dict1) state1.update_next_content_id_index(2) state1.update_interaction_answer_groups(state_answer_group_list1) exp_services.save_new_exploration(self.albert_id, exploration) state1.update_interaction_solution(solution1) state1.update_interaction_hints(hint_list1) # Start RuleInputToCustomizationArgsMappingOneOffJob job on sample # exploration. job_id = ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.create_new()) ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.enqueue(job_id)) self.process_and_flush_pending_mapreduce_tasks() actual_output = ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.get_output(job_id)) self.assertEqual(actual_output, []) customization_args_dict2 = { 'choices': {'value': [{ 'html': '<p>This is value1 for DragAndDropSort</p>', 'content_id': 'ca_choices_0' }, { 'html': '<p>This is value2 for DragAndDropSort</p>', 'content_id': 'ca_choices_1' }]}, 'allowMultipleItemsInSamePosition': {'value': True} } state_answer_group_list2 = [state_domain.AnswerGroup( state_domain.Outcome( 'State1', state_domain.SubtitledHtml( 'feedback', '<p>Outcome for state2</p>'), False, [], None, None), [ state_domain.RuleSpec( 'IsEqualToOrdering', { 'x': [[ '<p>This is value1 for DragAndDropSort</p>', '<p>This is value3 for DragAndDropSort</p>' ]] }), state_domain.RuleSpec( 'HasElementXBeforeElementY', { 'x': '<p>This is value3 for DragAndDropSort</p>', 'y': '<p>This is value1 for DragAndDropSort</p>' }), state_domain.RuleSpec( 'HasElementXAtPositionY', { 'x': '<p>This is value3 for DragAndDropSort</p>', 'y': 2 }) ], [], None )] solution2 = state_domain.Solution.from_dict('DragAndDropSortInput', { 'answer_is_exclusive': True, 'correct_answer': [['<p>This is value3 for DragAndDropSort</p>']], 'explanation': { 'content_id': 'solution', 'html': '' } }) hint_list2 = [state_domain.Hint.from_dict({ 'hint_content': { 'content_id': 'hint_0', 'html': '' } })] state2.update_interaction_id('DragAndDropSortInput') state2.update_interaction_customization_args(customization_args_dict2) state2.update_next_content_id_index(2) state2.update_interaction_answer_groups(state_answer_group_list2) state2.update_interaction_solution(solution2) state2.update_interaction_hints(hint_list2) exp_services.save_new_exploration(self.albert_id, exploration) rights_manager.publish_exploration(owner, self.VALID_EXP_ID) # Start ItemSelectionInteractionOneOff job on sample exploration. job_id = ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.create_new()) ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.enqueue(job_id)) self.process_and_flush_pending_mapreduce_tasks() actual_output = ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.get_output(job_id)) expected_output = [( u'[u\'exp_id0\', [u"<DragAndDropSortInput Answer> State: ' '\\u0627\\u062e\\u062a\\u0628\\u0627\\u0631\\u0627\\u062a, ' 'Invalid Values: [\'<p>This is value3 for DragAndDropSort</p>\']"' ', u"<DragAndDropSortInput Rule> State: \\u0627\\u062e\\u062a' '\\u0628\\u0627\\u0631\\u0627\\u062a, Answer Group Index: 0, ' 'Invalid Values: [u\'<p>This is value3 for DragAndDropSort</p>\']"' ', u"<DragAndDropSortInput Rule> State: \\u0627\\u062e\\u062a' '\\u0628\\u0627\\u0631\\u0627\\u062a, Answer Group Index: 0, ' 'Invalid Values: [u\'<p>This is value3 for DragAndDropSort</p>\']' '", u"<DragAndDropSortInput Rule> State: \\u0627\\u062e\\u062a' '\\u0628\\u0627\\u0631\\u0627\\u062a, Answer Group Index: 0, ' 'Invalid Values: [u\'<p>This is value3 for DragAndDropSort<' '/p>\']"]]' )] self.assertEqual(actual_output, expected_output) rights_manager.unpublish_exploration(self.admin, self.VALID_EXP_ID) # Start job on private exploration. job_id = ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.create_new()) ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.enqueue(job_id)) self.process_and_flush_pending_mapreduce_tasks() actual_output = ( interaction_jobs_one_off .RuleInputToCustomizationArgsMappingOneOffJob.get_output(job_id)) self.assertEqual(actual_output, [])