diff --git a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java index 175025d3bf9..d9036c0ff13 100644 --- a/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java +++ b/model/model-test/src/main/java/com/evolveum/midpoint/model/test/AbstractModelIntegrationTest.java @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.model.test; +import static java.util.Collections.singleton; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; @@ -44,6 +45,7 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.*; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.mutable.MutableInt; import org.jetbrains.annotations.NotNull; @@ -92,20 +94,6 @@ import com.evolveum.midpoint.model.common.stringpolicy.ValuePolicyProcessor; import com.evolveum.midpoint.notifications.api.NotificationManager; import com.evolveum.midpoint.notifications.api.transports.Message; -import com.evolveum.midpoint.prism.Containerable; -import com.evolveum.midpoint.prism.Item; -import com.evolveum.midpoint.prism.ItemDefinition; -import com.evolveum.midpoint.prism.PrismContainer; -import com.evolveum.midpoint.prism.PrismContainerDefinition; -import com.evolveum.midpoint.prism.PrismContainerValue; -import com.evolveum.midpoint.prism.PrismContext; -import com.evolveum.midpoint.prism.PrismObject; -import com.evolveum.midpoint.prism.PrismObjectDefinition; -import com.evolveum.midpoint.prism.PrismProperty; -import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.PrismReference; -import com.evolveum.midpoint.prism.PrismReferenceValue; -import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.crypto.EncryptionException; import com.evolveum.midpoint.prism.delta.ChangeType; import com.evolveum.midpoint.prism.delta.ContainerDelta; @@ -925,6 +913,17 @@ protected void unassignRole(String userOid, String roleOid) throws ObjectNotFoun TestUtil.assertSuccess(result); } + protected void unassignRoleByAssignmentValue(PrismObject focus, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, + SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, + PolicyViolationException, SecurityViolationException { + AssignmentType assignment = findAssignmentByTargetRequired(focus, roleOid); + ObjectDelta delta = DeltaBuilder.deltaFor(focus.getCompileTimeClass(), prismContext) + .item(FocusType.F_ASSIGNMENT) + .delete(assignment.clone()) + .asObjectDeltaCast(focus.getOid()); + modelService.executeChanges(singleton(delta), null, task, result); + } + protected void unassignRole(String userOid, String roleOid, Task task, OperationResult result) throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException { @@ -2920,7 +2919,7 @@ protected void restartTask(String taskOid) throws CommonException { taskManager.resumeTask(task, result); } else if (task.getExecutionStatus() == TaskExecutionStatus.CLOSED) { LOGGER.debug("Task {} is closed, scheduling it to run now", task); - taskManager.scheduleTasksNow(Collections.singleton(taskOid), result); + taskManager.scheduleTasksNow(singleton(taskOid), result); } else if (task.getExecutionStatus() == TaskExecutionStatus.RUNNABLE) { if (taskManager.getLocallyRunningTaskByIdentifier(task.getTaskIdentifier()) != null) { // Task is really executing. Let's wait until it finishes; hopefully it won't start again (TODO) @@ -2928,7 +2927,7 @@ protected void restartTask(String taskOid) throws CommonException { waitForTaskFinish(taskOid, false); } LOGGER.debug("Task {} is finished, scheduling it to run now", task); - taskManager.scheduleTasksNow(Collections.singleton(taskOid), result); + taskManager.scheduleTasksNow(singleton(taskOid), result); } else { throw new IllegalStateException("Task " + task + " cannot be restarted, because its state is: " + task.getExecutionStatus()); } @@ -4394,7 +4393,7 @@ protected void resetTriggerTask(String taskOid, File taskFile, OperationResult r .item(TaskType.F_SCHEDULE).replace() .asItemDeltas(), result); - taskManager.resumeTasks(Collections.singleton(taskOid), result); + taskManager.resumeTasks(singleton(taskOid), result); } protected void repoAddObjects(List objects, OperationResult result) diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java index 8edc5817ac1..7a69feee516 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/AbstractWfTestPolicy.java @@ -239,6 +239,11 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti userTemplateAssigningRole1aOidAfter = repoAddObjectFromFile(USER_TEMPLATE_ASSIGNING_ROLE_1A_AFTER, initResult).getOid(); } + @Override + protected PrismObject getDefaultActor() { + return userAdministrator; + } + protected void updateSystemConfiguration(SystemConfigurationType systemConfiguration) { // nothing to do by default } @@ -863,21 +868,22 @@ protected String getObjectOid() { protected List getExpectedWorkItems() { return null; } protected void assertDeltaExecuted(int number, boolean yes, Task rootTask, OperationResult result) throws Exception { } + // mutually exclusive with getApprovalSequence protected Boolean decideOnApproval(String executionId, org.activiti.engine.task.Task task) throws Exception { return true; } - protected void sortSubtasks(List subtasks) { - Collections.sort(subtasks, Comparator.comparing(this::getCompareKey)); + private void sortSubtasks(List subtasks) { + subtasks.sort(Comparator.comparing(this::getCompareKey)); } - protected void sortWorkItems(List workItems) { - Collections.sort(workItems, Comparator.comparing(this::getCompareKey)); + private void sortWorkItems(List workItems) { + workItems.sort(Comparator.comparing(this::getCompareKey)); } - protected String getCompareKey(Task task) { + private String getCompareKey(Task task) { return task.getTaskPrismObject().asObjectable().getWorkflowContext().getTargetRef().getOid(); } - protected String getCompareKey(WorkItemType workItem) { + private String getCompareKey(WorkItemType workItem) { return workItem.getOriginalAssigneeRef().getOid(); } diff --git a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java index caa643a74e6..2a9754cce8a 100644 --- a/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java +++ b/model/workflow-impl/src/test/java/com/evolveum/midpoint/wf/impl/policy/assignments/metarole/TestAssignmentsWithDifferentMetaroles.java @@ -20,6 +20,7 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.delta.ObjectDelta; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; +import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; @@ -48,6 +49,8 @@ import static com.evolveum.midpoint.xml.ns._public.common.common_3.AutomatedCompletionReasonType.AUTO_COMPLETION_CONDITION; import static com.evolveum.midpoint.xml.ns._public.common.common_3.AutomatedCompletionReasonType.NO_ASSIGNEES_FOUND; import static com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.PROCESS; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; import static org.testng.AssertJUnit.*; /** @@ -73,6 +76,9 @@ public class TestAssignmentsWithDifferentMetaroles extends AbstractWfTestPolicy protected static final File ROLE_ROLE24_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "role-role24-approval-and-enforce.xml"); protected static final File ROLE_ROLE25_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "role-role25-very-complex-approval.xml"); protected static final File ROLE_ROLE26_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "role-role26-no-approvers.xml"); + protected static final File ROLE_ROLE27_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "role-role27-modifications-and.xml"); + protected static final File ROLE_ROLE28_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "role-role28-modifications-or.xml"); + protected static final File ROLE_ROLE29_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "role-role29-modifications-no-items.xml"); protected static final File ORG_LEADS2122_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "org-leads2122.xml"); protected static final File USER_LEAD21_FILE = new File(TEST_ASSIGNMENTS_RESOURCE_DIR, "user-lead21.xml"); @@ -86,6 +92,9 @@ public class TestAssignmentsWithDifferentMetaroles extends AbstractWfTestPolicy protected String roleRole24Oid; protected String roleRole25Oid; protected String roleRole26Oid; + protected String roleRole27Oid; + protected String roleRole28Oid; + protected String roleRole29Oid; protected String orgLeads2122Oid; protected String userLead21Oid; @@ -103,6 +112,9 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti roleRole24Oid = repoAddObjectFromFile(ROLE_ROLE24_FILE, initResult).getOid(); roleRole25Oid = repoAddObjectFromFile(ROLE_ROLE25_FILE, initResult).getOid(); roleRole26Oid = repoAddObjectFromFile(ROLE_ROLE26_FILE, initResult).getOid(); + roleRole27Oid = repoAddObjectFromFile(ROLE_ROLE27_FILE, initResult).getOid(); + roleRole28Oid = repoAddObjectFromFile(ROLE_ROLE28_FILE, initResult).getOid(); + roleRole29Oid = repoAddObjectFromFile(ROLE_ROLE29_FILE, initResult).getOid(); orgLeads2122Oid = repoAddObjectFromFile(ORG_LEADS2122_FILE, initResult).getOid(); userLead21Oid = addAndRecomputeUser(USER_LEAD21_FILE, initTask, initResult); @@ -269,7 +281,6 @@ public void test300ApprovalAndEnforce() throws Exception { TestUtil.displayTestTitle(this, TEST_NAME); login(userAdministrator); Task task = createTask(TEST_NAME); - task.setOwner(userAdministrator); OperationResult result = task.getResult(); try { @@ -326,7 +337,6 @@ public void test500NoApprovers() throws Exception { TestUtil.displayTestTitle(this, TEST_NAME); login(userAdministrator); Task task = createTask(TEST_NAME); - task.setOwner(userAdministrator); OperationResult result = task.getResult(); assignRole(userJackOid, roleRole26Oid, task, result); @@ -348,6 +358,662 @@ public void test500NoApprovers() throws Exception { } } + // "assignment modification" (no specific items) + @Test + public void test600AssignRole29() throws Exception { + final String TEST_NAME = "test600AssignRole29"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + assignRole(userJackOid, roleRole29Oid, task, result); // should proceed without approvals + + // THEN + displayThen(TEST_NAME); + PrismObject jack = getUser(userJackOid); + display("jack", jack); + assertAssignedRoles(jack, roleRole29Oid); + } + + @Test + public void test610ModifyAssignmentOfRole29() throws Exception { + final String TEST_NAME = "test610ModifyAssignmentOfRole29"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + PrismObject jackBefore = getUser(userJackOid); + AssignmentType assignment = findAssignmentByTargetRequired(jackBefore, roleRole29Oid); + ObjectDelta deltaToApprove = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, assignment.getId(), AssignmentType.F_DESCRIPTION) + .replace("new description") + .asObjectDeltaCast(userJackOid); + ObjectDelta delta0 = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME) + .replace(PolyString.fromOrig("new full name")) + .asObjectDeltaCast(userJackOid); + + // +THEN + executeTest2(TEST_NAME, new TestDetails2() { + @Override + protected PrismObject getFocus(OperationResult result) throws Exception { + return jackBefore; + } + + @Override + protected ObjectDelta getFocusDelta() throws Exception { + return ObjectDelta.summarize(deltaToApprove, delta0); + } + + @Override + protected int getNumberOfDeltasToApprove() { + return 1; + } + + @Override + protected List getApprovals() { + return singletonList(true); + } + + @Override + protected List> getExpectedDeltasToApprove() { + return singletonList(deltaToApprove); + } + + @Override + protected ObjectDelta getExpectedDelta0() { + return delta0; + } + + @Override + protected String getObjectOid() { + return userJackOid; + } + + @Override + protected List getExpectedTasks() { + return singletonList(new ExpectedTask(roleRole29Oid, "Modifying assignment of Role29 on jack")); + } + + @Override + protected List getExpectedWorkItems() { + ExpectedTask etask = getExpectedTasks().get(0); + return singletonList(new ExpectedWorkItem(USER_ADMINISTRATOR_OID, roleRole29Oid, etask)); + } + + @Override + protected void assertDeltaExecuted(int number, boolean yes, Task rootTask, OperationResult result) throws Exception { + System.out.println("assertDeltaExecuted for number = " + number + ", yes = " + yes); + // todo + // e.g. check metadata + if (number == 0) { + PrismObject jack = getUser(userJackOid); + assertEquals("wrong new full name", yes ? "new full name" : "Jack Sparrow", jack.asObjectable().getFullName().getOrig()); + } else { + PrismObject jack = getUser(userJackOid); + AssignmentType assignment1 = findAssignmentByTargetRequired(jack, roleRole29Oid); + assertEquals("wrong new assignment description", yes ? "new description" : null, assignment1.getDescription()); + } + } + + @Override + protected Boolean decideOnApproval(String executionId, org.activiti.engine.task.Task task) throws Exception { + return true; + } + + @Override + public List getApprovalSequence() { + return null; + } + + @Override + protected void afterFirstClockworkRun(Task rootTask, List subtasks, List workItems, + OperationResult result) throws Exception { + // todo + } + + }, 1, false); + + // THEN + displayThen(TEST_NAME); + PrismObject jackAfter = getUser(userJackOid); + display("jack after", jackAfter); + assertAssignedRoles(jackAfter, roleRole29Oid); + } + + @Test + public void test620ModifyAssignmentOfRole29Immediate() throws Exception { + final String TEST_NAME = "test620ModifyAssignmentOfRole29Immediate"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + PrismObject jackBefore = getUser(userJackOid); + AssignmentType assignment = findAssignmentByTargetRequired(jackBefore, roleRole29Oid); + ObjectDelta deltaToApprove = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, assignment.getId(), AssignmentType.F_DESCRIPTION) + .replace("new description 2") + .asObjectDeltaCast(userJackOid); + ObjectDelta delta0 = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME) + .replace(PolyString.fromOrig("new full name 2")) + .asObjectDeltaCast(userJackOid); + + // +THEN + executeTest2(TEST_NAME, new TestDetails2() { + @Override + protected PrismObject getFocus(OperationResult result) throws Exception { + return jackBefore; + } + + @Override + protected ObjectDelta getFocusDelta() throws Exception { + return ObjectDelta.summarize(deltaToApprove, delta0); + } + + @Override + protected int getNumberOfDeltasToApprove() { + return 1; + } + + @Override + protected List getApprovals() { + return singletonList(true); + } + + @Override + protected List> getExpectedDeltasToApprove() { + return singletonList(deltaToApprove); + } + + @Override + protected ObjectDelta getExpectedDelta0() { + return delta0; + } + + @Override + protected String getObjectOid() { + return userJackOid; + } + + @Override + protected List getExpectedTasks() { + return singletonList(new ExpectedTask(roleRole29Oid, "Modifying assignment of Role29 on jack")); + } + + @Override + protected List getExpectedWorkItems() { + ExpectedTask etask = getExpectedTasks().get(0); + return singletonList(new ExpectedWorkItem(USER_ADMINISTRATOR_OID, roleRole29Oid, etask)); + } + + @SuppressWarnings("Duplicates") + @Override + protected void assertDeltaExecuted(int number, boolean yes, Task rootTask, OperationResult result) throws Exception { + System.out.println("assertDeltaExecuted for number = " + number + ", yes = " + yes); + // todo + // e.g. check metadata + if (number == 0) { + PrismObject jack = getUser(userJackOid); + assertEquals("wrong new full name", yes ? "new full name 2" : "new full name", jack.asObjectable().getFullName().getOrig()); + } else { + PrismObject jack = getUser(userJackOid); + AssignmentType assignment1 = findAssignmentByTargetRequired(jack, roleRole29Oid); + assertEquals("wrong new assignment description", yes ? "new description 2" : "new description", assignment1.getDescription()); + } + } + + @Override + protected Boolean decideOnApproval(String executionId, org.activiti.engine.task.Task task) throws Exception { + return true; + } + + @Override + public List getApprovalSequence() { + return null; + } + + @Override + protected void afterFirstClockworkRun(Task rootTask, List subtasks, List workItems, + OperationResult result) throws Exception { + // todo + } + + }, 1, true); + + // THEN + displayThen(TEST_NAME); + PrismObject jackAfter = getUser(userJackOid); + display("jack after", jackAfter); + assertAssignedRoles(jackAfter, roleRole29Oid); + } + + @Test + public void test630UnassignRole29() throws Exception { + final String TEST_NAME = "test630UnassignRole29"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + unassignRoleByAssignmentValue(getUser(userJackOid), roleRole29Oid, task, result); // should proceed without approvals + + // THEN + displayThen(TEST_NAME); + PrismObject jack = getUser(userJackOid); + display("jack", jack); + assertNotAssignedRole(jack, roleRole29Oid); + } + + // assignment modification ("or" of 2 items) + @Test + public void test700AssignRole28() throws Exception { + final String TEST_NAME = "test700AssignRole28"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN/THEN + ObjectDelta deltaToApprove = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT) + .add(ObjectTypeUtil.createAssignmentTo(roleRole28Oid, ObjectTypes.ROLE, prismContext) + .description("description")) + .asObjectDeltaCast(userJackOid); + ObjectDelta delta0 = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME) + .replace(PolyString.fromOrig("new full name 3")) + .asObjectDeltaCast(userJackOid); + + PrismObject jackBefore = getUser(userJackOid); + + executeTest2(TEST_NAME, new TestDetails2() { + @Override + protected PrismObject getFocus(OperationResult result) throws Exception { + return jackBefore; + } + + @Override + protected ObjectDelta getFocusDelta() throws Exception { + return ObjectDelta.summarize(deltaToApprove, delta0); + } + + @Override + protected int getNumberOfDeltasToApprove() { + return 1; + } + + @Override + protected List getApprovals() { + return singletonList(true); + } + + @Override + protected List> getExpectedDeltasToApprove() { + return singletonList(deltaToApprove); + } + + @Override + protected ObjectDelta getExpectedDelta0() { + return delta0; + } + + @Override + protected String getObjectOid() { + return userJackOid; + } + + @Override + protected List getExpectedTasks() { + return singletonList(new ExpectedTask(roleRole28Oid, "Assigning Role28 to jack")); + } + + @Override + protected List getExpectedWorkItems() { + ExpectedTask etask = getExpectedTasks().get(0); + return singletonList(new ExpectedWorkItem(USER_ADMINISTRATOR_OID, roleRole28Oid, etask)); + } + + @Override + protected void assertDeltaExecuted(int number, boolean yes, Task rootTask, OperationResult result) throws Exception { + System.out.println("assertDeltaExecuted for number = " + number + ", yes = " + yes); + // todo + // e.g. check metadata + if (number == 0) { + PrismObject jack = getUser(userJackOid); + assertEquals("wrong new full name", yes ? "new full name 3" : "new full name 2", jack.asObjectable().getFullName().getOrig()); + } else { + PrismObject jack = getUser(userJackOid); + if (yes) { + assertAssignedRole(jack, roleRole28Oid); + } else { + assertNotAssignedRole(jack, roleRole28Oid); + } + } + } + + @Override + protected Boolean decideOnApproval(String executionId, org.activiti.engine.task.Task task) throws Exception { + return true; + } + + @Override + protected void afterFirstClockworkRun(Task rootTask, List subtasks, List workItems, + OperationResult result) throws Exception { + // todo + } + + }, 1, false); + + // THEN + displayThen(TEST_NAME); + PrismObject jack = getUser(userJackOid); + display("jack", jack); + assertAssignedRoles(jack, roleRole28Oid); + } + + @Test + public void test710ModifyAssignmentOfRole28() throws Exception { + final String TEST_NAME = "test710ModifyAssignmentOfRole28"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + PrismObject jackBefore = getUser(userJackOid); + AssignmentType assignment = findAssignmentByTargetRequired(jackBefore, roleRole28Oid); + ObjectDelta deltaToApprove = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, assignment.getId(), AssignmentType.F_DESCRIPTION) + .replace("new description") + .asObjectDeltaCast(userJackOid); + ObjectDelta delta0 = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME) + .replace(PolyString.fromOrig("new full name 4")) + .asObjectDeltaCast(userJackOid); + + // +THEN + executeTest2(TEST_NAME, new TestDetails2() { + @Override + protected PrismObject getFocus(OperationResult result) throws Exception { + return jackBefore; + } + + @Override + protected ObjectDelta getFocusDelta() throws Exception { + return ObjectDelta.summarize(deltaToApprove, delta0); + } + + @Override + protected int getNumberOfDeltasToApprove() { + return 1; + } + + @Override + protected List getApprovals() { + return singletonList(true); + } + + @Override + protected List> getExpectedDeltasToApprove() { + return singletonList(deltaToApprove); + } + + @Override + protected ObjectDelta getExpectedDelta0() { + return delta0; + } + + @Override + protected String getObjectOid() { + return userJackOid; + } + + @Override + protected List getExpectedTasks() { + return singletonList(new ExpectedTask(roleRole28Oid, "Modifying assignment of Role28 on jack")); + } + + @Override + protected List getExpectedWorkItems() { + ExpectedTask etask = getExpectedTasks().get(0); + return singletonList(new ExpectedWorkItem(USER_ADMINISTRATOR_OID, roleRole28Oid, etask)); + } + + @Override + protected void assertDeltaExecuted(int number, boolean yes, Task rootTask, OperationResult result) throws Exception { + System.out.println("assertDeltaExecuted for number = " + number + ", yes = " + yes); + // todo + // e.g. check metadata + if (number == 0) { + PrismObject jack = getUser(userJackOid); + assertEquals("wrong new full name", yes ? "new full name 4" : "new full name 3", jack.asObjectable().getFullName().getOrig()); + } else { + PrismObject jack = getUser(userJackOid); + AssignmentType assignment1 = findAssignmentByTargetRequired(jack, roleRole28Oid); + assertEquals("wrong new assignment description", yes ? "new description" : "description", assignment1.getDescription()); + } + } + + @Override + protected Boolean decideOnApproval(String executionId, org.activiti.engine.task.Task task) throws Exception { + return true; + } + + @Override + public List getApprovalSequence() { + return null; + } + + @Override + protected void afterFirstClockworkRun(Task rootTask, List subtasks, List workItems, + OperationResult result) throws Exception { + // todo + } + + }, 1, false); + + // THEN + displayThen(TEST_NAME); + PrismObject jackAfter = getUser(userJackOid); + display("jack after", jackAfter); + assertAssignedRoles(jackAfter, roleRole28Oid); + } + + @Test + public void test720UnassignRole28() throws Exception { + final String TEST_NAME = "test720UnassignRole28"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + PrismObject jackBefore = getUser(userJackOid); + AssignmentType assignment = findAssignmentByTargetRequired(jackBefore, roleRole28Oid); + ObjectDelta deltaToApprove = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT) + .delete(new AssignmentType().id(assignment.getId())) // id-only, to test the constraint + .asObjectDeltaCast(userJackOid); + ObjectDelta delta0 = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_FULL_NAME) + .replace(PolyString.fromOrig("new full name 5")) + .asObjectDeltaCast(userJackOid); + + // +THEN + executeTest2(TEST_NAME, new TestDetails2() { + @Override + protected PrismObject getFocus(OperationResult result) throws Exception { + return jackBefore; + } + + @Override + protected ObjectDelta getFocusDelta() throws Exception { + return ObjectDelta.summarize(deltaToApprove, delta0); + } + + @Override + protected int getNumberOfDeltasToApprove() { + return 1; + } + + @Override + protected List getApprovals() { + return singletonList(true); + } + + @Override + protected List> getExpectedDeltasToApprove() { + return singletonList(deltaToApprove); + } + + @Override + protected ObjectDelta getExpectedDelta0() { + return delta0; + } + + @Override + protected String getObjectOid() { + return userJackOid; + } + + @Override + protected List getExpectedTasks() { + return singletonList(new ExpectedTask(roleRole28Oid, "Unassigning Role28 from jack")); + } + + @Override + protected List getExpectedWorkItems() { + ExpectedTask etask = getExpectedTasks().get(0); + return singletonList(new ExpectedWorkItem(USER_ADMINISTRATOR_OID, roleRole28Oid, etask)); + } + + @Override + protected void assertDeltaExecuted(int number, boolean yes, Task rootTask, OperationResult result) throws Exception { + System.out.println("assertDeltaExecuted for number = " + number + ", yes = " + yes); + // todo + // e.g. check metadata + if (number == 0) { + PrismObject jack = getUser(userJackOid); + assertEquals("wrong new full name", yes ? "new full name 5" : "new full name 4", jack.asObjectable().getFullName().getOrig()); + } else { + PrismObject jack = getUser(userJackOid); + if (yes) { + assertNotAssignedRole(jack, roleRole28Oid); + } else { + assertAssignedRole(jack, roleRole28Oid); + } + } + } + + @Override + protected Boolean decideOnApproval(String executionId, org.activiti.engine.task.Task task) throws Exception { + return true; + } + + @Override + public List getApprovalSequence() { + return null; + } + + @Override + protected void afterFirstClockworkRun(Task rootTask, List subtasks, List workItems, + OperationResult result) throws Exception { + // todo + } + + }, 1, false); + + // THEN + displayThen(TEST_NAME); + PrismObject jackAfter = getUser(userJackOid); + display("jack after", jackAfter); + assertNotAssignedRole(jackAfter, roleRole28Oid); + } + + @Test + public void test800AssignRole27() throws Exception { + final String TEST_NAME = "test800AssignRole27"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT) + .add(ObjectTypeUtil.createAssignmentTo(roleRole27Oid, ObjectTypes.ROLE, prismContext) + .description("description")) + .asObjectDeltaCast(userJackOid); + executeChanges(delta, null, task, result); // should proceed without approvals (only 1 of the items is present) + + // THEN + displayThen(TEST_NAME); + PrismObject jack = getUser(userJackOid); + display("jack", jack); + assertAssignedRoles(jack, roleRole27Oid); + } + + @Test + public void test810ModifyAssignmentOfRole27() throws Exception { + final String TEST_NAME = "test810ModifyAssignmentOfRole27"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + PrismObject jackBefore = getUser(userJackOid); + AssignmentType assignmentBefore = findAssignmentByTargetRequired(jackBefore, roleRole27Oid); + ObjectDelta delta = DeltaBuilder.deltaFor(UserType.class, prismContext) + .item(UserType.F_ASSIGNMENT, assignmentBefore.getId(), AssignmentType.F_DESCRIPTION) + .replace("new description") + .asObjectDeltaCast(userJackOid); + + executeChanges(delta, null, task, result); // should proceed without approvals (only 1 of the items is present) + + // THEN + displayThen(TEST_NAME); + PrismObject jack = getUser(userJackOid); + display("jack", jack); + AssignmentType assignment = findAssignmentByTargetRequired(jack, roleRole27Oid); + assertEquals("Wrong description", "new description", assignment.getDescription()); + } + + @Test + public void test820UnassignRole27() throws Exception { + final String TEST_NAME = "test820UnassignRole27"; + TestUtil.displayTestTitle(this, TEST_NAME); + login(userAdministrator); + Task task = createTask(TEST_NAME); + OperationResult result = task.getResult(); + + // WHEN + displayWhen(TEST_NAME); + unassignRoleByAssignmentValue(getUser(userJackOid), roleRole27Oid, task, result); // should proceed without approvals + + // THEN + displayThen(TEST_NAME); + PrismObject jack = getUser(userJackOid); + display("jack", jack); + assertNotAssignedRole(jack, roleRole27Oid); + } + private void executeAssignRoles123ToJack(String TEST_NAME, boolean immediate, boolean approve1, boolean approve2, boolean approve3a, boolean approve3b, boolean securityDeputy) throws Exception { Task task = createTask("executeAssignRoles123ToJack"); @@ -512,7 +1178,7 @@ private void previewAssignRolesToJack(String TEST_NAME, boolean immediate, boole ModelExecuteOptions options = immediate ? ModelExecuteOptions.createExecuteImmediatelyAfterApproval() : new ModelExecuteOptions(); options.setPartialProcessing(new PartialProcessingOptionsType().approvals(PROCESS)); ModelContext modelContext = modelInteractionService - .previewChanges(Collections.singleton(primaryDelta), options, task, result); + .previewChanges(singleton(primaryDelta), options, task, result); List approvalInfo = modelContext.getHookPreviewResults(ApprovalSchemaExecutionInformationType.class); List enforceInfo = modelContext.getHookPreviewResults(PolicyRuleEnforcerHookPreviewOutputType.class); diff --git a/model/workflow-impl/src/test/resources/policy/assignments/role-role25-very-complex-approval.xml b/model/workflow-impl/src/test/resources/policy/assignments/role-role25-very-complex-approval.xml index 1c46b15fb03..b7f12e11a53 100644 --- a/model/workflow-impl/src/test/resources/policy/assignments/role-role25-very-complex-approval.xml +++ b/model/workflow-impl/src/test/resources/policy/assignments/role-role25-very-complex-approval.xml @@ -232,4 +232,26 @@ + + + + + activation/validTo + + + + + + 110 + + + + not-matching + reject + + + + + + \ No newline at end of file diff --git a/model/workflow-impl/src/test/resources/policy/assignments/role-role27-modifications-and.xml b/model/workflow-impl/src/test/resources/policy/assignments/role-role27-modifications-and.xml new file mode 100644 index 00000000000..10b3ad95590 --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/assignments/role-role27-modifications-and.xml @@ -0,0 +1,36 @@ + + + + Role27 + + + + + + description + activation/validFrom + + + + + + + + + + \ No newline at end of file diff --git a/model/workflow-impl/src/test/resources/policy/assignments/role-role28-modifications-or.xml b/model/workflow-impl/src/test/resources/policy/assignments/role-role28-modifications-or.xml new file mode 100644 index 00000000000..2ff7f59fe38 --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/assignments/role-role28-modifications-or.xml @@ -0,0 +1,39 @@ + + + + Role28 + + + + + + description + + + activation/validFrom + + + + + + + + + + + \ No newline at end of file diff --git a/model/workflow-impl/src/test/resources/policy/assignments/role-role29-modifications-no-items.xml b/model/workflow-impl/src/test/resources/policy/assignments/role-role29-modifications-no-items.xml new file mode 100644 index 00000000000..f90cd2cf0ca --- /dev/null +++ b/model/workflow-impl/src/test/resources/policy/assignments/role-role29-modifications-no-items.xml @@ -0,0 +1,34 @@ + + + + Role29 + + + + + modify + + + + + + + + + + \ No newline at end of file