Integrated lite controllers, services and tests in full version.

Change-Id: I14f9437d9cae6418b3b89bbfee810f95a0e74832
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManagerTest.java b/full/src/test/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManagerTest.java
index d29960b..7c27553 100644
--- a/full/src/test/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManagerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManagerTest.java
@@ -11,7 +11,6 @@
 import de.ids_mannheim.korap.config.BeanConfigTest;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.user.KorAPUser;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.UserDetails;
@@ -27,16 +26,16 @@
 public class KustvaktAuthenticationManagerTest extends BeanConfigTest {
 
     @Autowired
-    private AuthenticationManagerIface authManager;
+    private AuthenticationManager authenticationManager;
     
     @After
     public void after () {
         try {
-            User user = authManager
+            User user = authenticationManager
                     .getUser(
                             (String) KustvaktConfiguration.KUSTVAKT_USER
                                     .get(Attributes.USERNAME));
-            authManager
+            authenticationManager
                     .deleteAccount(user);
         }
         catch (KustvaktException e) {}
@@ -56,11 +55,11 @@
     @Test
     @Ignore
     public void testUserdetailsGet () throws KustvaktException {
-        User user = authManager
+        User user = authenticationManager
                 .getUser((String) KustvaktConfiguration.KUSTVAKT_USER
                         .get(Attributes.USERNAME));
 
-        Userdata data = authManager.getUserData(user, UserDetails.class);
+        Userdata data = authenticationManager.getUserData(user, UserDetails.class);
         assertNotNull(data);
     }
 
@@ -68,11 +67,11 @@
     @Test
     @Ignore
     public void testUsersettingsGet () throws KustvaktException {
-        User user = authManager
+        User user = authenticationManager
                 .getUser((String) KustvaktConfiguration.KUSTVAKT_USER
                         .get(Attributes.USERNAME));
 
-        Userdata data = authManager.getUserData(user, UserSettings.class);
+        Userdata data = authenticationManager.getUserData(user, UserSettings.class);
         assertNotNull(data);
     }
 
@@ -80,14 +79,14 @@
     @Test(expected = KustvaktException.class)
     public void testUserDetailsGetNonExistent () throws KustvaktException {
         User user = new KorAPUser(10, "random");
-        authManager.getUserData(user, UserDetails.class);
+        authenticationManager.getUserData(user, UserDetails.class);
     }
 
 
     @Test(expected = KustvaktException.class)
     public void testUserSettingsGetNonExistent () throws KustvaktException {
         User user = new KorAPUser(10, "random");
-        authManager.getUserData(user, UserSettings.class);
+        authenticationManager.getUserData(user, UserSettings.class);
     }
 
 
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java b/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java
index 6ef8f65..bb1923d 100644
--- a/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java
+++ b/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java
@@ -2,7 +2,7 @@
 
 import java.util.List;
 
-import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.authentication.AuthenticationManager;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
@@ -27,6 +27,6 @@
 
 	public  EncryptionIface getCrypto();
 
-	public  AuthenticationManagerIface getAuthManager();
+	public  AuthenticationManager getAuthManager();
 
 }
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java
index 93ce643..fd33b90 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/SearchControllerTest.java
@@ -178,7 +178,7 @@
         JsonNode node = JsonUtils.readTree(entity);
         assertNotNull(node);
         assertNotEquals(0, node.path("matches").size());
-        System.out.println(node);
+//        System.out.println(node);
         assertEquals("koral:docGroup", node.at("/collection/@type").asText());
         assertEquals("CC-BY.*",
                 node.at("/collection/operands/0/value").asText());
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerAdminTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerAdminTest.java
index 41d6f99..fb0a22c 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerAdminTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerAdminTest.java
@@ -120,7 +120,6 @@
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         String entity = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(4, node.size());
 
         boolean containsHiddenStatus = false;
         for (int i = 0; i < node.size(); i++) {
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteJerseyTest.java b/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteJerseyTest.java
new file mode 100644
index 0000000..1846495
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteJerseyTest.java
@@ -0,0 +1,54 @@
+package de.ids_mannheim.korap.web.lite.controller;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.springframework.web.context.ContextLoaderListener;
+
+import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
+import com.sun.jersey.test.framework.AppDescriptor;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
+import com.sun.jersey.test.framework.spi.container.TestContainerException;
+import com.sun.jersey.test.framework.spi.container.TestContainerFactory;
+import com.sun.jersey.test.framework.spi.container.grizzly.web.GrizzlyWebTestContainerFactory;
+
+public class LiteJerseyTest  extends JerseyTest{
+
+    public static final String API_VERSION = "v1.0";
+    private static String[] classPackages =
+            new String[] { "de.ids_mannheim.korap.web.controller",
+                    "de.ids_mannheim.korap.web.filter",
+                    "de.ids_mannheim.korap.web.utils" };
+    @Override
+    protected TestContainerFactory getTestContainerFactory ()
+            throws TestContainerException {
+        return new GrizzlyWebTestContainerFactory();
+    }
+
+    @Override
+    protected AppDescriptor configure () {
+        return new WebAppDescriptor.Builder(classPackages)
+                .servletClass(SpringServlet.class)
+                .contextListenerClass(ContextLoaderListener.class)
+                .contextParam("contextConfigLocation",
+                        "classpath:lite-config.xml")
+                .build();
+    }
+
+    @Override
+    protected int getPort (int defaultPort) {
+        int port = ThreadLocalRandom.current().nextInt(5000, 8000 + 1);
+        try {
+            ServerSocket socket = new ServerSocket(port);
+            socket.close();
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+            port = getPort(port);
+        }
+        return port;
+    }
+    
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteSearchControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteSearchControllerTest.java
new file mode 100644
index 0000000..9e1d779
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteSearchControllerTest.java
@@ -0,0 +1,377 @@
+package de.ids_mannheim.korap.web.lite.controller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Iterator;
+
+import javax.ws.rs.core.MediaType;
+
+import org.eclipse.jetty.http.HttpStatus;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.net.HttpHeaders;
+import com.sun.jersey.api.client.ClientResponse;
+
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.query.serialize.QuerySerializer;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class LiteSearchControllerTest extends LiteJerseyTest {
+
+    @Test
+    public void testGetJSONQuery () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("query")
+                .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
+                .queryParam("context", "sentence").queryParam("count", "13")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals("orth", node.at("/query/wrap/layer").asText());
+        assertEquals("opennlp", node.at("/query/wrap/foundry").asText());
+        assertEquals("sentence", node.at("/meta/context").asText());
+        assertEquals("13", node.at("/meta/count").asText());
+    }
+
+    @Test
+    public void testbuildAndPostQuery () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("query")
+                .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
+                .queryParam("cq", "corpusSigle=WPD | corpusSigle=GOE")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+
+        response = resource().path(API_VERSION).path("search")
+                .post(ClientResponse.class, query);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String matches = response.getEntity(String.class);
+        JsonNode match_node = JsonUtils.readTree(matches);
+        assertNotEquals(0, match_node.path("matches").size());
+    }
+
+    @Test
+    public void testQueryGet () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
+                .queryParam("context", "sentence").queryParam("count", "13")
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals("orth", node.at("/query/wrap/layer").asText());
+        assertEquals("base/s:s", node.at("/meta/context").asText());
+        assertEquals("13", node.at("/meta/count").asText());
+        assertNotEquals(0, node.at("/matches").size());
+    }
+
+    @Test
+    public void testQueryFailure () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[orth=das").queryParam("ql", "poliqarp")
+                .queryParam("cq", "corpusSigle=WPD | corpusSigle=GOE")
+                .queryParam("count", "13").get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals(302, node.at("/errors/0/0").asInt());
+        assertEquals(302, node.at("/errors/1/0").asInt());
+        assertTrue(node.at("/errors/2").isMissingNode());
+        assertFalse(node.at("/collection").isMissingNode());
+        assertEquals(13, node.at("/meta/count").asInt());
+    }
+
+    @Test
+    public void testFoundryRewrite () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
+                .queryParam("context", "sentence").queryParam("count", "13")
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals("orth", node.at("/query/wrap/layer").asText());
+        assertEquals("opennlp", node.at("/query/wrap/foundry").asText());
+    }
+
+    @Test
+    public void testQueryPost () throws KustvaktException {
+        QuerySerializer s = new QuerySerializer();
+        s.setQuery("[orth=das]", "poliqarp");
+
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .post(ClientResponse.class, s.toJSON());
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals("orth", node.at("/query/wrap/layer").asText());
+        assertNotEquals(0, node.at("/matches").size());
+    }
+
+    @Test
+    public void testParameterField () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
+                .queryParam("fields", "author, docSigle")
+                .queryParam("context", "sentence").queryParam("count", "13")
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals("orth", node.at("/query/wrap/layer").asText());
+        assertNotEquals(0, node.at("/matches").size());
+        assertEquals("[\"author, docSigle\"]",
+                node.at("/meta/fields").toString());
+    }
+
+    @Test
+    public void testMatchInfoGetWithoutSpans () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION)
+                .path("corpus/GOE/AGA/01784/p36-46(5)37-45(2)38-42/matchInfo")
+                .queryParam("foundry", "*").queryParam("spans", "false")
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String ent = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(ent);
+        assertNotNull(node);
+        assertEquals("GOE/AGA/01784", node.at("/textSigle").asText());
+        assertEquals("match-GOE/AGA/01784-p36-46(5)37-45(2)38-42",
+                node.at("/matchID").asText());
+        assertEquals("Belagerung von Mainz", node.at("/title").asText());
+    };
+
+    @Test
+    public void testMatchInfoGetWithoutHighlights () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION)
+                .path("corpus/GOE/AGA/01784/p36-46(5)37-45(2)38-42/matchInfo")
+                .queryParam("foundry", "xy").queryParam("spans", "false")
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String ent = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(ent);
+        assertNotNull(node);
+        assertEquals(
+                "<span class=\"context-left\"></span><span class=\"match\">der alte freie Weg nach Mainz war gesperrt, ich mußte über die Schiffbrücke bei Rüsselsheim; in Ginsheim ward <mark>gefüttert; der Ort ist sehr zerschossen; dann über die Schiffbrücke</mark> auf die Nonnenaue, wo viele Bäume niedergehauen lagen, sofort auf dem zweiten Teil der Schiffbrücke über den größern Arm des Rheins.</span><span class=\"context-right\"></span>",
+                node.at("/snippet").asText());
+        assertEquals("GOE/AGA/01784", node.at("/textSigle").asText());
+        assertEquals("match-GOE/AGA/01784-p36-46(5)37-45(2)38-42",
+                node.at("/matchID").asText());
+        assertEquals("Belagerung von Mainz", node.at("/title").asText());
+    };
+
+    @Test
+    public void testMatchInfoGetWithHighlights () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION)
+                .path("corpus/GOE/AGA/01784/p36-46(5)37-45(2)38-42/matchInfo")
+                .queryParam("foundry", "xy").queryParam("spans", "false")
+                .queryParam("hls", "true").get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String ent = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(ent);
+        assertNotNull(node);
+        assertEquals("GOE/AGA/01784", node.at("/textSigle").asText());
+        assertEquals(
+                "<span class=\"context-left\"></span><span class=\"match\">"
+                        + "der alte freie Weg nach Mainz war gesperrt, ich mußte über die "
+                        + "Schiffbrücke bei Rüsselsheim; in Ginsheim ward <mark>gefüttert; "
+                        + "<mark class=\"class-5 level-0\">der <mark class=\"class-2 level-1\">"
+                        + "Ort ist sehr zerschossen; dann</mark> über die Schiffbrücke</mark></mark> "
+                        + "auf die Nonnenaue, wo viele Bäume niedergehauen lagen, sofort auf dem "
+                        + "zweiten Teil der Schiffbrücke über den größern Arm des Rheins.</span>"
+                        + "<span class=\"context-right\"></span>",
+                node.at("/snippet").asText());
+        assertEquals("match-GOE/AGA/01784-p36-46(5)37-45(2)38-42",
+                node.at("/matchID").asText());
+        assertEquals("Belagerung von Mainz", node.at("/title").asText());
+    };
+
+    @Test
+    public void testMatchInfoGet2 () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION)
+
+                .path("corpus/GOE/AGA/01784/p36-46/matchInfo")
+                .queryParam("foundry", "*").get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String ent = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(ent);
+        assertNotNull(node);
+        assertEquals("GOE/AGA/01784", node.at("/textSigle").asText());
+        assertEquals("Belagerung von Mainz", node.at("/title").asText());
+    };
+
+    @Test
+    public void testCollectionQueryParameter () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("query")
+                .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
+                .queryParam("fields", "author, docSigle")
+                .queryParam("context", "sentence").queryParam("count", "13")
+                .queryParam("cq", "textClass=Politik & corpus=WPD")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals("orth", node.at("/query/wrap/layer").asText());
+        assertEquals("Politik",
+                node.at("/collection/operands/0/value").asText());
+        assertEquals("WPD", node.at("/collection/operands/1/value").asText());
+
+        response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
+                .queryParam("fields", "author, docSigle")
+                .queryParam("context", "sentence").queryParam("count", "13")
+                .queryParam("cq", "textClass=Politik & corpus=WPD")
+                .get(ClientResponse.class);
+        // String version =
+        // LucenePackage.get().getImplementationVersion();;
+        // System.out.println("VERSION "+ version);
+        // System.out.println("RESPONSE "+ response);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        query = response.getEntity(String.class);
+        node = JsonUtils.readTree(query);
+        assertNotNull(node);
+        assertEquals("orth", node.at("/query/wrap/layer").asText());
+        assertEquals("Politik",
+                node.at("/collection/operands/0/value").asText());
+        assertEquals("WPD", node.at("/collection/operands/1/value").asText());
+    }
+
+    @Test
+    public void testMetaFields () throws KustvaktException {
+        ClientResponse response =
+                resource().path(API_VERSION).path("/corpus/GOE/AGA/01784")
+                        .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String resp = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(resp);
+        // System.err.println(node.toString());
+
+        Iterator<JsonNode> fieldIter = node.at("/document/fields").elements();
+
+        int checkC = 0;
+        while (fieldIter.hasNext()) {
+            JsonNode field = (JsonNode) fieldIter.next();
+
+            String key = field.at("/key").asText();
+
+            assertEquals("koral:field", field.at("/@type").asText());
+
+            switch (key) {
+                case "textSigle":
+                    assertEquals("type:string", field.at("/type").asText());
+                    assertEquals("GOE/AGA/01784", field.at("/value").asText());
+                    checkC++;
+                    break;
+                case "author":
+                    assertEquals("type:text", field.at("/type").asText());
+                    assertEquals("Goethe, Johann Wolfgang von",
+                            field.at("/value").asText());
+                    checkC++;
+                    break;
+                case "docSigle":
+                    assertEquals("type:string", field.at("/type").asText());
+                    assertEquals("GOE/AGA", field.at("/value").asText());
+                    checkC++;
+                    break;
+                case "docTitle":
+                    assertEquals("type:text", field.at("/type").asText());
+                    assertEquals(
+                            "Goethe: Autobiographische Schriften II, (1817-1825, 1832)",
+                            field.at("/value").asText());
+                    checkC++;
+                    break;
+                case "pubDate":
+                    assertEquals("type:date", field.at("/type").asText());
+                    assertEquals(1982, field.at("/value").asInt());
+                    checkC++;
+                    break;
+            };
+        };
+        assertEquals(5, checkC);
+    };
+
+    @Test
+    public void testSearchWithoutVersion () throws KustvaktException {
+        ClientResponse response = resource().path("api").path("search")
+                .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
+                .accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
+        assertEquals(HttpStatus.PERMANENT_REDIRECT_308, response.getStatus());
+        URI location = response.getLocation();
+        assertEquals("/api/v1.0/search", location.getPath());
+    }
+
+    @Test
+    public void testSearchWrongVersion () throws KustvaktException {
+        ClientResponse response = resource().path("api").path("v0.2")
+                .path("search").queryParam("q", "[orth=der]")
+                .queryParam("ql", "poliqarp").accept(MediaType.APPLICATION_JSON)
+                .get(ClientResponse.class);
+        assertEquals(HttpStatus.PERMANENT_REDIRECT_308, response.getStatus());
+        URI location = response.getLocation();
+        assertEquals("/api/v1.0/search", location.getPath());
+    }
+
+    @Test
+    public void testSearchWithIP () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "Wasser").queryParam("ql", "poliqarp")
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertTrue(node.at("/collection").isMissingNode());
+    }
+
+    @Test
+    public void testSearchWithAuthorizationHeader () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "Wasser").queryParam("ql", "poliqarp")
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("test", "pwd"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertTrue(node.at("/collection").isMissingNode());
+    }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteStatisticControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteStatisticControllerTest.java
new file mode 100644
index 0000000..e974c69
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/lite/controller/LiteStatisticControllerTest.java
@@ -0,0 +1,59 @@
+package de.ids_mannheim.korap.web.lite.controller;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.api.client.ClientResponse;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class LiteStatisticControllerTest extends LiteJerseyTest{
+
+    @Test
+    public void testStatistics () throws KustvaktException{
+        ClientResponse response = resource().path(API_VERSION)
+                .path("statistics")
+                .queryParam("corpusQuery", "textType=Autobiographie & corpusSigle=GOE")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertEquals(9, node.at("/documents").asInt());
+        assertEquals(527662, node.at("/tokens").asInt());
+        assertEquals(19387, node.at("/sentences").asInt());
+        assertEquals(514, node.at("/paragraphs").asInt());
+    }
+
+    @Test
+    public void testEmptyStatistics () throws KustvaktException{
+        ClientResponse response = resource().path(API_VERSION)
+            .path("statistics")
+            .queryParam("corpusQuery", "")
+            .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String query = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(query);
+        assertEquals(11, node.at("/documents").asInt());
+        assertEquals(665842, node.at("/tokens").asInt());
+        assertEquals(25074, node.at("/sentences").asInt());
+        assertEquals(772, node.at("/paragraphs").asInt());
+
+        response = resource().path(API_VERSION)
+                .path("statistics")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        query = response.getEntity(String.class);
+        node = JsonUtils.readTree(query);
+        assertEquals(11, node.at("/documents").asInt());
+        assertEquals(665842, node.at("/tokens").asInt());
+        assertEquals(25074, node.at("/sentences").asInt());
+        assertEquals(772, node.at("/paragraphs").asInt());
+    }
+    
+}
diff --git a/full/src/test/resources/kustvakt-test.conf b/full/src/test/resources/kustvakt-test.conf
index 356d46e..b1d9e21 100644
--- a/full/src/test/resources/kustvakt-test.conf
+++ b/full/src/test/resources/kustvakt-test.conf
@@ -12,9 +12,8 @@
 ldap.config = file-path-to-ldap-config
 
 # Kustvakt
-
-current.api.version = v1.1
 # multiple versions separated by space
+current.api.version = v1.1
 supported.api.version = v0.1 v1.0
 
 ## server
diff --git a/full/src/test/resources/test-config.xml b/full/src/test/resources/test-config.xml
index 26dc607..a0bc2ce 100644
--- a/full/src/test/resources/test-config.xml
+++ b/full/src/test/resources/test-config.xml
@@ -158,16 +158,20 @@
 	</bean>
 
 	<!-- Data access objects -->
+	<bean id="adminDao" class="de.ids_mannheim.korap.dao.AdminDaoImpl" />
 	<bean id="resourceDao" class="de.ids_mannheim.korap.dao.ResourceDao" />
 	<bean id="accessScopeDao" class="de.ids_mannheim.korap.oauth2.dao.AccessScopeDao" />
-	<bean id="authorizationDao" class="de.ids_mannheim.korap.oauth2.dao.AuthorizationCacheDao" />
+	<bean id="authorizationDao" class="de.ids_mannheim.korap.oauth2.dao.CachedAuthorizationDaoImpl" />
+	
+	<!-- Services -->
+	<bean id="scopeService" class="de.ids_mannheim.korap.oauth2.service.OAuth2ScopeServiceImpl" />
 	
 	<!-- props are injected from default-config.xml -->
 	<bean id="kustvakt_config" class="de.ids_mannheim.korap.config.FullConfiguration">
 		<constructor-arg name="properties" ref="props" />
 	</bean>
 
-	<bean id="initializator" class="de.ids_mannheim.korap.config.Initializator"
+	<bean id="initializator" class="de.ids_mannheim.de.init.InitializatorImpl"
 		init-method="initTest">
 	</bean>
 
@@ -189,7 +193,7 @@
 		<constructor-arg value="http,https" />
 	</bean>
 
-	<bean id="kustvakt_rewrite" class="de.ids_mannheim.korap.rewrite.FullRewriteHandler">
+	<bean id="rewriteHandler" class="de.ids_mannheim.korap.rewrite.FullRewriteHandler">
 		<constructor-arg ref="kustvakt_config" />
 	</bean>
 
@@ -288,7 +292,7 @@
 	</util:list>
 
 	<!-- specify type for constructor argument -->
-	<bean id="kustvakt_authenticationmanager"
+	<bean id="authenticationManager"
 		class="de.ids_mannheim.korap.authentication.KustvaktAuthenticationManager">
 		<constructor-arg type="de.ids_mannheim.korap.interfaces.EntityHandlerIface"
 			ref="kustvakt_userdb" />