Fix sharing published vc and retrieve group vc

Change-Id: Ib3b937c8fc25117d79fb5b89f53b45e3c7bbad9b
diff --git a/src/main/java/de/ids_mannheim/korap/dao/QueryDao.java b/src/main/java/de/ids_mannheim/korap/dao/QueryDao.java
index e17582a..4026284 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/QueryDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/QueryDao.java
@@ -6,6 +6,26 @@
 import java.util.List;
 import java.util.Set;
 
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.constant.GroupMemberStatus;
+import de.ids_mannheim.korap.constant.QueryType;
+import de.ids_mannheim.korap.constant.ResourceType;
+import de.ids_mannheim.korap.entity.QueryAccess;
+import de.ids_mannheim.korap.entity.QueryAccess_;
+import de.ids_mannheim.korap.entity.QueryDO;
+import de.ids_mannheim.korap.entity.QueryDO_;
+import de.ids_mannheim.korap.entity.Role;
+import de.ids_mannheim.korap.entity.Role_;
+import de.ids_mannheim.korap.entity.UserGroup;
+import de.ids_mannheim.korap.entity.UserGroupMember;
+import de.ids_mannheim.korap.entity.UserGroupMember_;
+import de.ids_mannheim.korap.entity.UserGroup_;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.user.User.CorpusAccess;
+import de.ids_mannheim.korap.utils.ParameterChecker;
 import jakarta.persistence.EntityManager;
 import jakarta.persistence.NoResultException;
 import jakarta.persistence.NonUniqueResultException;
@@ -18,27 +38,6 @@
 import jakarta.persistence.criteria.Predicate;
 import jakarta.persistence.criteria.Root;
 
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
-
-import de.ids_mannheim.korap.constant.GroupMemberStatus;
-import de.ids_mannheim.korap.constant.QueryAccessStatus;
-import de.ids_mannheim.korap.constant.QueryType;
-import de.ids_mannheim.korap.constant.ResourceType;
-import de.ids_mannheim.korap.constant.UserGroupStatus;
-import de.ids_mannheim.korap.entity.QueryAccess;
-import de.ids_mannheim.korap.entity.QueryAccess_;
-import de.ids_mannheim.korap.entity.QueryDO;
-import de.ids_mannheim.korap.entity.QueryDO_;
-import de.ids_mannheim.korap.entity.UserGroup;
-import de.ids_mannheim.korap.entity.UserGroupMember;
-import de.ids_mannheim.korap.entity.UserGroupMember_;
-import de.ids_mannheim.korap.entity.UserGroup_;
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.user.User.CorpusAccess;
-import de.ids_mannheim.korap.utils.ParameterChecker;
-
 /**
  * QueryDao manages database queries and transactions
  * regarding virtual corpus and KorAP queries.
@@ -273,35 +272,19 @@
         CriteriaQuery<QueryDO> cq = builder.createQuery(QueryDO.class);
 
         Root<QueryDO> query = cq.from(QueryDO.class);
-        Join<QueryDO, QueryAccess> access = query.join(QueryDO_.queryAccess);
-
-        // Predicate corpusStatus = builder.and(
-        // builder.notEqual(access.get(QueryAccess_.status),
-        // VirtualCorpusAccessStatus.HIDDEN),
-        // builder.notEqual(access.get(QueryAccess_.status),
-        // VirtualCorpusAccessStatus.DELETED));
-
+        Join<QueryDO, Role> roles = query.join(QueryDO_.roles);
+        Join<Role, UserGroupMember> members = roles
+                .join(Role_.userGroupMembers);
+        
         Predicate type = builder.equal(query.get(QueryDO_.queryType),
                 queryType);
-
-        Predicate accessStatus = builder.notEqual(
-                access.get(QueryAccess_.status), QueryAccessStatus.DELETED);
-
-        Predicate userGroupStatus = builder.notEqual(
-                access.get(QueryAccess_.userGroup).get(UserGroup_.status),
-                UserGroupStatus.DELETED);
-        Join<UserGroup, UserGroupMember> members = access
-                .join(QueryAccess_.userGroup).join(UserGroup_.members);
-
         Predicate memberStatus = builder.equal(
                 members.get(UserGroupMember_.status), GroupMemberStatus.ACTIVE);
-
         Predicate user = builder.equal(members.get(UserGroupMember_.userId),
                 userId);
 
         cq.select(query);
-        cq.where(builder.and(type, accessStatus, userGroupStatus, memberStatus,
-                user));
+        cq.where(builder.and(type, memberStatus, user));
 
         Query q = entityManager.createQuery(cq);
         return q.getResultList();
@@ -352,14 +335,12 @@
                 .createQuery(QueryDO.class);
 
         Root<QueryDO> query = criteriaQuery.from(QueryDO.class);
-        Join<QueryDO, QueryAccess> queryAccess = query
-                .join(QueryDO_.queryAccess);
-        Join<QueryAccess, UserGroup> accessGroup = queryAccess
-                .join(QueryAccess_.userGroup);
+        Join<QueryDO, Role> query_role = query
+                .join(QueryDO_.roles);
 
         criteriaQuery.select(query);
-        criteriaQuery
-                .where(builder.equal(accessGroup.get(UserGroup_.id), groupId));
+        criteriaQuery.where(builder.equal(
+                query_role.get(Role_.userGroup).get(UserGroup_.id), groupId));
         Query q = entityManager.createQuery(criteriaQuery);
         return q.getResultList();
     }
diff --git a/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java b/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
index 72fdb69..4fcba47 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/RoleDao.java
@@ -14,6 +14,7 @@
 import de.ids_mannheim.korap.entity.Role_;
 import de.ids_mannheim.korap.entity.UserGroupMember;
 import de.ids_mannheim.korap.entity.UserGroupMember_;
+import de.ids_mannheim.korap.entity.UserGroup_;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import jakarta.persistence.EntityManager;
@@ -44,17 +45,6 @@
     @PersistenceContext
     private EntityManager entityManager;
 
-    //    public void deleteRole (Role role) {
-    //        entityManager.remove(role);
-    //        entityManager.flush();
-    //    }
-    //
-    //    public void editRoleName (int roleId, PredefinedRole name) {
-    //        Role r = retrieveRoleById(roleId);
-    //        r.setName(name);
-    //        entityManager.persist(r);
-    //    }
-
     public void addRole (Role newRole) {
         entityManager.persist(newRole);
         entityManager.flush();
@@ -191,19 +181,20 @@
         
     }
 
-    public Role retrieveRoleByPrivilegeAndQuery (PrivilegeType p,
-            int queryId) throws KustvaktException {
+    public Role retrieveRoleByGroupIdQueryIdPrivilege (int groupId, int queryId,
+            PrivilegeType p) throws KustvaktException {
 
         CriteriaBuilder cb = entityManager.getCriteriaBuilder();
         CriteriaQuery<Role> query = cb.createQuery(Role.class);
 
         Root<Role> role = query.from(Role.class);
+        role.fetch("userGroup", JoinType.INNER);
         role.fetch(Role_.query, JoinType.INNER);
 
         query.select(role);
-        query.where(
-                cb.equal(role.get(Role_.query).get(QueryDO_.id), queryId),
-                cb.equal(role.get(Role_.privilege), p));
+        query.where(cb.equal(role.get(Role_.query).get(QueryDO_.id), queryId),
+                cb.equal(role.get(Role_.privilege), p), cb.equal(
+                        role.get(Role_.userGroup).get(UserGroup_.id), groupId));
 
         TypedQuery<Role> q = entityManager.createQuery(query);
         return (Role) q.getSingleResult();
diff --git a/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java b/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
index a79e13f..85b35e8 100644
--- a/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
+++ b/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
@@ -375,24 +375,6 @@
 
     }
 
-    public void addQueryToGroup (QueryDO query, String createdBy,
-            QueryAccessStatus status, UserGroup group) {
-        QueryAccess accessGroup = new QueryAccess();
-        accessGroup.setCreatedBy(createdBy);
-        accessGroup.setStatus(status);
-        accessGroup.setUserGroup(group);
-        accessGroup.setQuery(query);;
-        entityManager.persist(accessGroup);
-    }
-
-    public void addQueryToGroup (List<QueryDO> queries, String createdBy,
-            UserGroup group, QueryAccessStatus status) {
-
-        for (QueryDO q : queries) {
-            addQueryToGroup(q, createdBy, status, group);
-        }
-    }
-
     public void deleteQueryFromGroup (int queryId, int groupId)
             throws KustvaktException {
         ParameterChecker.checkIntegerValue(queryId, "queryId");
diff --git a/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java b/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java
index 77d8102..8320c45 100644
--- a/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java
+++ b/src/main/java/de/ids_mannheim/korap/entity/QueryDO.java
@@ -65,7 +65,7 @@
     private String queryLanguage;
 
     @OneToMany(mappedBy = "query", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
-    private List<QueryAccess> queryAccess;
+    private List<Role> roles;
 
     @Override
     public String toString () {
diff --git a/src/main/java/de/ids_mannheim/korap/service/QueryService.java b/src/main/java/de/ids_mannheim/korap/service/QueryService.java
index 3a9483f..eba6a28 100644
--- a/src/main/java/de/ids_mannheim/korap/service/QueryService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/QueryService.java
@@ -246,7 +246,7 @@
                 // else remains the same
             }
             else if (type.equals(ResourceType.PUBLISHED)) {
-                publishQuery(existingQuery.getId());
+                publishQuery(existingQuery.getId(), username, queryName);
             }
         }
 
@@ -256,14 +256,16 @@
                 queryLanguage);
     }
 
-    private void publishQuery (int queryId) throws KustvaktException {
+    private void publishQuery (int queryId, String queryCreator,
+            String queryName) throws KustvaktException {
 
 //        QueryAccess access = accessDao.retrieveHiddenAccess(queryId);
         // check if hidden access exists
 //        if (access == null) {
             QueryDO query = queryDao.retrieveQueryById(queryId);
             // create and assign a new hidden group
-            int groupId = userGroupService.createAutoHiddenGroup();
+            int groupId = userGroupService.createAutoHiddenGroup(queryCreator,
+                    queryName);
             UserGroup autoHidden = userGroupService
                     .retrieveUserGroupById(groupId);
 //            accessDao.createAccessToQuery(query, autoHidden);
@@ -396,7 +398,7 @@
                     cause.getMessage());
         }
         if (type.equals(ResourceType.PUBLISHED)) {
-            publishQuery(queryId);
+            publishQuery(queryId, queryCreator, queryName);
         }
     }
 
@@ -511,7 +513,12 @@
                         e.getMessage());
             }
 
-            queryDao.editQuery(query, null, ResourceType.PROJECT, null, null,
+            ResourceType queryType = query.getType();
+            if(queryType.equals(ResourceType.PRIVATE)) {
+                queryType = ResourceType.PROJECT;
+            }
+                
+            queryDao.editQuery(query, null, queryType, null, null,
                     null, null, null, query.isCached(), null, null);
         }
     }
@@ -704,8 +711,9 @@
                         .retrieveHiddenUserGroupByQueryId(query.getId());
                 try {
                     
-                    Role r1= roleDao.retrieveRoleByPrivilegeAndQuery(
-                            PrivilegeType.READ_QUERY, query.getId());
+                    Role r1= roleDao.retrieveRoleByGroupIdQueryIdPrivilege(
+                            userGroup.getId(),query.getId(),
+                            PrivilegeType.READ_QUERY);
                     Set<Role> memberRoles = new HashSet<Role>();
                     memberRoles.add(r1);
                     
diff --git a/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java b/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
index 4bf3bff..da81edb 100644
--- a/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
+++ b/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
@@ -289,10 +289,12 @@
         }
     }
 
-    public int createAutoHiddenGroup () throws KustvaktException {
+    public int createAutoHiddenGroup (String queryCreator, String queryName) 
+            throws KustvaktException {
         String code = random.createRandomCode();
         String groupName = "auto-" + code;
-        int groupId = userGroupDao.createGroup(groupName, "auto-hidden-group",
+        int groupId = userGroupDao.createGroup(groupName, "auto-hidden-group for "
+                + "~"+queryCreator+"/"+queryName,
                 "system", UserGroupStatus.HIDDEN);
 
         return groupId;
diff --git a/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java b/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
index 4064dd8..067ee6a 100644
--- a/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
+++ b/src/test/java/de/ids_mannheim/korap/dao/UserGroupDaoTest.java
@@ -11,51 +11,39 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
-import de.ids_mannheim.korap.constant.QueryAccessStatus;
-import de.ids_mannheim.korap.constant.QueryType;
-import de.ids_mannheim.korap.constant.ResourceType;
-import de.ids_mannheim.korap.entity.QueryDO;
 import de.ids_mannheim.korap.entity.Role;
 import de.ids_mannheim.korap.entity.UserGroup;
 import de.ids_mannheim.korap.entity.UserGroupMember;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.user.User.CorpusAccess;
 
 @ExtendWith(SpringExtension.class)
 @ContextConfiguration("classpath:test-config.xml")
-public class UserGroupDaoTest extends DaoTestBase{
-    
-    @Autowired
-    private QueryDao virtualCorpusDao;
+public class UserGroupDaoTest extends DaoTestBase {
 
     @Autowired
     private RoleDao roleDao;
 
-    private void testGroupMemberAndRoles (UserGroup group, String createdBy) {
-     // group member
-        List<UserGroupMember> members = group.getMembers();
-        assertEquals(1, members.size());
-        UserGroupMember m = members.get(0);
-        assertEquals(createdBy, m.getUserId());
-        
-        // member roles
-        Set<Role> roles = roleDao.retrieveRoleByGroupMemberId(m.getId());
-        assertEquals(2, roles.size());
-    }
-
     @Test
     public void createDeleteNewUserGroup () throws KustvaktException {
         String groupName = "test-group";
         String createdBy = "test-user";
         UserGroup group = createUserGroup(groupName, createdBy);
-        
-        testGroupMemberAndRoles(group, createdBy);
-        
+
+        // group member
+        List<UserGroupMember> members = group.getMembers();
+        assertEquals(1, members.size());
+        UserGroupMember m = members.get(0);
+        assertEquals(createdBy, m.getUserId());
+
+        // member roles
+        Set<Role> roles = roleDao.retrieveRoleByGroupMemberId(m.getId());
+        assertEquals(5, roles.size());
+
         int groupId = group.getId();
-//        // retrieve VC by group
-//        List<QueryDO> vc = virtualCorpusDao.retrieveQueryByGroup(groupId);
-//        assertEquals(0, vc.size());
-        
+        //        // retrieve VC by group
+        //        List<QueryDO> vc = virtualCorpusDao.retrieveQueryByGroup(groupId);
+        //        assertEquals(0, vc.size());
+
         deleteUserGroup(groupId, createdBy);
     }
 
@@ -66,19 +54,19 @@
         List<UserGroupMember> members = userGroupDao
                 .retrieveGroupById(group.getId(), true).getMembers();
         assertEquals(4, members.size());
-        
+
         UserGroupMember m = members.get(1);
         Set<Role> roles = m.getRoles();
         assertEquals(0, roles.size());
-//        assertEquals(2, roles.size());
-        
-//        List<Role> sortedRoles = new ArrayList<>(roles);
-//        Collections.sort(sortedRoles);
-//        assertEquals(PredefinedRole.USER_GROUP_MEMBER.name(),
-//                sortedRoles.get(0).getName());
-//        assertEquals(PredefinedRole.VC_ACCESS_MEMBER.name(),
-//                sortedRoles.get(1).getName());
-        
+        //        assertEquals(2, roles.size());
+
+        //        List<Role> sortedRoles = new ArrayList<>(roles);
+        //        Collections.sort(sortedRoles);
+        //        assertEquals(PredefinedRole.USER_GROUP_MEMBER.name(),
+        //                sortedRoles.get(0).getName());
+        //        assertEquals(PredefinedRole.VC_ACCESS_MEMBER.name(),
+        //                sortedRoles.get(1).getName());
+
         retrieveGroupByUserId();
         deleteUserGroup(group.getId(), "dory");
     }
@@ -89,30 +77,4 @@
         group = userGroupDao.retrieveGroupByUserId("pearl");
         assertEquals(0, group.size());
     }
-
-    @Test
-    public void addVCToGroup () throws KustvaktException {
-        UserGroup group = createDoryGroup();
-        // dory group
-        int groupId = group.getId();
-       
-        String createdBy = "dory";
-        String name = "dory new vc";
-        int id = virtualCorpusDao.createQuery(name, ResourceType.PROJECT,
-                QueryType.VIRTUAL_CORPUS, CorpusAccess.PUB, "corpusSigle=WPD15",
-                "", "", "", false, createdBy, null, null);
-        QueryDO virtualCorpus = virtualCorpusDao.retrieveQueryById(id);
-        userGroupDao.addQueryToGroup(virtualCorpus, createdBy,
-                QueryAccessStatus.ACTIVE, group);
-        List<QueryDO> vc = virtualCorpusDao.retrieveQueryByGroup(groupId);
-        assertEquals(1, vc.size());
-        assertEquals(name, vc.get(0).getName());
-        // delete vc from group
-        userGroupDao.deleteQueryFromGroup(virtualCorpus.getId(), groupId);
-        vc = virtualCorpusDao.retrieveQueryByGroup(groupId);
-        assertEquals(0, vc.size());
-        // delete vc
-        virtualCorpusDao.deleteQuery(virtualCorpus);
-        deleteUserGroup(group.getId(), "dory");
-    }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDaoTest.java b/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDaoTest.java
deleted file mode 100644
index 72f1e0f..0000000
--- a/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDaoTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package de.ids_mannheim.korap.dao;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-import de.ids_mannheim.korap.constant.QueryAccessStatus;
-import de.ids_mannheim.korap.entity.QueryAccess;
-import de.ids_mannheim.korap.entity.UserGroup;
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-
-@ExtendWith(SpringExtension.class)
-@ContextConfiguration("classpath:test-config.xml")
-public class VirtualCorpusAccessDaoTest {
-
-    @Autowired
-    private QueryAccessDao dao;
-
-    @Test
-    public void getAccessByVC () throws KustvaktException {
-        List<QueryAccess> vcaList = dao.retrieveActiveAccessByQuery(2);
-        QueryAccess access = vcaList.get(0);
-        assertEquals(QueryAccessStatus.ACTIVE, access.getStatus());
-        assertEquals(access.getCreatedBy(), "dory");
-        UserGroup group = access.getUserGroup();
-        assertEquals(2, group.getId());
-    }
-}
diff --git a/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java b/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java
index cfd226b..b46ff3a 100644
--- a/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java
+++ b/src/test/java/de/ids_mannheim/korap/dao/VirtualCorpusDaoTest.java
@@ -90,14 +90,12 @@
     public void retrieveVCByUserDory () throws KustvaktException {
         List<QueryDO> virtualCorpora = dao.retrieveQueryByUser("dory",
                 QueryType.VIRTUAL_CORPUS);
-        // System.out.println(virtualCorpora);
-        assertEquals(4, virtualCorpora.size());
+        assertEquals(3, virtualCorpora.size());
         // ordered by id
         Iterator<QueryDO> i = virtualCorpora.iterator();
         assertEquals(i.next().getName(), "dory-vc");
         assertEquals(i.next().getName(), "group-vc");
         assertEquals(i.next().getName(), "system-vc");
-        assertEquals(i.next().getName(), "published-vc");
     }
 
     /**
@@ -110,9 +108,8 @@
     public void retrieveVCByUserNemo () throws KustvaktException {
         List<QueryDO> virtualCorpora = dao.retrieveQueryByUser("nemo",
                 QueryType.VIRTUAL_CORPUS);
-        assertEquals(3, virtualCorpora.size());
+        assertEquals(2, virtualCorpora.size());
         Iterator<QueryDO> i = virtualCorpora.iterator();
-        assertEquals(i.next().getName(), "group-vc");
         assertEquals(i.next().getName(), "system-vc");
         assertEquals(i.next().getName(), "nemo-vc");
     }
@@ -144,9 +141,8 @@
     public void retrieveVCByUserPearl () throws KustvaktException {
         List<QueryDO> virtualCorpora = dao.retrieveQueryByUser("pearl",
                 QueryType.VIRTUAL_CORPUS);
-        assertEquals(2, virtualCorpora.size());
+        assertEquals(1, virtualCorpora.size());
         Iterator<QueryDO> i = virtualCorpora.iterator();
         assertEquals(i.next().getName(), "system-vc");
-        assertEquals(i.next().getName(), "published-vc");
     }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java
index f05d05d..cc1c1b7 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/usergroup/UserGroupTestBase.java
@@ -8,6 +8,7 @@
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
+import de.ids_mannheim.korap.constant.PredefinedRole;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.controller.OAuth2TestBase;
@@ -109,6 +110,14 @@
 //        assertEquals(Status.OK.getStatusCode(), response.getStatus());
     }
 
+    protected void addAdminRole (String groupName, String memberName,
+            String addedBy) throws KustvaktException {
+        Form form = new Form();
+        form.param("memberUsername", memberName);
+        form.param("role", PredefinedRole.GROUP_ADMIN.name());
+        addMemberRole(groupName, addedBy, form);
+    }
+    
     protected void addMemberRole (String groupName, String addedBy,
             Form form) throws KustvaktException {
         Response response = target().path(API_VERSION).path("group")
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusAccessTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusAccessTest.java
index 311ceca..08b511b 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusAccessTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusAccessTest.java
@@ -7,7 +7,6 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 
-import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.constant.PredefinedRole;
 import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
@@ -53,35 +52,25 @@
     // node.at("/errors/0/0").asInt());
     // assertEquals("vcId", node.at("/errors/0/1").asText());
     // }
-    private void testlistAccessByGroup (JsonNode node, String vcName,
-            String groupName) throws KustvaktException {
-        //        System.out.println(node.toPrettyString());
-        //        assertEquals(1, node.at("/0/accessId").asInt());
-        //        assertEquals(2, node.at("/0/queryId").asInt());
-        assertEquals(node.at("/0/queryName").asText(), vcName);
-        //        assertEquals(2, node.at("/0/userGroupId").asInt());
-        assertEquals(node.at("/0/userGroupName").asText(), groupName);
-    }
 
     @Test
     public void testDeleteSharedVC () throws KustvaktException {
         createDoryGroup();
 
-        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);
+        createProjectVC(username, vcName);
 
         String groupName = "dory-group";
-        testShareVCByCreator(username, vcName, groupName);
+        shareVCByCreator(username, vcName, groupName);
 
         JsonNode node = listAccessByGroup(username, groupName);
         assertEquals(1, node.size());
-        testlistAccessByGroup(node, vcName, groupName);
+//      System.out.println(node.toPrettyString());
+      //        assertEquals(2, node.at("/0/queryId").asInt());
+      assertEquals(node.at("/0/queryName").asText(), vcName);
+      //        assertEquals(2, node.at("/0/userGroupId").asInt());
+      assertEquals(node.at("/0/userGroupName").asText(), groupName);
 
         // delete project VC
         deleteVC(vcName, username, username);
@@ -103,7 +92,7 @@
         assertEquals(vcName, node.at("/name").asText());
         assertEquals(node.at("/type").asText(), "private");
         // share vc to group
-        Response response = testShareVCByCreator("marlin", vcName, groupName);
+        Response response = shareVCByCreator("marlin", vcName, groupName);
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         // check the vc type
         node = retrieveVCInfo("marlin", "marlin", vcName);
@@ -159,7 +148,7 @@
 
     private void testShareVC_nonUniqueAccess (String vcCreator, String vcName,
             String groupName) throws ProcessingException, KustvaktException {
-        Response response = testShareVCByCreator(vcCreator, vcName, groupName);
+        Response response = shareVCByCreator(vcCreator, vcName, groupName);
         JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
         assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
         assertEquals(StatusCodes.DB_INSERT_FAILED,
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusControllerTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusControllerTest.java
index b27a593..25ad065 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusControllerTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusControllerTest.java
@@ -42,10 +42,8 @@
 
     @Test
     public void testCreatePrivateVC () throws KustvaktException {
-        String json = "{\"type\": \"PRIVATE\""
-                + ",\"queryType\": \"VIRTUAL_CORPUS\""
-                + ",\"corpusQuery\": \"corpusSigle=GOE\"}";
-        createVC(authHeader, testUser, "new_vc", json);
+        createPrivateVC(testUser, "new_vc");
+        
         // list user VC
         JsonNode node = listVC(testUser);
         assertEquals(2, node.size());
@@ -285,7 +283,7 @@
                 + ",\"queryType\": \"VIRTUAL_CORPUS\""
                 + ",\"corpusQuery\": \"corpusSigle=GOE\"}";
         for (int i = 1; i < 6; i++) {
-            createVC(authHeader, testUser, "new_vc_" + i, json);
+            createPrivateVC(testUser, "new_vc_" + i);
         }
         Response response = target().path(API_VERSION).path("vc")
                 .path("~" + testUser).path("new_vc_6").request()
@@ -402,37 +400,4 @@
                 node.at("/errors/0/1").asText());
         checkWWWAuthenticateHeader(response);
     }
-
-    @Test
-    public void testPublishProjectVC () throws KustvaktException {
-        String vcName = "group-vc";
-        // check the vc type
-        JsonNode node = retrieveVCInfo("dory", "dory", vcName);
-        assertEquals(ResourceType.PROJECT.displayName(),
-                node.get("type").asText());
-        // edit vc
-        String json = "{\"type\": \"PUBLISHED\"}";
-        editVC("dory", "dory", vcName, json);
-        // check VC
-        node = testListOwnerVC("dory");
-        JsonNode n = node.get(1);
-        assertEquals(ResourceType.PUBLISHED.displayName(),
-                n.get("type").asText());
-        // check hidden VC access
-        node = listAccessByGroup("admin", "");
-        assertEquals(4, node.size());
-        node = node.get(node.size() - 1);
-        assertEquals(vcName, node.at("/queryName").asText());
-        assertEquals(node.at("/createdBy").asText(), "system");
-        assertTrue(node.at("/userGroupName").asText().startsWith("auto"));
-        // edit 2nd
-        json = "{\"type\": \"PROJECT\"}";
-        editVC("dory", "dory", vcName, json);
-        node = testListOwnerVC("dory");
-        assertEquals(ResourceType.PROJECT.displayName(),
-                node.get(1).get("type").asText());
-        // check VC access
-        node = listAccessByGroup("admin", "");
-        assertEquals(3, node.size());
-    }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusInfoTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusInfoTest.java
index 513beef..6129f3e 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusInfoTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusInfoTest.java
@@ -3,21 +3,18 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import jakarta.ws.rs.ProcessingException;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.core.Form;
-import jakarta.ws.rs.core.MediaType;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.Status;
-
 import org.junit.jupiter.api.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;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
 
 public class VirtualCorpusInfoTest extends VirtualCorpusTestBase {
 
@@ -116,31 +113,6 @@
     }
 
     @Test
-    public void testRetrievePublishedVC ()
-            throws ProcessingException, KustvaktException {
-        JsonNode node = retrieveVCInfo("gill", "marlin", "published-vc");
-        assertEquals(node.at("/name").asText(), "published-vc");
-        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")
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusPublishedTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusPublishedTest.java
index 2f711e3..c70414a 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusPublishedTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusPublishedTest.java
@@ -8,10 +8,13 @@
 
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
 import de.ids_mannheim.korap.constant.PredefinedRole;
+import de.ids_mannheim.korap.constant.ResourceType;
 import de.ids_mannheim.korap.constant.UserGroupStatus;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
 
 public class VirtualCorpusPublishedTest extends VirtualCorpusTestBase{
     
@@ -31,24 +34,18 @@
         assertEquals(UserGroupStatus.HIDDEN.name(), 
                 node.at("/status").asText());
         
-        testAccessPublishedVC("gill", testUser, vcName);
+        testRetrievePublishedVC("gill", testUser, vcName);
         
-        deleteVC(vcName, testUser, testUser);
-        
-        // EM: check if the hidden groups are deleted as well
-        node = getHiddenGroup(vcName);
-        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
-                node.at("/errors/0/0").asInt());
-        assertEquals("No hidden group for query " + vcName + " is found",
-                node.at("/errors/0/1").asText());
+        String groupName = node.at("/name").asText();
+        testDeletePublishedVCUnauthorized(testUser, vcName, "gill");
+        testDeletePublishedVC(testUser, vcName, testUser, groupName);
     }
     
-    private void testAccessPublishedVC (String username, String vcCreator,
+    private void testRetrievePublishedVC (String username, String vcCreator,
             String vcName) throws ProcessingException, KustvaktException {
         retrieveVCInfo(username, vcCreator, vcName);
         
         JsonNode node = getHiddenGroup(vcName);
-        System.out.println(node.toPrettyString());
         assertEquals("system", node.at("/owner").asText());
         assertEquals(UserGroupStatus.HIDDEN.name(), 
                 node.at("/status").asText());
@@ -67,6 +64,38 @@
         assertEquals(1, node.at("/0/members").size());
     }
     
+    private void testDeletePublishedVC (String vcCreator, String vcName,
+            String deletedBy, String hiddenGroupName) throws KustvaktException {
+        deleteVC(vcName, vcCreator, deletedBy);
+
+        // EM: check if the hidden groups are deleted as well
+        JsonNode node = getHiddenGroup(vcName);
+        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+                node.at("/errors/0/0").asInt());
+        assertEquals("No hidden group for query " + vcName + " is found",
+                node.at("/errors/0/1").asText());
+        
+        testHiddenGroupNotFound(hiddenGroupName);
+    }
+    
+    private void testHiddenGroupNotFound (String hiddenGroupName)
+            throws KustvaktException {
+        JsonNode node = listAccessByGroup("admin", hiddenGroupName);
+        assertEquals(StatusCodes.NO_RESOURCE_FOUND,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Group " + hiddenGroupName + " is not found",
+                node.at("/errors/0/1").asText());
+
+    }
+
+    private void testDeletePublishedVCUnauthorized (String vcCreator,
+            String vcName, String deletedBy)
+            throws KustvaktException {
+        Response response = deleteVC(vcName, vcCreator, deletedBy);
+        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+        testResponseUnauthorized(response, deletedBy);
+    }
+    
     @Test
     public void testMarlinPublishedVC () throws KustvaktException {
         
@@ -83,9 +112,15 @@
         node = listVC("marlin");
         assertEquals(4, node.size());
         
-        testSharePublishedVC(vcName);
+        String groupName = testSharePublishedVC(vcName);
         
-        deleteVC(vcName, "marlin", "marlin");
+        // dory is a member
+        testDeletePublishedVCUnauthorized("marlin", vcName, "dory");
+        // add dory as group admin
+        addAdminRole(marlinGroupName, "dory", "marlin");
+        testDeletePublishedVCUnauthorized("marlin", vcName, "dory");
+        
+        testDeletePublishedVC("marlin",vcName,"marlin", groupName);
         
         node = listAccessByGroup("admin", marlinGroupName);
         assertEquals(0, node.size());
@@ -93,7 +128,7 @@
         deleteGroupByName(marlinGroupName, "marlin");
     }
     
-    private void testSharePublishedVC (String vcName) throws KustvaktException {
+    private String testSharePublishedVC (String vcName) throws KustvaktException {
         createMarlinGroup();
         inviteMember(marlinGroupName, "marlin", "dory");
         subscribe(marlinGroupName, "dory");
@@ -103,6 +138,11 @@
 
         shareVC("marlin", vcName, marlinGroupName, "marlin");
         
+        node = listVC("dory");
+        assertEquals(4, node.size());
+        node = listVC("marlin");
+        assertEquals(4, node.size());
+        
         // check marlin-group access
         node = listAccessByGroup("admin", marlinGroupName);
         assertEquals(1, node.size());
@@ -116,7 +156,62 @@
         node = listAccessByGroup("admin", hiddenGroupName);
         assertEquals(0, node.at("/0/members").size());
         
-//        testAccessPublishedVC("dory", "marlin", vcName);
+        testAddMemberAfterSharingPublishedVC(hiddenGroupName);
+        testRetrievePublishedVC("dory", "marlin", vcName);
+        return hiddenGroupName;
     }
     
+    private void testAddMemberAfterSharingPublishedVC (String hiddenGroupName)
+            throws KustvaktException {
+        JsonNode node = listVC("nemo");
+        assertEquals(2, node.size());
+
+        inviteMember(marlinGroupName, "marlin", "nemo");
+        subscribe(marlinGroupName, "nemo");
+
+        node = listVC("nemo");
+        assertEquals(3, node.size());
+
+        node = listAccessByGroup("admin", marlinGroupName);
+        assertEquals(3, node.at("/0/members").size());
+
+        node = listAccessByGroup("admin", hiddenGroupName);
+        assertEquals(0, node.at("/0/members").size());
+    }
+    
+    @Test
+    public void testPublishProjectVC () throws KustvaktException {
+        String vcName = "group-vc";
+        JsonNode node = retrieveVCInfo("dory", "dory", vcName);
+        assertEquals(ResourceType.PROJECT.displayName(),
+                node.get("type").asText());
+        
+        // edit PROJECT to PUBLISHED vc
+        String json = "{\"type\": \"PUBLISHED\"}";
+        editVC("dory", "dory", vcName, json);
+        
+        // check VC type
+        node = testListOwnerVC("dory");
+        JsonNode n = node.get(1);
+        assertEquals(ResourceType.PUBLISHED.displayName(),
+                n.get("type").asText());
+        
+        // check hidden group and roles
+        node = getHiddenGroup(vcName);
+        String hiddenGroupName = node.at("/name").asText();
+        node = listAccessByGroup("admin", hiddenGroupName);
+        assertEquals(1, node.size());
+        node = node.get(0);
+        assertEquals(vcName, node.at("/queryName").asText());
+        assertEquals(hiddenGroupName, node.at("/userGroupName").asText());
+        
+        // change PUBLISHED to PROJECT
+        json = "{\"type\": \"PROJECT\"}";
+        editVC("dory", "dory", vcName, json);
+        node = testListOwnerVC("dory");
+        assertEquals(ResourceType.PROJECT.displayName(),
+                node.get(1).get("type").asText());
+        
+        testHiddenGroupNotFound(hiddenGroupName);
+    }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java
index e086e15..638a041 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusReferenceTest.java
@@ -11,12 +11,12 @@
 import org.springframework.beans.factory.annotation.Autowired;
 
 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.cache.VirtualCorpusCache;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.constant.GroupMemberStatus;
+import de.ids_mannheim.korap.constant.UserGroupStatus;
 import de.ids_mannheim.korap.dao.QueryDao;
 import de.ids_mannheim.korap.entity.QueryDO;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
@@ -24,13 +24,10 @@
 import de.ids_mannheim.korap.init.NamedVCLoader;
 import de.ids_mannheim.korap.util.QueryException;
 import de.ids_mannheim.korap.utils.JsonUtils;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.core.Form;
-import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.Response.Status;
 
-public class VirtualCorpusReferenceTest extends SpringJerseyTest {
+public class VirtualCorpusReferenceTest extends VirtualCorpusTestBase {
 
     @Autowired
     private NamedVCLoader vcLoader;
@@ -202,30 +199,27 @@
 
     @Test
     public void testSearchWithRefPublishedVc () throws KustvaktException {
+        String vcName = "marlin-published-vc";
+        createPublishedVC("marlin", vcName);
+
         Response response = target().path(API_VERSION).path("search")
                 .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
-                .queryParam("cq", "referTo \"marlin/published-vc\"").request()
+                .queryParam("cq", "referTo \"marlin/" + vcName + "\"").request()
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue("squirt", "pass"))
                 .get();
         String ent = response.readEntity(String.class);
         JsonNode node = JsonUtils.readTree(ent);
         assertTrue(node.at("/matches").size() > 0);
-        Form f = new Form();
-        f.param("status", "HIDDEN");
-        // check dory in the hidden group of the vc
-        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\":\"squirt\""));
+
+        node = getHiddenGroup(vcName);
+        assertEquals("system", node.at("/owner").asText());
+        assertEquals(UserGroupStatus.HIDDEN.name(),
+                node.at("/status").asText());
+        node = node.at("/members");
+        assertEquals("squirt", node.at("/0/userId").asText());
+        assertEquals(GroupMemberStatus.ACTIVE.name(),
+                node.at("/0/status").asText());
+        deleteVC(vcName, "marlin", "marlin");
     }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
index 0cdd70a..c4a43f7 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusSharingTest.java
@@ -3,15 +3,11 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-import jakarta.ws.rs.ProcessingException;
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.core.Form;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.Status;
-
 import org.apache.http.HttpStatus;
 import org.junit.jupiter.api.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.GroupMemberStatus;
@@ -19,6 +15,11 @@
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.utils.JsonUtils;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Form;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
 
 public class VirtualCorpusSharingTest extends VirtualCorpusTestBase {
 
@@ -27,7 +28,7 @@
     @Test
     public void testShareUnknownVC ()
             throws ProcessingException, KustvaktException {
-        Response response = testShareVCByCreator("marlin", "non-existing-vc",
+        Response response = shareVCByCreator("marlin", "non-existing-vc",
                 "marlin group");
         JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
         assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
@@ -38,7 +39,7 @@
     @Test
     public void testShareUnknownGroup ()
             throws ProcessingException, KustvaktException {
-        Response response = testShareVCByCreator("marlin", "marlin-vc",
+        Response response = shareVCByCreator("marlin", "marlin-vc",
                 "non-existing-group");
         JsonNode node = JsonUtils.readTree(response.readEntity(String.class));
         assertEquals(HttpStatus.SC_NOT_FOUND, response.getStatus());
@@ -59,7 +60,7 @@
     }
 
     @Test
-    public void testShareVC_byMember ()
+    public void testSharePrivateVCByGroupAdmin ()
             throws ProcessingException, KustvaktException {
         createMarlinGroup();
         inviteMember(marlinGroupName, "marlin", "nemo");
@@ -68,7 +69,7 @@
         JsonNode node = listAccessByGroup("marlin", marlinGroupName);
         assertEquals(0, node.size());
         
-        Response response = testShareVCByCreator("nemo", "nemo-vc",
+        Response response = shareVCByCreator("nemo", "nemo-vc",
                 marlinGroupName);
         testResponseUnauthorized(response, "nemo");
         
@@ -78,7 +79,7 @@
         form.param("role", PredefinedRole.GROUP_ADMIN.name());
         addMemberRole(marlinGroupName, "marlin", form);
 
-        response = testShareVCByCreator("nemo", "nemo-vc", marlinGroupName);
+        response = shareVCByCreator("nemo", "nemo-vc", marlinGroupName);
         
         node = listAccessByGroup("marlin", marlinGroupName);
         assertEquals(1, node.size());
@@ -87,24 +88,23 @@
     }
 
     @Test
-    public void testCreateShareProjectVC () throws KustvaktException {
-        String json = "{\"type\": \"PROJECT\""
-                + ",\"queryType\": \"VIRTUAL_CORPUS\""
-                + ",\"corpusQuery\": \"corpusSigle=GOE\"}";
+    public void testShareProjectVC () throws KustvaktException {
         String vcName = "new_project_vc";
-        String authHeader = HttpAuthorizationHandler
-                .createBasicAuthorizationHeaderValue(testUser, "pass");
-        createVC(authHeader, testUser, vcName, json);
+        createProjectVC(testUser, vcName);
+        
         // retrieve vc info
         JsonNode vcInfo = retrieveVCInfo(testUser, testUser, vcName);
         assertEquals(vcName, vcInfo.get("name").asText());
+        
         // list user VC
         JsonNode node = listVC(testUser);
         assertEquals(2, node.size());
         assertEquals(vcName, node.get(1).get("name").asText());
+        
         // search by non member
         Response response = searchWithVCRef("dory", testUser, vcName);
         assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+        
         // create user group
         String groupName = "owidGroup";
         String memberName = "darla";
@@ -114,13 +114,13 @@
         testInviteMember(groupName, testUser, "darla");
         subscribeToGroup(memberName, groupName);
         checkMemberInGroup(memberName, testUser, groupName);
+        
         // share vc to group
-        testShareVCByCreator(testUser, vcName, groupName);
+        shareVCByCreator(testUser, vcName, groupName);
         
         // check member roles
         node = listAccessByGroup(testUser, groupName);
         assertEquals(1, node.size());
-//        System.out.println(node.toPrettyString());
         
         // search by member
         response = searchWithVCRef(memberName, testUser, vcName);
@@ -172,17 +172,4 @@
         assertEquals(PredefinedRole.GROUP_MEMBER.name(),
                 node.at("/members/1/roles/0").asText());
     }
-
-    private Response searchWithVCRef (String username, String vcCreator,
-            String vcName) throws KustvaktException {
-        Response response = target().path(API_VERSION).path("search")
-                .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
-                .queryParam("cq",
-                        "referTo \"" + vcCreator + "/" + vcName + "\"")
-                .request()
-                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
-                        .createBasicAuthorizationHeaderValue(username, "pass"))
-                .get();
-        return response;
-    }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java
index d043460..6972e16 100644
--- a/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java
+++ b/src/test/java/de/ids_mannheim/korap/web/controller/vc/VirtualCorpusTestBase.java
@@ -17,6 +17,7 @@
 
 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;
@@ -53,6 +54,40 @@
 
         assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
     }
+    
+    protected void createVC (String username, String vcName,
+            ResourceType vcType) throws KustvaktException {
+        String vcJson = "{\"type\": \""+vcType+"\""
+                + ",\"queryType\": \"VIRTUAL_CORPUS\""
+                + ",\"corpusQuery\": \"corpusSigle=GOE\"}";
+
+        String authHeader = HttpAuthorizationHandler
+                .createBasicAuthorizationHeaderValue(username, "pass");
+        
+        Response response = target().path(API_VERSION).path("vc")
+                .path("~" + username).path(vcName).request()
+                .header(Attributes.AUTHORIZATION, authHeader)
+                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+                .put(Entity.json(vcJson));
+
+        assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+    }
+    
+    protected void createPrivateVC (String username, String vcName)
+            throws KustvaktException {
+        createVC(username, vcName, ResourceType.PRIVATE);
+    }
+    
+    protected void createProjectVC (String username, String vcName)
+            throws KustvaktException {
+        createVC(username, vcName, ResourceType.PROJECT);
+    }
+
+    protected void createPublishedVC (String username, String vcName)
+            throws KustvaktException {
+        createVC(username, vcName, ResourceType.PUBLISHED);
+    }
+
 
     protected void editVC (String username, String vcCreator, String vcName,
             String vcJson) throws KustvaktException {
@@ -114,7 +149,7 @@
         return node;
     }
 
-    protected Response testShareVCByCreator (String vcCreator, String vcName,
+    protected Response shareVCByCreator (String vcCreator, String vcName,
             String groupName) throws ProcessingException, KustvaktException {
 
         return target().path(API_VERSION).path("vc").path("~" + vcCreator)
@@ -146,7 +181,7 @@
         return node;
     }
 
-    protected void deleteVC (String vcName, String vcCreator, String username)
+    protected Response deleteVC (String vcName, String vcCreator, String username)
             throws KustvaktException {
         Response response = target().path(API_VERSION).path("vc")
                 .path("~" + vcCreator).path(vcName).request()
@@ -154,7 +189,8 @@
                         .createBasicAuthorizationHeaderValue(username, "pass"))
                 .delete();
 
-        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+//        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        return response;
     }
 
     protected void testResponseUnauthorized (Response response, String username)
@@ -210,14 +246,16 @@
         return response;
     }
     
-    protected void createPublishedVC (String username, String vcName)
-            throws KustvaktException {
-        String json = "{\"type\": \"PUBLISHED\""
-                + ",\"queryType\": \"VIRTUAL_CORPUS\""
-                + ",\"corpusQuery\": \"corpusSigle=GOE\"}";
-
-        String authHeader = HttpAuthorizationHandler
-                .createBasicAuthorizationHeaderValue(username, "pass");
-        createVC(authHeader, username, vcName, json);
+    protected Response searchWithVCRef (String username, String vcCreator,
+            String vcName) throws KustvaktException {
+        Response response = target().path(API_VERSION).path("search")
+                .queryParam("q", "[orth=der]").queryParam("ql", "poliqarp")
+                .queryParam("cq",
+                        "referTo \"" + vcCreator + "/" + vcName + "\"")
+                .request()
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(username, "pass"))
+                .get();
+        return response;
     }
 }