/* * (C) Copyright 2006-2017 Nuxeo (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: * Thomas Roger <troger@nuxeo.com> * Mincong Huang <mhuang@nuxeo.com> */ package org.nuxeo.ecm.automation.core.test.directory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; 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.OperationException; import org.nuxeo.ecm.automation.OperationParameters; import org.nuxeo.ecm.automation.core.operations.services.directory.CreateDirectoryEntries; import org.nuxeo.ecm.automation.core.operations.services.directory.DeleteDirectoryEntries; import org.nuxeo.ecm.automation.core.operations.services.directory.ReadDirectoryEntries; import org.nuxeo.ecm.automation.core.operations.services.directory.UpdateDirectoryEntries; 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.DocumentModelList; import org.nuxeo.ecm.core.test.CoreFeature; import org.nuxeo.ecm.core.test.DefaultRepositoryInit; import org.nuxeo.ecm.core.test.annotations.RepositoryConfig; import org.nuxeo.ecm.directory.DirectoryException; import org.nuxeo.ecm.directory.Session; import org.nuxeo.ecm.directory.api.DirectoryService; 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 <a href="mailto:troger@nuxeo.com">Thomas Roger</a> * @since 5.7 */ @RunWith(FeaturesRunner.class) @Features(CoreFeature.class) @RepositoryConfig(init = DefaultRepositoryInit.class) @Deploy({ "org.nuxeo.ecm.directory.api", "org.nuxeo.ecm.directory", "org.nuxeo.ecm.directory.sql", "org.nuxeo.ecm.directory.types.contrib", "org.nuxeo.ecm.actions", "org.nuxeo.ecm.automation.core", "org.nuxeo.ecm.automation.features" }) @LocalDeploy("org.nuxeo.ecm.automation.features:test-directories-sql-contrib.xml") public class DirectoryOperationsTest { @Inject protected CoreSession session; @Inject AutomationService service; @Inject protected DirectoryService directoryService; protected void createEntry(String id, String label, int obsolete) { Map<String, Object> m = new HashMap<>(); m.put("id", id); m.put("label", label); m.put("obsolete", obsolete); try (Session directorySession = directoryService.open("continent")) { directorySession.createEntry(m); } } @Test public void shouldCreateNewEntriesIfAllParamsFilled() throws Exception { String newEntries = "[{\"id\": \"newContinent\", \"label\": \"newLabel\", \"obsolete\": 0}," + "{\"id\": \"anotherContinent\", \"label\": \"anotherLabel\", \"obsolete\": 0}]"; Map<String, Object> params = new HashMap<>(); params.put("directoryName", "continent"); params.put("entries", newEntries); OperationParameters oparams = new OperationParameters(CreateDirectoryEntries.ID, params); OperationContext ctx = new OperationContext(session); OperationChain chain = new OperationChain("fakeChain"); chain.add(oparams); Blob result = (Blob) service.run(ctx, chain); assertNotNull(result); ObjectMapper mapper = new ObjectMapper(); List<String> createdIds = mapper.readValue(result.getString(), new TypeReference<List<String>>() { }); assertEquals(2, createdIds.size()); assertEquals("newContinent", createdIds.get(0)); assertEquals("anotherContinent", createdIds.get(1)); try (Session directorySession = directoryService.open("continent")) { try { assertEntriesIn(directorySession); } finally { // tear down createdIds.forEach(directorySession::deleteEntry); } } } @Test public void shouldCreateNewEntriesIfSomeParamsMissing() throws Exception { // Field 'obsolete' is missing on purpose. String newEntries = "[{\"id\": \"newContinent\", \"label\": \"newLabel\"}," + "{\"id\": \"anotherContinent\", \"label\": \"anotherLabel\"}]"; Map<String, Object> params = new HashMap<>(); params.put("directoryName", "continent"); params.put("entries", newEntries); OperationParameters oparams = new OperationParameters(CreateDirectoryEntries.ID, params); OperationContext ctx = new OperationContext(session); OperationChain chain = new OperationChain("fakeChain"); chain.add(oparams); Blob result = (Blob) service.run(ctx, chain); assertNotNull(result); ObjectMapper mapper = new ObjectMapper(); List<String> createdIds = mapper.readValue(result.getString(), new TypeReference<List<String>>() { }); assertEquals(2, createdIds.size()); assertEquals("newContinent", createdIds.get(0)); assertEquals("anotherContinent", createdIds.get(1)); try (Session directorySession = directoryService.open("continent")) { try { assertEntriesIn(directorySession); } finally { // tear down createdIds.forEach(directorySession::deleteEntry); } } } private void assertEntriesIn(Session directorySession) { // assert using method 'Session#getEntry' DocumentModel entry = directorySession.getEntry("newContinent"); assertEquals("newLabel", entry.getProperty("vocabulary", "label")); assertEquals(0L, entry.getProperty("vocabulary", "obsolete")); entry = directorySession.getEntry("anotherContinent"); assertEquals("anotherLabel", entry.getProperty("vocabulary", "label")); assertEquals(0L, entry.getProperty("vocabulary", "obsolete")); // assert using method 'Session#query' Map<String, Serializable> filter = new HashMap<>(); filter.put("obsolete", 0L); DocumentModelList docs = directorySession.query(filter, Collections.emptySet(), Collections.emptyMap(), false); assertEquals(9, docs.size()); } @Test public void shouldNotCreateNewEntryIFEntryAlreadyExsists() throws Exception { String newEntries = "[{\"id\": \"europe\", \"label\": \"europe\", \"obsolete\": 0}]"; Map<String, Object> params = new HashMap<>(); params.put("directoryName", "continent"); params.put("entries", newEntries); OperationParameters oparams = new OperationParameters(CreateDirectoryEntries.ID, params); OperationContext ctx = new OperationContext(session); OperationChain chain = new OperationChain("fakeChain"); chain.add(oparams); try { service.run(ctx, chain); fail(); } catch (OperationException e) { if (!(e.getCause() instanceof DirectoryException)) { fail(); } assertEquals(e.getCause().getMessage(), "Entry with id europe already exists"); } } @Test public void shouldDeleteEntries() throws Exception { createEntry("entryToDelete", "entryToDeleteLabel", 0); Map<String, Object> params = new HashMap<>(); params.put("directoryName", "continent"); params.put("entries", "[\"entryToDelete\"]"); OperationParameters oparams = new OperationParameters(DeleteDirectoryEntries.ID, params); OperationContext ctx = new OperationContext(session); OperationChain chain = new OperationChain("fakeChain"); chain.add(oparams); Blob result = (Blob) service.run(ctx, chain); assertNotNull(result); ObjectMapper mapper = new ObjectMapper(); List<String> deleteIds = mapper.readValue(result.getString(), new TypeReference<List<String>>() { }); assertEquals(1, deleteIds.size()); assertEquals("entryToDelete", deleteIds.get(0)); try (Session directorySession = directoryService.open("continent")) { assertNull(directorySession.getEntry("entryToDelete")); } } @Test public void shouldMarkEntriesAsObsolete() throws Exception { createEntry("entryToMarkAsObsolete", "entryToMarkAsObsoleteLabel", 0); Map<String, Object> params = new HashMap<>(); params.put("directoryName", "continent"); params.put("markObsolete", true); params.put("entries", "[\"entryToMarkAsObsolete\"]"); OperationParameters oparams = new OperationParameters(DeleteDirectoryEntries.ID, params); OperationContext ctx = new OperationContext(session); OperationChain chain = new OperationChain("fakeChain"); chain.add(oparams); Blob result = (Blob) service.run(ctx, chain); assertNotNull(result); ObjectMapper mapper = new ObjectMapper(); List<String> deleteIds = mapper.readValue(result.getString(), new TypeReference<List<String>>() { }); assertEquals(1, deleteIds.size()); assertEquals("entryToMarkAsObsolete", deleteIds.get(0)); try (Session directorySession = directoryService.open("continent")) { DocumentModel entry = directorySession.getEntry("entryToMarkAsObsolete"); assertNotNull(entry); assertEquals(1L, entry.getProperty("vocabulary", "obsolete")); } } @Test public void shouldUpdateEntries() throws Exception { createEntry("entryToUpdate", "entryToUpdateLabel", 0); String entriesToUpdate = "[{\"id\": \"entryToUpdate\", \"label\": \"newEntryToUpdateLabel\", \"obsolete\": 0}]"; Map<String, Object> params = new HashMap<>(); params.put("directoryName", "continent"); params.put("entries", entriesToUpdate); OperationParameters oparams = new OperationParameters(UpdateDirectoryEntries.ID, params); OperationContext ctx = new OperationContext(session); OperationChain chain = new OperationChain("fakeChain"); chain.add(oparams); Blob result = (Blob) service.run(ctx, chain); assertNotNull(result); ObjectMapper mapper = new ObjectMapper(); List<String> updatedIds = mapper.readValue(result.getString(), new TypeReference<List<String>>() { }); assertEquals(1, updatedIds.size()); assertEquals("entryToUpdate", updatedIds.get(0)); try (Session directorySession = directoryService.open("continent")) { DocumentModel entry = directorySession.getEntry("entryToUpdate"); assertNotNull(entry); assertEquals("newEntryToUpdateLabel", entry.getProperty("vocabulary", "label")); } } @Test public void shouldReadEntries() throws Exception { String entriesToRead = "[\"europe\", \"asia\", \"oceania\"]"; Map<String, Object> params = new HashMap<>(); params.put("directoryName", "continent"); params.put("entries", entriesToRead); OperationParameters oparams = new OperationParameters(ReadDirectoryEntries.ID, params); OperationContext ctx = new OperationContext(session); OperationChain chain = new OperationChain("fakeChain"); chain.add(oparams); Blob result = (Blob) service.run(ctx, chain); assertNotNull(result); ObjectMapper mapper = new ObjectMapper(); List<Map<String, Object>> entries = mapper.readValue(result.getString(), new TypeReference<List<Map<String, Object>>>() { }); assertEquals(3, entries.size()); Map<String, Object> entry = entries.get(0); assertEquals("europe", entry.get("id")); assertEquals("label.directories.continent.europe", entry.get("label")); assertEquals(0, entry.get("obsolete")); entry = entries.get(1); assertEquals("asia", entry.get("id")); assertEquals("label.directories.continent.asia", entry.get("label")); assertEquals(0, entry.get("obsolete")); entry = entries.get(2); assertEquals("oceania", entry.get("id")); assertEquals("label.directories.continent.oceania", entry.get("label")); assertEquals(0, entry.get("obsolete")); } }