def test_can_see_learnt_topics(self): self.login(self.VIEWER_EMAIL) response = self.get_json(feconf.LEARNER_DASHBOARD_DATA_URL) self.assertEqual(len(response['learnt_topics_list']), 0) self.save_new_topic(self.TOPIC_ID_1, self.owner_id, name=self.TOPIC_NAME_1, url_fragment='topic-one', description='A new topic', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[self.subtopic_0], next_subtopic_id=1) self.save_new_story(self.STORY_ID_1, self.owner_id, self.TOPIC_ID_1) topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID_1, self.STORY_ID_1) topic_services.publish_story(self.TOPIC_ID_1, self.STORY_ID_1, self.admin_id) topic_services.publish_topic(self.TOPIC_ID_1, self.admin_id) learner_progress_services.mark_story_as_completed( self.viewer_id, self.STORY_ID_1) learner_progress_services.mark_topic_as_learnt(self.viewer_id, self.TOPIC_ID_1) response = self.get_json(feconf.LEARNER_DASHBOARD_DATA_URL) self.assertEqual(len(response['learnt_topics_list']), 1) self.assertEqual(response['learnt_topics_list'][0]['id'], self.TOPIC_ID_1) self.logout()
def test_completed_topic_is_not_added_to_learner_goals(self): learner_progress_services.validate_and_add_topic_to_learn_goal( self.viewer_id, self.TOPIC_ID_1) self.assertEqual(self._get_all_topic_ids_to_learn(self.viewer_id), [self.TOPIC_ID_1]) learner_progress_services.mark_topic_as_learnt(self.viewer_id, self.TOPIC_ID_2) # Test that the topic added to the in the learnt list doesn't get # added to the learner goals. self.assertEqual(self._get_all_topic_ids_to_learn(self.viewer_id), [self.TOPIC_ID_1])
def test_get_learner_dashboard_ids(self): self.login(self.VIEWER_EMAIL) self.save_new_default_exploration(self.EXP_ID_1, self.owner_id, title=self.EXP_TITLE_1) self.publish_exploration(self.owner_id, self.EXP_ID_1) self.save_new_default_exploration(self.EXP_ID_2, self.owner_id, title=self.EXP_TITLE_2) self.publish_exploration(self.owner_id, self.EXP_ID_2) self.save_new_default_exploration(self.EXP_ID_3, self.owner_id, title=self.EXP_TITLE_3) self.publish_exploration(self.owner_id, self.EXP_ID_3) self.save_new_default_collection(self.COL_ID_1, self.owner_id, title=self.COL_TITLE_1) self.publish_collection(self.owner_id, self.COL_ID_1) self.save_new_default_collection(self.COL_ID_2, self.owner_id, title=self.COL_TITLE_2) self.publish_collection(self.owner_id, self.COL_ID_2) self.save_new_default_collection(self.COL_ID_3, self.owner_id, title=self.COL_TITLE_3) self.publish_collection(self.owner_id, self.COL_ID_3) self.save_new_topic(self.TOPIC_ID_1, self.owner_id, name=self.TOPIC_NAME_1, url_fragment='topic-one', description='A new topic', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[self.subtopic_0], next_subtopic_id=1) self.save_new_story(self.STORY_ID_1, self.owner_id, self.TOPIC_ID_1) topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID_1, self.STORY_ID_1) topic_services.publish_story(self.TOPIC_ID_1, self.STORY_ID_1, self.admin_id) topic_services.publish_topic(self.TOPIC_ID_1, self.admin_id) self.save_new_topic(self.TOPIC_ID_2, self.owner_id, name=self.TOPIC_NAME_2, url_fragment='topic-two', description='A new topic', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[self.subtopic_1], next_subtopic_id=1) self.save_new_story(self.STORY_ID_2, self.owner_id, self.TOPIC_ID_2) topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID_2, self.STORY_ID_2) topic_services.publish_story(self.TOPIC_ID_2, self.STORY_ID_2, self.admin_id) topic_services.publish_topic(self.TOPIC_ID_2, self.admin_id) self.save_new_topic(self.TOPIC_ID_3, self.owner_id, name=self.TOPIC_NAME_3, url_fragment='topic-three', description='A new topic', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[self.subtopic_1], next_subtopic_id=1) self.save_new_story(self.STORY_ID_3, self.owner_id, self.TOPIC_ID_3) topic_services.add_canonical_story(self.owner_id, self.TOPIC_ID_3, self.STORY_ID_3) topic_services.publish_story(self.TOPIC_ID_3, self.STORY_ID_3, self.admin_id) topic_services.publish_topic(self.TOPIC_ID_3, self.admin_id) state_name = 'state_name' version = 1 learner_progress_services.mark_exploration_as_completed( self.viewer_id, self.EXP_ID_1) learner_progress_services.mark_exploration_as_incomplete( self.viewer_id, self.EXP_ID_2, state_name, version) learner_progress_services.add_exp_to_learner_playlist( self.viewer_id, self.EXP_ID_3) learner_progress_services.mark_collection_as_completed( self.viewer_id, self.COL_ID_1) learner_progress_services.mark_collection_as_incomplete( self.viewer_id, self.COL_ID_2) learner_progress_services.add_collection_to_learner_playlist( self.viewer_id, self.COL_ID_3) learner_progress_services.mark_story_as_completed( self.viewer_id, self.STORY_ID_1) learner_progress_services.mark_topic_as_learnt(self.viewer_id, self.TOPIC_ID_1) learner_progress_services.record_topic_started(self.viewer_id, self.TOPIC_ID_2) learner_progress_services.validate_and_add_topic_to_learn_goal( self.viewer_id, self.TOPIC_ID_3) response = self.get_json(feconf.LEARNER_DASHBOARD_IDS_DATA_URL) learner_dashboard_activity_ids = ( response['learner_dashboard_activity_ids']) self.assertEqual( learner_dashboard_activity_ids['completed_exploration_ids'], [self.EXP_ID_1]) self.assertEqual( learner_dashboard_activity_ids['incomplete_exploration_ids'], [self.EXP_ID_2]) self.assertEqual( learner_dashboard_activity_ids['exploration_playlist_ids'], [self.EXP_ID_3]) self.assertEqual( learner_dashboard_activity_ids['completed_collection_ids'], [self.COL_ID_1]) self.assertEqual( learner_dashboard_activity_ids['incomplete_collection_ids'], [self.COL_ID_2]) self.assertEqual( learner_dashboard_activity_ids['collection_playlist_ids'], [self.COL_ID_3]) self.assertEqual(learner_dashboard_activity_ids['completed_story_ids'], [self.STORY_ID_1]) self.assertEqual(learner_dashboard_activity_ids['learnt_topic_ids'], [self.TOPIC_ID_1]) self.assertEqual( learner_dashboard_activity_ids['partially_learnt_topic_ids'], [self.TOPIC_ID_2]) self.assertEqual(learner_dashboard_activity_ids['topic_ids_to_learn'], [self.TOPIC_ID_3])
def post(self, story_id, node_id): story = story_fetchers.get_story_by_id(story_id) if story is None: logging.error('Could not find a story corresponding to ' '%s id.' % story_id) self.render_json({}) return topic = topic_fetchers.get_topic_by_id(story.corresponding_topic_id) completed_nodes = story_fetchers.get_completed_nodes_in_story( self.user_id, story_id) completed_node_ids = [ completed_node.id for completed_node in completed_nodes ] ordered_nodes = story.story_contents.get_ordered_nodes() (next_exp_ids, next_node_id, completed_node_ids) = (self._record_node_completion( story_id, node_id, completed_node_ids, ordered_nodes)) ready_for_review_test = False exp_summaries = ( summary_services.get_displayable_exp_summary_dicts_matching_ids( next_exp_ids)) # If there are no questions for any of the acquired skills that the # learner has completed, do not show review tests. acquired_skills = skill_fetchers.get_multi_skills( story.get_acquired_skill_ids_for_node_ids(completed_node_ids)) acquired_skill_ids = [skill.id for skill in acquired_skills] questions_available = len( question_services.get_questions_by_skill_ids( 1, acquired_skill_ids, False)) > 0 learner_completed_story = len(completed_node_ids) == len(ordered_nodes) learner_at_review_point_in_story = ( len(exp_summaries) != 0 and (len(completed_node_ids) & constants.NUM_EXPLORATIONS_PER_REVIEW_TEST == 0)) if questions_available and (learner_at_review_point_in_story or learner_completed_story): ready_for_review_test = True # If there is no next_node_id, the story is marked as completed else # mark the story as incomplete. if next_node_id is None: learner_progress_services.mark_story_as_completed( self.user_id, story_id) else: learner_progress_services.record_story_started( self.user_id, story.id) completed_story_ids = ( learner_progress_services.get_all_completed_story_ids( self.user_id)) story_ids_in_topic = [] for story in topic.canonical_story_references: story_ids_in_topic.append(story.story_id) is_topic_completed = set(story_ids_in_topic).intersection( set(completed_story_ids)) # If at least one story in the topic is completed, # mark the topic as learnt else mark it as partially learnt. if not is_topic_completed: learner_progress_services.record_topic_started( self.user_id, topic.id) else: learner_progress_services.mark_topic_as_learnt( self.user_id, topic.id) return self.render_json({ 'summaries': exp_summaries, 'ready_for_review_test': ready_for_review_test, 'next_node_id': next_node_id })
def test_add_topic_to_learner_goal(self): self.login(self.VIEWER_EMAIL) csrf_token = self.get_new_csrf_token() # Add one topic to the learner goal. self.post_json('%s/%s/%s' % (feconf.LEARNER_GOALS_DATA_URL, constants.ACTIVITY_TYPE_LEARN_TOPIC, self.TOPIC_ID_1), {}, csrf_token=csrf_token) self.assertEqual( learner_goals_services.get_all_topic_ids_to_learn(self.viewer_id), [self.TOPIC_ID_1]) # Add another topic. self.post_json('%s/%s/%s' % (feconf.LEARNER_GOALS_DATA_URL, constants.ACTIVITY_TYPE_LEARN_TOPIC, self.TOPIC_ID_2), {}, csrf_token=csrf_token) self.assertEqual( learner_goals_services.get_all_topic_ids_to_learn(self.viewer_id), [self.TOPIC_ID_1, self.TOPIC_ID_2]) # If a topic belongs to the completed list, it should not be added. learner_progress_services.mark_topic_as_learnt(self.viewer_id, self.TOPIC_ID_3) response = self.post_json( '%s/%s/%s' % (feconf.LEARNER_GOALS_DATA_URL, constants.ACTIVITY_TYPE_LEARN_TOPIC, self.TOPIC_ID_3), {}, csrf_token=csrf_token) self.assertEqual(response['belongs_to_learnt_list'], True) self.assertEqual( learner_goals_services.get_all_topic_ids_to_learn(self.viewer_id), [self.TOPIC_ID_1, self.TOPIC_ID_2]) # Fail to add one topic to the learner goal. response = self.post_json( '%s/%s/%s' % (feconf.LEARNER_GOALS_DATA_URL, 'InvalidActivityType', self.TOPIC_ID_1), {}, csrf_token=csrf_token, expected_status_int=400) self.assertEqual(response['error'], 'Invalid activityType: InvalidActivityType') # Now we begin testing of not exceeding the limit of activities in the # learner goals. # Add feconf.MAX_CURRENT_GOALS_COUNT - 2 activities to reach # the maximum limit. for topic_id in python_utils.RANGE(2, feconf.MAX_CURRENT_GOALS_COUNT + 1): self.post_json('%s/%s/%s' % (feconf.LEARNER_GOALS_DATA_URL, constants.ACTIVITY_TYPE_LEARN_TOPIC, 'topic_id_%s' % topic_id), {}, csrf_token=csrf_token) # Now if we try and add a topic we should get a message saying we # are exceeding the limit. response = self.post_json( '%s/%s/%s' % (feconf.LEARNER_GOALS_DATA_URL, constants.ACTIVITY_TYPE_LEARN_TOPIC, 'topic_id_%s' % python_utils.UNICODE(feconf.MAX_CURRENT_GOALS_COUNT + 3)), {}, csrf_token=csrf_token) self.assertEqual(response['goals_limit_exceeded'], True) self.logout()