/*
* Copyright (c) 2010-2016 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.wf.impl.legacy;
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.model.api.context.ModelState;
import com.evolveum.midpoint.model.api.hooks.HookOperationMode;
import com.evolveum.midpoint.model.impl.lens.LensContext;
import com.evolveum.midpoint.model.impl.lens.LensProjectionContext;
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.result.OperationResult;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.IntegrationTestTools;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.wf.impl.WorkflowResult;
import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import java.io.File;
import java.util.List;
import static com.evolveum.midpoint.test.IntegrationTestTools.display;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertTrue;
/**
* @author mederly
*/
@ContextConfiguration(locations = {"classpath:ctx-workflow-test-main.xml"})
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class TestAddAssociationLegacy extends AbstractWfTestLegacy {
protected static final Trace LOGGER = TraceManager.getTrace(TestAddAssociationLegacy.class);
private static final File REQ_SHADOW_MODIFY_ADD_ENTITLEMENT_TESTERS = new File(TEST_RESOURCE_DIR,
"shadow-modify-add-entitlement-testers.xml");
private static final File REQ_SHADOW_MODIFY_ADD_ENTITLEMENT_GUESTS = new File(TEST_RESOURCE_DIR,
"shadow-modify-add-entitlement-guests.xml");
public TestAddAssociationLegacy() throws JAXBException {
super();
}
private String jackAccountShadowOid;
private String elisabethAccountShadowOid;
@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
super.initSystem(initTask, initResult);
modifyUserAddAccount(USER_JACK_OID, ACCOUNT_SHADOW_JACK_DUMMY_FILE, initTask, initResult);
importObjectFromFile(USER_ELISABETH_FILE, initResult);
modifyUserAddAccount(USER_ELISABETH_OID, ACCOUNT_SHADOW_ELISABETH_DUMMY_FILE, initTask, initResult);
}
/**
* Add entitlement to user jack
*/
@Test
public void test010AddJackToTesters() throws Exception {
TestUtil.displayTestTile(this, "test010AddJackToTesters");
executeTest("test010AddJackToTesters", USER_JACK_OID, new TestDetails() {
@Override
int subtaskCount() {
return 1;
}
@Override
boolean immediate() {
return false;
}
@Override
boolean checkObjectOnSubtasks() {
return true;
}
@Override
boolean removeAssignmentsBeforeTest() {
return false;
}
@Override
public LensContext createModelContext(OperationResult result) throws Exception {
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_JACK_OID, result);
UserType jack = context.getFocusContext().getObjectCurrent().asObjectable();
AssertJUnit.assertEquals("Jack has wrong number of accounts", 1, jack.getLinkRef().size());
jackAccountShadowOid = jack.getLinkRef().get(0).getOid();
LensProjectionContext accountContext = fillContextWithAccount(context, jackAccountShadowOid, result);
ObjectModificationType modElement = PrismTestUtil.parseAtomicValue(REQ_SHADOW_MODIFY_ADD_ENTITLEMENT_TESTERS, ObjectModificationType.COMPLEX_TYPE);
ObjectDelta shadowDelta = DeltaConvertor.createObjectDelta(modElement, ShadowType.class, prismContext);
shadowDelta.setOid(jackAccountShadowOid);
accountContext.setPrimaryDelta(shadowDelta);
return context;
}
@Override
public void assertsAfterClockworkRun(Task rootTask, List<Task> wfSubtasks, OperationResult result) throws Exception {
ModelContext taskModelContext = wfTaskUtil.getModelContext(rootTask, result);
IntegrationTestTools.display("model context from the root task", taskModelContext);
assertEquals("Wrong # of projection contexts in root task", 1, taskModelContext.getProjectionContexts().size());
assertTrue("There are modifications in primary focus delta", ObjectDelta.isNullOrEmpty(taskModelContext.getFocusContext().getPrimaryDelta()));
assertTrue("There are modifications left in primary projection delta",
ObjectDelta.isNullOrEmpty(
((LensProjectionContext) (taskModelContext.getProjectionContexts().iterator().next()))
.getPrimaryDelta()));
ShadowType account = getObject(ShadowType.class, jackAccountShadowOid).asObjectable();
IntegrationTestTools.display("jack dummy account after first clockwork run", account);
assertEquals("Unexpected associations present", 0, account.getAssociation().size());
}
@Override
void assertsRootTaskFinishes(Task task, List<Task> subtasks, OperationResult result) throws Exception {
ShadowType account = getObject(ShadowType.class, jackAccountShadowOid).asObjectable();
IntegrationTestTools.display("jack dummy account", account);
assertHasAssociation(account, new QName("group"), GROUP_TESTERS_OID);
checkWorkItemAuditRecords(createResultMap(GROUP_TESTERS_OID, WorkflowResult.APPROVED));
}
@Override
boolean decideOnApproval(String executionId) throws Exception {
return true;
}
});
}
/**
* Add entitlement to user elisabeth (rejected)
*/
@Test
public void test020AddElisabethToTestersRejected() throws Exception {
TestUtil.displayTestTile(this, "test020AddElisabethToTestersRejected");
executeTest("test020AddElisabethToTestersRejected", USER_ELISABETH_OID, new TestDetails() {
@Override
int subtaskCount() {
return 1;
}
@Override
boolean immediate() {
return false;
}
@Override
boolean checkObjectOnSubtasks() {
return true;
}
@Override
boolean removeAssignmentsBeforeTest() {
return false;
}
@Override
public LensContext createModelContext(OperationResult result) throws Exception {
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_ELISABETH_OID, result);
UserType elisabeth = context.getFocusContext().getObjectCurrent().asObjectable();
AssertJUnit.assertEquals("Elisabeth has wrong number of accounts", 1, elisabeth.getLinkRef().size());
elisabethAccountShadowOid = elisabeth.getLinkRef().get(0).getOid();
LensProjectionContext accountContext = fillContextWithAccount(context, elisabethAccountShadowOid, result);
ObjectModificationType modElement = PrismTestUtil.parseAtomicValue(REQ_SHADOW_MODIFY_ADD_ENTITLEMENT_TESTERS, ObjectModificationType.COMPLEX_TYPE);
ObjectDelta shadowDelta = DeltaConvertor.createObjectDelta(modElement, ShadowType.class, prismContext);
shadowDelta.setOid(elisabethAccountShadowOid);
accountContext.setPrimaryDelta(shadowDelta);
return context;
}
@Override
public void assertsAfterClockworkRun(Task rootTask, List<Task> wfSubtasks, OperationResult result) throws Exception {
ModelContext taskModelContext = wfTaskUtil.getModelContext(rootTask, result);
IntegrationTestTools.display("model context from the root task", taskModelContext);
assertEquals("Wrong # of projection contexts in root task", 1, taskModelContext.getProjectionContexts().size());
assertTrue("There are modifications in primary focus delta", ObjectDelta.isNullOrEmpty(taskModelContext.getFocusContext().getPrimaryDelta()));
assertTrue("There are modifications left in primary projection delta",
ObjectDelta.isNullOrEmpty(
((LensProjectionContext) (taskModelContext.getProjectionContexts().iterator().next()))
.getPrimaryDelta()));
ShadowType account = getObject(ShadowType.class, elisabethAccountShadowOid).asObjectable();
IntegrationTestTools.display("elisabeth dummy account after first clockwork run", account);
assertEquals("Unexpected associations present", 0, account.getAssociation().size());
}
@Override
void assertsRootTaskFinishes(Task task, List<Task> subtasks, OperationResult result) throws Exception {
ShadowType account = getObject(ShadowType.class, elisabethAccountShadowOid).asObjectable();
IntegrationTestTools.display("elisabeth dummy account", account);
assertEquals("Unexpected associations present", 0, account.getAssociation().size());
checkWorkItemAuditRecords(createResultMap(GROUP_TESTERS_OID, WorkflowResult.REJECTED));
}
@Override
boolean decideOnApproval(String executionId) throws Exception {
return false;
}
});
}
/**
* Add entitlement for 'guests' to user jack - should be created without starting wf process
*/
@Test
public void test100AddJackToGuests() throws Exception {
final String TEST_NAME = "test100AddJackToGuests";
TestUtil.displayTestTile(this, TEST_NAME);
Task modelTask = taskManager.createTaskInstance(TEST_NAME);
OperationResult result = new OperationResult(TEST_NAME);
modelTask.setOwner(repositoryService.getObject(UserType.class, USER_ADMINISTRATOR_OID, null, result));
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_JACK_OID, result);
UserType jack = context.getFocusContext().getObjectCurrent().asObjectable();
AssertJUnit.assertEquals("Jack has wrong number of accounts", 1, jack.getLinkRef().size());
jackAccountShadowOid = jack.getLinkRef().get(0).getOid();
ShadowType accountBefore = getObject(ShadowType.class, jackAccountShadowOid).asObjectable();
assertEquals("Wrong # of jack's account associations", 1, accountBefore.getAssociation().size());
assertHasAssociation(accountBefore, new QName("group"), GROUP_TESTERS_OID);
LensProjectionContext accountContext = fillContextWithAccount(context, jackAccountShadowOid, result);
ObjectModificationType modElement = PrismTestUtil.parseAtomicValue(REQ_SHADOW_MODIFY_ADD_ENTITLEMENT_GUESTS, ObjectModificationType.COMPLEX_TYPE);
ObjectDelta shadowDelta = DeltaConvertor.createObjectDelta(modElement, ShadowType.class, prismContext);
shadowDelta.setOid(jackAccountShadowOid);
accountContext.setPrimaryDelta(shadowDelta);
HookOperationMode mode = clockwork.run(context, modelTask, result);
assertEquals("Unexpected state of the context - workflow was started even if it should not", ModelState.FINAL, context.getState());
assertEquals("Wrong mode after clockwork.run in " + context.getState(), HookOperationMode.FOREGROUND, mode);
ShadowType accountAfter = getObject(ShadowType.class, jackAccountShadowOid).asObjectable();
assertEquals("Wrong # of jack's account associations", 2, accountAfter.getAssociation().size());
assertHasAssociation(accountAfter, new QName("group"), GROUP_TESTERS_OID);
assertHasAssociation(accountAfter, new QName("group"), GROUP_GUESTS_OID);
}
public void assertHasAssociation(ShadowType shadow, QName associationName, String entitlementOid) {
for (ShadowAssociationType association : shadow.getAssociation()) {
if (QNameUtil.match(association.getName(), associationName) &&
entitlementOid.equals(association.getShadowRef().getOid())) {
return;
}
}
AssertJUnit.fail("No association of type " + associationName + " of " + entitlementOid + " in " + ObjectTypeUtil.toShortString(shadow));
}
@Test
public void zzzMarkAsNotInitialized() {
display("Setting class as not initialized");
unsetSystemInitialized();
}
}