def test_delete(self): question_services.create_new_question_skill_link( self.question_id, self.skill_id) question_services.create_new_question_skill_link( self.question_id_2, self.skill_id) with self.swap(constants, 'ENABLE_NEW_STRUCTURE_EDITORS', True): self.login(self.NEW_USER_EMAIL) self.delete_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id, self.skill_id), expected_status_int=401) self.logout() self.login(self.ADMIN_EMAIL) self.delete_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id, self.skill_id)) question_summaries, _ = ( question_services.get_question_summaries_linked_to_skills( 5, [self.skill_id], '')) self.assertEqual(len(question_summaries), 1) self.assertEqual(question_summaries[0].id, self.question_id_2) self.logout() self.login(self.TOPIC_MANAGER_EMAIL) self.delete_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id_2, self.skill_id)) question_summaries, _ = ( question_services.get_question_summaries_linked_to_skills( 5, [self.skill_id], '')) self.assertEqual(len(question_summaries), 0) self.logout()
def test_linking_same_skill_to_question_twice(self): question_id_2 = question_services.get_new_question_id() self.save_new_question(question_id_2, self.editor_id, self._create_valid_question_data('ABC'), ['skill_1']) skill_ids = [ skill.id for skill in question_services.get_skills_linked_to_question(question_id_2) ] self.assertEqual(len(skill_ids), 1) self.assertEqual(skill_ids[0], 'skill_1') question_services.create_new_question_skill_link( self.editor_id, question_id_2, 'skill_1', 0.3) skill_ids = [ skill.id for skill in question_services.get_skills_linked_to_question(question_id_2) ] self.assertEqual(len(skill_ids), 1) self.assertEqual(skill_ids[0], 'skill_1') question_services.create_new_question_skill_link( self.editor_id, question_id_2, 'skill_2', 0.3) skill_ids = [ skill.id for skill in question_services.get_skills_linked_to_question(question_id_2) ] self.assertEqual(len(skill_ids), 2) self.assertItemsEqual(skill_ids, ['skill_1', 'skill_2'])
def setUp(self): super(SkillOpportunityModelValidatorTests, self).setUp() self.job_class = ( prod_validation_jobs_one_off.SkillOpportunityModelAuditOneOffJob) self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME) self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME) self.admin_id = self.get_user_id_from_email(self.ADMIN_EMAIL) self.owner_id = self.get_user_id_from_email(self.OWNER_EMAIL) self.set_admins([self.ADMIN_USERNAME]) self.admin = user_services.get_user_actions_info(self.admin_id) for i in python_utils.RANGE(3): skill_id = '%s' % i self.save_new_skill(skill_id, self.admin_id, description='description %d' % i) self.QUESTION_ID = question_services.get_new_question_id() self.save_new_question(self.QUESTION_ID, self.owner_id, self._create_valid_question_data('ABC'), ['0']) question_services.create_new_question_skill_link( self.owner_id, self.QUESTION_ID, '0', 0.3) self.model_instance_0 = ( opportunity_models.SkillOpportunityModel.get('0')) self.model_instance_1 = ( opportunity_models.SkillOpportunityModel.get('1')) self.model_instance_2 = ( opportunity_models.SkillOpportunityModel.get('2'))
def _generate_dummy_skill_and_questions(self): """Generate and loads the database with a skill and 15 questions linked to the skill. Raises: Exception. Cannot load new structures data in production mode. Exception. User does not have enough rights to generate data. """ if constants.DEV_MODE: if feconf.ROLE_ID_CURRICULUM_ADMIN not in self.user.roles: raise Exception( 'User does not have enough rights to generate data.') skill_id = skill_services.get_new_skill_id() skill_name = 'Dummy Skill %s' % python_utils.UNICODE( random.getrandbits(32)) skill = self._create_dummy_skill(skill_id, skill_name, '<p>Dummy Explanation 1</p>') skill_services.save_new_skill(self.user_id, skill) for i in range(15): question_id = question_services.get_new_question_id() question_name = 'Question number %s %s' % ( python_utils.UNICODE(i), skill_name) question = self._create_dummy_question(question_id, question_name, [skill_id]) question_services.add_question(self.user_id, question) question_difficulty = list( constants.SKILL_DIFFICULTY_LABEL_TO_FLOAT.values()) random_difficulty = random.choice(question_difficulty) question_services.create_new_question_skill_link( self.user_id, question_id, skill_id, random_difficulty) else: raise Exception('Cannot generate dummy skills in production.')
def accept(self, unused_commit_message): """Accepts the suggestion. Args: unused_commit_message: str. This parameter is passed in for consistency with the existing suggestions. As a default commit message is used in the add_question function, the arg is unused. """ question_dict = self.change.question_dict question_dict['version'] = 1 question_dict['id'] = (question_services.get_new_question_id()) question_dict['linked_skill_ids'] = [self.change.skill_id] question = question_domain.Question.from_dict(question_dict) question.validate() self._copy_new_images_to_target_entity_storage() question_services.add_question(self.author_id, question) skill = skill_fetchers.get_skill_by_id(self.change.skill_id, strict=False) if skill is None: raise utils.ValidationError( 'The skill with the given id doesn\'t exist.') question_services.create_new_question_skill_link( self.author_id, question_dict['id'], self.change.skill_id, self._get_skill_difficulty())
def post(self, skill_id): """Handles POST requests.""" if not constants.ENABLE_NEW_STRUCTURE_EDITORS: raise self.PageNotFoundException skill_domain.Skill.require_valid_skill_id(skill_id) skill = skill_services.get_skill_by_id(skill_id, strict=False) if skill is None: raise self.PageNotFoundException( 'The skill with the given id doesn\'t exist.') question_dict = self.payload.get('question_dict') if ((question_dict['id'] is not None) or ('question_state_data' not in question_dict) or ('language_code' not in question_dict) or (question_dict['version'] != 1)): raise self.InvalidInputException question_dict['question_state_data_schema_version'] = ( feconf.CURRENT_STATES_SCHEMA_VERSION) question_dict['id'] = question_services.get_new_question_id() try: question = question_domain.Question.from_dict(question_dict) except: raise self.InvalidInputException question_services.add_question(self.user_id, question) # TODO(vinitamurthi): Replace DEFAULT_SKILL_DIFFICULTY # with a value passed from the frontend. question_services.create_new_question_skill_link( question.id, skill_id, constants.DEFAULT_SKILL_DIFFICULTY) self.values.update({'question_id': question.id}) self.render_json(self.values)
def post(self, skill_id): """Handles POST requests.""" if not feconf.ENABLE_NEW_STRUCTURES: raise self.PageNotFoundException skill_domain.Skill.require_valid_skill_id(skill_id) skill = skill_services.get_skill_by_id(skill_id, strict=False) if skill is None: raise self.PageNotFoundException( 'The skill with the given id doesn\'t exist.') question_dict = self.payload.get('question_dict') if ((question_dict['id'] is not None) or ('question_state_data' not in question_dict) or ('language_code' not in question_dict) or (question_dict['version'] != 1) or (question_dict['question_state_schema_version'] != (feconf.CURRENT_STATES_SCHEMA_VERSION))): raise self.InvalidInputException question_dict['id'] = question_services.get_new_question_id() question = question_domain.Question.from_dict(question_dict) question_services.add_question(self.user_id, question) question_services.create_new_question_skill_link(question.id, skill_id) self.values.update({'question_id': question.id}) self.render_json(self.values)
def put(self, question_id): """Updates the QuestionSkillLink models with respect to the given question. """ skill_ids_task_list = self.payload.get('skill_ids_task_list') if skill_ids_task_list is None: raise self.InvalidInputException( 'Missing fields \'skill_ids_task_list\'in payload') for task_dict in skill_ids_task_list: if not 'id' in task_dict: raise self.InvalidInputException('Missing skill ID.') if task_dict['task'] == 'remove': question_services.delete_question_skill_link( self.user_id, question_id, task_dict['id']) elif task_dict['task'] == 'add': question_services.create_new_question_skill_link( self.user_id, question_id, task_dict['id'], task_dict['difficulty']) elif task_dict['task'] == 'update_difficulty': question_services.update_question_skill_link_difficulty( question_id, task_dict['id'], float(task_dict['difficulty'])) else: raise self.InvalidInputException('Invalid task.') self.render_json(self.values)
def test_get_question_count_succeeds(self): self.login(self.ADMIN_EMAIL) question_id = question_services.get_new_question_id() question_id_1 = question_services.get_new_question_id() self.save_new_question(question_id, self.admin_id, self._create_valid_question_data('ABC'), [self.skill_id]) self.save_new_question(question_id_1, self.admin_id, self._create_valid_question_data('ABC2'), [self.skill_id_2]) question_services.create_new_question_skill_link( self.admin_id, question_id, self.skill_id, 0.5) question_services.create_new_question_skill_link( self.admin_id, question_id_1, self.skill_id_2, 0.3) json_response = self.get_json( '%s/%s,%s' % (feconf.QUESTION_COUNT_URL_PREFIX, self.skill_id, self.skill_id_2)) self.assertEqual(json_response['total_question_count'], 2) json_response = self.get_json( '%s/%s' % (feconf.QUESTION_COUNT_URL_PREFIX, self.skill_id)) self.assertEqual(json_response['total_question_count'], 1) json_response = self.get_json( '%s/%s' % (feconf.QUESTION_COUNT_URL_PREFIX, self.skill_id_2)) self.assertEqual(json_response['total_question_count'], 1)
def setUp(self): """Completes the setup for QuestionSkillLinkHandlerTest.""" super(EditableQuestionDataHandlerTest, self).setUp() self.skill_id = skill_services.get_new_skill_id() self.save_new_skill(self.skill_id, self.admin_id, 'Skill Description') question_services.create_new_question_skill_link( self.question_id, self.skill_id)
def accept(self, unused_commit_message): """Accepts the suggestion. Args: unused_commit_message: str. This parameter is passed in for consistency with the existing suggestions. As a default commit message is used in the add_question function, the arg is unused. """ question_dict = self.change.question_dict question_dict['version'] = 1 question_dict['id'] = (question_services.get_new_question_id()) html_list = self.get_all_html_content_strings() filenames = ( html_cleaner.get_image_filenames_from_html_strings(html_list)) image_context = fs_services.get_image_context_for_suggestion_target( self.target_type) fs_services.copy_images(image_context, self.target_id, feconf.ENTITY_TYPE_QUESTION, self.target_id, filenames) question_dict['linked_skill_ids'] = [self.change.skill_id] question = question_domain.Question.from_dict(question_dict) question.validate() question_services.add_question(self.author_id, question) skill = skill_fetchers.get_skill_by_id(self.change.skill_id, strict=False) if skill is None: raise utils.ValidationError( 'The skill with the given id doesn\'t exist.') question_services.create_new_question_skill_link( self.author_id, question_dict['id'], self.change.skill_id, self._get_skill_difficulty())
def test_get_questions_by_skill_ids(self): question_services.create_new_question_skill_link( self.question_id, 'skill_1') questions, _ = ( question_services.get_questions_by_skill_ids(2, ['skill_1'], '')) self.assertEqual(len(questions), 1) self.assertEqual(questions[0].to_dict(), self.question.to_dict())
def test_get_questions_succeeds(self): for _ in python_utils.RANGE(0, 4): question_id = question_services.get_new_question_id() self.save_new_question(question_id, self.admin_id, self._create_valid_question_data('ABC'), [self.skill_id, self.skill_id_2]) question_services.create_new_question_skill_link( self.admin_id, question_id, self.skill_id, 0.5) question_services.create_new_question_skill_link( self.admin_id, question_id, self.skill_id_2, 0.3) self.login(self.ADMIN_EMAIL) with self.swap(constants, 'NUM_QUESTIONS_PER_PAGE', 2): json_response = self.get_json('%s/%s,%s?cursor=' % (feconf.QUESTIONS_LIST_URL_PREFIX, self.skill_id, self.skill_id_2)) question_summary_dicts = json_response['question_summary_dicts'] self.assertEqual(len(question_summary_dicts), 2) next_start_cursor = json_response['next_start_cursor'] json_response = self.get_json( '%s/%s,%s?cursor=%s' % (feconf.QUESTIONS_LIST_URL_PREFIX, self.skill_id, self.skill_id_2, next_start_cursor)) question_summary_dicts_2 = ( json_response['question_summary_dicts']) self.assertEqual(len(question_summary_dicts_2), 2) for i in python_utils.RANGE(0, 2): self.assertEqual( question_summary_dicts[i]['skill_descriptions'], ['Skill Description 2', 'Skill Description']) self.assertEqual( question_summary_dicts_2[i]['skill_descriptions'], ['Skill Description 2', 'Skill Description']) self.assertEqual(question_summary_dicts[i]['skill_ids'], [self.skill_id_2, self.skill_id]) self.assertEqual(question_summary_dicts_2[i]['skill_ids'], [self.skill_id_2, self.skill_id]) self.assertEqual( question_summary_dicts[i]['skill_difficulties'], [0.3, 0.5]) self.assertEqual( question_summary_dicts_2[i]['skill_difficulties'], [0.3, 0.5]) json_response = self.get_json( '%s/%s?cursor=' % (feconf.QUESTIONS_LIST_URL_PREFIX, self.skill_id)) question_summary_dicts_3 = ( json_response['question_summary_dicts']) self.assertEqual(len(question_summary_dicts_3), 2) for i in python_utils.RANGE(0, 2): self.assertEqual( question_summary_dicts_3[i]['skill_description'], 'Skill Description') self.assertEqual(question_summary_dicts_3[i]['skill_id'], self.skill_id) self.assertEqual( question_summary_dicts_3[i]['skill_difficulty'], 0.5) self.assertNotEqual(question_summary_dicts[0]['summary']['id'], question_summary_dicts_2[0]['summary']['id']) self.logout()
def test_put_with_admin_email_allows_updation(self): question_services.create_new_question_skill_link( self.editor_id, self.question_id, self.skill_id, 0.5) ( question_summaries, merged_question_skill_links, _) = ( question_services.get_displayable_question_skill_link_details( 5, [self.skill_id], '')) self.assertEqual(len(question_summaries), 1) self.assertEqual( merged_question_skill_links[0].skill_difficulties, [0.5]) self.login(self.ADMIN_EMAIL) csrf_token = self.get_new_csrf_token() self.put_json( '%s/%s' % ( feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id ), { 'new_difficulty': 0.9, 'action': 'update_difficulty', 'skill_id': self.skill_id }, csrf_token=csrf_token) self.put_json( '%s/%s' % ( feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id ), { 'difficulty': 0.6, 'action': 'edit_links', 'skill_ids_task_list': [{ 'id': 'skill_2', 'task': 'add' }] }, csrf_token=csrf_token) ( question_summaries, merged_question_skill_links, _) = ( question_services.get_displayable_question_skill_link_details( 5, [self.skill_id, 'skill_2'], '')) self.assertEqual(len(question_summaries), 1) self.assertEqual(len(merged_question_skill_links), 1) self.assertEqual( merged_question_skill_links[0].skill_difficulties, [0.6, 0.9]) self.put_json( '%s/%s' % ( feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id ), { 'difficulty': 0.9, 'action': 'edit_links', 'skill_ids_task_list': [{ 'id': 'skill_2', 'task': 'remove' }] }, csrf_token=csrf_token) question_summaries, _, _ = ( question_services.get_displayable_question_skill_link_details( 5, ['skill_2'], '')) self.assertEqual(len(question_summaries), 0) self.logout()
def setUp(self): super(MergeSkillHandlerTests, self).setUp() self.url = feconf.MERGE_SKILLS_URL self.question_id = question_services.get_new_question_id() self.question = self.save_new_question( self.question_id, self.admin_id, self._create_valid_question_data('ABC'), [self.linked_skill_id]) question_services.create_new_question_skill_link( self.admin_id, self.question_id, self.linked_skill_id, 0.5)
def test_get_questions_and_skill_descriptions_by_skill_ids(self): question_services.create_new_question_skill_link( self.editor_id, self.question_id, 'skill_1', 0.3) questions, _ = (question_fetchers. get_questions_and_skill_descriptions_by_skill_ids( 2, ['skill_1'], 0)) self.assertEqual(len(questions), 1) self.assertEqual(questions[0].to_dict(), self.question.to_dict())
def test_get(self): # Create 5 questions linked to the same skill. for i in range(0, 3): #pylint: disable=unused-variable question_id = question_services.get_new_question_id() self.save_new_question(question_id, self.admin_id, self._create_valid_question_data('ABC')) question_services.create_new_question_skill_link( question_id, self.skill_id) with self.swap(constants, 'ENABLE_NEW_STRUCTURES', True): self.login(self.ADMIN_EMAIL) with self.swap(constants, 'NUM_QUESTIONS_PER_PAGE', 1): json_response = self.get_json( '%s/%s?cursor=' % (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id)) question_summary_dicts = json_response[ 'question_summary_dicts'] self.assertEqual(len(question_summary_dicts), 1) next_start_cursor = json_response['next_start_cursor'] json_response = self.get_json( '%s/%s?cursor=%s' % (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id, next_start_cursor)) question_summary_dicts_2 = ( json_response['question_summary_dicts']) self.assertEqual(len(question_summary_dicts_2), 1) self.assertNotEqual(question_summary_dicts[0]['id'], question_summary_dicts_2[0]['id']) self.logout() self.login(self.TOPIC_MANAGER_EMAIL) response = self.testapp.get( '%s/%s?cursor=' % (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id)) self.assertEqual(response.status_int, 200) self.logout() topic_services.assign_role(self.admin, self.topic_manager, topic_domain.ROLE_MANAGER, self.topic_id) self.login(self.TOPIC_MANAGER_EMAIL) json_response = self.get_json( '%s/%s' % (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id)) question_summary_dicts = json_response['question_summary_dicts'] self.assertEqual(len(question_summary_dicts), 3) self.logout() self.login(self.NEW_USER_EMAIL) response = self.testapp.get( '%s/%s?cursor=' % (feconf.TOPIC_EDITOR_QUESTION_URL, self.topic_id), expect_errors=True) self.assertEqual(response.status_int, 401) self.logout()
def test_get_with_twenty_or_more_questions(self): number_of_questions = 50 self.topic_id = 'new_topic' self.skill_id_1 = skill_services.get_new_skill_id() self.skill_id_2 = skill_services.get_new_skill_id() self.topic = topic_domain.Topic.create_default_topic( self.topic_id, 'new_topic', 'new-topic', 'description', 'fragm') self.topic.uncategorized_skill_ids.append(self.skill_id_1) self.topic.thumbnail_filename = 'Image.svg' self.topic.thumbnail_bg_color = ( constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0]) self.topic.practice_tab_is_displayed = True subtopic_1 = topic_domain.Subtopic.create_default_subtopic( 1, 'Subtopic Title 1', 'url-frag-one') subtopic_1.skill_ids = [self.skill_id_2] subtopic_1.url_fragment = 'sub-one-frag' self.topic.subtopics = [subtopic_1] self.topic.next_subtopic_id = 2 self.topic.skill_ids_for_diagnostic_test = [self.skill_id_2] topic_services.save_new_topic(self.admin_id, self.topic) topic_services.publish_topic(self.topic_id, self.admin_id) self.save_new_skill(self.skill_id_1, self.admin_id, description='Skill Description 1') for index in range(number_of_questions): question_id = question_services.get_new_question_id() self.save_new_question(question_id, self.admin_id, self._create_valid_question_data(index), [self.skill_id_1]) question_services.create_new_question_skill_link( self.admin_id, question_id, self.skill_id_1, 0.5) json_response = self.get_json('%s/staging/%s' % (feconf.TOPIC_DATA_HANDLER, 'new-topic')) expected_dict = { 'topic_name': 'new_topic', 'topic_id': self.topic_id, 'canonical_story_dicts': [], 'additional_story_dicts': [], 'uncategorized_skill_ids': [self.skill_id_1], 'subtopics': [subtopic_1.to_dict()], 'degrees_of_mastery': { self.skill_id_1: None, self.skill_id_2: None }, 'skill_descriptions': { self.skill_id_1: 'Skill Description 1', self.skill_id_2: None }, 'practice_tab_is_displayed': True } self.assertDictContainsSubset(expected_dict, json_response) self.logout()
def post(self, question_id, skill_id): """Links a question to a skill.""" skill_domain.Skill.require_valid_skill_id(skill_id) skill = skill_services.get_skill_by_id(skill_id, strict=False) if skill is None: raise self.PageNotFoundException( 'The skill with the given id doesn\'t exist.') # TODO(vinitamurthi): Replace DEFAULT_SKILL_DIFFICULTY # with a value passed from the frontend. question_services.create_new_question_skill_link( question_id, skill_id, constants.DEFAULT_SKILL_DIFFICULTY) self.render_json(self.values)
def post(self, question_id, skill_id): """Links a question to a skill.""" if not constants.ENABLE_NEW_STRUCTURES: raise self.PageNotFoundException skill_domain.Skill.require_valid_skill_id(skill_id) skill = skill_services.get_skill_by_id(skill_id, strict=False) if skill is None: raise self.PageNotFoundException( 'The skill with the given id doesn\'t exist.') question_services.create_new_question_skill_link(question_id, skill_id) self.render_json(self.values)
def test_get_with_more_questions_with_fifty_or_more_skills(self): number_of_skills = 60 number_of_questions = [0] * 60 number_of_questions[46] = 2 number_of_questions[20] = 3 number_of_questions[29] = 10 self.topic_id = 'new_topic' skill_ids = ([ skill_services.get_new_skill_id() for _ in python_utils.RANGE(number_of_skills) ]) self.topic = topic_domain.Topic.create_default_topic( self.topic_id, 'new_topic', 'new-topic', 'description') for index in python_utils.RANGE(number_of_skills): self.topic.uncategorized_skill_ids.append(skill_ids[index]) self.topic.thumbnail_filename = 'Image.svg' self.topic.thumbnail_bg_color = ( constants.ALLOWED_THUMBNAIL_BG_COLORS['topic'][0]) self.topic.practice_tab_is_displayed = True subtopic_1 = topic_domain.Subtopic.create_default_subtopic( 1, 'Subtopic Title 1') subtopic_1.skill_ids = ['skill_id_1'] subtopic_1.url_fragment = 'sub-one-frag' self.topic.subtopics = [subtopic_1] self.topic.next_subtopic_id = 2 topic_services.save_new_topic(self.admin_id, self.topic) topic_services.publish_topic(self.topic_id, self.admin_id) for i in python_utils.RANGE(number_of_skills): self.save_new_skill(skill_ids[i], self.admin_id, description='Skill Description') for i in python_utils.RANGE(number_of_skills): for j in python_utils.RANGE(number_of_questions[i]): question_id = question_services.get_new_question_id() self.save_new_question(question_id, self.admin_id, self._create_valid_question_data(j), [skill_ids[i]]) question_services.create_new_question_skill_link( self.admin_id, question_id, skill_ids[i], 0.5) json_response = self.get_json('%s/staging/%s' % (feconf.TOPIC_DATA_HANDLER, 'new-topic')) expected_dict = { 'topic_name': 'new_topic', 'topic_id': self.topic_id, 'canonical_story_dicts': [], 'additional_story_dicts': [], 'practice_tab_is_displayed': True } self.assertDictContainsSubset(expected_dict, json_response) self.logout()
def test_get_questions_with_multi_skill_ids(self): question_id_1 = question_services.get_new_question_id() question_1 = self.save_new_question( question_id_1, self.editor_id, self._create_valid_question_data('ABC'), ['skill_1', 'skill_2']) question_services.create_new_question_skill_link( self.editor_id, question_id_1, 'skill_1', 0.3) question_services.create_new_question_skill_link( self.editor_id, question_id_1, 'skill_2', 0.5) questions, _, _ = (question_services. get_questions_and_skill_descriptions_by_skill_ids( 2, ['skill_1', 'skill_2'], '')) self.assertEqual(len(questions), 1) self.assertEqual(questions[0].to_dict(), question_1.to_dict())
def test_get_question_skill_links_of_question(self): # If the question id doesnt exist at all, it returns an empty list. skills = (question_services.get_skills_linked_to_question( 'non_existent_question_id')) self.assertEqual(len(skills), 0) question_id_2 = question_services.get_new_question_id() self.save_new_question(question_id_2, self.editor_id, self._create_valid_question_data('ABC')) question_id_3 = question_services.get_new_question_id() self.save_new_question(question_id_3, self.editor_id, self._create_valid_question_data('ABC')) question_services.create_new_question_skill_link( self.question_id, 'skill_1', 0.5) question_services.create_new_question_skill_link( question_id_2, 'skill_1', 0.3) question_services.create_new_question_skill_link( question_id_2, 'skill_2', 0.0) question_services.create_new_question_skill_link( question_id_3, 'skill_2', 0.1) skills = ( question_services.get_skills_linked_to_question(question_id_2)) self.assertTrue(isinstance(skills[0], skill_domain.Skill)) self.assertEqual(len(skills), 2) skill_ids = [skill.id for skill in skills] self.assertItemsEqual(skill_ids, ['skill_1', 'skill_2'])
def test_get_question_skill_links_of_question(self): # If the question id doesnt exist at all, it returns an empty list. question_skill_links = ( question_services.get_question_skill_links_of_question( 'non_existent_question_id')) self.assertEqual(len(question_skill_links), 0) question_id_2 = question_services.get_new_question_id() self.save_new_question(question_id_2, self.editor_id, self._create_valid_question_data('ABC')) question_id_3 = question_services.get_new_question_id() self.save_new_question(question_id_3, self.editor_id, self._create_valid_question_data('ABC')) question_services.create_new_question_skill_link( self.question_id, 'skill_1') question_services.create_new_question_skill_link( question_id_2, 'skill_1') question_services.create_new_question_skill_link( question_id_2, 'skill_2') question_services.create_new_question_skill_link( question_id_3, 'skill_2') question_skill_links = ( question_services.get_question_skill_links_of_question( question_id_2)) self.assertTrue( isinstance(question_skill_links[0], question_domain.QuestionSkillLink)) self.assertEqual(len(question_skill_links), 2) skill_ids = [ question_skill.skill_id for question_skill in question_skill_links ] self.assertItemsEqual(skill_ids, ['skill_1', 'skill_2'])
def test_get_questions_and_skill_descriptions_by_skill_ids(self) -> None: question_services.create_new_question_skill_link( # type: ignore[no-untyped-call] self.editor_id, self.question_id, 'skill_1', 0.3) questions, _ = (question_fetchers. get_questions_and_skill_descriptions_by_skill_ids( 2, ['skill_1'], 0)) # Ruling out the possibility of None for mypy type checking. assert questions[0] is not None self.assertEqual(len(questions), 1) self.assertEqual( questions[0].to_dict(), self.question.to_dict()) # type: ignore[no-untyped-call]
def test_create_question_skill_link_increments_question_count(self): opportunity_services.create_skill_opportunity(self.SKILL_ID, 'description') self.save_new_question(self.QUESTION_ID, self.USER_ID, self._create_valid_question_data('ABC'), [self.SKILL_ID]) question_services.create_new_question_skill_link( self.USER_ID, self.QUESTION_ID, self.SKILL_ID, 0.3) skill_opportunities, _, _ = ( opportunity_services.get_skill_opportunities(None)) opportunity = skill_opportunities[0] self.assertEqual(opportunity.question_count, 1)
def test_get_skills_of_question(self): # If the question id doesnt exist at all, it returns an empty list. with self.assertRaisesRegexp( Exception, 'Entity for class QuestionModel with id ' 'non_existent_question_id not found'): question_services.get_skills_linked_to_question( 'non_existent_question_id') question_id_2 = question_services.get_new_question_id() self.save_new_question( question_id_2, self.editor_id, self._create_valid_question_data('ABC'), ['skill_1']) question_id_3 = question_services.get_new_question_id() self.save_new_question( question_id_3, self.editor_id, self._create_valid_question_data('ABC'), ['skill_2']) question_services.create_new_question_skill_link( self.editor_id, self.question_id, 'skill_1', 0.5) question_services.create_new_question_skill_link( self.editor_id, question_id_2, 'skill_1', 0.3) question_services.create_new_question_skill_link( self.editor_id, question_id_2, 'skill_2', 0.0) question_services.create_new_question_skill_link( self.editor_id, question_id_3, 'skill_2', 0.1) skills = ( question_services.get_skills_linked_to_question( question_id_2)) self.assertTrue(isinstance(skills[0], skill_domain.Skill)) self.assertEqual(len(skills), 2) skill_ids = [skill.id for skill in skills] self.assertItemsEqual( skill_ids, ['skill_1', 'skill_2'])
def test_get_question_summaries_and_skill_descriptions_with_no_skill_ids( self): question_id = question_services.get_new_question_id() self.save_new_question(question_id, self.editor_id, self._create_valid_question_data('ABC')) question_services.create_new_question_skill_link( question_id, 'skill_1', 0.5) question_summaries, skill_descriptions, _ = ( question_services.get_question_summaries_and_skill_descriptions( 2, [], '')) self.assertEqual(question_summaries, []) self.assertEqual(skill_descriptions, [])
def test_delete_with_admin_email_allows_question_deletion(self): question_services.create_new_question_skill_link( self.editor_id, self.question_id, self.skill_id, 0.3) question_services.create_new_question_skill_link( self.editor_id, self.question_id_2, self.skill_id, 0.3) self.login(self.ADMIN_EMAIL) self.delete_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id, self.skill_id)) question_summaries, grouped_skill_descriptions, _ = ( question_services.get_question_summaries_and_skill_descriptions( 5, [self.skill_id], '')) self.assertEqual(len(question_summaries), 1) self.assertEqual(question_summaries[0].id, self.question_id_2) self.assertEqual(grouped_skill_descriptions[0], ['Skill Description']) self.logout()
def test_delete_with_topic_manager_email_allows_question_deletion(self): question_services.create_new_question_skill_link( self.editor_id, self.question_id, self.skill_id, 0.5) question_services.create_new_question_skill_link( self.editor_id, self.question_id_2, self.skill_id, 0.5) self.login(self.TOPIC_MANAGER_EMAIL) self.delete_json('%s/%s/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id, self.skill_id)) question_summaries, skill_descriptions, _ = ( question_services.get_question_summaries_and_skill_descriptions( 5, [self.skill_id], '')) self.assertEqual(len(question_summaries), 1) self.assertEqual(question_summaries[0].id, self.question_id_2) self.assertEqual(skill_descriptions[0], 'Skill Description') self.logout()