/*
* 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.certification.test;
import com.evolveum.icf.dummy.resource.DummyResource;
import com.evolveum.midpoint.certification.api.OutcomeUtils;
import com.evolveum.midpoint.certification.impl.*;
import com.evolveum.midpoint.model.api.AccessCertificationService;
import com.evolveum.midpoint.model.test.AbstractModelIntegrationTest;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.xml.XmlTypeConverter;
import com.evolveum.midpoint.schema.GetOperationOptions;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.MidPointConstants;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.CertCampaignTypeUtil;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.schema.util.WorkItemTypeUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.test.DummyResourceContoller;
import com.evolveum.midpoint.test.util.TestUtil;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import javax.xml.datatype.XMLGregorianCalendar;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.stream.Collectors;
import static com.evolveum.midpoint.schema.RetrieveOption.INCLUDE;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignStateType.*;
import static com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_CASE;
import static org.testng.AssertJUnit.*;
/**
* @author mederly
*
*/
public class AbstractCertificationTest extends AbstractModelIntegrationTest {
@Autowired
private AccCertResponseComputationHelper computationHelper;
public static final File SYSTEM_CONFIGURATION_FILE = new File(COMMON_DIR, "system-configuration.xml");
public static final String SYSTEM_CONFIGURATION_OID = SystemObjectsType.SYSTEM_CONFIGURATION.value();
protected static final File ORGS_AND_USERS_FILE = new File(COMMON_DIR, "orgs-and-users.xml");
protected static final File USER_BOB_FILE = new File(COMMON_DIR, "user-bob.xml");
protected static final File USER_BOB_DEPUTY_FULL_FILE = new File(COMMON_DIR, "user-bob-deputy-full.xml");
protected static final File USER_BOB_DEPUTY_NO_ASSIGNMENTS_FILE = new File(COMMON_DIR, "user-bob-deputy-no-assignments.xml");
protected static final File USER_BOB_DEPUTY_NO_PRIVILEGES_FILE = new File(COMMON_DIR, "user-bob-deputy-no-privileges.xml");
protected static final File USER_ADMINISTRATOR_DEPUTY_NO_ASSIGNMENTS_FILE = new File(COMMON_DIR, "user-administrator-deputy-no-assignments.xml");
protected static final File USER_ADMINISTRATOR_DEPUTY_NONE_FILE = new File(COMMON_DIR, "user-administrator-deputy-none.xml");
protected static final String ORG_GOVERNOR_OFFICE_OID = "00000000-8888-6666-0000-100000000001";
protected static final String ORG_SCUMM_BAR_OID = "00000000-8888-6666-0000-100000000006";
protected static final String ORG_MINISTRY_OF_OFFENSE_OID = "00000000-8888-6666-0000-100000000003";
protected static final String ORG_MINISTRY_OF_DEFENSE_OID = "00000000-8888-6666-0000-100000000002";
protected static final String ORG_MINISTRY_OF_RUM_OID = "00000000-8888-6666-0000-100000000004";
protected static final String ORG_SWASHBUCKLER_SECTION_OID = "00000000-8888-6666-0000-100000000005";
protected static final String ORG_PROJECT_ROOT_OID = "00000000-8888-6666-0000-200000000000";
protected static final String ORG_SAVE_ELAINE_OID = "00000000-8888-6666-0000-200000000001";
protected static final String ORG_EROOT_OID = "00000000-8888-6666-0000-300000000000";
protected static final String USER_ELAINE_OID = "c0c010c0-d34d-b33f-f00d-11111111111e";
protected static final String USER_GUYBRUSH_OID = "c0c010c0-d34d-b33f-f00d-111111111116";
protected static final String USER_LECHUCK_OID = "c0c010c0-d34d-b33f-f00d-1c1c11cc11c2";
protected static final String USER_CHEESE_OID = "c0c010c0-d34d-b33f-f00d-111111111130";
protected static final String USER_CHEF_OID = "c0c010c0-d34d-b33f-f00d-111111111131";
protected static final String USER_BARKEEPER_OID = "c0c010c0-d34d-b33f-f00d-111111111132";
protected static final String USER_CARLA_OID = "c0c010c0-d34d-b33f-f00d-111111111133";
protected static final String USER_BOB_OID = "c0c010c0-d34d-b33f-f00d-111111111134";
protected static final String USER_BOB_DEPUTY_FULL_OID = "71d27191-df8c-4513-836e-ed01c68a4ab4";
protected static final String USER_BOB_DEPUTY_NO_ASSIGNMENTS_OID = "afc1c45d-fdb8-48cf-860b-b305f96a07e3";
protected static final String USER_BOB_DEPUTY_NO_PRIVILEGES_OID = "ad371f45-352d-4c1f-80f3-2e279af399ae";
protected static final String USER_ADMINISTRATOR_DEPUTY_NO_ASSIGNMENTS_OID = "0b88d83f-1722-4b13-b7cc-a2d500470d7f";
protected static final String USER_ADMINISTRATOR_DEPUTY_NONE_OID = "e38df3fc-3510-45c2-a379-2b4a1406d4b6";
public static final File USER_ADMINISTRATOR_FILE = new File(COMMON_DIR, "user-administrator.xml");
protected static final String USER_ADMINISTRATOR_OID = "00000000-0000-0000-0000-000000000002";
protected static final String USER_ADMINISTRATOR_NAME = "administrator";
protected static final File USER_JACK_FILE = new File(COMMON_DIR, "user-jack.xml");
protected static final String USER_JACK_OID = "c0c010c0-d34d-b33f-f00d-111111111111";
protected static final String USER_JACK_USERNAME = "jack";
public static final File ROLE_REVIEWER_FILE = new File(COMMON_DIR, "role-reviewer.xml");
protected static final String ROLE_REVIEWER_OID = "00000000-d34d-b33f-f00d-ffffffff0000";
public static final File ORG_SECURITY_TEAM_FILE = new File(COMMON_DIR, "org-security-team.xml");
protected static final String ORG_SECURITY_TEAM_OID = "e015eb10-1426-4104-86c0-eb0cf9dc423f";
public static final File ROLE_EROOT_USER_ASSIGNMENT_CAMPAIGN_OWNER_FILE = new File(COMMON_DIR, "role-eroot-user-assignment-campaign-owner.xml");
protected static final String ROLE_EROOT_USER_ASSIGNMENT_CAMPAIGN_OWNER_OID = "00000000-d34d-b33f-f00d-ffffffff0001";
public static final File ROLE_SUPERUSER_FILE = new File(COMMON_DIR, "role-superuser.xml");
protected static final String ROLE_SUPERUSER_OID = "00000000-0000-0000-0000-000000000004";
public static final File METAROLE_CXO_FILE = new File(COMMON_DIR, "metarole-cxo.xml");
protected static final String METAROLE_CXO_OID = "00000000-d34d-b33f-f00d-444444444444";
public static final File ROLE_CEO_FILE = new File(COMMON_DIR, "role-ceo.xml");
protected static final String ROLE_CEO_OID = "00000000-d34d-b33f-f00d-000000000001";
public static final File ROLE_COO_FILE = new File(COMMON_DIR, "role-coo.xml");
protected static final String ROLE_COO_OID = "00000000-d34d-b33f-f00d-000000000002";
public static final File ROLE_CTO_FILE = new File(COMMON_DIR, "role-cto.xml");
protected static final String ROLE_CTO_OID = "00000000-d34d-b33f-f00d-000000000003";
protected static final File ROLE_INDUCEMENT_CERT_DEF_FILE = new File(COMMON_DIR, "certification-of-role-inducements.xml");
protected static final File TASK_TRIGGER_SCANNER_FILE = new File(COMMON_DIR, "task-trigger-scanner-manual.xml");
protected static final String TASK_TRIGGER_SCANNER_OID = "00000000-0000-0000-0000-000000000007";
protected DummyResource dummyResource;
protected DummyResourceContoller dummyResourceCtl;
protected ResourceType resourceDummyType;
protected PrismObject<ResourceType> resourceDummy;
protected DummyResource dummyResourceBlack;
protected DummyResourceContoller dummyResourceCtlBlack;
protected ResourceType resourceDummyBlackType;
protected PrismObject<ResourceType> resourceDummyBlack;
protected static final File RESOURCE_DUMMY_FILE = new File(COMMON_DIR, "resource-dummy.xml");
protected static final String RESOURCE_DUMMY_OID = "10000000-0000-0000-0000-000000000004";
protected static final String RESOURCE_DUMMY_NAMESPACE = "http://midpoint.evolveum.com/xml/ns/public/resource/instance/10000000-0000-0000-0000-000000000004";
protected static final String DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME = "sea";
protected static final String RESOURCE_DUMMY_BLACK_FILENAME = COMMON_DIR + "/resource-dummy-black.xml";
protected static final String RESOURCE_DUMMY_BLACK_OID = "10000000-0000-0000-0000-000000000305";
protected static final String RESOURCE_DUMMY_BLACK_NAME = "black";
protected static final String RESOURCE_DUMMY_BLACK_NAMESPACE = MidPointConstants.NS_RI;
protected static final Trace LOGGER = TraceManager.getTrace(AbstractModelIntegrationTest.class);
@Autowired protected CertificationManagerImpl certificationManager;
@Autowired protected AccessCertificationService certificationService;
@Autowired protected AccCertUpdateHelper updateHelper;
@Autowired protected AccCertQueryHelper queryHelper;
protected RoleType roleCeo;
protected RoleType roleCoo;
protected RoleType roleCto;
protected RoleType roleSuperuser;
protected UserType userAdministrator;
protected UserType userJack;
protected UserType userElaine;
protected UserType userGuybrush;
@Override
public void initSystem(Task initTask, OperationResult initResult) throws Exception {
LOGGER.trace("initSystem");
super.initSystem(initTask, initResult);
modelService.postInit(initResult);
// System Configuration
try {
repoAddObjectFromFile(SYSTEM_CONFIGURATION_FILE, initResult);
} catch (ObjectAlreadyExistsException e) {
throw new ObjectAlreadyExistsException("System configuration already exists in repository;" +
"looks like the previous test haven't cleaned it up", e);
}
repoAddObjectsFromFile(ORGS_AND_USERS_FILE, RoleType.class, initResult);
repoAddObjectFromFile(USER_BOB_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_BOB_DEPUTY_FULL_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_BOB_DEPUTY_NO_ASSIGNMENTS_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_BOB_DEPUTY_NO_PRIVILEGES_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_ADMINISTRATOR_DEPUTY_NO_ASSIGNMENTS_FILE, UserType.class, initResult);
repoAddObjectFromFile(USER_ADMINISTRATOR_DEPUTY_NONE_FILE, UserType.class, initResult);
// roles
repoAddObjectFromFile(METAROLE_CXO_FILE, RoleType.class, initResult);
roleSuperuser = repoAddObjectFromFile(ROLE_SUPERUSER_FILE, RoleType.class, initResult).asObjectable();
roleCeo = repoAddObjectFromFile(ROLE_CEO_FILE, RoleType.class, initResult).asObjectable();
roleCoo = repoAddObjectFromFile(ROLE_COO_FILE, RoleType.class, initResult).asObjectable();
roleCto = repoAddObjectFromFile(ROLE_CTO_FILE, RoleType.class, initResult).asObjectable();
repoAddObjectFromFile(ROLE_REVIEWER_FILE, RoleType.class, initResult).asObjectable();
repoAddObjectFromFile(ROLE_EROOT_USER_ASSIGNMENT_CAMPAIGN_OWNER_FILE, RoleType.class, initResult).asObjectable();
repoAddObjectFromFile(ORG_SECURITY_TEAM_FILE, OrgType.class, initResult).asObjectable();
// Administrator
userAdministrator = repoAddObjectFromFile(USER_ADMINISTRATOR_FILE, UserType.class, initResult).asObjectable();
login(userAdministrator.asPrismObject());
// Users
userJack = repoAddObjectFromFile(USER_JACK_FILE, UserType.class, initResult).asObjectable();
userElaine = getUser(USER_ELAINE_OID).asObjectable();
userGuybrush = getUser(USER_GUYBRUSH_OID).asObjectable();
// Resources
dummyResourceCtl = DummyResourceContoller.create(null);
dummyResourceCtl.extendSchemaPirate();
dummyResource = dummyResourceCtl.getDummyResource();
dummyResourceCtl.addAttrDef(dummyResource.getAccountObjectClass(),
DUMMY_ACCOUNT_ATTRIBUTE_SEA_NAME, String.class, false, false);
resourceDummy = importAndGetObjectFromFile(ResourceType.class, RESOURCE_DUMMY_FILE, RESOURCE_DUMMY_OID, initTask, initResult);
resourceDummyType = resourceDummy.asObjectable();
dummyResourceCtl.setResource(resourceDummy);
dummyResourceCtlBlack = DummyResourceContoller.create(RESOURCE_DUMMY_BLACK_NAME, resourceDummyBlack);
dummyResourceCtlBlack.extendSchemaPirate();
dummyResourceBlack = dummyResourceCtlBlack.getDummyResource();
resourceDummyBlack = importAndGetObjectFromFile(ResourceType.class, RESOURCE_DUMMY_BLACK_FILENAME, RESOURCE_DUMMY_BLACK_OID, initTask, initResult);
resourceDummyBlackType = resourceDummyBlack.asObjectable();
dummyResourceCtlBlack.setResource(resourceDummyBlack);
// Recompute relevant objects
recomputeUser(USER_JACK_OID, initTask, initResult);
recomputeUser(USER_ELAINE_OID, initTask, initResult);
recomputeUser(USER_GUYBRUSH_OID, initTask, initResult);
recomputeFocus(RoleType.class, ROLE_CEO_OID, initTask, initResult);
recomputeFocus(RoleType.class, ROLE_COO_OID, initTask, initResult);
recomputeFocus(RoleType.class, ROLE_CTO_OID, initTask, initResult);
recomputeFocus(RoleType.class, ROLE_REVIEWER_OID, initTask, initResult);
recomputeFocus(RoleType.class, ROLE_EROOT_USER_ASSIGNMENT_CAMPAIGN_OWNER_OID, initTask, initResult);
recomputeFocus(OrgType.class, ORG_SECURITY_TEAM_OID, initTask, initResult);
}
protected AccessCertificationCaseType checkCase(Collection<AccessCertificationCaseType> caseList, String subjectOid, String targetOid, FocusType focus, String campaignOid) {
AccessCertificationCaseType ccase = findCase(caseList, subjectOid, targetOid);
assertNotNull("Certification case for " + subjectOid + ":" + targetOid + " was not found", ccase);
assertNotNull("reviewRequestedTimestamp", ccase.getCurrentStageCreateTimestamp());
assertNotNull("deadline", ccase.getCurrentStageDeadline());
assertNull("remediedTimestamp", ccase.getRemediedTimestamp());
return checkSpecificCase(ccase, focus);
}
protected AccessCertificationCaseType checkWorkItem(Collection<AccessCertificationWorkItemType> workItems, String subjectOid, String targetOid, FocusType focus, String campaignOid) {
AccessCertificationWorkItemType workItem = findWorkItem(workItems, subjectOid, targetOid);
assertNotNull("Certification work item for " + subjectOid + ":" + targetOid + " was not found", workItem);
AccessCertificationCaseType ccase = CertCampaignTypeUtil.getCase(workItem);
assertNotNull("No case for " + workItem, ccase);
assertNotNull("reviewRequestedTimestamp", ccase.getCurrentStageCreateTimestamp());
assertNotNull("deadline", ccase.getCurrentStageDeadline());
assertNull("remediedTimestamp", ccase.getRemediedTimestamp());
return checkSpecificCase(ccase, focus);
}
protected AccessCertificationCaseType checkCase(Collection<AccessCertificationCaseType> caseList, String objectOid,
String targetOid, FocusType focus, String campaignOid,
String tenantOid, String orgOid, ActivationStatusType administrativeStatus) {
AccessCertificationCaseType aCase = checkCase(caseList, objectOid, targetOid, focus, campaignOid);
String realTenantOid = aCase.getTenantRef() != null ? aCase.getTenantRef().getOid() : null;
String realOrgOid = aCase.getOrgRef() != null ? aCase.getOrgRef().getOid() : null;
ActivationStatusType realStatus = aCase.getActivation() != null ? aCase.getActivation().getAdministrativeStatus() : null;
assertEquals("incorrect tenant org", tenantOid, realTenantOid);
assertEquals("incorrect org org", orgOid, realOrgOid);
assertEquals("incorrect admin status", administrativeStatus, realStatus);
return aCase;
}
protected AccessCertificationCaseType checkWorkItem(Collection<AccessCertificationWorkItemType> workItems, String objectOid,
String targetOid, FocusType focus, String campaignOid,
String tenantOid, String orgOid, ActivationStatusType administrativeStatus) {
AccessCertificationCaseType aCase = checkWorkItem(workItems, objectOid, targetOid, focus, campaignOid);
String realTenantOid = aCase.getTenantRef() != null ? aCase.getTenantRef().getOid() : null;
String realOrgOid = aCase.getOrgRef() != null ? aCase.getOrgRef().getOid() : null;
ActivationStatusType realStatus = aCase.getActivation() != null ? aCase.getActivation().getAdministrativeStatus() : null;
assertEquals("incorrect tenant org", tenantOid, realTenantOid);
assertEquals("incorrect org org", orgOid, realOrgOid);
assertEquals("incorrect admin status", administrativeStatus, realStatus);
return aCase;
}
protected AccessCertificationCaseType checkSpecificCase(AccessCertificationCaseType ccase, FocusType focus) {
assertEquals("Wrong class for case", AccessCertificationAssignmentCaseType.class, ccase.getClass());
AccessCertificationAssignmentCaseType acase = (AccessCertificationAssignmentCaseType) ccase;
long id = acase.getAssignment().getId();
List<AssignmentType> assignmentList;
if (Boolean.TRUE.equals(acase.isIsInducement())) {
assignmentList = ((AbstractRoleType) focus).getInducement();
} else {
assignmentList = focus.getAssignment();
}
for (AssignmentType assignment : assignmentList) {
if (id == assignment.getId()) {
assertEquals("Wrong assignment in certification case", assignment, acase.getAssignment());
return ccase;
}
}
fail("Assignment with ID " + id + " not found among assignments of " + focus);
return null; // won't come here
}
protected AccessCertificationCaseType findCase(Collection<AccessCertificationCaseType> caseList, String subjectOid, String targetOid) {
for (AccessCertificationCaseType acase : caseList) {
if (acase.getTargetRef() != null && acase.getTargetRef().getOid().equals(targetOid) &&
acase.getObjectRef() != null && acase.getObjectRef().getOid().equals(subjectOid)) {
return acase;
}
}
return null;
}
protected AccessCertificationWorkItemType findWorkItem(Collection<AccessCertificationWorkItemType> workItems, String subjectOid, String targetOid) {
for (AccessCertificationWorkItemType workItem : workItems) {
AccessCertificationCaseType aCase = CertCampaignTypeUtil.getCase(workItem);
if (aCase != null && aCase.getTargetRef() != null && aCase.getTargetRef().getOid().equals(targetOid) &&
aCase.getObjectRef() != null && aCase.getObjectRef().getOid().equals(subjectOid)) {
return workItem;
}
}
return null;
}
protected void assertApproximateTime(String itemName, Date expected, XMLGregorianCalendar actual) {
assertNotNull("missing " + itemName, actual);
Date actualAsDate = XmlTypeConverter.toDate(actual);
assertTrue(itemName + " out of range; expected " + expected + ", found " + actualAsDate,
Math.abs(actualAsDate.getTime() - expected.getTime()) < 600000); // 10 minutes
}
protected void assertAfterCampaignCreate(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition) {
assertEquals("Unexpected certification cases", 0, campaign.getCase().size());
assertStateAndStage(campaign, CREATED, 0);
assertEquals("Unexpected # of stages", definition.getStageDefinition().size(), campaign.getStageDefinition().size());
assertDefinitionAndOwner(campaign, definition);
assertNull("Unexpected start time", campaign.getStartTimestamp());
assertNull("Unexpected end time", campaign.getEndTimestamp());
}
protected void assertAfterCampaignStart(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition, int cases) throws ConfigurationException, ObjectNotFoundException, SchemaException, CommunicationException, SecurityViolationException {
assertStateAndStage(campaign, IN_REVIEW_STAGE, 1);
assertDefinitionAndOwner(campaign, definition);
assertApproximateTime("start time", new Date(), campaign.getStartTimestamp());
assertNull("Unexpected end time", campaign.getEndTimestamp());
assertEquals("wrong # of defined stages", definition.getStageDefinition().size(), campaign.getStageDefinition().size());
assertEquals("wrong # of stages", 1, campaign.getStage().size());
AccessCertificationStageType stage = campaign.getStage().get(0);
assertEquals("wrong stage #", 1, stage.getNumber());
assertApproximateTime("stage 1 start", new Date(), stage.getStartTimestamp());
assertNotNull("stage 1 deadline", stage.getDeadline()); // too lazy to compute exact datetime
assertNull("unexpected stage 1 end", stage.getEndTimestamp());
assertEquals("Wrong number of certification cases", cases, campaign.getCase().size());
PrismObject<AccessCertificationDefinitionType> def = getObjectViaRepo(AccessCertificationDefinitionType.class, definition.getOid());
assertApproximateTime("last campaign started", new Date(), def.asObjectable().getLastCampaignStartedTimestamp());
assertNull("unexpected last campaign closed", def.asObjectable().getLastCampaignClosedTimestamp());
}
protected void assertAfterStageOpen(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition, int stageNumber) throws ConfigurationException, ObjectNotFoundException, SchemaException, CommunicationException, SecurityViolationException {
assertStateAndStage(campaign, IN_REVIEW_STAGE, stageNumber);
assertDefinitionAndOwner(campaign, definition);
assertApproximateTime("start time", new Date(), campaign.getStartTimestamp());
assertNull("Unexpected end time", campaign.getEndTimestamp());
assertEquals("wrong # of defined stages", definition.getStageDefinition().size(), campaign.getStageDefinition().size());
assertEquals("wrong # of stages", stageNumber, campaign.getStage().size());
AccessCertificationStageType stage = CertCampaignTypeUtil.findStage(campaign, stageNumber);
assertEquals("wrong stage #", stageNumber, stage.getNumber());
assertApproximateTime("stage start", new Date(), stage.getStartTimestamp());
assertNotNull("stage deadline", stage.getDeadline()); // too lazy to compute exact datetime
assertNull("unexpected stage end", stage.getEndTimestamp());
}
protected void assertStateAndStage(AccessCertificationCampaignType campaign, AccessCertificationCampaignStateType state, int stage) {
assertEquals("Unexpected campaign state", state, campaign.getState());
assertEquals("Unexpected stage number", stage, campaign.getStageNumber());
}
protected void assertDefinitionAndOwner(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType certificationDefinition) {
assertDefinitionAndOwner(campaign, certificationDefinition, getSecurityContextUserOid());
}
protected void assertDefinitionAndOwner(AccessCertificationCampaignType campaign,
AccessCertificationDefinitionType certificationDefinition, String expectedOwnerOid) {
assertRefEquals("Unexpected ownerRef", ObjectTypeUtil.createObjectRef(expectedOwnerOid, ObjectTypes.USER), campaign.getOwnerRef());
assertRefEquals("Unexpected definitionRef",
ObjectTypeUtil.createObjectRef(certificationDefinition),
campaign.getDefinitionRef());
}
protected void assertCaseReviewers(AccessCertificationCaseType _case, AccessCertificationResponseType currentStageOutcome,
int currentStage, List<String> reviewerOidList) {
assertEquals("wrong current stage outcome for "+_case, OutcomeUtils.toUri(currentStageOutcome), _case.getCurrentStageOutcome());
assertEquals("wrong current stage number for "+_case, currentStage, _case.getStageNumber());
Set<String> realReviewerOids = CertCampaignTypeUtil.getCurrentReviewers(_case).stream().map(ref -> ref.getOid()).collect(Collectors.toSet());
assertEquals("wrong reviewer oids for "+_case, new HashSet<>(reviewerOidList), realReviewerOids);
}
protected void recordDecision(String campaignOid, AccessCertificationCaseType _case, AccessCertificationResponseType response,
String comment, String reviewerOid, Task task, OperationResult result)
throws CommunicationException, ObjectNotFoundException, ObjectAlreadyExistsException, SchemaException, SecurityViolationException, ConfigurationException {
Authentication originalAuthentication = null;
String realReviewerOid;
if (reviewerOid != null) {
originalAuthentication = SecurityContextHolder.getContext().getAuthentication();
login(getUser(reviewerOid));
realReviewerOid = reviewerOid;
} else {
realReviewerOid = securityEnforcer.getPrincipal().getOid();
}
List<AccessCertificationWorkItemType> workItems = _case.getWorkItem().stream()
.filter(wi -> ObjectTypeUtil.containsOid(wi.getAssigneeRef(), realReviewerOid))
.filter(wi -> wi.getStageNumber() == _case.getStageNumber())
.collect(Collectors.toList());
assertEquals("Wrong # of current work items for " + realReviewerOid + " in " + _case, 1, workItems.size());
long id = _case.asPrismContainerValue().getId();
certificationManager.recordDecision(campaignOid, id, workItems.get(0).getId(), response, comment, task, result);
if (reviewerOid != null) {
SecurityContextHolder.getContext().setAuthentication(originalAuthentication);
}
}
// TODO remove redundant check on outcomes (see assertCaseOutcome)
protected void assertSingleDecision(AccessCertificationCaseType _case, AccessCertificationResponseType response, String comment,
int stageNumber, String reviewerOid, AccessCertificationResponseType currentStageOutcome, boolean checkHistory) {
List<AccessCertificationWorkItemType> currentWorkItems = getCurrentWorkItems(_case, stageNumber, false);
assertEquals("wrong # of decisions for stage " + stageNumber + " for case #" + _case.getId(), 1, currentWorkItems.size());
AccessCertificationWorkItemType workItem = currentWorkItems.get(0);
assertEquals("wrong response", response, OutcomeUtils.fromUri(WorkItemTypeUtil.getOutcome(workItem)));
assertEquals("wrong comment", comment, WorkItemTypeUtil.getComment(workItem));
assertEquals("Wrong # of reviewers", 1, workItem.getAssigneeRef().size());
assertRefEquals("wrong reviewerRef", ObjectTypeUtil.createObjectRef(reviewerOid, ObjectTypes.USER), workItem.getAssigneeRef().get(0));
assertEquals("wrong stage number", (Integer) stageNumber, workItem.getStageNumber());
if (response != null) {
assertApproximateTime("timestamp", new Date(), workItem.getOutputChangeTimestamp());
}
assertEquals("wrong current stage outcome", OutcomeUtils.toUri(currentStageOutcome), _case.getCurrentStageOutcome());
if (checkHistory) {
assertHistoricOutcome(_case, stageNumber, currentStageOutcome);
}
}
protected void assertReviewerDecision(AccessCertificationCaseType _case, AccessCertificationResponseType response, String comment,
int stageNumber, String reviewerOid, AccessCertificationResponseType currentStageOutcome, boolean checkHistory) {
AccessCertificationWorkItemType workItem = getWorkItemsForReviewer(_case, stageNumber, reviewerOid);
assertNotNull("No work item for reviewer " + reviewerOid + " in stage " + stageNumber, workItem);
assertEquals("wrong response", response, OutcomeUtils.fromUri(WorkItemTypeUtil.getOutcome(workItem)));
assertEquals("wrong comment", comment, WorkItemTypeUtil.getComment(workItem));
if (response != null) {
assertApproximateTime("timestamp", new Date(), workItem.getOutputChangeTimestamp());
}
assertEquals("wrong current stage outcome", OutcomeUtils.toUri(currentStageOutcome), _case.getCurrentStageOutcome());
if (checkHistory) {
assertHistoricOutcome(_case, stageNumber, currentStageOutcome);
}
}
protected void assertHistoricOutcome(AccessCertificationCaseType aCase, int stageNumber, AccessCertificationResponseType outcome) {
boolean found = false;
for (CaseEventType event : aCase.getEvent()) {
if (!(event instanceof StageCompletionEventType)) {
continue;
}
StageCompletionEventType completionEvent = (StageCompletionEventType) event;
if (completionEvent.getStageNumber() == stageNumber) {
assertEquals("Wrong outcome stored for stage #" + stageNumber + " in " + aCase, OutcomeUtils.toUri(outcome), completionEvent.getOutcome());
if (found) {
fail("Duplicate outcome stored for stage #" + stageNumber + " in " + aCase);
}
found = true;
}
}
assertTrue("No outcome stored for stage #" + stageNumber + " in " + aCase, found);
}
protected void assertCaseHistoricOutcomes(AccessCertificationCaseType aCase, AccessCertificationResponseType... outcomes) {
for (int stage = 0; stage < outcomes.length; stage++) {
assertHistoricOutcome(aCase, stage+1, outcomes[stage]);
}
assertEquals("wrong # of stored stage outcomes", outcomes.length, CertCampaignTypeUtil.getCompletedStageEvents(aCase).size());
}
// we return also closed ones (TODO: what is meant by 'current' work items?)
public List<AccessCertificationWorkItemType> getCurrentWorkItems(AccessCertificationCaseType _case, int stageNumber, boolean decidedOnly) {
List<AccessCertificationWorkItemType> rv = new ArrayList<>();
for (AccessCertificationWorkItemType workItem : _case.getWorkItem()) {
if (decidedOnly && WorkItemTypeUtil.getOutcome(workItem) == null) {
continue;
}
if (workItem.getStageNumber() == stageNumber) {
rv.add(workItem.clone());
}
}
return rv;
}
public AccessCertificationWorkItemType getWorkItemsForReviewer(AccessCertificationCaseType _case, int stageNumber, String reviewerOid) {
for (AccessCertificationWorkItemType workItem : _case.getWorkItem()) {
if (workItem.getStageNumber() == stageNumber && ObjectTypeUtil.containsOid(workItem.getAssigneeRef(), reviewerOid)) {
return workItem;
}
}
return null;
}
protected void assertNoDecision(AccessCertificationCaseType _case, int stage, AccessCertificationResponseType aggregatedResponse, boolean checkHistory) {
List<AccessCertificationWorkItemType> currentWorkItems = getCurrentWorkItems(_case, stage, true);
assertEquals("wrong # of decisions", 0, currentWorkItems.size());
assertEquals("wrong current response", OutcomeUtils.toUri(aggregatedResponse), _case.getCurrentStageOutcome());
if (checkHistory) {
assertHistoricOutcome(_case, stage, aggregatedResponse);
}
}
protected void assertCurrentState(AccessCertificationCaseType _case, AccessCertificationResponseType aggregatedResponse, int currentResponseStage) {
assertEquals("wrong current response", OutcomeUtils.toUri(aggregatedResponse), _case.getCurrentStageOutcome());
assertEquals("wrong current response stage number", currentResponseStage, _case.getStageNumber());
}
protected void assertWorkItems(AccessCertificationCaseType _case, int count) {
assertEquals("Wrong # of work items", count, _case.getWorkItem().size());
}
protected void assertDecision2(AccessCertificationCaseType _case, AccessCertificationResponseType response, String comment,
int stageNumber, String reviewerOid, AccessCertificationResponseType aggregatedResponse) {
AccessCertificationWorkItemType workItem = CertCampaignTypeUtil.findWorkItem(_case, stageNumber, reviewerOid);
assertNotNull("decision does not exist", workItem);
assertEquals("wrong response", response, OutcomeUtils.fromUri(WorkItemTypeUtil.getOutcome(workItem)));
assertEquals("wrong comment", comment, WorkItemTypeUtil.getComment(workItem));
if (response != null) {
assertApproximateTime("timestamp", new Date(), workItem.getOutputChangeTimestamp());
}
assertEquals("wrong current response", OutcomeUtils.toUri(aggregatedResponse), _case.getCurrentStageOutcome());
}
protected AccessCertificationCampaignType getCampaignWithCases(String campaignOid) throws ConfigurationException, ObjectNotFoundException, SchemaException, CommunicationException, SecurityViolationException {
Task task = taskManager.createTaskInstance(AbstractModelIntegrationTest.class.getName() + ".getObject");
OperationResult result = task.getResult();
Collection<SelectorOptions<GetOperationOptions>> options =
Arrays.asList(SelectorOptions.create(F_CASE, GetOperationOptions.createRetrieve(INCLUDE)));
AccessCertificationCampaignType campaign = modelService.getObject(AccessCertificationCampaignType.class, campaignOid, options, task, result).asObjectable();
result.computeStatus();
TestUtil.assertSuccess(result);
return campaign;
}
protected void assertAfterStageClose(AccessCertificationCampaignType campaign, AccessCertificationDefinitionType definition, int stageNumber) {
assertStateAndStage(campaign, REVIEW_STAGE_DONE, stageNumber);
assertDefinitionAndOwner(campaign, definition);
assertNull("Unexpected end time", campaign.getEndTimestamp());
assertEquals("wrong # of stages", stageNumber, campaign.getStage().size());
AccessCertificationStageType stage = CertCampaignTypeUtil.getCurrentStage(campaign);
assertEquals("wrong stage #", stageNumber, stage.getNumber());
assertApproximateTime("stage 1 start", new Date(), stage.getStartTimestamp());
assertApproximateTime("stage 1 end", new Date(), stage.getStartTimestamp());
for (AccessCertificationCaseType aCase : campaign.getCase()) {
if (aCase.getStageNumber() != stageNumber) {
continue;
}
checkCaseOutcomes(aCase, campaign, stageNumber);
}
}
private void checkCaseOutcomes(AccessCertificationCaseType aCase, AccessCertificationCampaignType campaign, int stageNumber) {
List<AccessCertificationResponseType> stageOutcomes = new ArrayList<>(stageNumber);
for (int i = 1; i <= stageNumber; i++) {
stageOutcomes.add(checkCaseStageOutcome(aCase, stageNumber));
}
assertEquals("Wrong # of completed stage outcomes", stageNumber, CertCampaignTypeUtil.getCompletedStageEvents(aCase).size());
AccessCertificationResponseType expectedOverall = computationHelper.computeOverallOutcome(aCase, campaign);
assertEquals("Inconsistent overall outcome", OutcomeUtils.toUri(expectedOverall), aCase.getOutcome());
}
private AccessCertificationResponseType checkCaseStageOutcome(AccessCertificationCaseType aCase, int stageNumber) {
return OutcomeUtils.fromUri(CertCampaignTypeUtil.getStageOutcome(aCase, stageNumber));
}
// completedStage - if null, checks the stage outcome in the history list
protected void assertCaseOutcome(List<AccessCertificationCaseType> caseList, String subjectOid, String targetOid,
AccessCertificationResponseType stageOutcome, AccessCertificationResponseType overallOutcome, Integer completedStage) {
AccessCertificationCaseType ccase = findCase(caseList, subjectOid, targetOid);
assertEquals("Wrong stage outcome in " + ccase, OutcomeUtils.toUri(stageOutcome), ccase.getCurrentStageOutcome());
assertEquals("Wrong overall outcome in " + ccase, OutcomeUtils.toUri(overallOutcome), ccase.getOutcome());
if (completedStage != null) {
assertHistoricOutcome(ccase, completedStage, stageOutcome);
}
}
protected void assertPercentComplete(String campaignOid, int expCasesComplete, int expCasesDecided, int expDecisionsDone) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
AccessCertificationCampaignType campaign = getCampaignWithCases(campaignOid);
assertPercentComplete(campaign, expCasesComplete, expCasesDecided, expDecisionsDone);
}
protected void assertPercentComplete(AccessCertificationCampaignType campaign, int expCasesComplete, int expCasesDecided, int expDecisionsDone) {
int casesCompletePercentage = Math.round(CertCampaignTypeUtil.getCasesCompletedPercentage(campaign));
System.out.println("Cases completed = " + casesCompletePercentage + " %");
assertEquals("Wrong case complete percentage", expCasesComplete, casesCompletePercentage);
int casesDecidedPercentage = Math.round(CertCampaignTypeUtil.getCasesDecidedPercentage(campaign));
System.out.println("Cases decided = " + casesDecidedPercentage + " %");
assertEquals("Wrong case complete percentage", expCasesDecided, casesDecidedPercentage);
int decisionsDonePercentage = Math.round(CertCampaignTypeUtil.getDecisionsDonePercentage(campaign));
System.out.println("Decisions completed = " + decisionsDonePercentage + " %");
assertEquals("Wrong decisions complete percentage", expDecisionsDone, decisionsDonePercentage);
}
public void reimportTriggerTask(OperationResult result) throws FileNotFoundException {
taskManager.suspendAndDeleteTasks(Collections.singletonList(TASK_TRIGGER_SCANNER_OID), 60000L, true, result);
importObjectFromFile(TASK_TRIGGER_SCANNER_FILE, result);
}
public void importTriggerTask(OperationResult result) throws FileNotFoundException {
importObjectFromFile(TASK_TRIGGER_SCANNER_FILE, result);
}
}