def test_put_with_skill_mastery_lower_than_zero(self): skill_services.create_user_skill_mastery(self.user_id, self.skill_id_1, self.degree_of_mastery_1) skill_services.create_user_skill_mastery(self.user_id, self.skill_id_2, self.degree_of_mastery_2) payload = {} mastery_change_per_skill = { self.skill_id_1: -0.5, self.skill_id_2: 0.3 } payload['mastery_change_per_skill'] = mastery_change_per_skill self.login(self.NEW_USER_EMAIL) csrf_token = self.get_new_csrf_token() self.put_json('%s' % feconf.SKILL_MASTERY_DATA_URL, payload, csrf_token=csrf_token) degrees_of_mastery = {self.skill_id_1: 0.0, self.skill_id_2: 0.8} self.assertEqual( skill_services.get_multi_user_skill_mastery( self.user_id, [self.skill_id_1, self.skill_id_2]), degrees_of_mastery) self.logout()
def test_get_multi_users_subtopic_pages_progress(self) -> None: degree_of_mastery = 0.5 student_id_1 = 'student_1' student_id_2 = 'student_2' # Add some subtopic progress for the student. skill_services.create_user_skill_mastery( # type: ignore[no-untyped-call] student_id_1, 'skill_id_1', degree_of_mastery) subtopic_page_id = '{}:{}'.format(self.TOPIC_ID_1, 1) progress = ( subtopic_page_services.get_multi_users_subtopic_pages_progress( [student_id_1, student_id_2], [subtopic_page_id])) student_1_progress = progress[student_id_1] student_2_progress = progress[student_id_2] self.assertEqual(len(student_1_progress), 1) self.assertEqual(len(student_2_progress), 1) self.assertEqual(student_1_progress[0]['subtopic_id'], 1) self.assertEqual(student_1_progress[0]['subtopic_title'], 'Naming Numbers') self.assertEqual(student_1_progress[0]['parent_topic_id'], self.TOPIC_ID_1) self.assertEqual(student_1_progress[0]['parent_topic_name'], 'Place Values') self.assertEqual(student_1_progress[0]['subtopic_mastery'], degree_of_mastery) self.assertIsNone(student_2_progress[0]['subtopic_mastery'])
def setUp(self): super(SkillMasteryServicesUnitTests, self).setUp() self.SKILL_ID_1 = skill_services.get_new_skill_id() self.SKILL_ID_2 = skill_services.get_new_skill_id() self.SKILL_IDS = [self.SKILL_ID_1, self.SKILL_ID_2] skill_services.create_user_skill_mastery(self.USER_ID, self.SKILL_ID_1, self.DEGREE_OF_MASTERY_1) skill_services.create_user_skill_mastery(self.USER_ID, self.SKILL_ID_2, self.DEGREE_OF_MASTERY_2)
def setUp(self): """Completes the sign-up process for the various users.""" super(BaseTopicViewerControllerTests, self).setUp() self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME) self.user_id = self.get_user_id_from_email(self.NEW_USER_EMAIL) 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_USERNAME]) self.admin = user_services.UserActionsInfo(self.admin_id) self.topic_id = 'topic' self.story_id = 'story' self.topic_id_1 = 'topic1' self.skill_id_1 = skill_services.get_new_skill_id() self.skill_id_2 = skill_services.get_new_skill_id() self.story = story_domain.Story.create_default_story( self.story_id, 'story_title', self.topic_id_1) self.story.description = 'story_description' self.topic = topic_domain.Topic.create_default_topic( self.topic_id, 'public_topic_name', 'abbrev') self.topic.uncategorized_skill_ids.append(self.skill_id_1) self.topic.subtopics.append( topic_domain.Subtopic(1, 'subtopic_name', [self.skill_id_2])) self.topic.next_subtopic_id = 2 self.topic.thumbnail_filename = 'Image.png' self.topic.canonical_story_references.append( topic_domain.StoryReference.create_default_story_reference( self.story_id)) topic_services.save_new_topic(self.admin_id, self.topic) story_services.save_new_story(self.admin_id, self.story) self.topic = topic_domain.Topic.create_default_topic( self.topic_id_1, 'private_topic_name', 'abbrev') self.topic.thumbnail_filename = 'Image.png' topic_services.save_new_topic(self.admin_id, self.topic) topic_services.publish_topic(self.topic_id, self.admin_id) topic_services.publish_story(self.topic_id, self.story_id, self.admin_id) self.save_new_skill(self.skill_id_1, self.user_id, description='Skill Description 1') self.save_new_skill(self.skill_id_2, self.user_id, description='Skill Description 2') skill_services.create_user_skill_mastery(self.user_id, self.skill_id_1, 0.3) skill_services.create_user_skill_mastery(self.user_id, self.skill_id_2, 0.5)
def test_get_with_skill_without_skill_mastery(self): skill_services.create_user_skill_mastery(self.user_id, self.skill_id_1, self.degree_of_mastery_1) skill_ids = [self.skill_id_1, self.skill_id_2] self.login(self.NEW_USER_EMAIL) response_json = self.get_json( '%s' % feconf.SKILL_MASTERY_DATA_URL, params={'comma_separated_skill_ids': ','.join(skill_ids)}) degrees_of_mastery = { self.skill_id_1: self.degree_of_mastery_1, self.skill_id_2: None } self.assertEqual(response_json['degrees_of_mastery'], degrees_of_mastery) self.logout()
def test_filter_skills_by_mastery(self): # Create feconf.MAX_NUMBER_OF_SKILL_IDS + 3 skill_ids # to test two things: # 1. The skill_ids should be sorted. # 2. The filtered skill_ids should be feconf.MAX_NUMBER_OF_SKILL_IDS # in number. # List of mastery values (float values between 0.0 and 1.0) masteries = [self.DEGREE_OF_MASTERY_1, self.DEGREE_OF_MASTERY_2, None] # Creating feconf.MAX_NUMBER_OF_SKILL_IDS additional user skill # masteries. for _ in python_utils.RANGE(feconf.MAX_NUMBER_OF_SKILL_IDS): skill_id = skill_services.get_new_skill_id() mastery = random.random() masteries.append(mastery) skill_services.create_user_skill_mastery(self.USER_ID, skill_id, mastery) self.SKILL_IDS.append(skill_id) # Sorting the masteries, which should represent the masteries of the # skill_ids that are finally returned. masteries.sort() degrees_of_masteries = skill_services.get_multi_user_skill_mastery( self.USER_ID, self.SKILL_IDS) arranged_filtered_skill_ids = skill_services.filter_skills_by_mastery( self.USER_ID, self.SKILL_IDS) self.assertEqual(len(arranged_filtered_skill_ids), feconf.MAX_NUMBER_OF_SKILL_IDS) # Assert that all the returned skill_ids are a part of the first # feconf.MAX_NUMBER_OF_SKILL_IDS sorted skill_ids. for i in python_utils.RANGE(feconf.MAX_NUMBER_OF_SKILL_IDS): self.assertIn(degrees_of_masteries[arranged_filtered_skill_ids[i]], masteries[:feconf.MAX_NUMBER_OF_SKILL_IDS]) # Testing the arrangement. excluded_skill_ids = list( set(self.SKILL_IDS) - set(arranged_filtered_skill_ids)) for skill_id in excluded_skill_ids: self.SKILL_IDS.remove(skill_id) self.assertEqual(arranged_filtered_skill_ids, self.SKILL_IDS)
def test_get_with_valid_skill_ids_list(self): skill_services.create_user_skill_mastery(self.user_id, self.skill_id_1, self.degree_of_mastery_1) skill_services.create_user_skill_mastery(self.user_id, self.skill_id_2, self.degree_of_mastery_2) skill_ids = [self.skill_id_1, self.skill_id_2] self.login(self.NEW_USER_EMAIL) response_json = self.get_json( '%s' % feconf.SKILL_MASTERY_DATA_URL, params={'selected_skill_ids': json.dumps(skill_ids)}) degrees_of_mastery = { self.skill_id_1: self.degree_of_mastery_1, self.skill_id_2: self.degree_of_mastery_2 } self.assertEqual(response_json['degrees_of_mastery'], degrees_of_mastery) self.logout()
def setUp(self): """Completes the sign-up process for the various users.""" super(BaseTopicViewerControllerTests, self).setUp() self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME) self.user_id = self.get_user_id_from_email(self.NEW_USER_EMAIL) self.signup(self.CURRICULUM_ADMIN_EMAIL, self.CURRICULUM_ADMIN_USERNAME) self.admin_id = self.get_user_id_from_email(self.CURRICULUM_ADMIN_EMAIL) self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME]) self.admin = user_services.get_user_actions_info(self.admin_id) self.topic_id = 'topic' self.story_id_1 = 'story_id_1' self.story_id_2 = 'story_id_2' self.topic_id_1 = 'topic1' self.topic_id_2 = 'topic2' self.skill_id_1 = skill_services.get_new_skill_id() self.skill_id_2 = skill_services.get_new_skill_id() self.story_1 = story_domain.Story.create_default_story( self.story_id_1, 'story_title', 'description', self.topic_id_1, 'story-frag-one') self.story_1.description = 'story_description' self.story_1.node_titles = [] self.story_2 = story_domain.Story.create_default_story( self.story_id_2, 'story_title', 'description', self.topic_id_2, 'story-frag-two') self.story_2.description = 'story_description' self.story_2.node_titles = [] self.topic = topic_domain.Topic.create_default_topic( self.topic_id, 'public_topic_name', 'public', 'description') self.topic.uncategorized_skill_ids.append(self.skill_id_1) self.topic.subtopics.append(topic_domain.Subtopic( 1, 'subtopic_name', [self.skill_id_2], 'image.svg', constants.ALLOWED_THUMBNAIL_BG_COLORS['subtopic'][0], 21131, 'subtopic-name')) self.topic.next_subtopic_id = 2 self.topic.thumbnail_filename = 'Image.svg' self.topic.thumbnail_bg_color = ( constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0]) self.topic.canonical_story_references.append( topic_domain.StoryReference.create_default_story_reference( self.story_id_1)) self.topic.additional_story_references.append( topic_domain.StoryReference.create_default_story_reference( self.story_id_2)) self.topic.meta_tag_content = 'topic meta content' self.topic.page_title_fragment_for_web = 'topic page title' topic_services.save_new_topic(self.admin_id, self.topic) story_services.save_new_story(self.admin_id, self.story_1) story_services.save_new_story(self.admin_id, self.story_2) self.topic = topic_domain.Topic.create_default_topic( self.topic_id_1, 'private_topic_name', 'private_topic_name', 'description') self.topic.thumbnail_filename = 'Image.svg' self.topic.thumbnail_bg_color = ( constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0]) self.topic.url_fragment = 'private' topic_services.save_new_topic(self.admin_id, self.topic) topic_services.publish_topic(self.topic_id, self.admin_id) topic_services.publish_story( self.topic_id, self.story_id_1, self.admin_id) topic_services.publish_story( self.topic_id, self.story_id_2, self.admin_id) self.save_new_skill( self.skill_id_1, self.user_id, description='Skill Description 1') self.save_new_skill( self.skill_id_2, self.user_id, description='Skill Description 2') skill_services.create_user_skill_mastery( self.user_id, self.skill_id_1, 0.3) skill_services.create_user_skill_mastery( self.user_id, self.skill_id_2, 0.5)
def test_get_with_valid_topic_ids(self): topic_id_1 = topic_fetchers.get_new_topic_id() topic_id_2 = topic_fetchers.get_new_topic_id() self.save_new_topic(topic_id_1, self.user_id, name='Name 1', abbreviated_name='topic-one', url_fragment='topic-one', description='Description 1', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[ self.skill_id_1, self.skill_id_2, self.skill_id_3 ], subtopics=[], next_subtopic_id=1) self.save_new_topic(topic_id_2, self.user_id, name='Name 2', abbreviated_name='topic-two', url_fragment='topic-two', description='Description 2', canonical_story_ids=[], additional_story_ids=[], uncategorized_skill_ids=[ self.skill_id_3, self.skill_id_4, self.skill_id_5 ], subtopics=[], next_subtopic_id=1) # Update Topic 1. changelist = [ topic_domain.TopicChange({ 'cmd': topic_domain.CMD_ADD_SUBTOPIC, 'title': 'Title 1', 'subtopic_id': 1 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_UPDATE_SUBTOPIC_PROPERTY, 'property_name': (topic_domain.SUBTOPIC_PROPERTY_URL_FRAGMENT), 'old_value': '', 'new_value': 'subtopic-one-one', 'subtopic_id': 1 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC, 'old_subtopic_id': None, 'new_subtopic_id': 1, 'skill_id': self.skill_id_1 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC, 'old_subtopic_id': None, 'new_subtopic_id': 1, 'skill_id': self.skill_id_2 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_ADD_SUBTOPIC, 'title': 'Title 2', 'subtopic_id': 2 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_UPDATE_SUBTOPIC_PROPERTY, 'property_name': (topic_domain.SUBTOPIC_PROPERTY_URL_FRAGMENT), 'old_value': '', 'new_value': 'subtopic-one-two', 'subtopic_id': 2 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC, 'old_subtopic_id': None, 'new_subtopic_id': 2, 'skill_id': self.skill_id_3 }) ] topic_services.update_topic_and_subtopic_pages(self.user_id, topic_id_1, changelist, 'Added subtopics.') # Update Topic 2. changelist = [ topic_domain.TopicChange({ 'cmd': topic_domain.CMD_ADD_SUBTOPIC, 'title': 'Title 1', 'subtopic_id': 1 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_UPDATE_SUBTOPIC_PROPERTY, 'property_name': (topic_domain.SUBTOPIC_PROPERTY_URL_FRAGMENT), 'old_value': '', 'new_value': 'subtopic-two-one', 'subtopic_id': 1 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC, 'old_subtopic_id': None, 'new_subtopic_id': 1, 'skill_id': self.skill_id_3 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC, 'old_subtopic_id': None, 'new_subtopic_id': 1, 'skill_id': self.skill_id_4 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_ADD_SUBTOPIC, 'title': 'Title 2', 'subtopic_id': 2 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_UPDATE_SUBTOPIC_PROPERTY, 'property_name': (topic_domain.SUBTOPIC_PROPERTY_URL_FRAGMENT), 'old_value': '', 'new_value': 'subtopic-two-two', 'subtopic_id': 2 }), topic_domain.TopicChange({ 'cmd': topic_domain.CMD_MOVE_SKILL_ID_TO_SUBTOPIC, 'old_subtopic_id': None, 'new_subtopic_id': 2, 'skill_id': self.skill_id_5 }) ] topic_services.update_topic_and_subtopic_pages(self.user_id, topic_id_2, changelist, 'Added subtopics.') skill_services.create_user_skill_mastery(self.user_id, self.skill_id_1, self.degree_of_mastery_1) skill_services.create_user_skill_mastery(self.user_id, self.skill_id_2, self.degree_of_mastery_2) skill_services.create_user_skill_mastery(self.user_id, self.skill_id_5, self.degree_of_mastery_5) skill_services.create_user_skill_mastery(self.user_id, self.skill_id_6, self.degree_of_mastery_6) self.login(self.NEW_USER_EMAIL) # First case: One subtopic mastery doesn't exist. response_json = self.get_json('%s' % feconf.SUBTOPIC_MASTERY_DATA_URL, params={ 'comma_separated_topic_ids': ','.join([topic_id_1, topic_id_2]) }) degrees_of_mastery_1 = { u'1': python_utils.divide( self.degree_of_mastery_1 + self.degree_of_mastery_2, 2) } degrees_of_mastery_2 = {u'2': self.degree_of_mastery_5} self.assertEqual(response_json['subtopic_mastery_dict'], { topic_id_1: degrees_of_mastery_1, topic_id_2: degrees_of_mastery_2 }) # Second case: One skill mastery doesn't exist. skill_services.create_user_skill_mastery(self.user_id, self.skill_id_3, self.degree_of_mastery_3) response_json = self.get_json('%s' % feconf.SUBTOPIC_MASTERY_DATA_URL, params={ 'comma_separated_topic_ids': ','.join([topic_id_1, topic_id_2]) }) degrees_of_mastery_1 = { u'1': python_utils.divide( self.degree_of_mastery_1 + self.degree_of_mastery_2, 2), u'2': self.degree_of_mastery_3 } degrees_of_mastery_2 = { u'1': self.degree_of_mastery_3, u'2': self.degree_of_mastery_5 } self.assertEqual(response_json['subtopic_mastery_dict'], { topic_id_1: degrees_of_mastery_1, topic_id_2: degrees_of_mastery_2 }) # Third case: All masteries exist. skill_services.create_user_skill_mastery(self.user_id, self.skill_id_4, self.degree_of_mastery_4) response_json = self.get_json('%s' % feconf.SUBTOPIC_MASTERY_DATA_URL, params={ 'comma_separated_topic_ids': ','.join([topic_id_1, topic_id_2]) }) degrees_of_mastery_1 = { u'1': python_utils.divide( self.degree_of_mastery_1 + self.degree_of_mastery_2, 2), u'2': self.degree_of_mastery_3 } degrees_of_mastery_2 = { u'1': python_utils.divide( self.degree_of_mastery_3 + self.degree_of_mastery_4, 2), u'2': self.degree_of_mastery_5 } self.assertEqual(response_json['subtopic_mastery_dict'], { topic_id_1: degrees_of_mastery_1, topic_id_2: degrees_of_mastery_2 }) self.logout()
def setUp(self): super(LearnerGroupStudentProgressHandlerTests, self).setUp() self.signup(self.NEW_USER_EMAIL, self.NEW_USER_USERNAME) self.signup(self.CURRICULUM_ADMIN_EMAIL, self.CURRICULUM_ADMIN_USERNAME) self.signup(self.STUDENT_1_EMAIL, self.STUDENT_1_USERNAME) self.signup(self.STUDENT_2_EMAIL, self.STUDENT_2_USERNAME) self.STUDENT_ID_1 = self.get_user_id_from_email(self.STUDENT_1_EMAIL) self.STUDENT_ID_2 = self.get_user_id_from_email(self.STUDENT_2_EMAIL) self.facilitator_id = self.get_user_id_from_email(self.NEW_USER_EMAIL) self.admin_id = self.get_user_id_from_email( self.CURRICULUM_ADMIN_EMAIL) self.set_curriculum_admins([self.CURRICULUM_ADMIN_USERNAME]) self.admin = user_services.get_user_actions_info(self.admin_id) self.LEARNER_GROUP_ID = ( learner_group_fetchers.get_new_learner_group_id()) learner_group_services.create_learner_group( self.LEARNER_GROUP_ID, 'Learner Group Name', 'Description', [self.facilitator_id], [self.STUDENT_ID_1, self.STUDENT_ID_2], [self.SUBTOPIC_PAGE_ID_1], [self.STORY_ID_1]) # Set up topics, subtopics and stories for learner group syllabus. self.save_new_valid_exploration(self.EXP_ID_0, self.admin_id, title='Title 1', end_state_name='End', correctness_feedback_enabled=True) self.save_new_valid_exploration(self.EXP_ID_1, self.admin_id, title='Title 2', end_state_name='End', correctness_feedback_enabled=True) self.save_new_valid_exploration(self.EXP_ID_7, self.admin_id, title='Title 3', end_state_name='End', correctness_feedback_enabled=True) self.publish_exploration(self.admin_id, self.EXP_ID_0) self.publish_exploration(self.admin_id, self.EXP_ID_1) self.publish_exploration(self.admin_id, self.EXP_ID_7) story = story_domain.Story.create_default_story( self.STORY_ID_1, 'Title', 'Description', self.TOPIC_ID_1, self.STORY_URL_FRAGMENT) story.meta_tag_content = 'story meta content' exp_summary_dicts = ( summary_services.get_displayable_exp_summary_dicts_matching_ids( [self.EXP_ID_0, self.EXP_ID_1, self.EXP_ID_7], user=self.admin)) self.node_1 = { 'id': self.NODE_ID_1, 'title': 'Title 1', 'description': 'Description 1', 'thumbnail_filename': 'image_1.svg', 'thumbnail_bg_color': constants.ALLOWED_THUMBNAIL_BG_COLORS['chapter'][0], 'thumbnail_size_in_bytes': 21131, 'destination_node_ids': ['node_3'], 'acquired_skill_ids': [], 'prerequisite_skill_ids': [], 'outline': '', 'outline_is_finalized': False, 'exploration_id': self.EXP_ID_1, 'exp_summary_dict': exp_summary_dicts[1], 'completed': False } self.node_2 = { 'id': self.NODE_ID_2, 'title': 'Title 2', 'description': 'Description 2', 'thumbnail_filename': 'image_2.svg', 'thumbnail_bg_color': constants.ALLOWED_THUMBNAIL_BG_COLORS['chapter'][0], 'thumbnail_size_in_bytes': 21131, 'destination_node_ids': ['node_1'], 'acquired_skill_ids': [], 'prerequisite_skill_ids': [], 'outline': '', 'outline_is_finalized': False, 'exploration_id': self.EXP_ID_0, 'exp_summary_dict': exp_summary_dicts[0], 'completed': True } self.node_3 = { 'id': self.NODE_ID_3, 'title': 'Title 3', 'description': 'Description 3', 'thumbnail_filename': 'image_3.svg', 'thumbnail_bg_color': constants.ALLOWED_THUMBNAIL_BG_COLORS['chapter'][0], 'thumbnail_size_in_bytes': 21131, 'destination_node_ids': [], 'acquired_skill_ids': [], 'prerequisite_skill_ids': [], 'outline': '', 'outline_is_finalized': False, 'exploration_id': self.EXP_ID_7, 'exp_summary_dict': exp_summary_dicts[2], 'completed': False } story.story_contents.nodes = [ story_domain.StoryNode.from_dict(self.node_1), story_domain.StoryNode.from_dict(self.node_2), story_domain.StoryNode.from_dict(self.node_3) ] self.nodes = story.story_contents.nodes story.story_contents.initial_node_id = 'node_2' story.story_contents.next_node_id = 'node_4' story_services.save_new_story(self.admin_id, story) self.subtopic_1 = topic_domain.Subtopic.create_default_subtopic( 1, 'Subtopic Title 1', 'sub-one-frag') self.subtopic_2 = topic_domain.Subtopic.create_default_subtopic( 2, 'Subtopic Title 2', 'sub-two-frag') self.SKILL_ID_1 = skill_services.get_new_skill_id() self.SKILL_ID_2 = skill_services.get_new_skill_id() self.subtopic_1.skill_ids = [self.SKILL_ID_1] self.subtopic_2.skill_ids = [self.SKILL_ID_2] self.save_new_topic(self.TOPIC_ID_1, 'user', name='Topic', description='A new topic', canonical_story_ids=[story.id], additional_story_ids=[], uncategorized_skill_ids=[], subtopics=[self.subtopic_1, self.subtopic_2], next_subtopic_id=3) topic_services.publish_topic(self.TOPIC_ID_1, self.admin_id) topic_services.publish_story(self.TOPIC_ID_1, self.STORY_ID_1, self.admin_id) # Add the invited students to the learner group. learner_group_services.add_student_to_learner_group( self.LEARNER_GROUP_ID, self.STUDENT_ID_1, True) learner_group_services.add_student_to_learner_group( self.LEARNER_GROUP_ID, self.STUDENT_ID_2, False) # Add some progress for the students. story_services.record_completed_node_in_story_context( self.STUDENT_ID_1, self.STORY_ID_1, self.NODE_ID_1) story_services.record_completed_node_in_story_context( self.STUDENT_ID_1, self.STORY_ID_1, self.NODE_ID_2) story_services.record_completed_node_in_story_context( self.STUDENT_ID_2, self.STORY_ID_1, self.NODE_ID_3) self.SKILL_IDS = [self.SKILL_ID_1, self.SKILL_ID_2] skill_services.create_user_skill_mastery(self.STUDENT_ID_1, self.SKILL_ID_1, self.DEGREE_OF_MASTERY_1) skill_services.create_user_skill_mastery(self.STUDENT_ID_2, self.SKILL_ID_2, self.DEGREE_OF_MASTERY_2)