-
Notifications
You must be signed in to change notification settings - Fork 470
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#11265 : Adding more tests to the four-eye sub-action integration test.
- Loading branch information
1 parent
f9e34a3
commit 6b81895
Showing
3 changed files
with
291 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,9 +11,7 @@ | |
import com.dotcms.contenttype.transform.contenttype.StructureTransformer; | ||
import com.dotcms.util.IntegrationTestInitService; | ||
import com.dotmarketing.beans.Host; | ||
import com.dotmarketing.beans.Permission; | ||
import com.dotmarketing.business.APILocator; | ||
import com.dotmarketing.business.PermissionAPI; | ||
import com.dotmarketing.business.Role; | ||
import com.dotmarketing.business.RoleAPI; | ||
import com.dotmarketing.business.UserAPI; | ||
|
@@ -27,205 +25,263 @@ | |
import com.dotmarketing.portlets.workflows.business.BaseWorkflowIntegrationTest; | ||
import com.dotmarketing.portlets.workflows.business.WorkflowAPI; | ||
import com.dotmarketing.portlets.workflows.model.WorkflowActionClass; | ||
import com.dotmarketing.portlets.workflows.model.WorkflowActionClassParameter; | ||
import com.dotmarketing.portlets.workflows.model.WorkflowActionletParameter; | ||
import com.dotmarketing.portlets.workflows.model.WorkflowProcessor; | ||
import com.liferay.portal.model.User; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.Date; | ||
import java.util.List; | ||
import org.junit.AfterClass; | ||
import org.junit.Assert; | ||
import org.junit.BeforeClass; | ||
import org.junit.Test; | ||
|
||
/** | ||
* This class verifies the correct behavior of the {@link FourEyeApproverActionlet}, which requires | ||
* a specific number of users to approve a content BEFORE it can be published. The workflow action | ||
* that triggers this action should have the following actionlets in it: | ||
* <ol> | ||
* <li>Unlock Content.</li> | ||
* <li>'4 Eye' Approval.</li> | ||
* <li>Publish Content.</li> | ||
* </ol> | ||
* This ensures that a contentlet will be correctly published after the required approvers have | ||
* accepted the new content. This is how the Multiple Approver action works too. | ||
* | ||
* @author Jose Castro | ||
* @version 4.3.0 | ||
* @since Jan 10, 2018 | ||
*/ | ||
public class FourEyeApproverActionletTest extends BaseWorkflowIntegrationTest { | ||
|
||
private static RoleAPI roleAPI; | ||
private static WorkflowAPI workflowAPI; | ||
private static ContentletAPI contentletAPI; | ||
private static LanguageAPI languageAPI; | ||
private static ContentTypeAPI contentTypeAPI; | ||
private static UserAPI userAPI; | ||
|
||
private static Role publisherRole; | ||
private static User systemUser; | ||
|
||
private static CreateSchemeStepActionResult schemeStepActionResult = null; | ||
private static ContentType type = null; | ||
private static Contentlet contentlet = null; | ||
private static User publisher1; | ||
private static User publisher2; | ||
|
||
@BeforeClass | ||
public static void prepare() throws Exception { | ||
// Setting up the web app environment | ||
IntegrationTestInitService.getInstance().init(); | ||
|
||
systemUser = APILocator.systemUser(); | ||
roleAPI = APILocator.getRoleAPI(); | ||
publisherRole = roleAPI.findRoleByName("Publisher / Legal", null); | ||
|
||
workflowAPI = APILocator.getWorkflowAPI(); | ||
contentTypeAPI = APILocator.getContentTypeAPI(systemUser); | ||
contentletAPI = APILocator.getContentletAPI(); | ||
languageAPI = APILocator.getLanguageAPI(); | ||
userAPI = APILocator.getUserAPI(); | ||
final RoleAPI roleAPI = APILocator.getRoleAPI(); | ||
|
||
final long sysTime = System.currentTimeMillis(); | ||
// Get the test role and two users from such a role | ||
final Role publisherRole = roleAPI.findRoleByName("Publisher / Legal", null); | ||
publisher1 = userAPI.getUsersByNameOrEmailOrUserID("[email protected]", 0, 1).get(0); | ||
publisher2 = userAPI.getUsersByNameOrEmailOrUserID("[email protected]", 0, 1).get(0); | ||
|
||
// creates the scheme and actions | ||
// Create the scheme and actions. This method allows you to add just one sub-action | ||
// in the beginning | ||
final long sysTime = System.currentTimeMillis(); | ||
schemeStepActionResult = createSchemeStepActionActionlet | ||
("itFourEyeApprovalScheme_" + sysTime, "step1", "action1", | ||
CheckinContentActionlet.class); | ||
|
||
final List<Permission> permissions = new ArrayList<>(); | ||
Permission permission = new Permission(schemeStepActionResult.getAction().getId(), publisherRole.getId(), PermissionAPI.PERMISSION_USE); | ||
permissions.add(permission); | ||
workflowAPI.saveAction(schemeStepActionResult.getAction(), permissions); | ||
|
||
WorkflowActionClass wac = new WorkflowActionClass(); | ||
wac.setActionId(schemeStepActionResult.getAction().getId()); | ||
wac.setClazz(FourEyeApproverActionlet.class.getName()); | ||
wac.setName(WorkFlowActionlet.class.cast(FourEyeApproverActionlet.class.newInstance()).getName()); | ||
wac.setOrder(1); | ||
workflowAPI.saveActionClass(wac); | ||
|
||
wac = new WorkflowActionClass(); | ||
wac.setActionId(schemeStepActionResult.getAction().getId()); | ||
wac.setClazz(PublishContentActionlet.class.getName()); | ||
wac.setName(WorkFlowActionlet.class.cast(PublishContentActionlet.class.newInstance()).getName()); | ||
wac.setOrder(2); | ||
workflowAPI.saveActionClass(wac); | ||
|
||
List<WorkflowActionClass> actionClasses = workflowAPI | ||
.findActionClasses(schemeStepActionResult.getAction()); | ||
|
||
wac = actionClasses.get(1); | ||
WorkFlowActionlet actionlet = workflowAPI.findActionlet(wac.getClazz()); | ||
List<WorkflowActionletParameter> actionletParams = actionlet.getParameters(); | ||
|
||
List<WorkflowActionClassParameter> newParams = new ArrayList<>(); | ||
WorkflowActionClassParameter testParam = new WorkflowActionClassParameter(); | ||
testParam.setActionClassId(wac.getId()); | ||
testParam.setKey(actionletParams.get(0).getKey()); | ||
testParam.setValue("[email protected],[email protected]"); | ||
newParams.add(testParam); | ||
|
||
testParam = new WorkflowActionClassParameter(); | ||
testParam.setActionClassId(wac.getId()); | ||
testParam.setKey(actionletParams.get(1).getKey()); | ||
testParam.setValue("2"); | ||
newParams.add(testParam); | ||
|
||
testParam = new WorkflowActionClassParameter(); | ||
testParam.setActionClassId(wac.getId()); | ||
testParam.setKey(actionletParams.get(2).getKey()); | ||
testParam.setValue("'4 Eye' Approval Required"); | ||
newParams.add(testParam); | ||
|
||
testParam = new WorkflowActionClassParameter(); | ||
testParam.setActionClassId(wac.getId()); | ||
testParam.setKey(actionletParams.get(3).getKey()); | ||
testParam.setValue("Please review this content."); | ||
newParams.add(testParam); | ||
|
||
workflowAPI.saveWorkflowActionClassParameters(newParams); | ||
|
||
//Map<String, WorkflowActionClassParameter> enteredParams = workflowAPI.findParamsForActionClass(wac); | ||
|
||
// creates the type to trigger the scheme | ||
createTestType(); | ||
|
||
// associated the scheme to the type | ||
// Set the role ID of the people who can use the action | ||
addWhoCanUseToAction(schemeStepActionResult.getAction(), | ||
Collections.singletonList(publisherRole.getId())); | ||
// Add the remaining two sub-actions for this test | ||
addActionletToAction(schemeStepActionResult.getAction().getId(), | ||
FourEyeApproverActionlet.class, 1); | ||
addActionletToAction(schemeStepActionResult.getAction().getId(), | ||
PublishContentActionlet.class, 2); | ||
// Add the required parameters to the '4-eyes' sub-action | ||
final List<WorkflowActionClass> actionletClasses = getActionletsFromAction( | ||
schemeStepActionResult.getAction()); | ||
WorkflowActionClass workflowActionClass = actionletClasses.get(1); | ||
addParameterValuesToActionlet(workflowActionClass, | ||
Arrays.asList("[email protected],[email protected]", "2", | ||
"'4 Eye' Approval Required", "Please review this content.")); | ||
|
||
// Create the content type to trigger the scheme | ||
createTestContentType(); | ||
|
||
// Associate the scheme to the content type | ||
workflowAPI.saveSchemesForStruct(new StructureTransformer(type).asStructure(), | ||
Arrays.asList(schemeStepActionResult.getScheme())); | ||
Collections.singletonList(schemeStepActionResult.getScheme())); | ||
} | ||
|
||
/** | ||
* Creates the test Content Type | ||
* | ||
* @throws DotDataException | ||
* @throws DotSecurityException | ||
*/ | ||
private static void createTestType() | ||
private static void createTestContentType() | ||
throws DotDataException, DotSecurityException { | ||
|
||
type = contentTypeAPI.save( | ||
ContentTypeBuilder.builder(BaseContentType.CONTENT.immutableClass()) | ||
.expireDateVar(null).folder(FolderAPI.SYSTEM_FOLDER).host(Host.SYSTEM_HOST) | ||
.description("SaveContentActionletTest...") | ||
.name("SaveContentActionletTest").owner(APILocator.systemUser().toString()) | ||
.variable("SaveContentActionletTest").build()); | ||
|
||
.description("Content Type for testing the 4-Eye Approval actionlet.") | ||
.name("FourEyeActionletTest").owner(APILocator.systemUser().toString()) | ||
.variable("FourEyeActionletTest").build()); | ||
final List<Field> fields = new ArrayList<>(type.fields()); | ||
|
||
fields.add(FieldBuilder.builder(TextField.class).name("title").variable("title") | ||
.contentTypeId(type.id()).dataType(DataTypes.TEXT).indexed(true).build()); | ||
fields.add(FieldBuilder.builder(TextField.class).name("txt").variable("txt") | ||
.contentTypeId(type.id()).dataType(DataTypes.TEXT).indexed(true).build()); | ||
|
||
type = contentTypeAPI.save(type, fields); | ||
} | ||
|
||
@Test | ||
public void runActionlet() throws DotSecurityException, DotDataException, InterruptedException { | ||
User publisher1 = userAPI.getUsersByNameOrEmailOrUserID("[email protected]", 0, 2).get(0); | ||
User publisher2 = userAPI.getUsersByNameOrEmailOrUserID("[email protected]", 0, 2).get(0); | ||
public void contentApprovalWithTwoApprovers() | ||
throws DotSecurityException, DotDataException { | ||
// Create a contentlet first and save it | ||
final long languageId = languageAPI.getDefaultLanguage().getId(); | ||
Contentlet cont = new Contentlet(); | ||
final Contentlet cont = new Contentlet(); | ||
cont.setContentTypeId(type.id()); | ||
cont.setOwner(APILocator.systemUser().toString()); | ||
cont.setModDate(new Date()); | ||
cont.setLanguageId(languageId); | ||
cont.setStringProperty("title", "Test Save"); | ||
cont.setStringProperty("txt", "Test Save Text"); | ||
cont.setStringProperty("title", "4-Eye Approval Test Title"); | ||
cont.setStringProperty("txt", "4-Eye Approval Test Text"); | ||
cont.setHost("48190c8c-42c4-46af-8d1a-0cd5db894797"); | ||
cont.setFolder("b37bed19-b1fd-497d-be5e-f8cc33c3fb8d"); | ||
|
||
// first save | ||
final Contentlet contentlet1 = contentletAPI.checkin(cont, systemUser, false); | ||
boolean isLive = false; | ||
Assert.assertFalse("The contentlet cannot be live, it has just been created.", | ||
contentlet1.isLive()); | ||
|
||
// triggering the save content action | ||
// Set the appropriate workflow action to the contentlet | ||
contentlet1.setStringProperty(Contentlet.WORKFLOW_ACTION_KEY, | ||
schemeStepActionResult.getAction().getId()); | ||
contentlet1.setStringProperty("title", "Test Save"); | ||
contentlet1.setStringProperty("txt", "Test Save Text"); | ||
|
||
// Triggering the save content action | ||
WorkflowProcessor processor = | ||
workflowAPI.fireWorkflowPreCheckin(contentlet1, publisher1); | ||
workflowAPI.fireWorkflowPostCheckin(processor); | ||
|
||
Thread.sleep(2000); | ||
// The contentlet MUST NOT be live yet, it needs one more approval | ||
final Contentlet contentlet2 = contentletAPI | ||
.findContentletByIdentifier(contentlet1.getIdentifier(), | ||
false, languageId, systemUser, false); | ||
isLive = contentlet2.isLive(); | ||
Assert.assertFalse("The contentlet cannot be live, it needs 1 more approver.", | ||
contentlet2.isLive()); | ||
|
||
processor = workflowAPI.fireWorkflowPreCheckin(contentlet2, publisher2); | ||
workflowAPI.fireWorkflowPostCheckin(processor); | ||
|
||
Thread.sleep(2000); | ||
Contentlet contentlet3 = contentletAPI | ||
// The contentlet MUST be live now as it has been approved by another user | ||
final Contentlet contentlet3 = contentletAPI | ||
.findContentletByIdentifier(contentlet2.getIdentifier(), | ||
false, languageId, systemUser, false); | ||
isLive = contentlet3.isLive(); | ||
Assert.assertTrue("The contentlet MUST be live, it has all the approvers.", | ||
contentlet2.isLive()); | ||
|
||
int counter = 0; | ||
// Cleanup | ||
contentlet = contentlet3; | ||
contentletAPI.delete(contentlet3, systemUser, false); | ||
} | ||
|
||
@Test | ||
public void contentApprovalWithOneApprover() | ||
throws DotSecurityException, DotDataException, InterruptedException { | ||
// Create a contentlet first and save it | ||
final long languageId = languageAPI.getDefaultLanguage().getId(); | ||
final Contentlet cont = new Contentlet(); | ||
cont.setContentTypeId(type.id()); | ||
cont.setOwner(APILocator.systemUser().toString()); | ||
cont.setModDate(new Date()); | ||
cont.setLanguageId(languageId); | ||
cont.setStringProperty("title", "4-Eye Approval Test Title"); | ||
cont.setStringProperty("txt", "4-Eye Approval Test Text"); | ||
cont.setHost("48190c8c-42c4-46af-8d1a-0cd5db894797"); | ||
cont.setFolder("b37bed19-b1fd-497d-be5e-f8cc33c3fb8d"); | ||
final Contentlet contentlet1 = contentletAPI.checkin(cont, systemUser, false); | ||
Assert.assertFalse("The contentlet cannot be live, it has just been created.", | ||
contentlet1.isLive()); | ||
|
||
// Set the appropriate workflow action to the contentlet | ||
contentlet1.setStringProperty(Contentlet.WORKFLOW_ACTION_KEY, | ||
schemeStepActionResult.getAction().getId()); | ||
contentlet1.setStringProperty("title", "Test Save"); | ||
contentlet1.setStringProperty("txt", "Test Save Text"); | ||
|
||
// Triggering the save content action | ||
WorkflowProcessor processor = | ||
workflowAPI.fireWorkflowPreCheckin(contentlet1, publisher1); | ||
workflowAPI.fireWorkflowPostCheckin(processor); | ||
|
||
// The contentlet MUST NOT be live yet, it needs one more approval | ||
final Contentlet contentlet2 = contentletAPI | ||
.findContentletByIdentifier(contentlet1.getIdentifier(), | ||
false, languageId, systemUser, false); | ||
Assert.assertFalse("The contentlet cannot be live, it needs 1 more approver.", | ||
contentlet2.isLive()); | ||
|
||
// Cleanup | ||
contentletAPI.delete(contentlet2, systemUser, false); | ||
} | ||
|
||
@Test | ||
public void unauthorizedUserTriggeringWorkflowAction() | ||
throws DotSecurityException, DotDataException { | ||
// Create a contentlet first and save it | ||
final long languageId = languageAPI.getDefaultLanguage().getId(); | ||
final Contentlet cont = new Contentlet(); | ||
cont.setContentTypeId(type.id()); | ||
cont.setOwner(APILocator.systemUser().toString()); | ||
cont.setModDate(new Date()); | ||
cont.setLanguageId(languageId); | ||
cont.setStringProperty("title", "4-Eye Approval Test Title"); | ||
cont.setStringProperty("txt", "4-Eye Approval Test Text"); | ||
cont.setHost("48190c8c-42c4-46af-8d1a-0cd5db894797"); | ||
cont.setFolder("b37bed19-b1fd-497d-be5e-f8cc33c3fb8d"); | ||
final Contentlet contentlet1 = contentletAPI.checkin(cont, systemUser, false); | ||
Assert.assertFalse("The contentlet cannot be live, it has just been created.", | ||
contentlet1.isLive()); | ||
|
||
contentlet1.setStringProperty(Contentlet.WORKFLOW_ACTION_KEY, | ||
schemeStepActionResult.getAction().getId()); | ||
contentlet1.setStringProperty("title", "Test Save"); | ||
contentlet1.setStringProperty("txt", "Test Save Text"); | ||
|
||
// Expect the correct 'user cannot read' exception | ||
boolean isErrorExpected = false; | ||
final String expectedErrorMsg = "User Joe Contributor : dotcms.org.2789 cannot read action action1"; | ||
try { | ||
// Triggering the save content action with a non-authorized user | ||
User incorrectUser = userAPI.getUsersByNameOrEmailOrUserID("[email protected]", 0, 1).get(0); | ||
workflowAPI.fireWorkflowPreCheckin(contentlet1, incorrectUser); | ||
} catch (Exception e) { | ||
// Get the expected error message that validates if user can use the workflow action | ||
final String errorMsg = e.getCause().getCause().getMessage(); | ||
isErrorExpected = expectedErrorMsg.equalsIgnoreCase(errorMsg); | ||
} | ||
|
||
// Cleanup | ||
contentletAPI.delete(contentlet1, systemUser, false); | ||
|
||
Assert.assertTrue( | ||
"The root cause of the exception IS NOT the expected error. Please check this test.", | ||
isErrorExpected); | ||
} | ||
|
||
/** | ||
* Remove the content type and workflows created | ||
* Removes the test contentlet, workflow, and content type. | ||
*/ | ||
@AfterClass | ||
public static void cleanup() | ||
throws DotDataException, DotSecurityException, AlreadyExistException { | ||
try { | ||
if (null != contentlet) { | ||
contentletAPI.delete(contentlet, APILocator.systemUser(), false); | ||
contentletAPI.delete(contentlet, systemUser, false); | ||
} | ||
} finally { | ||
try { | ||
|
Oops, something went wrong.