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 get(self, comma_separated_skill_ids): """Handles GET requests.""" start_cursor = self.request.get('cursor') skill_ids = comma_separated_skill_ids.split(',') for skill_id in skill_ids: try: skill_domain.Skill.require_valid_skill_id(skill_id) except Exception: raise self.PageNotFoundException(Exception('Invalid skill id')) try: skill_services.get_multi_skills(skill_ids) except Exception as e: raise self.PageNotFoundException(e) ( question_summaries, merged_question_skill_links, next_start_cursor) = ( question_services.get_displayable_question_skill_link_details( constants.NUM_QUESTIONS_PER_PAGE, skill_ids, start_cursor) ) return_dicts = [] for index, summary in enumerate(question_summaries): if summary is not None: if len(skill_ids) == 1: return_dicts.append({ 'summary': summary.to_dict(), 'skill_id': merged_question_skill_links[ index].skill_ids[0], 'skill_description': ( merged_question_skill_links[ index].skill_descriptions[0]), 'skill_difficulty': ( merged_question_skill_links[ index].skill_difficulties[0]) }) else: return_dicts.append({ 'summary': summary.to_dict(), 'skill_ids': merged_question_skill_links[ index].skill_ids, 'skill_descriptions': ( merged_question_skill_links[ index].skill_descriptions), 'skill_difficulties': ( merged_question_skill_links[ index].skill_difficulties) }) self.values.update({ 'question_summary_dicts': return_dicts, 'next_start_cursor': next_start_cursor }) self.render_json(self.values)
def test_update_question_skill_link_difficulty(self): question_services.create_new_question_skill_link( self.editor_id, self.question_id, 'skill_1', 0.3) _, merged_question_skill_links, _ = ( question_services.get_displayable_question_skill_link_details( 2, ['skill_1'], '')) self.assertEqual(merged_question_skill_links[0].skill_difficulties, [0.3]) question_services.update_question_skill_link_difficulty( self.question_id, 'skill_1', 0.9) _, merged_question_skill_links, _ = ( question_services.get_displayable_question_skill_link_details( 2, ['skill_1'], '')) self.assertEqual(merged_question_skill_links[0].skill_difficulties, [0.9]) with self.assertRaisesRegexp( Exception, 'The given question and skill are not linked.'): question_services.update_question_skill_link_difficulty( self.question_id, 'skill_10', 0.9)
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/%s' % (feconf.QUESTION_SKILL_LINK_URL_PREFIX, self.question_id, self.skill_id), {'new_difficulty': 0.9}, csrf_token=csrf_token) (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.9]) self.logout()
def test_get_displayable_question_skill_link_details_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'), ['skill_1']) question_services.create_new_question_skill_link( self.editor_id, question_id, 'skill_1', 0.5) question_summaries, merged_question_skill_links, _ = ( question_services.get_displayable_question_skill_link_details( 2, [], '')) self.assertEqual(question_summaries, []) self.assertEqual(merged_question_skill_links, [])
def test_accept_question_suggestion(self): suggestion_to_accept = self.get_json( '%s?suggestion_type=%s' % ( feconf.SUGGESTION_LIST_URL_PREFIX, suggestion_models.SUGGESTION_TYPE_ADD_QUESTION) )['suggestions'][0] self.login(self.ADMIN_EMAIL) csrf_token = self.get_new_csrf_token() with self.swap(constants, 'ENABLE_NEW_STRUCTURE_VIEWER_UPDATES', True): self.put_json('%s/topic/%s/%s' % ( feconf.SUGGESTION_ACTION_URL_PREFIX, suggestion_to_accept['target_id'], suggestion_to_accept['suggestion_id']), { 'action': u'accept', 'commit_message': u'commit message', 'review_message': u'This looks good!', 'skill_id': self.SKILL_ID }, csrf_token=csrf_token) suggestion_post_accept = self.get_json( '%s?suggestion_type=%s' % ( feconf.SUGGESTION_LIST_URL_PREFIX, suggestion_models.SUGGESTION_TYPE_ADD_QUESTION) )['suggestions'][0] self.assertEqual( suggestion_post_accept['status'], suggestion_models.STATUS_ACCEPTED) ( questions, merged_question_skill_links, _) = ( question_services.get_displayable_question_skill_link_details( 1, [self.SKILL_ID], '')) self.assertEqual(len(questions), 1) self.assertEqual(questions[0].creator_id, self.author_id) self.assertEqual( merged_question_skill_links[0].skill_descriptions, [self.SKILL_DESCRIPTION]) self.assertEqual( merged_question_skill_links[0].skill_difficulties, [0.3]) self.assertEqual( questions[0].question_content, self.question_dict['question_state_data']['content']['html'] ) thread_messages = feedback_services.get_messages( suggestion_to_accept['suggestion_id']) last_message = thread_messages[len(thread_messages) - 1] self.assertEqual(last_message.text, 'This looks good!')
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.3) 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, merged_question_skill_links, _) = (question_services.get_displayable_question_skill_link_details( 5, [self.skill_id], '')) self.assertEqual(len(question_summaries), 1) self.assertEqual(question_summaries[0].id, self.question_id_2) self.assertEqual(merged_question_skill_links[0].skill_descriptions, ['Skill Description']) self.assertEqual(merged_question_skill_links[0].skill_difficulties, [0.5]) self.logout()
def test_put_with_topic_manager_email_allows_updation(self): question_services.create_new_question_skill_link( self.editor_id, self.question_id, self.skill_id, 0.3) self.login(self.TOPIC_MANAGER_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.6, 'action': 'update_difficulty', 'skill_id': self.skill_id }, csrf_token=csrf_token) (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(len(merged_question_skill_links), 1) self.assertEqual(merged_question_skill_links[0].skill_difficulties, [0.6]) self.logout()
def test_create_and_get_question_skill_link(self): question_id_2 = question_services.get_new_question_id() with self.assertRaises(Exception): question_services.create_new_question_skill_link( self.editor_id, question_id_2, 'skill_1', 0.5) 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, self.question_id, 'skill_3', 0.8) 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_3, 'skill_2', 0.2) question_summaries, merged_question_skill_links, _ = ( question_services.get_displayable_question_skill_link_details( 5, ['skill_1', 'skill_2', 'skill_3'], '')) with self.assertRaisesRegexp( Exception, 'Querying linked question summaries for more than 3 ' 'skills at a time is not supported currently.'): question_services.get_displayable_question_skill_link_details( 5, ['skill_1', 'skill_2', 'skill_3', 'skill_4'], '') question_ids = [summary.id for summary in question_summaries] self.assertEqual(len(question_ids), 3) self.assertEqual(len(merged_question_skill_links), 3) self.assertItemsEqual(question_ids, [self.question_id, question_id_2, question_id_3]) self.assertItemsEqual(question_ids, [ question_skill_link.question_id for question_skill_link in merged_question_skill_links ]) # Make sure the correct skill description corresponds to respective # question summaries. for index, link_object in enumerate(merged_question_skill_links): if question_ids[index] == self.question_id: self.assertEqual( ['Skill Description 3', 'Skill Description 1'], link_object.skill_descriptions) self.assertEqual([0.8, 0.5], link_object.skill_difficulties) elif question_ids[index] == question_id_2: self.assertEqual(['Skill Description 1'], link_object.skill_descriptions) self.assertEqual([0.3], link_object.skill_difficulties) else: self.assertEqual(['Skill Description 2'], link_object.skill_descriptions) self.assertEqual([0.2], link_object.skill_difficulties) question_summaries, merged_question_skill_links, _ = ( question_services.get_displayable_question_skill_link_details( 5, ['skill_1', 'skill_3'], '')) question_ids = [summary.id for summary in question_summaries] self.assertEqual(len(question_ids), 2) self.assertItemsEqual(question_ids, [self.question_id, question_id_2]) with self.assertRaisesRegexp( Exception, 'The given question is already linked to given skill'): question_services.create_new_question_skill_link( self.editor_id, self.question_id, 'skill_1', 0.3)
def get(self, comma_separated_skill_ids): """Handles GET requests.""" try: offset = int(self.request.get('offset')) except Exception: raise self.InvalidInputException('Invalid offset') skill_ids = comma_separated_skill_ids.split(',') skill_ids = list(set(skill_ids)) try: _require_valid_skill_ids(skill_ids) except utils.ValidationError: raise self.InvalidInputException('Invalid skill id') try: skill_fetchers.get_multi_skills(skill_ids) except Exception as e: raise self.PageNotFoundException(e) question_summaries, merged_question_skill_links = ( question_services.get_displayable_question_skill_link_details( constants.NUM_QUESTIONS_PER_PAGE + 1, skill_ids, offset)) if len(question_summaries) <= constants.NUM_QUESTIONS_PER_PAGE: more = False else: more = True question_summaries.pop() merged_question_skill_links.pop() return_dicts = [] for index, summary in enumerate(question_summaries): if summary is not None: if len(skill_ids) == 1: return_dicts.append({ 'summary': summary.to_dict(), 'skill_id': merged_question_skill_links[index].skill_ids[0], 'skill_description': (merged_question_skill_links[index]. skill_descriptions[0]), 'skill_difficulty': (merged_question_skill_links[index]. skill_difficulties[0]) }) else: return_dicts.append({ 'summary': summary.to_dict(), 'skill_ids': merged_question_skill_links[index].skill_ids, 'skill_descriptions': (merged_question_skill_links[index].skill_descriptions ), 'skill_difficulties': (merged_question_skill_links[index].skill_difficulties) }) self.values.update({ 'question_summary_dicts': return_dicts, 'more': more }) self.render_json(self.values)