/* * Copyright (c) 2010-2015 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.repo.sql; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.schema.DeltaConvertor; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.MidPointPrismContextFactory; import com.evolveum.midpoint.schema.RetrieveOption; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.fail; /** * @author mederly */ @ContextConfiguration(locations = {"../../../../../ctx-test.xml"}) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class UserPhotoTest extends BaseSQLRepoTest { private static final File TEST_DIR = new File("src/test/resources/photo"); private static final File USER_FILE = new File(TEST_DIR, "user.xml"); private static final File T001_ADD_EMPLOYEE_TYPE = new File(TEST_DIR, "t001-add-employeeType.xml"); private static final File T002_REMOVE_PHOTO = new File(TEST_DIR, "t002-remove-photo.xml"); private static final File T003_RE_ADD_PHOTO = new File(TEST_DIR, "t003-re-add-photo.xml"); private static final File T004_CHANGE_PHOTO = new File(TEST_DIR, "t004-change-photo.xml"); private static final File T005_ADD_PHOTO_BY_ADD = new File(TEST_DIR, "t005-add-photo-by-add.xml"); private static final File T006_ADD_PHOTO_BY_ADD_OTHER = new File(TEST_DIR, "t006-add-photo-by-add-other.xml"); private static final File T007_REMOVE_PHOTO_BY_DELETE = new File(TEST_DIR, "t007-remove-photo-by-delete.xml"); private static final File T008_REMOVE_OTHER_PHOTO_BY_DELETE = new File(TEST_DIR, "t008-remove-other-photo-by-delete.xml"); private String userOid; @BeforeClass public void beforeClass() throws Exception { super.beforeClass(); PrismTestUtil.resetPrismContext(MidPointPrismContextFactory.FACTORY); } @Test public void test010AddUser() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test010AddUser"); PrismObject<UserType> user = PrismTestUtil.parseObject(USER_FILE); userOid = repositoryService.addObject(user, null, result); checkObject(userOid, USER_FILE, result); checkObjectNoPhoto(userOid, USER_FILE, result); } @Test public void test020ModifyUser() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test020ModifyUser"); ObjectDelta delta = parseDelta(userOid, T001_ADD_EMPLOYEE_TYPE); repositoryService.modifyObject(UserType.class, userOid, delta.getModifications(), result); checkObject(userOid, USER_FILE, result, delta); } @Test public void test030RemovePhotoByReplace() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test030RemovePhotoByReplace"); ObjectDelta delta1 = parseDelta(userOid, T001_ADD_EMPLOYEE_TYPE); ObjectDelta delta2 = parseDelta(userOid, T002_REMOVE_PHOTO); repositoryService.modifyObject(UserType.class, userOid, delta2.getModifications(), result); checkObject(userOid, USER_FILE, result, delta1, delta2); } @Test public void test040ReAddPhoto() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test040ReAddPhoto"); ObjectDelta delta1 = parseDelta(userOid, T001_ADD_EMPLOYEE_TYPE); ObjectDelta delta2 = parseDelta(userOid, T002_REMOVE_PHOTO); ObjectDelta delta3 = parseDelta(userOid, T003_RE_ADD_PHOTO); repositoryService.modifyObject(UserType.class, userOid, delta3.getModifications(), result); checkObject(userOid, USER_FILE, result, delta1, delta2, delta3); } @Test public void test050ChangePhoto() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test050ReplacePhoto"); ObjectDelta delta1 = parseDelta(userOid, T001_ADD_EMPLOYEE_TYPE); ObjectDelta delta2 = parseDelta(userOid, T002_REMOVE_PHOTO); ObjectDelta delta3 = parseDelta(userOid, T003_RE_ADD_PHOTO); ObjectDelta delta4 = parseDelta(userOid, T004_CHANGE_PHOTO); repositoryService.modifyObject(UserType.class, userOid, delta4.getModifications(), result); checkObject(userOid, USER_FILE, result, delta1, delta2, delta3, delta4); } /** * Checks that after removing a user the photo is removed as well. */ @Test public void test099DeleteUser() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test099DeleteUser"); repositoryService.deleteObject(UserType.class, userOid, result); PrismObject<UserType> user = PrismTestUtil.parseObject(USER_FILE); user.asObjectable().setJpegPhoto(null); String oid = repositoryService.addObject(user, null, result); assertEquals("Oid was changed", userOid, oid); checkObject(userOid, user, true, result); // there should be no photo there } @Test public void test100AddPhotoByAdd() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test100AddPhotoByAdd"); ObjectDelta delta = parseDelta(userOid, T005_ADD_PHOTO_BY_ADD); repositoryService.modifyObject(UserType.class, userOid, delta.getModifications(), result); checkObject(userOid, USER_FILE, result); // no need to mention delta here, because object now should be equal to USER_FILE checkObjectNoPhoto(userOid, USER_FILE, result); } @Test public void test110DuplicatePhotoAddSame() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test110DuplicatePhotoAddSame"); ObjectDelta delta = parseDelta(userOid, T005_ADD_PHOTO_BY_ADD); // adding the same value again repositoryService.modifyObject(UserType.class, userOid, delta.getModifications(), result); checkObject(userOid, USER_FILE, result); // no need to mention delta here, because object now should be equal to USER_FILE checkObjectNoPhoto(userOid, USER_FILE, result); } @Test public void test120DuplicatePhotoAddOther() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test120DuplicatePhotoAddOther"); // because photo is single-value, the ADD operation will simply replace the old value ObjectDelta delta = parseDelta(userOid, T006_ADD_PHOTO_BY_ADD_OTHER); repositoryService.modifyObject(UserType.class, userOid, delta.getModifications(), result); checkObject(userOid, USER_FILE, result, delta); } @Test public void test130RemoveNonExistingPhotoByDelete() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test130RemoveNonExistingPhotoByDelete"); ObjectDelta delta1 = parseDelta(userOid, T006_ADD_PHOTO_BY_ADD_OTHER); ObjectDelta delta2 = parseDelta(userOid, T007_REMOVE_PHOTO_BY_DELETE); repositoryService.modifyObject(UserType.class, userOid, delta2.getModifications(), result); // should not remove the photo because the value is different checkObject(userOid, USER_FILE, result, delta1); checkObject(userOid, USER_FILE, result, delta1, delta2); // should be equivalent } @Test public void test140RemoveExistingPhotoByDelete() throws Exception { OperationResult result = new OperationResult(UserPhotoTest.class.getName() + ".test140RemoveExistingPhotoByDelete"); ObjectDelta delta1 = parseDelta(userOid, T006_ADD_PHOTO_BY_ADD_OTHER); ObjectDelta delta2 = parseDelta(userOid, T007_REMOVE_PHOTO_BY_DELETE); ObjectDelta delta3 = parseDelta(userOid, T008_REMOVE_OTHER_PHOTO_BY_DELETE); repositoryService.modifyObject(UserType.class, userOid, delta3.getModifications(), result); // this one should remove the photo checkObject(userOid, USER_FILE, result, delta1, delta2, delta3); // just to be 100% sure ;) ObjectDelta deltaRemoveByReplace = parseDelta(userOid, T002_REMOVE_PHOTO); // this deletes photo by setting jpegPhoto:=null checkObject(userOid, USER_FILE, result, deltaRemoveByReplace); } protected ObjectDelta<UserType> parseDelta(String oid, File file) throws SchemaException, IOException { ObjectModificationType modification = PrismTestUtil.parseAtomicValue(file, ObjectModificationType.COMPLEX_TYPE); ObjectDelta<UserType> delta = DeltaConvertor.createObjectDelta(modification, UserType.class, prismContext); delta.setOid(oid); return delta; } private void checkObject(String oid, File file, OperationResult result) throws SchemaException, IOException, ObjectNotFoundException { PrismObject<UserType> expected = PrismTestUtil.parseObject(file); checkObject(oid, expected, true, result); } private void checkObjectNoPhoto(String oid, File file, OperationResult result) throws SchemaException, IOException, ObjectNotFoundException { PrismObject<UserType> expected = PrismTestUtil.parseObject(file); expected.asObjectable().setJpegPhoto(null); checkObject(oid, expected, false, result); } private void checkObject(String oid, PrismObject<UserType> expected, boolean loadPhoto, OperationResult result) throws ObjectNotFoundException, SchemaException { Collection<SelectorOptions<GetOperationOptions>> options; if (loadPhoto) { options = Arrays.asList(SelectorOptions.create(UserType.F_JPEG_PHOTO, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE))); } else { options = null; } PrismObject<UserType> real = repositoryService.getObject(UserType.class, oid, options, result); ObjectDelta<UserType> delta = expected.diff(real); System.out.println("Expected object = \n" + expected.debugDump()); System.out.println("Real object in repo = \n" + real.debugDump()); System.out.println("Difference = \n" + delta.debugDump()); if (!delta.isEmpty()) { fail("Objects are not equal.\n*** Expected:\n" + expected.debugDump() + "\n*** Got:\n" + real.debugDump() + "\n*** Delta:\n" + delta.debugDump()); } } private void checkObject(String oid, File file, OperationResult result, ObjectDelta<UserType>... appliedDeltas) throws SchemaException, IOException, ObjectNotFoundException { PrismObject<UserType> expected = PrismTestUtil.parseObject(file); for (ObjectDelta<UserType> delta : appliedDeltas) { delta.applyTo(expected); } checkObject(oid, expected, true, result); } }