/* * (C) Copyright 2006-2007 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: * Florent Guillaume * * $Id: TestMemoryDirectory.java 30381 2008-02-20 20:12:09Z gracinet $ */ package org.nuxeo.ecm.directory.memory; 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 static org.junit.Assert.fail; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.directory.BaseSession; import org.nuxeo.ecm.directory.Directory; import org.nuxeo.ecm.directory.DirectoryException; import org.nuxeo.ecm.directory.api.DirectoryService; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.test.NXRuntimeTestCase; /** * @author Florent Guillaume */ public class TestMemoryDirectory extends NXRuntimeTestCase { MemoryDirectory memDir; MemoryDirectorySession dir; DocumentModel entry; static final String SCHEMA_NAME = "myschema"; @Override @Before public void setUp() throws Exception { super.setUp(); deployBundle("org.nuxeo.ecm.core.schema"); deployContrib("org.nuxeo.ecm.directory.core.tests", "test-schema.xml"); MemoryDirectoryDescriptor descr = new MemoryDirectoryDescriptor(); descr.name = "mydir"; descr.schemaName = SCHEMA_NAME; descr.idField = "i"; descr.passwordField = "pw"; descr.schemaSet = new HashSet<>(Arrays.asList("i", "pw", "a", "int", "b")); memDir = new MemoryDirectory(descr); dir = (MemoryDirectorySession) memDir.getSession(); Map<String, Object> e1 = new HashMap<String, Object>(); e1.put("i", "1"); e1.put("pw", "secr"); e1.put("a", "AAA"); e1.put("b", "BCD"); e1.put("int", 3); e1.put("x", "XYZ"); // shouldn't be put in storage entry = dir.createEntry(e1); } @Test public void testSchemaIntrospection() throws Exception { MemoryDirectoryDescriptor descr = new MemoryDirectoryDescriptor(); descr.name = "adir"; descr.schemaName = SCHEMA_NAME; descr.idField = "i"; descr.passwordField = "pw"; MemoryDirectory md = new MemoryDirectory(descr); assertEquals(new HashSet<String>(Arrays.asList("i", "pw", "a", "int", "b", "x")), md.schemaSet); } @Test public void testCreate() throws Exception { // created in setUp assertEquals("1", entry.getProperty(SCHEMA_NAME, "i")); assertEquals("secr", entry.getProperty(SCHEMA_NAME, "pw")); assertEquals("AAA", entry.getProperty(SCHEMA_NAME, "a")); assertEquals("BCD", entry.getProperty(SCHEMA_NAME, "b")); assertNull(entry.getProperty(SCHEMA_NAME, "x")); // create one with the same id, must fail Map<String, Object> e2 = new HashMap<String, Object>(); e2.put("i", "1"); try { entry = dir.createEntry(e2); fail("Should raise an error, entry already exists"); } catch (DirectoryException e) { } } @Test public void testCreateFromModel() throws Exception { DocumentModel entry = BaseSession.createEntryModel(null, SCHEMA_NAME, null, null); entry.setProperty(SCHEMA_NAME, "i", "yo"); assertNull(dir.getEntry("yo")); dir.createEntry(entry); assertNotNull(dir.getEntry("yo")); // create one with existing same id, must fail entry.setProperty(SCHEMA_NAME, "i", "1"); try { entry = dir.createEntry(entry); fail("Should raise an error, entry already exists"); } catch (DirectoryException e) { } } @Test public void testHasEntry() throws Exception { assertTrue(dir.hasEntry("1")); assertFalse(dir.hasEntry("foo")); } @Test public void testAuthenticate() throws Exception { assertTrue(dir.authenticate("1", "secr")); assertFalse(dir.authenticate("1", "haha")); assertFalse(dir.authenticate("2", "any")); } @Test public void testGetEntry() throws Exception { DocumentModel entry = dir.getEntry("1"); assertEquals("AAA", entry.getProperty(SCHEMA_NAME, "a")); assertNull(dir.getEntry("no-such-entry")); } @Test public void testGetEntries() throws Exception { Map<String, Object> e2 = new HashMap<String, Object>(); e2.put("i", "2"); entry = dir.createEntry(e2); DocumentModelList l = dir.getEntries(); assertEquals(2, l.size()); assertEquals("1", l.get(0).getId()); assertEquals("2", l.get(1).getId()); } @Test public void testUpdateEntry() throws Exception { DocumentModel e = dir.getEntry("1"); assertEquals("BCD", e.getProperty(SCHEMA_NAME, "b")); e.setProperty(SCHEMA_NAME, "b", "babar"); dir.updateEntry(e); e = dir.getEntry("1"); assertEquals("babar", e.getProperty(SCHEMA_NAME, "b")); String id = "no-such-entry"; Map<String, Object> map = new HashMap<String, Object>(); map.put("i", id); DocumentModel entry = BaseSession.createEntryModel(null, SCHEMA_NAME, id, map); try { dir.updateEntry(entry); } catch (DirectoryException de) { assertEquals("UpdateEntry failed: entry 'no-such-entry' not found", de.getMessage()); } } @Test public void testDeleteEntry() throws Exception { DocumentModelList l = dir.getEntries(); assertEquals(1, l.size()); dir.deleteEntry("1"); l = dir.getEntries(); assertEquals(0, l.size()); } @Test public void testQuery() throws Exception { Map<String, Object> e2 = new HashMap<String, Object>(); e2.put("i", "2"); e2.put("pw", "guess"); e2.put("a", "AAA222"); e2.put("b", "BCD"); dir.createEntry(e2); Map<String, Serializable> filter = new HashMap<String, Serializable>(); DocumentModelList entries; DocumentModel e; // empty filter means everything (like getEntries) entries = dir.query(filter); assertNotNull(entries); assertEquals(2, entries.size()); // filter with no known field is same as empty filter.put("bobo", "bibi"); entries = dir.query(filter); assertNotNull(entries); assertEquals(2, entries.size()); // no result filter.clear(); filter.put("a", "gaga"); entries = dir.query(filter); assertEquals(0, entries.size()); // no fulltext filter.put("a", "A"); entries = dir.query(filter); assertEquals(0, entries.size()); // simple query filter.put("a", "AAA"); entries = dir.query(filter); assertEquals(1, entries.size()); e = entries.get(0); assertEquals("1", e.getId()); assertEquals("BCD", e.getProperty(SCHEMA_NAME, "b")); // add unknown field filter.put("bobo", "bibi"); entries = dir.query(filter); assertEquals(1, entries.size()); assertEquals("1", entries.get(0).getId()); // two criteria filter.clear(); filter.put("a", "AAA"); filter.put("b", "BCD"); entries = dir.query(filter); assertEquals(1, entries.size()); e = entries.get(0); assertEquals("1", e.getId()); assertEquals("secr", e.getProperty(SCHEMA_NAME, "pw")); // query not matching although each criterion matches one entry filter.put("a", "AAA"); filter.put("pw", "guess"); entries = dir.query(filter); assertEquals(0, entries.size()); } @Test public void testQueryFts() throws Exception { Map<String, Serializable> filter = new HashMap<String, Serializable>(); Set<String> fulltext = new HashSet<String>(); // trying to cheat filter.put("a", "*"); assertEquals(0, dir.query(filter, fulltext).size()); // fulltext filter.clear(); fulltext.add("b"); // only initial match filter.put("b", "c"); assertEquals(0, dir.query(filter, fulltext).size()); // lowercase initial match filter.put("b", "b"); assertEquals(1, dir.query(filter, fulltext).size()); // 2nd criterion not matching filter.put("a", "a"); assertEquals(0, dir.query(filter, fulltext).size()); // 2nd criterion matching filter.put("a", "AAA"); assertEquals(1, dir.query(filter, fulltext).size()); // 2nd criterion matching as fulltext filter.put("a", "a"); fulltext.add("a"); assertEquals(1, dir.query(filter, fulltext).size()); // empty filter marked fulltext should match all filter.clear(); fulltext.clear(); filter.put("a", ""); fulltext.add("a"); assertEquals(1, dir.query(filter, fulltext).size()); } @Test public void testGetProjection() throws Exception { List<String> list; Map<String, Serializable> filter = new HashMap<String, Serializable>(); Map<String, Object> e2 = new HashMap<String, Object>(); e2.put("i", "2"); e2.put("pw", "guess"); e2.put("a", "AAA222"); e2.put("b", "BCD"); dir.createEntry(e2); // empty filter list = dir.getProjection(filter, "a"); assertEquals(2, list.size()); // XXX test projection on unknown column // simple query filter.put("a", "AAA"); list = dir.getProjection(filter, "b"); assertEquals(1, list.size()); assertEquals("BCD", list.get(0)); // add unknown field filter.put("bobo", "bibi"); list = dir.getProjection(filter, "a"); assertEquals(1, list.size()); assertEquals("AAA", list.get(0)); // two criteria filter.clear(); filter.put("a", "AAA"); filter.put("b", "BCD"); list = dir.getProjection(filter, "a"); assertEquals(1, list.size()); assertEquals("AAA", list.get(0)); // query not matching although each criterion matches one entry filter.put("a", "AAA"); filter.put("pw", "guess"); list = dir.getProjection(filter, "a"); assertEquals(0, list.size()); } protected static List<String> entryIds(List<DocumentModel> entries) { List<String> ids = new ArrayList<String>(entries.size()); for (DocumentModel entry : entries) { ids.add(entry.getId()); } return ids; } // actually tests AbstractDirectory.orderEntry @Test public void testOrderBy() throws Exception { Map<String, Object> e2 = new HashMap<String, Object>(); e2.put("i", "2"); e2.put("pw", "guess"); e2.put("a", "ZZZ"); e2.put("b", "AAA"); dir.createEntry(e2); Map<String, Serializable> filter = Collections.emptyMap(); Set<String> fulltext = Collections.emptySet(); Map<String, String> orderBy = new LinkedHashMap<String, String>(); // our data: // 1 -> AAA, BCD // 2 -> ZZZ, AAA // a orderBy.clear(); orderBy.put("a", "asc"); DocumentModelList entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); orderBy.put("a", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); // b orderBy.clear(); orderBy.put("b", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); orderBy.put("b", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); // a then b orderBy.clear(); orderBy.put("a", "asc"); orderBy.put("b", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); orderBy.clear(); orderBy.put("a", "asc"); orderBy.put("b", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); orderBy.clear(); orderBy.put("a", "desc"); orderBy.put("b", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); orderBy.clear(); orderBy.put("a", "desc"); orderBy.put("b", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); // b then a orderBy.clear(); orderBy.put("b", "asc"); orderBy.put("a", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); orderBy.clear(); orderBy.put("b", "asc"); orderBy.put("a", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); orderBy.clear(); orderBy.put("b", "desc"); orderBy.put("a", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); orderBy.clear(); orderBy.put("b", "desc"); orderBy.put("a", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); // with an equality case DocumentModel entry = dir.getEntry("2"); entry.setProperty(SCHEMA_NAME, "a", "AAA"); dir.updateEntry(entry); // our data: // 1 -> AAA, BCD // 2 -> AAA, AAA orderBy.clear(); orderBy.put("a", "asc"); orderBy.put("b", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); orderBy.clear(); orderBy.put("a", "asc"); orderBy.put("b", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); orderBy.clear(); orderBy.put("a", "desc"); orderBy.put("b", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("2", "1"), entryIds(entries)); orderBy.clear(); orderBy.put("a", "desc"); orderBy.put("b", "desc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); // check number ordering entry = dir.getEntry("1"); entry.setProperty(SCHEMA_NAME, "int", 2); dir.updateEntry(entry); entry = dir.getEntry("2"); entry.setProperty(SCHEMA_NAME, "int", 10); dir.updateEntry(entry); orderBy.clear(); orderBy.put("a", "asc"); entries = dir.query(filter, fulltext, orderBy); assertEquals(Arrays.asList("1", "2"), entryIds(entries)); } @Test public void testServiceUnregistration() throws Exception { MemoryDirectoryDescriptor descr = new MemoryDirectoryDescriptor(); descr.name = "mydir"; descr.schemaName = SCHEMA_NAME; descr.idField = "i"; descr.passwordField = "pw"; descr.schemaSet = new HashSet<>(Arrays.asList("i")); deployBundle("org.nuxeo.ecm.directory"); DirectoryService service = Framework.getService(DirectoryService.class); service.registerDirectoryDescriptor(descr); Directory dir = service.getDirectory("mydir"); assertNotNull(dir); List<Directory> dirs = service.getDirectories(); assertEquals(1, dirs.size()); assertNotNull(dirs.get(0)); assertEquals(dir, dirs.get(0)); service.unregisterDirectoryDescriptor(descr); dir = service.getDirectory("mydir"); assertNull(dir); dirs = service.getDirectories(); assertEquals(0, dirs.size()); } }