def test_collection_change_object_with_delete_collection_skill(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'delete_collection_skill', 'skill_id': 'skill_id', }) self.assertEqual(col_change_object.skill_id, 'skill_id')
def test_collection_change_object_with_add_collection_skill(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'add_collection_skill', 'name': 'name' }) self.assertEqual(col_change_object.name, 'name')
def apply_change_list(collection_id, change_list): """Applies a changelist to a pristine collection and returns the result. Args: collection_id: str. ID of the given collection. change_list: list(dict). A change list to be applied to the given collection. Each entry is a dict that represents a CollectionChange object. Returns: Collection. The resulting collection domain object. Raises: Exception. The change list is not applicable on the given collection. """ collection = get_collection_by_id(collection_id) try: changes = [ collection_domain.CollectionChange(change_dict) for change_dict in change_list ] for change in changes: if change.cmd == collection_domain.CMD_ADD_COLLECTION_NODE: collection.add_node(change.exploration_id) elif change.cmd == collection_domain.CMD_DELETE_COLLECTION_NODE: collection.delete_node(change.exploration_id) elif change.cmd == collection_domain.CMD_SWAP_COLLECTION_NODES: collection.swap_nodes(change.first_index, change.second_index) elif change.cmd == collection_domain.CMD_EDIT_COLLECTION_PROPERTY: if (change.property_name == collection_domain.COLLECTION_PROPERTY_TITLE): collection.update_title(change.new_value) elif (change.property_name == collection_domain.COLLECTION_PROPERTY_CATEGORY): collection.update_category(change.new_value) elif (change.property_name == collection_domain.COLLECTION_PROPERTY_OBJECTIVE): collection.update_objective(change.new_value) elif (change.property_name == collection_domain.COLLECTION_PROPERTY_LANGUAGE_CODE): collection.update_language_code(change.new_value) elif (change.property_name == collection_domain.COLLECTION_PROPERTY_TAGS): collection.update_tags(change.new_value) elif (change.cmd == collection_domain.CMD_MIGRATE_SCHEMA_TO_LATEST_VERSION): # Loading the collection model from the datastore into an # Collection domain object automatically converts it to use the # latest schema version. As a result, simply resaving the # collection is sufficient to apply the schema migration. continue return collection except Exception as e: logging.error('%s %s %s %s' % (e.__class__.__name__, e, collection_id, change_list)) raise e
def test_collection_change_object_with_delete_collection_node(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'delete_collection_node', 'exploration_id': 'exploration_id', }) self.assertEqual(col_change_object.cmd, 'delete_collection_node') self.assertEqual(col_change_object.exploration_id, 'exploration_id')
def test_collection_change_object_with_invalid_change_dict(self): # Raises exception as 'cmd' command is not found in change_dict. with self.assertRaisesRegexp(Exception, 'Invalid change_dict:'): collection_domain.CollectionChange({'invalid_cmd': 'data'}) # Raises exception due to invalid property name. with self.assertRaisesRegexp(Exception, 'Invalid change_dict:'): collection_domain.CollectionChange({ 'cmd': 'edit_collection_property', 'property_name': 'invalid_property_name', }) # Raises exception due to invalid command. with self.assertRaisesRegexp(Exception, 'Invalid change_dict:'): collection_domain.CollectionChange({ 'cmd': 'invalid_cmd' })
def test_to_dict(self): col_change_dict = { 'cmd': 'remove_question_id_from_skill', 'skill_id': 'skill_id', 'question_id': 'question_id' } col_change_object = collection_domain.CollectionChange(col_change_dict) self.assertEqual(col_change_object.to_dict(), col_change_dict)
def test_collection_change_object_with_add_question_id_to_skill(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'add_question_id_to_skill', 'skill_id': 'skill_id', 'question_id': 'question_id' }) self.assertEqual(col_change_object.skill_id, 'skill_id') self.assertEqual(col_change_object.question_id, 'question_id')
def test_collection_change_object_with_swap_nodes(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'swap_nodes', 'first_index': 'first_index', 'second_index': 'second_index' }) self.assertEqual(col_change_object.first_index, 'first_index') self.assertEqual(col_change_object.second_index, 'second_index')
def validate_collection_change(obj): """Validates collection change. Args: obj: dict. Data that needs to be validated. """ # No explicit call to validate_dict method is necessary, because # CollectionChange calls validate method while initialization. collection_domain.CollectionChange(obj) # type: ignore[no-untyped-call]
def validate_collection_change(obj): # type: (Dict[String, Any]) -> None """Validates collection change. Args: obj: dict. Data that needs to be validated. """ # No explicit call to validate_dict method is necessary, because # CollectionChange calls validate method while initialization. collection_domain.CollectionChange(obj)
def test_collection_change_object_with_remove_question_id_from_skill(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'remove_question_id_from_skill', 'skill_id': 'skill_id', 'question_id': 'question_id' }) self.assertEqual(col_change_object.cmd, 'remove_question_id_from_skill') self.assertEqual(col_change_object.skill_id, 'skill_id') self.assertEqual(col_change_object.question_id, 'question_id')
def test_collection_change_object_with_missing_attribute_in_cmd(self): with self.assertRaisesRegexp( utils.ValidationError, ('The following required attributes are missing: ' 'exploration_id, new_value')): collection_domain.CollectionChange({ 'cmd': 'edit_collection_node_property', 'property_name': 'category', 'old_value': 'old_value' })
def test_collection_change_object_with_create_new(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'create_new', 'category': 'category', 'title': 'title' }) self.assertEqual(col_change_object.cmd, 'create_new') self.assertEqual(col_change_object.category, 'category') self.assertEqual(col_change_object.title, 'title')
def apply_change_list(collection_id, change_list): """Applies a changelist to a pristine collection and returns the result. Each entry in change_list is a dict that represents an CollectionChange object. Returns: the resulting collection domain object. """ collection = get_collection_by_id(collection_id) try: changes = [ collection_domain.CollectionChange(change_dict) for change_dict in change_list ] for change in changes: if change.cmd == collection_domain.CMD_ADD_COLLECTION_NODE: collection.add_node(change.exploration_id) elif change.cmd == collection_domain.CMD_DELETE_COLLECTION_NODE: collection.delete_node(change.exploration_id) elif (change.cmd == collection_domain.CMD_EDIT_COLLECTION_NODE_PROPERTY): collection_node = collection.get_node(change.exploration_id) if (change.property_name == collection_domain.COLLECTION_NODE_PROPERTY_PREREQUISITE_SKILLS): # pylint: disable=line-too-long collection_node.update_prerequisite_skills( change.new_value) elif (change.property_name == collection_domain.COLLECTION_NODE_PROPERTY_ACQUIRED_SKILLS): # pylint: disable=line-too-long collection_node.update_acquired_skills(change.new_value) elif change.cmd == collection_domain.CMD_EDIT_COLLECTION_PROPERTY: if (change.property_name == collection_domain.COLLECTION_PROPERTY_TITLE): collection.update_title(change.new_value) elif (change.property_name == collection_domain.COLLECTION_PROPERTY_CATEGORY): collection.update_category(change.new_value) elif (change.property_name == collection_domain.COLLECTION_PROPERTY_OBJECTIVE): collection.update_objective(change.new_value) elif (change.cmd == collection_domain.CMD_MIGRATE_SCHEMA_TO_LATEST_VERSION): # Loading the collection model from the datastore into an # Collection domain object automatically converts it to use the # latest schema version. As a result, simply resaving the # collection is sufficient to apply the schema migration. continue return collection except Exception as e: logging.error('%s %s %s %s' % (e.__class__.__name__, e, collection_id, change_list)) raise
def test_collection_change_object_with_invalid_collection_property(self): with self.assertRaisesRegexp( utils.ValidationError, ('Value for property_name in cmd edit_collection_property: ' 'invalid is not allowed')): collection_domain.CollectionChange({ 'cmd': 'edit_collection_property', 'property_name': 'invalid', 'old_value': 'old_value', 'new_value': 'new_value', })
def test_collection_change_object_with_edit_collection_property(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'edit_collection_property', 'property_name': 'category', 'new_value': 'new_value', 'old_value': 'old_value' }) self.assertEqual(col_change_object.cmd, 'edit_collection_property') self.assertEqual(col_change_object.property_name, 'category') self.assertEqual(col_change_object.new_value, 'new_value') self.assertEqual(col_change_object.old_value, 'old_value')
def test_collection_change_object_with_migrate_schema_to_latest_version( self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'migrate_schema_to_latest_version', 'from_version': 'from_version', 'to_version': 'to_version', }) self.assertEqual( col_change_object.cmd, 'migrate_schema_to_latest_version') self.assertEqual(col_change_object.from_version, 'from_version') self.assertEqual(col_change_object.to_version, 'to_version')
def test_collection_change_object_with_extra_attribute_in_cmd(self): with self.assertRaisesRegexp( utils.ValidationError, ('The following extra attributes are present: invalid')): collection_domain.CollectionChange({ 'cmd': 'edit_collection_node_property', 'exploration_id': 'exploration_id', 'property_name': 'category', 'old_value': 'old_value', 'new_value': 'new_value', 'invalid': 'invalid' })
def test_collection_change_object_with_edit_collection_node_property(self): col_change_object = collection_domain.CollectionChange({ 'cmd': 'edit_collection_node_property', 'exploration_id': 'exploration_id', 'property_name': 'property_name', 'new_value': 'new_value', 'old_value': 'old_value' }) self.assertEqual(col_change_object.exploration_id, 'exploration_id') self.assertEqual(col_change_object.property_name, 'property_name') self.assertEqual(col_change_object.new_value, 'new_value') self.assertEqual(col_change_object.old_value, 'old_value')
def validate_collection_change(collection_change_dict): """Validates collection change. Args: collection_change_dict: dict. Data that needs to be validated. Returns: dict. Returns collection change dict after validation. """ # No explicit call to validate_dict method is necessary, because # CollectionChange calls validate method while initialization. # Object should not be returned from here because it requires modification # in many of the methods in the domain layer of the codebase and we are # planning to remove collections from our codebase hence modification is # not done here. collection_domain.CollectionChange(collection_change_dict) return collection_change_dict
def test_collection_change_object_with_missing_cmd(self) -> None: with self.assertRaisesRegex( # type: ignore[no-untyped-call] utils.ValidationError, 'Missing cmd key in change dict'): collection_domain.CollectionChange({'invalid': 'data'})
def test_collection_change_object_with_invalid_cmd(self) -> None: with self.assertRaisesRegex( # type: ignore[no-untyped-call] utils.ValidationError, 'Command invalid is not allowed'): collection_domain.CollectionChange({'cmd': 'invalid'})
def test_collection_change_object_with_invalid_cmd(self): with self.assertRaisesRegexp(utils.ValidationError, 'Command invalid is not allowed'): collection_domain.CollectionChange({'cmd': 'invalid'})
def test_collection_change_object_with_missing_cmd(self): with self.assertRaisesRegexp(utils.ValidationError, 'Missing cmd key in change dict'): collection_domain.CollectionChange({'invalid': 'data'})