def test_can_see_partially_learnt_topics(self):
        self.login(self.VIEWER_EMAIL)

        response = self.get_json(feconf.LEARNER_DASHBOARD_DATA_URL)
        self.assertEqual(len(response['partially_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)
        topic_services.publish_topic(self.TOPIC_ID_1, self.admin_id)

        learner_progress_services.record_topic_started(self.viewer_id,
                                                       self.TOPIC_ID_1)
        response = self.get_json(feconf.LEARNER_DASHBOARD_DATA_URL)
        self.assertEqual(len(response['partially_learnt_topics_list']), 1)
        self.assertEqual(response['partially_learnt_topics_list'][0]['id'],
                         self.TOPIC_ID_1)
        self.logout()
Esempio n. 2
0
    def post(self, exploration_id):
        """Handles POST requests.

        Args:
            exploration_id: str. The ID of the exploration.
        """
        version = self.payload.get('version')
        if version is None:
            raise self.InvalidInputException(
                'NONE EXP VERSION: Maybe quit')
        state_name = self.payload.get('state_name')
        user_id = self.user_id
        collection_id = self.payload.get('collection_id')
        story_id = exp_services.get_story_id_linked_to_exploration(
            exploration_id)

        if user_id:
            learner_progress_services.mark_exploration_as_incomplete(
                user_id, exploration_id, state_name, version)

        if user_id and collection_id:
            learner_progress_services.mark_collection_as_incomplete(
                user_id, collection_id)

        if user_id and story_id:
            story = story_fetchers.get_story_by_id(story_id)
            if story is not None:
                learner_progress_services.record_story_started(
                    user_id, story.id)
                if story.corresponding_topic_id is not None:
                    learner_progress_services.record_topic_started(
                        user_id, story.corresponding_topic_id)
            else:
                logging.error(
                    'Could not find a story corresponding to %s '
                    'id.' % story_id)
                self.render_json({})
                return

        event_services.MaybeLeaveExplorationEventHandler.record(
            exploration_id,
            version,
            state_name,
            self.payload.get('session_id'),
            self.payload.get('client_time_spent_in_secs'),
            self.payload.get('params'),
            feconf.PLAY_TYPE_NORMAL)
        self.render_json(self.values)
    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])
Esempio n. 4
0
    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
        })