/*
* (C) Copyright 2010 Nuxeo SA (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* Anahide Tchertchian
*/
package org.nuxeo.ecm.automation.task.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TimeZone;
import javax.inject.Inject;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.nuxeo.ecm.automation.AutomationService;
import org.nuxeo.ecm.automation.OperationChain;
import org.nuxeo.ecm.automation.OperationContext;
import org.nuxeo.ecm.automation.task.CreateTask.OperationTaskVariableName;
import org.nuxeo.ecm.automation.task.GetUserTasks;
import org.nuxeo.ecm.core.api.Blob;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.NuxeoPrincipal;
import org.nuxeo.ecm.core.api.security.SecurityConstants;
import org.nuxeo.ecm.core.event.EventService;
import org.nuxeo.ecm.core.test.CoreFeature;
import org.nuxeo.ecm.platform.task.Task;
import org.nuxeo.ecm.platform.task.TaskComment;
import org.nuxeo.ecm.platform.task.TaskService;
import org.nuxeo.runtime.api.Framework;
import org.nuxeo.runtime.test.runner.Deploy;
import org.nuxeo.runtime.test.runner.Features;
import org.nuxeo.runtime.test.runner.FeaturesRunner;
import org.nuxeo.runtime.test.runner.LocalDeploy;
/**
* @author Anahide Tchertchian
*/
@RunWith(FeaturesRunner.class)
@Features(CoreFeature.class)
@Deploy({ "org.nuxeo.ecm.automation.core", "org.nuxeo.ecm.platform.query.api",
"org.nuxeo.ecm.platform.task.automation", "org.nuxeo.ecm.platform.task.core",
"org.nuxeo.ecm.platform.task.testing" })
@LocalDeploy("org.nuxeo.ecm.platform.task.automation:test-operations.xml")
public class TaskAutomationTest {
@Inject
CoreSession coreSession;
@Inject
AutomationService automationService;
@Inject
TaskService taskService;
protected DocumentModel document;
@Before
public void initRepo() throws Exception {
document = coreSession.createDocumentModel("/", "task-root", "TaskRoot");
document.setPropertyValue("dc:title", "Task");
document = coreSession.createDocument(document);
document = coreSession.createDocumentModel("/", "src", "Folder");
document.setPropertyValue("dc:title", "Source");
document = coreSession.createDocument(document);
coreSession.save();
document = coreSession.getDocument(document.getRef());
Framework.getService(EventService.class).waitForAsyncCompletion();
}
@Test
public void testCreateSingleTaskChain() throws Exception {
List<Task> tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertNotNull(tasks);
assertEquals(0, tasks.size());
try (OperationContext ctx = new OperationContext(coreSession)) {
ctx.setInput(document);
automationService.run(ctx, "createSingleTaskChain");
}
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertEquals(1, tasks.size());
Task task = tasks.get(0);
assertEquals("single test task", task.getName());
List<String> pooledActorIds = task.getActors();
assertEquals(3, pooledActorIds.size());
assertTrue(pooledActorIds.contains(SecurityConstants.MEMBERS));
assertTrue(pooledActorIds.contains("myuser"));
assertTrue(pooledActorIds.contains(SecurityConstants.ADMINISTRATOR));
List<TaskComment> comments = task.getComments();
assertEquals(1, comments.size());
TaskComment comment = comments.get(0);
assertEquals(SecurityConstants.ADMINISTRATOR, comment.getAuthor());
assertEquals("test comment", comment.getText());
Calendar calendar = Calendar.getInstance();
calendar.set(2006, 6, 6, 15, 10, 15);
calendar.set(Calendar.MILLISECOND, 0);
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
assertEquals(calendar.getTime(), task.getDueDate());
// task status
assertTrue(task.isOpened());
assertFalse(task.isCancelled());
assertFalse(task.hasEnded());
assertEquals(6, task.getVariables().size());
assertEquals(document.getRepositoryName(),
task.getVariable(TaskService.VariableName.documentRepositoryName.name()));
assertEquals(document.getId(), task.getVariable(TaskService.VariableName.documentId.name()));
assertEquals("test directive", task.getVariable(TaskService.VariableName.directive.name()));
assertEquals("true", task.getVariable(OperationTaskVariableName.createdFromCreateTaskOperation.name()));
assertEquals("true", task.getVariable(TaskService.VariableName.createdFromTaskService.name()));
assertEquals(SecurityConstants.ADMINISTRATOR, task.getInitiator());
// accept task
taskService.acceptTask(coreSession, (NuxeoPrincipal) coreSession.getPrincipal(), task, "ok i'm in");
coreSession.save();
// test task again
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
// ended tasks are filtered
assertEquals(0, tasks.size());
// check document metadata
assertNull(document.getPropertyValue("dc:description"));
}
@Test
public void testGetUserTasks() throws Exception {
OperationContext ctx = new OperationContext(coreSession);
ctx.setInput(document);
automationService.run(ctx, "createSingleTaskChain");
ctx.clear();
OperationChain chain = new OperationChain("test");
chain.add(GetUserTasks.ID);
Blob blob = (Blob) automationService.run(ctx, chain);
JSONArray rows = JSONArray.fromObject(blob.getString());
assertEquals(1, rows.size());
JSONObject obj = rows.getJSONObject(0);
assertNotNull(obj.get("id")); // can be 1 or 2 depending
assertEquals(obj.get("docref"), document.getRef().toString());
assertEquals(obj.get("name"), "single test task");
assertEquals(obj.get("directive"), "test directive");
assertEquals(obj.get("comment"), "test comment");
assertNotNull(obj.get("startDate"));
assertNotNull(obj.get("dueDate"));
assertTrue((Boolean) obj.get("expired"));
}
@Test
public void testCreateSingleTaskChainWithoutActors() throws Exception {
List<Task> tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertNotNull(tasks);
assertEquals(0, tasks.size());
try (OperationContext ctx = new OperationContext(coreSession)) {
ctx.setInput(document);
automationService.run(ctx, "createSingleTaskChainWithoutActors");
}
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertEquals(0, tasks.size());
}
@Test
public void testCreateSeveralTasksChain() throws Exception {
List<Task> tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertNotNull(tasks);
assertEquals(0, tasks.size());
try (OperationContext ctx = new OperationContext(coreSession)) {
ctx.setInput(document);
automationService.run(ctx, "createSeveralTasksChain");
}
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
Collections.sort(tasks, new TaskInstanceComparator());
assertEquals(3, tasks.size());
Task task1 = tasks.get(0);
assertEquals("several test tasks", task1.getName());
List<String> pooledActorIds = task1.getActors();
assertEquals(1, pooledActorIds.size());
assertEquals(SecurityConstants.ADMINISTRATOR, pooledActorIds.get(0));
List<TaskComment> comments = task1.getComments();
assertEquals(0, comments.size());
// task status
assertTrue(task1.isOpened());
assertFalse(task1.isCancelled());
assertFalse(task1.hasEnded());
assertEquals(5, task1.getVariables().size());
assertEquals(document.getRepositoryName(),
task1.getVariable(TaskService.VariableName.documentRepositoryName.name()));
assertEquals(document.getId(), task1.getVariable(TaskService.VariableName.documentId.name()));
assertNull(task1.getVariable(TaskService.VariableName.directive.name()));
assertEquals("true", task1.getVariable(OperationTaskVariableName.createdFromCreateTaskOperation.name()));
assertEquals("true", task1.getVariable(TaskService.VariableName.createdFromTaskService.name()));
assertEquals(SecurityConstants.ADMINISTRATOR, task1.getInitiator());
// accept task
taskService.acceptTask(coreSession, (NuxeoPrincipal) coreSession.getPrincipal(), task1, "ok i'm in");
coreSession.save();
// test task again
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
// ended tasks are filtered
assertEquals(2, tasks.size());
Collections.sort(tasks, new TaskInstanceComparator());
// check other tasks
Task task2 = tasks.get(0);
assertEquals("several test tasks", task2.getName());
pooledActorIds = task2.getActors();
assertEquals(1, pooledActorIds.size());
assertEquals(SecurityConstants.MEMBERS, pooledActorIds.get(0));
comments = task2.getComments();
assertEquals(0, comments.size());
// task status
assertTrue(task2.isOpened());
assertFalse(task2.isCancelled());
assertFalse(task2.hasEnded());
assertEquals(5, task2.getVariables().size());
assertEquals(document.getRepositoryName(),
task2.getVariable(TaskService.VariableName.documentRepositoryName.name()));
assertEquals(document.getId(), task2.getVariable(TaskService.VariableName.documentId.name()));
assertNull(task2.getVariable(TaskService.VariableName.directive.name()));
assertEquals("true", task2.getVariable(OperationTaskVariableName.createdFromCreateTaskOperation.name()));
assertEquals("true", task2.getVariable(TaskService.VariableName.createdFromTaskService.name()));
assertEquals(SecurityConstants.ADMINISTRATOR, task2.getInitiator());
Task task3 = tasks.get(1);
assertEquals("several test tasks", task3.getName());
pooledActorIds = task3.getActors();
assertEquals(1, pooledActorIds.size());
assertEquals("myuser", pooledActorIds.get(0));
comments = task3.getComments();
assertEquals(0, comments.size());
// task status
assertTrue(task3.isOpened());
assertFalse(task3.isCancelled());
assertFalse(task3.hasEnded());
assertEquals(5, task3.getVariables().size());
assertEquals(document.getRepositoryName(),
task3.getVariable(TaskService.VariableName.documentRepositoryName.name()));
assertEquals(document.getId(), task3.getVariable(TaskService.VariableName.documentId.name()));
assertNull(task3.getVariable(TaskService.VariableName.directive.name()));
assertEquals("true", task3.getVariable(OperationTaskVariableName.createdFromCreateTaskOperation.name()));
assertEquals("true", task3.getVariable(TaskService.VariableName.createdFromTaskService.name()));
assertEquals(SecurityConstants.ADMINISTRATOR, task3.getInitiator());
// check document metadata
assertNull(document.getPropertyValue("dc:description"));
}
@Test
public void testCreateSingleTaskAndRunOperationChain() throws Exception {
List<Task> tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertNotNull(tasks);
assertEquals(0, tasks.size());
try (OperationContext ctx = new OperationContext(coreSession)) {
ctx.setInput(document);
automationService.run(ctx, "createSingleTaskAndRunOperationChain");
}
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertEquals(1, tasks.size());
Task task = tasks.get(0);
// accept task
taskService.acceptTask(coreSession, (NuxeoPrincipal) coreSession.getPrincipal(), task, "ok i'm in");
coreSession.save();
// test task again
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
// ended tasks are filtered
assertEquals(0, tasks.size());
// check document metadata, refetching doc from core
document = coreSession.getDocument(document.getRef());
assertEquals("This document has been accepted", document.getPropertyValue("dc:description"));
// run another time, and this time reject
try (OperationContext ctx = new OperationContext(coreSession)) {
ctx.setInput(document);
automationService.run(ctx, "createSingleTaskAndRunOperationChain");
}
tasks = taskService.getTaskInstances(document, (NuxeoPrincipal) null, coreSession);
assertEquals(1, tasks.size());
taskService.rejectTask(coreSession, (NuxeoPrincipal) coreSession.getPrincipal(), tasks.get(0),
"i don't agree with what you're saying");
document = coreSession.getDocument(document.getRef());
assertEquals("This document has been rejected !!!", document.getPropertyValue("dc:description"));
}
class TaskInstanceComparator implements Comparator<Task> {
@Override
public int compare(Task o1, Task o2) {
// return o1.getCreated().compareTo(o2.getCreated());
// stupid MySQL doesn't have subsecond resolution
// sorting by first actor is enough for this test
String a1 = o1.getActors().get(0);
String a2 = o2.getActors().get(0);
return a1.compareTo(a2);
}
}
}