Added tests for store- and update-resource services.

Change-Id: Ib1c0ea95025ba2b6a6906afae685b2e91670f75d
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java b/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java
index 6a71682..5cd7e23 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/SecurityManager.java
@@ -140,7 +140,7 @@
 
 
     public static SecurityManager init (String id, User user,
-            Permissions.Permission ... perms) throws KustvaktException  {
+            Permissions.Permission ... perms) throws KustvaktException {
         SecurityManager p = new SecurityManager(user);
         p.findPolicies(id, false, perms);
         return p;
@@ -158,8 +158,7 @@
             return this.resource;
         }
         else {
-            jlog.error(
-                    "Reading the resource '{}' is not allowed for user '{}'",
+            jlog.error("Reading the resource '{}' is not allowed for user '{}'",
                     this.resource.getPersistentID(), this.user.getUsername());
             throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
                     evaluator.getResourceID());
@@ -167,8 +166,8 @@
     }
 
 
-    public void updateResource (T resource) throws NotAuthorizedException,
-            KustvaktException {
+    public void updateResource (T resource)
+            throws NotAuthorizedException, KustvaktException {
         if (evaluator.isAllowed(Permissions.Permission.WRITE)) {
             ResourceOperationIface iface = handlers.get(resource.getClass());
             if (iface != null)
@@ -193,11 +192,11 @@
      * @throws KustvaktException
      */
     // todo: delete only works with find, not with init constructor!
-    public void deleteResource () throws NotAuthorizedException,
-            KustvaktException {
+    public void deleteResource ()
+            throws NotAuthorizedException, KustvaktException {
         if (evaluator.isAllowed(Permissions.Permission.DELETE)) {
-            ResourceOperationIface iface = handlers.get(this.resource
-                    .getClass());
+            ResourceOperationIface iface = handlers
+                    .get(this.resource.getClass());
             if (iface != null)
                 iface.deleteResource(this.evaluator.getResourceID(), this.user);
             else
@@ -229,27 +228,28 @@
         if (id instanceof Integer)
             this.policies = policydao.getPolicies((Integer) id, this.user,
                     b.getPbyte());
-        
+
         this.evaluator = new PolicyEvaluator(this.user, this.policies);
 
         if (this.policies == null) {
             jlog.error("No policies found for resource id '{}' for user '{}'",
                     id, user.getId());
-            throw new KustvaktException(StatusCodes.NO_VALUE_FOUND, "Resource not found!",
-                    String.valueOf(id));
+            throw new KustvaktException(StatusCodes.NO_VALUE_FOUND,
+                    "Resource not found!", String.valueOf(id));
         }
         return true;
     }
 
 
     // todo:  security log shows id 'null' --> better way?
-    private T findResource (Class type) throws NotAuthorizedException,
-            KustvaktException {
+    private T findResource (Class type) throws KustvaktException {
         if (!evaluator.isAllowed()) {
             jlog.error("Permission denied for resource id '{}' for user '{}'",
                     this.evaluator.getResourceID(), user.getId());
-            throw new NotAuthorizedException(StatusCodes.NO_POLICY_PERMISSION,
-                    this.evaluator.getResourceID());
+            throw new KustvaktException(StatusCodes.NO_POLICY_PERMISSION,
+                    "Permission denied for resource id "
+                            + this.evaluator.getResourceID() + " for the user.",
+                            user.getUsername());
         }
 
         ResourceOperationIface iface = handlers.get(type);
@@ -257,6 +257,16 @@
             iface = handlers.get(KustvaktResource.class);
         T resource = (T) iface.findbyId(this.evaluator.getResourceID(),
                 this.user);
+        
+        if(type != null && !resource.getClass().equals(type)) {
+            throw new KustvaktException(StatusCodes.NO_VALUE_FOUND,
+                    "Resource with id " + this.evaluator.getResourceID()
+                            + " and type " + type.getSimpleName()
+                            + " is not found. Found resource with id "
+                            + this.evaluator.getResourceID() + " and type "
+                            + resource.getClass().getSimpleName() + ".");
+        }
+
         // fixme: this
         // fixme: deprecated!
         resource.setManaged(this.evaluator.isManaged());
@@ -272,8 +282,8 @@
     }
 
 
-    public static SecurityManager register (KustvaktResource resource, User user)
-            throws KustvaktException, NotAuthorizedException {
+    public static SecurityManager register (KustvaktResource resource,
+            User user) throws KustvaktException, NotAuthorizedException {
         SecurityManager p = new SecurityManager(user);
         if (!User.UserFactory.isDemo(user.getUsername())) {
             if (resource.getParentID() != null) {
@@ -306,8 +316,8 @@
                         + resource.getPersistentID() + "@" + resource.getId()
                         + "', name: " + resource.getName());
                 // storing resource is called twice. first when this is register and later in idsbootstrap to create cstorage entry. how to unify this?
-                ResourceOperationIface iface = p.handlers.get(resource
-                        .getClass());
+                ResourceOperationIface iface = p.handlers
+                        .get(resource.getClass());
                 if (iface != null)
                     resource.setId(iface.storeResource(resource, user));
                 else
@@ -330,7 +340,8 @@
                         resource.getPersistentID(), user.getId());
                 throw new KustvaktException(user.getId(),
                         StatusCodes.POLICY_ERROR_DEFAULT,
-                        "Resource could not be registered", resource.toString());
+                        "Resource could not be registered",
+                        resource.toString());
             }
         }
         return p;
@@ -422,8 +433,8 @@
     }
 
 
-    public void deletePolicies () throws NotAuthorizedException,
-            KustvaktException {
+    public void deletePolicies ()
+            throws NotAuthorizedException, KustvaktException {
         for (SecurityPolicy p : new ArrayList<>(this.policies[0]))
             deletePolicy(p);
     }
@@ -439,8 +450,8 @@
 
 
     // todo:
-    public void deletePolicy (SecurityPolicy policy) throws KustvaktException,
-            NotAuthorizedException {
+    public void deletePolicy (SecurityPolicy policy)
+            throws KustvaktException, NotAuthorizedException {
         // todo: get rid of this: use sql to match policy id and target according to evaluator!
         if (!matchTarget(policy.getTarget()))
             // adjust message
@@ -453,8 +464,8 @@
             throw new KustvaktException(user.getId(), StatusCodes.NO_POLICIES,
                     this.evaluator.getResourceID());
         }
-        if (contains(policy)
-                && (evaluator.isAllowed(Permissions.Permission.DELETE_POLICY))) {
+        if (contains(policy) && (evaluator
+                .isAllowed(Permissions.Permission.DELETE_POLICY))) {
             policydao.deletePolicy(policy, this.user);
         }
         else if (silent) {
@@ -470,8 +481,8 @@
     }
 
 
-    public void modifyPolicy (SecurityPolicy policy) throws KustvaktException,
-            NotAuthorizedException {
+    public void modifyPolicy (SecurityPolicy policy)
+            throws KustvaktException, NotAuthorizedException {
         if (!matchTarget(policy.getTarget()))
             throw new NotAuthorizedException(StatusCodes.ILLEGAL_ARGUMENT);
 
@@ -484,8 +495,8 @@
                     this.evaluator.getResourceID());
         }
 
-        if (contains(policy)
-                && (evaluator.isAllowed(Permissions.Permission.MODIFY_POLICY))) {
+        if (contains(policy) && (evaluator
+                .isAllowed(Permissions.Permission.MODIFY_POLICY))) {
             policydao.updatePolicy(policy, this.user);
         }
         else if (silent) {
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
index 4f384c7..a13958e 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
@@ -424,9 +424,10 @@
         }
 
         if (resource != null) {
-            if (resource instanceof VirtualCollection)
-                query = JsonUtils
-                        .toJSON(cquery.and().mergeWith(resource.getData()));
+            if (resource instanceof VirtualCollection) {
+                JsonNode node = cquery.and().mergeWith(resource.getData());
+                query = JsonUtils.toJSON(node);
+            }
             else if (resource instanceof Corpus) {
                 cquery.and().with(Attributes.CORPUS_SIGLE, "=",
                         resource.getPersistentID());
@@ -531,7 +532,7 @@
             MetaQueryBuilder meta) {
         String result;
         if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
-            result = searchNeo4J(query, pageLength, meta,false);
+            result = searchNeo4J(query, pageLength, meta, false);
         }
         else {
             result = searchKrill.search(query);
@@ -541,15 +542,15 @@
 
     }
 
+
     private String searchNeo4J (String query, int pageLength,
             MetaQueryBuilder meta, boolean raw) {
-        
-        if (raw){
-            throw KustvaktResponseHandler.throwit(
-                    StatusCodes.ILLEGAL_ARGUMENT,
+
+        if (raw) {
+            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     "raw not supported!", null);
         }
-        
+
         MultivaluedMap<String, String> map = new MultivaluedMapImpl();
         map.add("q", query);
         map.add("count", String.valueOf(pageLength));
@@ -565,6 +566,7 @@
 
     }
 
+
     /**
      * String search, String ql, List<String> parents, String cli,
      * String cri,
@@ -606,19 +608,18 @@
             User user = controller.getUser(context.getUsername());
             MetaQueryBuilder meta;
 
-            // EM: shouldnt this be the same as buildQueryWithId() ?
             if (!raw) {
                 meta = createMetaQuery(pageIndex, pageInteger, ctx, pageLength,
                         cutoff);
-                
+
                 QuerySerializer s = new QuerySerializer();
                 s.setQuery(query, ql, v);
-                
+
                 // add collection query
                 KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
                 builder.setBaseQuery(s.toJSON());
                 query = createQuery(user, type, id, builder);
-                
+
             }
             else {
                 meta = new MetaQueryBuilder();
@@ -814,6 +815,20 @@
     }
 
 
+    // EM: this handles layer id containing a slash. 
+    // Probably better to restrict the id not to contain any slash instead.
+    @POST
+    @Path("{type}/{id}/{child}")
+    public Response updateResource (@Context SecurityContext context,
+            @Context Locale locale, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("child") String child,
+            @QueryParam("name") String name,
+            @QueryParam("description") String description) {
+        return updateResource(context, locale, type,
+                StringUtils.joinResources(id, child), name, description);
+    }
+
+
     @POST
     @Path("{type}/{id}")
     public Response updateResource (@Context SecurityContext context,
@@ -947,13 +962,8 @@
 
 
     /**
-     * EM: store a virtual collection in a database, but
-     * /virtualcollection
-     * service (@see
-     * {@link #getResource(SecurityContext, Locale, String, String)})
-     * does not
-     * list it because the collection is not stored in the
-     * policy_store table as well.
+     * EM: store a virtual collection in resource_store, but
+     * not in the policy_store table as well.
      * 
      * Retrieve cached entry first and then store collection
      * 
@@ -961,6 +971,7 @@
      * @param locale
      * @param query
      * @return
+     * @throws KustvaktException
      */
     @POST
     @Path("{type}")
@@ -970,7 +981,8 @@
             @QueryParam("name") String name,
             @QueryParam("description") String description,
             @QueryParam("ref") String reference,
-            @QueryParam("cache") Boolean cache, String query) {
+            @QueryParam("cache") Boolean cache,
+            @QueryParam("query") String query) throws KustvaktException {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         filter = filter != null ? filter : false;
         cache = cache != null ? cache : false;
@@ -978,7 +990,7 @@
         reference = StringUtils.decodeHTML(reference);
         Map vals = new HashMap();
         User user;
-        Class ctype;
+        Class<KustvaktResource> ctype;
         try {
             ctype = ResourceFactory.getResourceClass(type);
 
@@ -1037,6 +1049,12 @@
                 vals = cachetmp.toMap();
             }
         }
+        else {
+            throw KustvaktResponseHandler.throwit(
+                    new KustvaktException(StatusCodes.UNSUPPORTED_RESOURCE,
+                            "Unsupported operation for the given resource type.",
+                            type));
+        }
         return Response.ok(JsonUtils.toJSON(vals)).build();
     }
 
diff --git a/src/test/java/de/ids_mannheim/korap/security/ResourcesTest.java b/src/test/java/de/ids_mannheim/korap/security/ResourcesTest.java
index fb83bb4..677f167 100644
--- a/src/test/java/de/ids_mannheim/korap/security/ResourcesTest.java
+++ b/src/test/java/de/ids_mannheim/korap/security/ResourcesTest.java
@@ -4,7 +4,6 @@
 import de.ids_mannheim.korap.config.ContextHolder;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.NotAuthorizedException;
 import de.ids_mannheim.korap.interfaces.db.EntityHandlerIface;
 import de.ids_mannheim.korap.resources.*;
 import de.ids_mannheim.korap.security.ac.ResourceFinder;
@@ -12,10 +11,14 @@
 import de.ids_mannheim.korap.security.ac.SecurityManager;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.TimeUtils;
+
+import org.hamcrest.core.StringStartsWith;
 import org.joda.time.DateTime;
 import org.junit.Assert;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 
 import java.util.Set;
 
@@ -24,7 +27,7 @@
 import static org.junit.Assert.assertNotNull;
 
 /**
- * @author hanl
+ * @author hanl, margaretha
  * @date 20/11/2015
  */
 // todo: run functions without data to check for nullpointers!
@@ -32,6 +35,8 @@
 
     private static Corpus c1;
 
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
 
     @Test
     public void testCreate () throws KustvaktException {
@@ -89,8 +94,12 @@
 
 
     // securitymanager does not allow for anonymous retrieval, only resourcefinder!
-    @Test(expected = NotAuthorizedException.class)
+    @Test 
     public void getResource () throws KustvaktException {
+        
+        exception.expect(KustvaktException.class);
+        exception.expectMessage(StringStartsWith.startsWith("Permission denied"));
+        
         User user = User.UserFactory.getDemoUser();
         SecurityManager m = SecurityManager.findbyId(2, user,
                 Permissions.Permission.READ);
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
index a5e91da..a5002c9 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
@@ -340,7 +340,8 @@
         HttpClient httpclient = HttpClients.createDefault();
         URIBuilder builder = new URIBuilder();
         builder.setScheme("http").setHost("localhost").setPort(8089)
-                .setPath("/api/v0.1/virtualcollection/00df953b-2227-4c23-84c1-5532c07bf8ce")
+                //.setPath("/api/v0.1/virtualcollection/00df953b-2227-4c23-84c1-5532c07bf8ce")
+                .setPath("/api/v0.1/virtualcollection/GOE-VC")
                 .setParameter("name", "Goethe collection")
                 .setParameter("description", "Goethe collection");
         URI uri = builder.build();
@@ -348,7 +349,18 @@
         httppost.addHeader(Attributes.AUTHORIZATION,
                 BasicHttpAuth.encode("kustvakt", "kustvakt2015"));
         HttpResponse response = httpclient.execute(httppost);
-
+        
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatusLine().getStatusCode());
+        
+//        assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
+//                response.getStatusLine().getStatusCode());
+        
+//        JsonNode errorNode = mapper.readTree(response.getEntity().getContent());
+//        assertEquals(
+//                "Resource not found!",
+//                errorNode.get("errors").get(0).get(1).asText());
+        
     }
 
 
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java
index 5fa2cd0..ce0e6ec 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java
@@ -121,17 +121,17 @@
                 .path(getAPIVersion())
                 .path("virtualcollection")
                 .queryParam("filter", "false")
+                .queryParam("query", "creationDate since 1775 & corpusSigle=GOE")
                 .queryParam("name", "Weimarer Werke")
                 .queryParam("description", "Goethe-Werke in Weimar (seit 1775)")
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
-                .post(ClientResponse.class, "creationDate since 1775 & corpusSigle=GOE");
+                .post(ClientResponse.class);
         
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
         
         String ent = response.getEntity(String.class);
-        
         JsonNode node = JsonUtils.readTree(ent);
         assertNotNull(node);
         assertTrue(node.isObject());
@@ -177,7 +177,7 @@
         ent = response.getEntity(String.class);
         node = JsonUtils.readTree(ent);
         assertNotNull(node);
-
+        System.out.println("NODE "+ent);
         assertEquals("koral:docGroup", node.at("/collection/@type").asText());
         assertEquals("koral:doc", node.at("/collection/operands/0/@type")
                 .asText());
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
index 4b4840d..4cdce89 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
@@ -27,11 +27,12 @@
 import de.ids_mannheim.korap.web.service.FastJerseyTest;
 
 /**
- * @author hanl
+ * @author hanl, margaretha
  * @date 14/01/2016
+ * @update 24/04/2017
  */
 public class ResourceServiceTest extends FastJerseyTest {
-    
+
     @BeforeClass
     public static void configure () throws Exception {
         FastJerseyTest.setPackages("de.ids_mannheim.korap.web.service.full",
@@ -39,12 +40,12 @@
                 "de.ids_mannheim.korap.web.utils");
     }
 
+
     // create a simple test collection for user kustvakt, otherwise test fails
     @Test
     @Ignore
     public void testStats () {
-        ClientResponse response = resource()
-                .path(getAPIVersion())
+        ClientResponse response = resource().path(getAPIVersion())
                 .path("collection")
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
@@ -57,10 +58,7 @@
         assertNotEquals(0, node.size());
         String id = node.path(1).path("id").asText();
 
-        response = resource()
-                .path(getAPIVersion())
-                .path("collection")
-                .path(id)
+        response = resource().path(getAPIVersion()).path("collection").path(id)
                 .path("stats")
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
@@ -76,26 +74,243 @@
         assertTrue(docs < 15);
     }
 
-    // EM: The test covers multiple operations because it deals with 
-    // the same resource and needs an order to operate (store followed by
-    // update followed by delete).
+
     @Test
-    public void testVirtualCollectionStoreUpdateDelete() throws KustvaktException, 
-        JsonProcessingException, IOException {
-    	// resource store service
-        ClientResponse response = resource()
-                .path(getAPIVersion())
-                .path("virtualcollection")
-                .queryParam("filter", "false")
+    public void testOwnerUpdateVirtualCollection () throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("virtualcollection").path("GOE-VC") // persistent id
+                .queryParam("name", "Goethe collection")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+        assertEquals("sqlite",
+                helper().getContext().getPersistenceClient().getDatabase());
+
+        KustvaktResource res = dao.findbyId("GOE-VC",
+                User.UserFactory.getDemoUser());
+        assertNotNull(res);
+        assertEquals("Goethe collection", res.getName().toString());
+
+    }
+
+
+    @Test
+    public void testOwnerUpdateCorpus () throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("corpus").path("GOE") // persistent id
+                .queryParam("name", "Goethe corpus")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+
+        KustvaktResource res = dao.findbyId("GOE",
+                User.UserFactory.getDemoUser());
+        assertNotNull(res);
+        assertEquals("Goethe corpus", res.getName().toString());
+
+    }
+
+
+    @Test
+    public void testOwnerUpdateFoundry () throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("foundry").path("malt") // persistent id
+                .queryParam("name", "malt parser")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+
+        KustvaktResource res = dao.findbyId("malt",
+                User.UserFactory.getDemoUser());
+        assertNotNull(res);
+        assertEquals("malt parser", res.getName().toString());
+
+    }
+
+
+    @Test
+    public void testOwnerUpdateLayer () throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion()).path("layer")
+                .path("mate/d").queryParam("name", "Mate dependency")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+
+        KustvaktResource res = dao.findbyId("mate/d",
+                User.UserFactory.getDemoUser());
+        assertNotNull(res);
+        assertEquals("Mate dependency", res.getName().toString());
+
+    }
+
+
+    @Test
+    public void testOwnerUpdateUnexistingCorpus () throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("corpus").path("GOEC") // persistent id
+                .queryParam("name", "Goethe corpus")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
+                response.getStatus());
+
+        JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+        assertEquals("Resource not found!",
+                node.get("errors").get(0).get(1).asText());
+
+    }
+
+
+    @Test
+    public void testUpdateUnauthorized () throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("corpus").path("GOE") // persistent id
+                .queryParam("name", "Goethe corpus").post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
+                response.getStatus());
+
+        JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+        assertEquals("Permission denied for resource id GOE for the user.",
+                node.get("errors").get(0).get(1).asText());
+
+    }
+
+
+    @Test
+    public void testStoreNewVirtualCollection () throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("virtualcollection").queryParam("filter", "false")
+                .queryParam("name", "Brown")
+                .queryParam("description", "Brown corpus")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        String ent = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(ent);
+        assertEquals("Brown", node.path("name").asText());
+        assertEquals("Brown corpus", node.path("description").asText());
+
+        String id = node.path("id").asText();
+
+        // check if the resource is in the db
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+        assertEquals("sqlite",
+                helper().getContext().getPersistenceClient().getDatabase());
+
+        assertNotEquals(0, dao.size());
+        KustvaktResource res = dao.findbyId(id, User.UserFactory.getDemoUser());
+        assertEquals("Brown", res.getName().toString());
+
+    }
+
+
+    @Test
+    public void testStoreUnsupportedType () throws KustvaktException {
+
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("corpus").queryParam("filter", "false")
+                .queryParam("name", "Brown")
+                .queryParam("description", "Brown corpus")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
+                response.getStatus());
+
+        String ent = response.getEntity(String.class);
+        System.out.println(ent);
+        JsonNode node = JsonUtils.readTree(ent);
+        assertEquals(402, node.at("/errors/0/0").asInt());
+        assertEquals("Unsupported operation for the given resource type.",
+                node.at("/errors/0/1").asText());
+    }
+
+
+    @Test
+    public void testStoreNewVirtualCollectionFromExistingCollection ()
+            throws KustvaktException {
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("virtualcollection").queryParam("filter", "true")
+                .queryParam("ref", "WPD15-VC")
+                .queryParam("name", "Wikipedia collection")
+                .queryParam("query", "author ~ Asdert")
+                .queryParam("description", "Wikipedia subcorpus from Asdert")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .post(ClientResponse.class);
+
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+
+        String ent = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(ent);
+        String id = node.path("id").asText();
+
+        assertEquals("Wikipedia collection", node.path("name").asText());
+        assertEquals("Wikipedia subcorpus from Asdert",
+                node.path("description").asText());
+        node = node.at("/data/collection/operands/1");
+        assertEquals("author", node.at("/key").asText());
+        assertEquals("Asdert", node.at("/value").asText());
+
+        // check if the resource is in the db
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+        KustvaktResource res = dao.findbyId(id, User.UserFactory.getDemoUser());
+        assertEquals("Wikipedia collection", res.getName().toString());
+    }
+
+
+    // EM: The test covers multiple ordered operations dealing with 
+    // the same resource (store followed by update followed by delete).
+    @Test
+    public void testVirtualCollectionStoreUpdateDelete ()
+            throws KustvaktException, JsonProcessingException, IOException {
+        // resource store service
+        ClientResponse response = resource().path(getAPIVersion())
+                .path("virtualcollection").queryParam("filter", "false")
                 .queryParam("name", "Goethe")
                 .queryParam("description", "Goethe corpus")
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
                 .post(ClientResponse.class);
-        
+
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
-        
+
         String ent = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(ent);
         assertNotNull(node);
@@ -104,78 +319,66 @@
         assertEquals("Goethe corpus", node.path("description").asText());
 
         String id = node.path("id").asText();
-        		
+
         // check if the resource is in the db
-        ResourceDao<?> dao = new ResourceDao<>(helper().getContext()
-                .getPersistenceClient());
-        assertEquals("sqlite", helper().getContext().getPersistenceClient()
-                .getDatabase());
+        ResourceDao<?> dao = new ResourceDao<>(
+                helper().getContext().getPersistenceClient());
+        assertEquals("sqlite",
+                helper().getContext().getPersistenceClient().getDatabase());
 
         assertNotEquals(0, dao.size());
-        KustvaktResource res = dao.findbyId(id,
-                User.UserFactory.getDemoUser());
+        KustvaktResource res = dao.findbyId(id, User.UserFactory.getDemoUser());
         assertNotNull(res);
-        Assert.assertEquals("Goethe",res.getName().toString());
-        
+        Assert.assertEquals("Goethe", res.getName().toString());
+
         // no update resource service
-        response = resource()
-                .path(getAPIVersion())
-                .path("virtualcollection")
-                .path(id)
-                .queryParam("name", "Goethe")
+        response = resource().path(getAPIVersion()).path("virtualcollection")
+                .path(id).queryParam("name", "Goethe")
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
                 .post(ClientResponse.class);
-        
+
         assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
-        
+
         node = JsonUtils.readTree(response.getEntity(String.class));
-        assertEquals(
-                "[No change has found.]",
+        assertEquals("[No change has found.]",
                 node.get("errors").get(0).get(2).asText());
-        
+
         // update resource service
-        response = resource()
-                .path(getAPIVersion())
-                .path("virtualcollection")
-                .path(id)
-                .queryParam("name", "Goethe collection")
+        response = resource().path(getAPIVersion()).path("virtualcollection")
+                .path(id).queryParam("name", "Goethe collection")
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
                 .post(ClientResponse.class);
-        
+
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
-        
-        res = dao.findbyId(id,
-                User.UserFactory.getDemoUser());
+
+        res = dao.findbyId(id, User.UserFactory.getDemoUser());
         assertNotNull(res);
-        Assert.assertEquals("Goethe collection",res.getName().toString());
-        
-        
+        Assert.assertEquals("Goethe collection", res.getName().toString());
+
+
         // delete resource service
-    	response = resource()
-                .path(getAPIVersion())
-                .path("virtualcollection")
+        response = resource().path(getAPIVersion()).path("virtualcollection")
                 .path(id)
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
                 .delete(ClientResponse.class);
-        
+
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
                 response.getStatus());
-        
-        // check if the resource is *not* in the db anymore
-        dao = new ResourceDao<>(helper().getContext()
-                .getPersistenceClient());
-        assertEquals("sqlite", helper().getContext().getPersistenceClient()
-                .getDatabase());
 
-        res = dao.findbyId(id,
-                User.UserFactory.getDemoUser());
-        assertEquals(null,res);
+        // check if the resource is *not* in the db anymore
+        dao = new ResourceDao<>(helper().getContext().getPersistenceClient());
+        assertEquals("sqlite",
+                helper().getContext().getPersistenceClient().getDatabase());
+
+        res = dao.findbyId(id, User.UserFactory.getDemoUser());
+        assertEquals(null, res);
     }
 
+
     @Override
     public void initMethod () throws KustvaktException {
         helper().runBootInterfaces();
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
index 126e577..6e4440f 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
@@ -15,11 +15,15 @@
 import com.sun.jersey.api.client.ClientResponse;
 
 import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.ContextHolder;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.db.EntityHandlerIface;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
 import de.ids_mannheim.korap.resources.Corpus;
 import de.ids_mannheim.korap.security.ac.ResourceFinder;
 import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
+import de.ids_mannheim.korap.security.auth.KustvaktAuthenticationManager;
+import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.service.FastJerseyTest;
 
@@ -214,14 +218,17 @@
     
     @Test
     public void testSearchForOwnersCorpusWithIntegerId () throws KustvaktException {
-        Set<Corpus> publicCorpora = ResourceFinder.searchPublic(Corpus.class);
-        Iterator<Corpus> i = publicCorpora.iterator();
+        
+        User kustvaktUser =  ((EntityHandlerIface) helper().getBean(ContextHolder.KUSTVAKT_USERDB))
+            .getAccount("kustvakt");
+        Set<Corpus> userCorpora = ResourceFinder.search(kustvaktUser, Corpus.class);
+        Iterator<Corpus> i = userCorpora.iterator();
         String id = null;
         while (i.hasNext()){
             Corpus c = i.next();
             if (c.getPersistentID().equals("WPD15")){
                 id =c.getId().toString();
-                System.out.println(id);
+//                System.out.println("Corpus "+id);
             }
         }
         ClientResponse response = resource().path(getAPIVersion())