Added and updated VC controller tests

Change-Id: Ifb9a3ca7f4358af57bdf862f951885b880967336
diff --git a/full/Changes b/full/Changes
index 6f89192..96d8e39 100644
--- a/full/Changes
+++ b/full/Changes
@@ -4,7 +4,8 @@
   for mounting into docker
 - Added an error for missing redirect uri in a token request 
   when it has been included in the authorization request.
-- Added tests for VC sharing and for OAuth2 client using VC services    
+- Added tests for VC sharing and for OAuth2 client using VC services
+- Added and updated VC controller tests
 
 # version 0.69.4
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
index 01e6bcd..e421a70 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
@@ -2,7 +2,6 @@
 
 import java.util.List;
 
-import javax.validation.constraints.Email;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusAccessTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusAccessTest.java
new file mode 100644
index 0000000..1fb98b8
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusAccessTest.java
@@ -0,0 +1,189 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertEquals;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.http.HttpStatus;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.constant.ResourceType;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class VirtualCorpusAccessTest extends VirtualCorpusTestBase {
+    private String testUser = "VirtualCorpusAccessTest";
+
+    @Test
+    public void testlistAccessByNonVCAAdmin () throws KustvaktException {
+        JsonNode node = listAccessByGroup("nemo", "dory-group");
+        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Unauthorized operation for user: nemo",
+                node.at("/errors/0/1").asText());
+    }
+
+    // @Test
+    // public void testlistAccessMissingId () throws KustvaktException
+    // {
+    // Response response =
+    // target().path(API_VERSION).path("vc")
+    // .path("access")
+    // .request().header(Attributes.AUTHORIZATION,
+    // HttpAuthorizationHandler
+    // .createBasicAuthorizationHeaderValue(
+    // testUser, "pass"))
+    // .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+    // .get();
+    // String entity = response.readEntity(String.class);
+    // JsonNode node = JsonUtils.readTree(entity);
+    // assertEquals(Status.BAD_REQUEST.getStatusCode(),
+    // response.getStatus());
+    // assertEquals(StatusCodes.MISSING_PARAMETER,
+    // node.at("/errors/0/0").asInt());
+    // assertEquals("vcId", node.at("/errors/0/1").asText());
+    // }
+
+    @Test
+    public void testlistAccessByGroup () throws KustvaktException {
+        Response response = target().path(API_VERSION).path("vc").path("access")
+                .queryParam("groupName", "dory-group").request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("dory", "pass"))
+                .get();
+        String entity = response.readEntity(String.class);
+        // System.out.println(entity);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(1, node.at("/0/accessId").asInt());
+        assertEquals(2, node.at("/0/queryId").asInt());
+        assertEquals("group-vc", node.at("/0/queryName").asText());
+        assertEquals(2, node.at("/0/userGroupId").asInt());
+
+        assertEquals("dory-group", node.at("/0/userGroupName").asText());
+    }
+    
+    @Test
+    public void testDeleteSharedVC () throws KustvaktException {
+        String json =
+                "{\"type\": \"PROJECT\"" + ",\"queryType\": \"VIRTUAL_CORPUS\""
+                        + ",\"corpusQuery\": \"corpusSigle=GOE\"}";
+        String vcName = "new_project_vc";
+        
+        String username = "dory";
+        String authHeader = HttpAuthorizationHandler
+                .createBasicAuthorizationHeaderValue(username, "pass");
+
+        createVC(authHeader, username, vcName, json);
+        
+        String groupName = "dory-group";
+        testShareVCByCreator(username, vcName, groupName);
+        JsonNode node = listAccessByGroup(username, groupName);
+        assertEquals(2, node.size());
+        
+        // delete project VC
+        deleteVC(vcName, username, username);
+        
+        node = listAccessByGroup(username, groupName);
+        assertEquals(1, node.size());
+    }
+
+    @Test
+    public void testCreateDeleteAccess ()
+            throws ProcessingException, KustvaktException {
+
+        String vcName = "marlin-vc";
+        String groupName = "marlin-group";
+
+        // check the vc type
+        JsonNode node = retrieveVCInfo("marlin", "marlin", vcName);
+        assertEquals(vcName, node.at("/name").asText());
+        assertEquals("private", node.at("/type").asText());
+
+        // share vc to group
+        Response response = testShareVCByCreator("marlin", vcName, groupName);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        // check the vc type
+        node = retrieveVCInfo("marlin", "marlin", vcName);
+        assertEquals("project", node.at("/type").asText());
+
+        // list vc access by marlin
+        node = listAccessByGroup("marlin", groupName);
+        assertEquals(2, node.size());
+        
+        // get access id
+        node = node.get(1);
+        assertEquals(5, node.at("/queryId").asInt());
+        assertEquals(vcName, node.at("/queryName").asText());
+        assertEquals(1, node.at("/userGroupId").asInt());
+        assertEquals(groupName, node.at("/userGroupName").asText());
+
+        String accessId = node.at("/accessId").asText();
+
+        testShareVC_nonUniqueAccess("marlin", vcName, groupName);
+        
+        // delete unauthorized
+        response = testDeleteAccess(testUser, accessId);
+        testResponseUnauthorized(response, testUser);
+        
+        // delete access by vc-admin
+        // dory is a vc-admin in marlin group
+        response = testDeleteAccess("dory", accessId);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        // list vc access by dory
+        node = listAccessByGroup("dory", groupName);
+        assertEquals(1, node.size());
+
+        // edit VC back to private
+        String json = "{\"type\": \"" + ResourceType.PRIVATE + "\"}";
+        editVC("marlin", "marlin", vcName, json);
+        node = retrieveVCInfo("marlin", "marlin", vcName);
+        assertEquals(ResourceType.PRIVATE.displayName(),
+                node.at("/type").asText());
+    }
+
+    private void testShareVC_nonUniqueAccess (String vcCreator, String vcName,
+            String groupName) throws ProcessingException, KustvaktException {
+        Response response = testShareVCByCreator(vcCreator, vcName, groupName);
+        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
+        assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
+        assertEquals(StatusCodes.DB_INSERT_FAILED,
+                node.at("/errors/0/0").asInt());
+
+        // EM: message differs depending on the database used
+        // for testing. The message below is from sqlite.
+        // assertTrue(node.at("/errors/0/1").asText()
+        // .startsWith("[SQLITE_CONSTRAINT_UNIQUE]"));
+    }
+
+    private Response testDeleteAccess (String username, String accessId)
+            throws ProcessingException, KustvaktException {
+        Response response = target().path(API_VERSION).path("vc").path("access")
+                .path(accessId).request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(username, "pass"))
+                .delete();
+
+        return response;
+    }
+
+
+    @Test
+    public void testDeleteNonExistingAccess ()
+            throws ProcessingException, KustvaktException {
+        Response response = testDeleteAccess("dory", "100");
+        assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+
+        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
+        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+                node.at("/errors/0/0").asInt());
+    }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusClientTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusClientTest.java
index 3315d57..277b5ab 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusClientTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusClientTest.java
@@ -18,7 +18,7 @@
     private String username = "VirtualCorpusClientTest";
 
     @Test
-    public void testVirtualCorpusWithClient () throws KustvaktException {
+    public void testVC_withClient () throws KustvaktException {
         // create client
         Response response = registerConfidentialClient(username);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -41,18 +41,28 @@
 
         String accessTokenHeader = "Bearer " + accessToken;
 
-        // create VC
+        // create VC 1
         String vcName = "vc-client1";
         String vcJson =
                 "{\"type\": \"PRIVATE\"" + ",\"queryType\": \"VIRTUAL_CORPUS\""
                         + ",\"corpusQuery\": \"creationDate since 1820\"}";
         createVC(accessTokenHeader, username, vcName, vcJson);
-
+        
+        // create VC 2
         vcName = "vc-client2";
         vcJson = "{\"type\": \"PRIVATE\"" + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + ",\"corpusQuery\": \"creationDate until 1820\"}";
         createVC(accessTokenHeader, username, vcName, vcJson);
 
+        // edit VC
+        String description = "vc created from client";
+        vcJson = "{\"description\": \""+description+"\"}";
+        editVC(username, username, vcName, vcJson);
+        
+        // retrieve vc info
+        node = retrieveVCInfo(username, username, vcName);
+        assertEquals(description, node.at("/description").asText());
+
         // list vc
         node = listVCWithAuthHeader(accessTokenHeader);
         assertEquals(3, node.size());
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerAdminTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerAdminTest.java
index 2738f0e..6063f0c 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerAdminTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerAdminTest.java
@@ -10,7 +10,6 @@
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.http.entity.ContentType;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -20,7 +19,6 @@
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
 /**
@@ -32,106 +30,6 @@
     private String admin = "admin";
     private String testUser = "VirtualCorpusControllerAdminTest";
 
-    private void testResponseUnauthorized (Response response) throws KustvaktException {
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: " + testUser,
-                node.at("/errors/0/1").asText());
-    }
-    
-    @Test
-    public void testRetrievePrivateVC () throws
-            ProcessingException, KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path("dory-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .get();
-
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-
-        assertEquals(1, node.at("/id").asInt());
-        assertEquals("dory-vc", node.at("/name").asText());
-    }
-    
-    @Test
-    public void testRetrievePrivateVCUnauthorized ()
-            throws ProcessingException, KustvaktException {
-        Response response = target().path(API_VERSION).path("vc").path("~dory")
-                .path("dory-vc").request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(testUser, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32").get();
-
-        testResponseUnauthorized(response);
-    }
-
-    @Test
-    public void testRetrieveProjectVC () throws
-            ProcessingException, KustvaktException {
-
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path("group-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .get();
-        String entity = response.readEntity(String.class);
-
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals("group-vc", node.at("/name").asText());
-        assertEquals(ResourceType.PROJECT.displayName(),
-                node.at("/type").asText());
-    }
-
-    
-    @Test
-    public void testRetrieveProjectVCUnauthorized () throws
-            ProcessingException, KustvaktException {
-
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path("group-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(testUser, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .get();
-        testResponseUnauthorized(response);
-    }
-
-    @Ignore
-    @Deprecated
-    @Test
-    public void testListUserVC () throws
-            ProcessingException, KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .queryParam("username", "dory")
-                .request()
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .get();
-
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(4, node.size());
-    }
-    
     private JsonNode testAdminListVC (String username)
             throws ProcessingException,
             KustvaktException {
@@ -200,7 +98,6 @@
                 .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .delete();
 
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -222,7 +119,6 @@
                 .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
                 .put(Entity.json(json));
 
@@ -247,7 +143,6 @@
                 .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
                 .put(Entity.json(json));
 
@@ -265,7 +160,6 @@
                 .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .delete();
 
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -307,7 +201,6 @@
                 .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .get();
         String entity = response.readEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
@@ -334,7 +227,11 @@
         node2 = testAdminListVC_UsingAdminToken(vcCreator,ResourceType.PROJECT);
         assertEquals(1, node2.size());
         
-        editVCType(admin, vcCreator, vcName, ResourceType.PRIVATE);
+        String json = "{\"type\": \"" + ResourceType.PRIVATE + "\"}";
+        editVC(admin, vcCreator, vcName, json);
+        node = retrieveVCInfo(admin, vcCreator, vcName);
+        assertEquals(ResourceType.PRIVATE.displayName(),
+                node.at("/type").asText());
         
         node2 = testAdminListVC_UsingAdminToken(vcCreator,ResourceType.PROJECT);
         assertEquals(0, node2.size());
@@ -350,7 +247,6 @@
                 .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .post(Entity.form(new Form()));
 
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
@@ -366,7 +262,6 @@
                 .request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(admin, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .delete();
 
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
index 26583de..3c67974 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
@@ -1,8 +1,5 @@
 package de.ids_mannheim.korap.web.controller;
 
-import static org.hamcrest.CoreMatchers.hasItem;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -10,21 +7,13 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
 
 import javax.ws.rs.ProcessingException;
 import javax.ws.rs.client.Entity;
-import javax.ws.rs.core.Form;
-import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.apache.http.HttpStatus;
 import org.apache.http.entity.ContentType;
-import org.glassfish.jersey.server.ContainerRequest;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -46,20 +35,6 @@
 
     private String testUser = "vcControllerTest";
 
-    private void checkWWWAuthenticateHeader (Response response) {
-        Set<Entry<String, List<Object>>> headers =
-                response.getHeaders().entrySet();
-
-        for (Entry<String, List<Object>> header : headers) {
-            System.out.println(header.toString());
-            if (header.getKey().equals(ContainerRequest.WWW_AUTHENTICATE)) {
-                assertThat(header.getValue(), not(hasItem("Api realm=\"Kustvakt\"")));
-                assertThat(header.getValue(), hasItem("Bearer realm=\"Kustvakt\""));
-                assertThat(header.getValue(), hasItem("Basic realm=\"Kustvakt\""));
-            }
-        }
-    }
-    
     private String authHeader;
     
     public VirtualCorpusControllerTest () throws KustvaktException {
@@ -67,230 +42,6 @@
                 .createBasicAuthorizationHeaderValue(testUser, "pass");
     }
 
-    
-    private JsonNode testListOwnerVC (String username)
-            throws ProcessingException,
-            KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .queryParam("filter-by", "own")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(username, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .get();
-
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
-        String entity = response.readEntity(String.class);
-        return JsonUtils.readTree(entity);
-    }
-
-    @Test
-    public void testRetrieveSystemVCInfo () throws
-            ProcessingException, KustvaktException {
-
-        JsonNode node = retrieveVCInfo(testUser, "system", "system-vc");
-        assertEquals("system-vc", node.at("/name").asText());
-        assertEquals(ResourceType.SYSTEM.displayName(),
-                node.at("/type").asText());
-//        assertEquals("koral:doc", node.at("/koralQuery/collection/@type").asText());
-        assertTrue(node.at("/query").isMissingNode());
-        assertTrue(node.at("/queryLanguage").isMissingNode());
-    }
-
-    @Test
-    public void testRetrieveSystemVCGuest () throws
-            ProcessingException, KustvaktException {
-
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~system").path("system-vc")
-                .request()
-                .get();
-        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
-        assertEquals("system-vc", node.at("/name").asText());
-        assertEquals(ResourceType.SYSTEM.displayName(),
-                node.at("/type").asText());
-//        assertEquals(11, node.at("/numberOfDoc").asInt());
-//        assertEquals(772, node.at("/numberOfParagraphs").asInt());
-//        assertEquals(25074, node.at("/numberOfSentences").asInt());
-//        assertEquals(665842, node.at("/numberOfTokens").asInt());
-    }
-
-    @Test
-    public void testRetrieveOwnerPrivateVCInfo ()
-            throws ProcessingException,
-            KustvaktException {
-
-        JsonNode node = retrieveVCInfo("dory", "dory", "dory-vc");
-        assertEquals("dory-vc", node.at("/name").asText());
-        assertEquals(ResourceType.PRIVATE.displayName(),
-                node.at("/type").asText());
-    }
-
-    @Test
-    public void testRetrievePrivateVCInfoUnauthorized ()
-            throws ProcessingException,
-            KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path("dory-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, authHeader)
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .get();
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: " + testUser,
-                node.at("/errors/0/1").asText());
-
-        checkWWWAuthenticateHeader(response);
-    }
-
-    @Test
-    public void testRetrieveProjectVCInfo () throws
-            ProcessingException, KustvaktException {
-
-        JsonNode node = retrieveVCInfo("nemo", "dory", "group-vc");
-        assertEquals("group-vc", node.at("/name").asText());
-        assertEquals(ResourceType.PROJECT.displayName(),
-                node.at("/type").asText());
-    }
-
-    @Test
-    public void testRetrieveProjectVCInfoByNonActiveMember ()
-            throws ProcessingException,
-            KustvaktException {
-
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path("group-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("marlin", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .get();
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: marlin",
-                node.at("/errors/0/1").asText());
-
-        checkWWWAuthenticateHeader(response);
-    }
-
-    @Test
-    public void testRetrievePublishedVCInfo () throws
-            ProcessingException, KustvaktException {
-
-        JsonNode node = retrieveVCInfo("gill", "marlin", "published-vc");
-        assertEquals("published-vc", node.at("/name").asText());
-        assertEquals(ResourceType.PUBLISHED.displayName(),
-                node.at("/type").asText());
-
-        Form f = new Form();
-        f.param("status", "HIDDEN");
-        // check gill in the hidden group of the vc
-        Response response = target().path(API_VERSION)
-                .path("admin").path("group").path("list")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("admin", "pass"))
-                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED)
-                .post(Entity.form(f));
-
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-        String entity = response.readEntity(String.class);
-        node = JsonUtils.readTree(entity);
-        assertEquals(3, node.at("/0/id").asInt());
-        String members = node.at("/0/members").toString();
-        assertTrue(members.contains("\"userId\":\"gill\""));
-    }
-
-    @Test
-    public void testListAvailableVCNemo () throws
-            ProcessingException, KustvaktException {
-        JsonNode node = listVC("nemo");
-        assertEquals(3, node.size());
-
-    }
-
-    @Test
-    public void testListAvailableVCPearl () throws
-            ProcessingException, KustvaktException {
-        JsonNode node = listVC("pearl");
-        assertEquals(2, node.size());
-
-    }
-
-    @Test
-    public void testListAvailableVCDory () throws
-            ProcessingException, KustvaktException {
-        JsonNode node = listVC("dory");
-        assertEquals(4, node.size());
-    }
-
-    @Ignore
-    @Deprecated
-    @Test
-    public void testListAvailableVCByOtherUser ()
-            throws ProcessingException,
-            KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory")
-                .request()
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("pearl", "pass"))
-                .get();
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: pearl",
-                node.at("/errors/0/1").asText());
-
-        checkWWWAuthenticateHeader(response);
-    }
-
-    @Test
-    public void testListAvailableVCByGuest () throws
-            ProcessingException, KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .request()
-                .get();
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: guest",
-                node.at("/errors/0/1").asText());
-
-        checkWWWAuthenticateHeader(response);
-    }
-    
-    private void testListSystemVC () throws KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .queryParam("filter-by", "system")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("pearl", "pass"))
-                .get();
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(2, node.size());
-        assertEquals(ResourceType.SYSTEM.displayName(),
-                node.at("/0/type").asText());
-        assertEquals(ResourceType.SYSTEM.displayName(),
-                node.at("/1/type").asText());
-    }
-
     @Test
     public void testCreatePrivateVC () throws KustvaktException {
         String json = "{\"type\": \"PRIVATE\""
@@ -322,9 +73,8 @@
         createVC(authHeader, testUser, vcName, json);
         
         // test list owner vc
-        JsonNode node = testListOwnerVC(testUser);
-        assertEquals(1, node.size());
-        assertEquals(vcName, node.get(0).get("name").asText());
+        JsonNode node = retrieveVCInfo(testUser, testUser, vcName);
+        assertEquals(vcName, node.get("name").asText());
 
         // EM: check hidden access
         node = listAccessByGroup("admin", "");
@@ -449,12 +199,21 @@
 
         assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
         
-        testListSystemVC();
+        JsonNode node = listSystemVC("pearl");
+        assertEquals(2, node.size());
+        assertEquals(ResourceType.SYSTEM.displayName(),
+                node.at("/0/type").asText());
+        assertEquals(ResourceType.SYSTEM.displayName(),
+                node.at("/1/type").asText());
+        
         deleteVC(vcName, "system","admin");
+        
+        node = listSystemVC("pearl");
+        assertEquals(1, node.size());
     }        
     
     @Test
-    public void testCreateSystemVCUnauthorized () throws KustvaktException {
+    public void testCreateSystemVC_unauthorized () throws KustvaktException {
         String json = "{\"type\": \"SYSTEM\""
                 + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + ",\"corpusQuery\": \"creationDate since 1820\"}";
@@ -466,20 +225,11 @@
                 .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
                 .put(Entity.json(json));
 
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: " + testUser,
-                node.at("/errors/0/1").asText());
-
-        checkWWWAuthenticateHeader(response);
+        testResponseUnauthorized(response, testUser);
     }
 
     @Test
-    public void testCreateVCInvalidName () throws KustvaktException {
+    public void testCreateVC_invalidName () throws KustvaktException {
         String json = "{\"type\": \"PRIVATE\""
                 + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + ",\"corpusQuery\": \"creationDate since 1820\"}";
@@ -500,7 +250,7 @@
 
     
     @Test
-    public void testCreateVCNameTooShort () throws KustvaktException {
+    public void testCreateVC_nameTooShort () throws KustvaktException {
         String json = "{\"type\": \"PRIVATE\""
                 + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + ",\"corpusQuery\": \"creationDate since 1820\"}";
@@ -522,7 +272,7 @@
     }
 
     @Test
-    public void testCreateVCUnauthorized () throws KustvaktException {
+    public void testCreateVC_unauthorized () throws KustvaktException {
         String json = "{\"type\": \"PRIVATE\","
                 + "\"corpusQuery\": \"creationDate since 1820\"}";
 
@@ -545,7 +295,7 @@
     }
 
     @Test
-    public void testCreateVCWithoutcorpusQuery () throws KustvaktException {
+    public void testCreateVC_withoutCorpusQuery () throws KustvaktException {
         String json = "{\"type\": \"PRIVATE\""
                 + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + "}";
@@ -568,7 +318,7 @@
     }
 
     @Test
-    public void testCreateVCWithoutEntity () throws KustvaktException {
+    public void testCreateVC_withoutEntity () throws KustvaktException {
         Response response = target().path(API_VERSION).path("vc")
                 .path("~"+testUser).path("new_vc")
                 .request()
@@ -586,7 +336,7 @@
     }
 
     @Test
-    public void testCreateVCWithoutType () throws KustvaktException {
+    public void testCreateVC_withoutType () throws KustvaktException {
         String json = "{\"corpusQuery\": " + "\"creationDate since 1820\""
                 + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + "}";
@@ -609,7 +359,7 @@
     }
 
     @Test
-    public void testCreateVCWithWrongType () throws KustvaktException {
+    public void testCreateVC_withWrongType () throws KustvaktException {
         String json = "{\"type\": \"PRIVAT\""
                 + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + ",\"corpusQuery\": \"creationDate since 1820\"}";
@@ -633,65 +383,51 @@
     }
 
     @Test
-    public void testDeleteVCUnauthorized () throws KustvaktException {
+    public void testDeleteVC_unauthorized () throws KustvaktException {
         Response response = target().path(API_VERSION).path("vc")
                 .path("~dory").path("dory-vc")
                 .request()
                 .header(Attributes.AUTHORIZATION, authHeader)
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-
                 .delete();
 
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: " + testUser,
-                node.at("/errors/0/1").asText());
-
-        checkWWWAuthenticateHeader(response);
+        testResponseUnauthorized(response, testUser);    
     }
 
     @Test
     public void testEditVC () throws KustvaktException {
-
         // 1st edit
         String json = "{\"description\": \"edited vc\"}";
-
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path("dory-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("dory", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
-                .put(Entity.json(json));
-
-        assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
-
+        editVC("dory", "dory", "dory-vc", json);
+        
         // check VC
-        JsonNode node = listVC("dory");
-        assertEquals("edited vc", node.get(0).get("description").asText());
+        JsonNode node = retrieveVCInfo("dory", "dory", "dory-vc");
+        assertEquals("edited vc", node.at("/description").asText());
 
         // 2nd edit
         json = "{\"description\": \"test vc\"}";
-
-        response = target().path(API_VERSION).path("vc").path("~dory")
-                .path("dory-vc")
-                .request()
+        editVC("dory", "dory", "dory-vc", json);
+        
+        // check VC
+        node = retrieveVCInfo("dory", "dory", "dory-vc");
+        assertEquals("test vc", node.at("/description").asText());
+    }
+    
+    @Test
+    public void testEditVCName () throws KustvaktException {
+        String json = "{\"name\": \"new-name\"}";
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~dory").path("dory-vc").request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue("dory", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
                 .put(Entity.json(json));
 
-        assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
-
-        // check VC
-        node = listVC("dory");
-        assertEquals("test vc", node.get(0).get("description").asText());
+        assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+        
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(StatusCodes.DESERIALIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
     }
 
     @Test
@@ -703,16 +439,7 @@
         assertEquals(2, node.at("/collection/operands").size());
         
         String json = "{\"corpusQuery\": \"corpusSigle=WPD17\"}";
-
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path("dory-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("dory", "pass"))
-                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
-                .put(Entity.json(json));
-
-        assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
+        editVC("dory", "dory", "dory-vc", json);
 
         node = testRetrieveKoralQuery("dory", "dory-vc");
         assertEquals("koral:doc", node.at("/collection/@type").asText());
@@ -738,7 +465,7 @@
     }
 
     @Test
-    public void testEditVCNotOwner () throws KustvaktException {
+    public void testEditVC_notOwner () throws KustvaktException {
         String json = "{\"description\": \"edited vc\"}";
 
         Response response = target().path(API_VERSION).path("vc")
@@ -772,15 +499,7 @@
 
         // edit vc
         String json = "{\"type\": \"PUBLISHED\"}";
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~dory").path(vcName)
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("dory", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
-                .put(Entity.json(json));
-        assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
+        editVC("dory", "dory", vcName, json);
 
         // check VC
         node = testListOwnerVC("dory");
@@ -798,17 +517,7 @@
 
         // edit 2nd
         json = "{\"type\": \"PROJECT\"}";
-
-        response = target().path(API_VERSION).path("vc").path("~dory")
-                .path("group-vc")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("dory", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
-                .put(Entity.json(json));
-
-        assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
+        editVC("dory", "dory", vcName, json);
 
         node = testListOwnerVC("dory");
         assertEquals(ResourceType.PROJECT.displayName(),
@@ -818,228 +527,4 @@
         node = listAccessByGroup("admin", "");
         assertEquals(3, node.size());
     }
-
-    @Test
-    public void testlistAccessByNonVCAAdmin () throws KustvaktException {
-        JsonNode node = listAccessByGroup("nemo", "dory-group");
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: nemo",
-                node.at("/errors/0/1").asText());
-    }
-
-    // @Test
-    // public void testlistAccessMissingId () throws KustvaktException
-    // {
-    // Response response =
-    // target().path(API_VERSION).path("vc")
-    // .path("access")
-    // .request().header(Attributes.AUTHORIZATION,
-    // HttpAuthorizationHandler
-    // .createBasicAuthorizationHeaderValue(
-    // testUser, "pass"))
-    // .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-    // .get();
-    // String entity = response.readEntity(String.class);
-    // JsonNode node = JsonUtils.readTree(entity);
-    // assertEquals(Status.BAD_REQUEST.getStatusCode(),
-    // response.getStatus());
-    // assertEquals(StatusCodes.MISSING_PARAMETER,
-    // node.at("/errors/0/0").asInt());
-    // assertEquals("vcId", node.at("/errors/0/1").asText());
-    // }
-
-    @Test
-    public void testlistAccessByGroup () throws KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .path("access").queryParam("groupName", "dory-group")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("dory", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .get();
-        String entity = response.readEntity(String.class);
-        // System.out.println(entity);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(1, node.at("/0/accessId").asInt());
-        assertEquals(2, node.at("/0/queryId").asInt());
-        assertEquals("group-vc", node.at("/0/queryName").asText());
-        assertEquals(2, node.at("/0/userGroupId").asInt());
-
-        assertEquals("dory-group", node.at("/0/userGroupName").asText());
-    }
-
-    @Test
-    public void testCreateDeleteAccess () throws
-            ProcessingException, KustvaktException {
-
-        String vcName = "marlin-vc";
-        String groupName = "marlin-group";
-
-        // check the vc type
-        JsonNode node = retrieveVCInfo("marlin", "marlin", vcName);
-        assertEquals(vcName, node.at("/name").asText());
-        assertEquals("private", node.at("/type").asText());
-
-        Response response =
-                testShareVCByCreator("marlin", vcName, groupName);
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
-        // check the vc type
-        node = retrieveVCInfo("marlin", "marlin", vcName);
-        assertEquals("project", node.at("/type").asText());
-
-        // list vc access by marlin
-        node = listAccessByGroup("marlin", groupName);
-        assertEquals(2, node.size());
-        node = node.get(1);
-        assertEquals(5, node.at("/queryId").asInt());
-        assertEquals(vcName, node.at("/queryName").asText());
-        assertEquals(1, node.at("/userGroupId").asInt());
-        assertEquals(groupName, node.at("/userGroupName").asText());
-
-        String accessId = node.at("/accessId").asText();
-
-        testShareVCNonUniqueAccess("marlin", vcName, groupName);
-        testDeleteAccessUnauthorized(accessId);
-
-        // delete access by vc-admin
-        // dory is a vc-admin in marlin group
-        response = testDeleteAccess("dory", accessId);
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
-
-        // list vc access by dory
-        node = listAccessByGroup("dory", groupName);
-        assertEquals(1, node.size());
-
-        editVCType("marlin", "marlin", vcName, ResourceType.PRIVATE);
-    }
-
-    private void testShareVCNonUniqueAccess (String vcCreator, String vcName,
-            String groupName) throws
-            ProcessingException, KustvaktException {
-        Response response =
-                testShareVCByCreator(vcCreator, vcName, groupName);
-        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
-        assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
-        assertEquals(StatusCodes.DB_INSERT_FAILED,
-                node.at("/errors/0/0").asInt());
-
-        // EM: message differs depending on the database used
-        // for testing. The message below is from sqlite.
-        // assertTrue(node.at("/errors/0/1").asText()
-        // .startsWith("[SQLITE_CONSTRAINT_UNIQUE]"));
-    }
-
-    @Test
-    public void testShareUnknownVC () throws
-            ProcessingException, KustvaktException {
-        Response response = testShareVCByCreator("marlin",
-                "non-existing-vc", "marlin group");
-        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
-        assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
-        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
-                node.at("/errors/0/0").asInt());
-    }
-
-    @Test
-    public void testShareUnknownGroup () throws
-            ProcessingException, KustvaktException {
-        Response response = testShareVCByCreator("marlin", "marlin-vc",
-                "non-existing-group");
-        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
-        assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
-        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
-                node.at("/errors/0/0").asInt());
-    }
-
-    @Test
-    public void testShareVCByVCAAdmin () throws
-            ProcessingException, KustvaktException {
-
-        // dory is VCA in marlin group
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~marlin").path("marlin-vc").path("share")
-                .path("@marlin group")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("dory", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .post(Entity.form(new Form()));
-
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: dory",
-                node.at("/errors/0/1").asText());
-    }
-
-    @Test
-    public void testShareVCByNonVCAAdmin () throws
-            ProcessingException, KustvaktException {
-
-        // nemo is not VCA in marlin group
-        Response response = target().path(API_VERSION).path("vc")
-                .path("~nemo").path("nemo-vc").path("share").path("@marlin-group")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue("nemo", "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .post(Entity.form(new Form()));
-
-        String entity = response.readEntity(String.class);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: nemo",
-                node.at("/errors/0/1").asText());
-    }
-
-    private Response testDeleteAccess (String username, String accessId)
-            throws ProcessingException,
-            KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .path("access").path(accessId)
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(username, "pass"))
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .delete();
-
-        return response;
-    }
-
-    private void testDeleteAccessUnauthorized (String accessId)
-            throws ProcessingException,
-            KustvaktException {
-        Response response = target().path(API_VERSION).path("vc")
-                .path("access").path(accessId)
-                .request()
-                .header(Attributes.AUTHORIZATION, authHeader)
-                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
-                .delete();
-
-        String entity = response.readEntity(String.class);
-        // System.out.println(entity);
-        JsonNode node = JsonUtils.readTree(entity);
-        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
-                node.at("/errors/0/0").asInt());
-        assertEquals("Unauthorized operation for user: " + testUser,
-                node.at("/errors/0/1").asText());
-    }
-
-    @Test
-    public void testDeleteNonExistingAccess () throws
-            ProcessingException, KustvaktException {
-        Response response = testDeleteAccess("dory", "100");
-        assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
-
-        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
-        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
-                node.at("/errors/0/0").asInt());
-    }
 }
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusInfoTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusInfoTest.java
new file mode 100644
index 0000000..ab04741
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusInfoTest.java
@@ -0,0 +1,185 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.net.HttpHeaders;
+
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.constant.ResourceType;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class VirtualCorpusInfoTest extends VirtualCorpusTestBase {
+
+    private String admin = "admin";
+    private String testUser = "VirtualCorpusInfoTest";
+    
+    
+    @Test
+    public void testRetrieveSystemVC() throws
+            ProcessingException, KustvaktException {
+
+        JsonNode node = retrieveVCInfo(testUser, "system", "system-vc");
+        assertEquals("system-vc", node.at("/name").asText());
+        assertEquals(ResourceType.SYSTEM.displayName(),
+                node.at("/type").asText());
+//        assertEquals("koral:doc", node.at("/koralQuery/collection/@type").asText());
+        assertTrue(node.at("/query").isMissingNode());
+        assertTrue(node.at("/queryLanguage").isMissingNode());
+    }
+
+    @Test
+    public void testRetrieveSystemVCGuest () throws
+            ProcessingException, KustvaktException {
+
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~system").path("system-vc")
+                .request()
+                .get();
+        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
+        assertEquals("system-vc", node.at("/name").asText());
+        assertEquals(ResourceType.SYSTEM.displayName(),
+                node.at("/type").asText());
+    }
+
+    @Test
+    public void testRetrieveOwnerPrivateVC()
+            throws ProcessingException,
+            KustvaktException {
+
+        JsonNode node = retrieveVCInfo("dory", "dory", "dory-vc");
+        assertEquals("dory-vc", node.at("/name").asText());
+        assertEquals(ResourceType.PRIVATE.displayName(),
+                node.at("/type").asText());
+    }
+
+    @Test
+    public void testRetrievePrivateVCUnauthorized ()
+            throws ProcessingException, KustvaktException {
+        Response response = target().path(API_VERSION).path("vc").path("~dory")
+                .path("dory-vc").request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(testUser, "pass"))
+                .get();
+        testResponseUnauthorized(response, testUser);
+    }
+
+    @Test
+    public void testRetrieveProjectVC() throws
+            ProcessingException, KustvaktException {
+
+        JsonNode node = retrieveVCInfo("nemo", "dory", "group-vc");
+        assertEquals("group-vc", node.at("/name").asText());
+        assertEquals(ResourceType.PROJECT.displayName(),
+                node.at("/type").asText());
+    }
+    
+    @Test
+    public void testRetrieveProjectVCUnauthorized () throws
+            ProcessingException, KustvaktException {
+
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~dory").path("group-vc")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(testUser, "pass"))
+                .get();
+        testResponseUnauthorized(response, testUser);
+    }
+
+
+    @Test
+    public void testRetrieveProjectVCbyNonActiveMember ()
+            throws ProcessingException,
+            KustvaktException {
+
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~dory").path("group-vc")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("marlin", "pass"))
+                .get();
+        testResponseUnauthorized(response, "marlin");
+    }
+
+    @Test
+    public void testRetrievePublishedVC () throws
+            ProcessingException, KustvaktException {
+
+        JsonNode node = retrieveVCInfo("gill", "marlin", "published-vc");
+        assertEquals("published-vc", node.at("/name").asText());
+        assertEquals(ResourceType.PUBLISHED.displayName(),
+                node.at("/type").asText());
+
+        Form f = new Form();
+        f.param("status", "HIDDEN");
+        // check gill in the hidden group of the vc
+        Response response = target().path(API_VERSION)
+                .path("admin").path("group").path("list")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("admin", "pass"))
+                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED)
+                .post(Entity.form(f));
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        String entity = response.readEntity(String.class);
+        node = JsonUtils.readTree(entity);
+        assertEquals(3, node.at("/0/id").asInt());
+        String members = node.at("/0/members").toString();
+        assertTrue(members.contains("\"userId\":\"gill\""));
+    }
+    
+    @Test
+    public void testAdminRetrievePrivateVC () throws
+            ProcessingException, KustvaktException {
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~dory").path("dory-vc")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(admin, "pass"))
+                .get();
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+
+        assertEquals(1, node.at("/id").asInt());
+        assertEquals("dory-vc", node.at("/name").asText());
+    }
+    @Test
+    public void testAdminRetrieveProjectVC () throws
+            ProcessingException, KustvaktException {
+
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~dory").path("group-vc")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(admin, "pass"))
+                .get();
+        String entity = response.readEntity(String.class);
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals("group-vc", node.at("/name").asText());
+        assertEquals(ResourceType.PROJECT.displayName(),
+                node.at("/type").asText());
+    }
+
+    
+
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusListTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusListTest.java
new file mode 100644
index 0000000..35fceb7
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusListTest.java
@@ -0,0 +1,106 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertEquals;
+
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.net.HttpHeaders;
+
+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.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class VirtualCorpusListTest extends VirtualCorpusTestBase {
+
+    @Test
+    public void testListVCNemo ()
+            throws ProcessingException, KustvaktException {
+        
+        JsonNode node = testListOwnerVC("nemo");
+        assertEquals(1, node.size());
+        
+        node = listSystemVC("nemo");
+        assertEquals(1, node.size());
+        
+        node = listVC("nemo");
+        assertEquals(3, node.size());
+    }
+
+    @Test
+    public void testListVCPearl ()
+            throws ProcessingException, KustvaktException {
+        JsonNode node = testListOwnerVC("pearl");
+        assertEquals(0, node.size());
+        
+        node = listVC("pearl");
+        assertEquals(2, node.size());        
+    }
+
+    @Test
+    public void testListVCDory ()
+            throws ProcessingException, KustvaktException {
+        JsonNode node = testListOwnerVC("dory");
+        assertEquals(2, node.size());
+        
+        node = listVC("dory");
+        assertEquals(4, node.size());
+    }
+    
+
+    @Test
+    public void testListAvailableVCGuest ()
+            throws ProcessingException, KustvaktException {
+        Response response =
+                target().path(API_VERSION).path("vc").request().get();
+        testResponseUnauthorized(response, "guest");
+    }
+
+    @Ignore
+    @Deprecated
+    @Test
+    public void testListAvailableVCByOtherUser ()
+            throws ProcessingException, KustvaktException {
+        Response response = target().path(API_VERSION).path("vc").path("~dory")
+                .request().header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("pearl", "pass"))
+                .get();
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+
+        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Unauthorized operation for user: pearl",
+                node.at("/errors/0/1").asText());
+
+        checkWWWAuthenticateHeader(response);
+    }
+    
+    @Ignore
+    @Deprecated
+    @Test
+    public void testListUserVC () throws
+            ProcessingException, KustvaktException {
+        Response response = target().path(API_VERSION).path("vc")
+                .queryParam("username", "dory")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("admin", "pass"))
+                .get();
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(4, node.size());
+    }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusSharingTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusSharingTest.java
index 701b8e5..7691965 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusSharingTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusSharingTest.java
@@ -9,6 +9,7 @@
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
+import org.apache.http.HttpStatus;
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -25,7 +26,60 @@
     private String testUser = "VirtualCorpusSharingTest";
 
     @Test
-    public void testProjectVC () throws KustvaktException {
+    public void testShareUnknownVC () throws
+            ProcessingException, KustvaktException {
+        Response response = testShareVCByCreator("marlin",
+                "non-existing-vc", "marlin group");
+        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
+        assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
+        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+                node.at("/errors/0/0").asInt());
+    }
+
+    @Test
+    public void testShareUnknownGroup () throws
+            ProcessingException, KustvaktException {
+        Response response = testShareVCByCreator("marlin", "marlin-vc",
+                "non-existing-group");
+        JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
+        assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
+        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+                node.at("/errors/0/0").asInt());
+    }
+
+    @Test
+    public void testShareVC_notOwner () throws
+            ProcessingException, KustvaktException {
+
+        // dory is VCA in marlin group
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~marlin").path("marlin-vc").path("share")
+                .path("@marlin group")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("dory", "pass"))
+                .post(Entity.form(new Form()));
+
+        testResponseUnauthorized(response, "dory");
+    }
+    
+    @Test
+    public void testShareVC_byMember () throws
+            ProcessingException, KustvaktException {
+
+        // nemo is not VCA in marlin group
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~nemo").path("nemo-vc").path("share").path("@marlin-group")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("nemo", "pass"))
+                .post(Entity.form(new Form()));
+
+        testResponseUnauthorized(response, "nemo");
+    }
+    
+    @Test
+    public void testCreateShareProjectVC () throws KustvaktException {
         String json =
                 "{\"type\": \"PROJECT\"" + ",\"queryType\": \"VIRTUAL_CORPUS\""
                         + ",\"corpusQuery\": \"corpusSigle=GOE\"}";
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusTestBase.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusTestBase.java
index b5454cf..7b354b5 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusTestBase.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusTestBase.java
@@ -1,7 +1,14 @@
 package de.ids_mannheim.korap.web.controller;
 
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
 import javax.ws.rs.ProcessingException;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Form;
@@ -9,14 +16,15 @@
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.http.entity.ContentType;
+import org.glassfish.jersey.server.ContainerRequest;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.net.HttpHeaders;
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.utils.JsonUtils;
 
 public abstract class VirtualCorpusTestBase extends OAuth2TestBase {
@@ -46,21 +54,16 @@
         assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
     }
 
-    protected void editVCType (String username, String vcCreator, String vcName,
-            ResourceType type) throws KustvaktException {
-        String json = "{\"type\": \"" + type + "\"}";
-
+    protected void editVC (String username, String vcCreator, String vcName,
+            String vcJson) throws KustvaktException {
         Response response = target().path(API_VERSION).path("vc")
                 .path("~" + vcCreator).path(vcName).request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue(username, "pass"))
                 .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
-                .put(Entity.json(json));
+                .put(Entity.json(vcJson));
 
         assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
-
-        JsonNode node = retrieveVCInfo(username, vcCreator, vcName);
-        assertEquals(type.displayName(), node.at("/type").asText());
     }
 
     protected JsonNode listVC (String username)
@@ -85,6 +88,31 @@
         String entity = response.readEntity(String.class);
         return JsonUtils.readTree(entity);
     }
+    
+    protected JsonNode testListOwnerVC (String username)
+            throws ProcessingException, KustvaktException {
+        Response response = target().path(API_VERSION).path("vc")
+                .queryParam("filter-by", "own").request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(username, "pass"))
+                .get();
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+
+        String entity = response.readEntity(String.class);
+        return JsonUtils.readTree(entity);
+    }
+
+    protected JsonNode listSystemVC (String username) throws KustvaktException {
+        Response response = target().path(API_VERSION).path("vc")
+                .queryParam("filter-by", "system").request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue("pearl", "pass"))
+                .get();
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        return node;
+    }
 
     protected Response testShareVCByCreator (String vcCreator, String vcName,
             String groupName) throws ProcessingException, KustvaktException {
@@ -118,4 +146,32 @@
 
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
     }
+    
+    protected void testResponseUnauthorized (Response response, String username)
+            throws KustvaktException {
+        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+
+        String entity = response.readEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+
+        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Unauthorized operation for user: " + username,
+                node.at("/errors/0/1").asText());
+        
+        checkWWWAuthenticateHeader(response);
+    }
+    
+    protected void checkWWWAuthenticateHeader (Response response) {
+        Set<Entry<String, List<Object>>> headers =
+                response.getHeaders().entrySet();
+
+        for (Entry<String, List<Object>> header : headers) {
+            if (header.getKey().equals(ContainerRequest.WWW_AUTHENTICATE)) {
+                assertThat(header.getValue(), not(hasItem("Api realm=\"Kustvakt\"")));
+                assertThat(header.getValue(), hasItem("Bearer realm=\"Kustvakt\""));
+                assertThat(header.getValue(), hasItem("Basic realm=\"Kustvakt\""));
+            }
+        }
+    }
 }