ubc.pavlab.aspiredb.server.project.ProjectManagerTest.java Source code

Java tutorial

Introduction

Here is the source code for ubc.pavlab.aspiredb.server.project.ProjectManagerTest.java

Source

/*
 * The aspiredb project
 * 
 * Copyright (c) 2012 University of British Columbia
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package ubc.pavlab.aspiredb.server.project;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import gemma.gsec.SecurityService;
import gemma.gsec.authentication.UserDetailsImpl;
import gemma.gsec.authentication.UserManager;
import ubc.pavlab.aspiredb.server.BaseSpringContextTest;
import ubc.pavlab.aspiredb.server.dao.CharacteristicDao;
import ubc.pavlab.aspiredb.server.dao.ProjectDao;
import ubc.pavlab.aspiredb.server.dao.SubjectDao;
import ubc.pavlab.aspiredb.server.dao.VariantDao;
import ubc.pavlab.aspiredb.server.model.Characteristic;
import ubc.pavlab.aspiredb.server.model.Project;
import ubc.pavlab.aspiredb.server.model.Subject;
import ubc.pavlab.aspiredb.server.model.Variant;
import ubc.pavlab.aspiredb.server.security.authorization.acl.AclTestUtils;
import ubc.pavlab.aspiredb.shared.CNVValueObject;
import ubc.pavlab.aspiredb.shared.CharacteristicValueObject;
import ubc.pavlab.aspiredb.shared.GenomicRange;
import ubc.pavlab.aspiredb.shared.VariantValueObject;

public class ProjectManagerTest extends BaseSpringContextTest {

    @Autowired
    private UserManager userManager;

    @Autowired
    private SecurityService securityService;

    @Autowired
    private ProjectManager projectManager;

    @Autowired
    private ProjectDao projectDao;

    @Autowired
    CharacteristicDao characteristicDao;

    @Autowired
    SubjectDao subjectDao;

    @Autowired
    VariantDao variantDao;

    @Autowired
    AclTestUtils aclTestUtils;

    String authorizedUsername = RandomStringUtils.randomAlphabetic(6);

    String aDifferentUsername = RandomStringUtils.randomAlphabetic(5);

    //    String patientId1 = RandomStringUtils.randomAlphabetic( 5 );
    //
    //    String patientId2 = RandomStringUtils.randomAlphabetic( 6 );

    String groupName = RandomStringUtils.randomAlphabetic(4);
    String anotherGroupName = RandomStringUtils.randomAlphabetic(5);

    //    String projectName = RandomStringUtils.randomAlphabetic( 5 );
    //    String projectDescription = RandomStringUtils.randomAlphabetic( 7 );
    //    String anotherProjectName = RandomStringUtils.randomAlphabetic( 4 );

    @Before
    public void setup() throws Exception {

        super.runAsAdmin();
        try {
            userManager.loadUserByUsername(authorizedUsername);
        } catch (UsernameNotFoundException e) {
            userManager.createUser(new UserDetailsImpl("jimmy", authorizedUsername, true, null,
                    RandomStringUtils.randomAlphabetic(10) + "@gmail.com", "key", new Date()));
        }

        try {
            userManager.loadUserByUsername(aDifferentUsername);
        } catch (UsernameNotFoundException e) {
            userManager.createUser(new UserDetailsImpl("foo", aDifferentUsername, true, null,
                    RandomStringUtils.randomAlphabetic(10) + "@gmail.com", "key", new Date()));
        }

        List<GrantedAuthority> authos = new ArrayList<GrantedAuthority>();
        //        authos.add( new GrantedAuthorityImpl( "GROUP_USER" ) );
        authos.add(new SimpleGrantedAuthority("GROUP_USER"));

        this.userManager.createGroup(groupName, authos);

        this.userManager.addUserToGroup(authorizedUsername, groupName);

        this.userManager.createGroup(anotherGroupName, authos);

        this.userManager.addUserToGroup(authorizedUsername, anotherGroupName);

    }

    @After
    public void tearDown() throws Exception {
        super.runAsAdmin();
        this.userManager.deleteUser(authorizedUsername);
        this.userManager.deleteGroup(groupName);

        this.userManager.deleteUser(aDifferentUsername);
        this.userManager.deleteGroup(anotherGroupName);
    }

    @Test
    public void testAddSubjectVariantsToProjectSecurity() {

        super.runAsAdmin();

        final String patientId = RandomStringUtils.randomAlphabetic(5);
        final String projectName = RandomStringUtils.randomAlphabetic(5);

        CharacteristicValueObject cvo = new CharacteristicValueObject();

        cvo.setKey("testChar");
        cvo.setValue("testcharvalue");

        Map<String, CharacteristicValueObject> charMap = new HashMap<String, CharacteristicValueObject>();
        charMap.put(cvo.getKey(), cvo);

        CNVValueObject cnv = new CNVValueObject();

        cnv.setCharacteristics(charMap);
        cnv.setType("GAIN");

        GenomicRange gr = new GenomicRange("X", 3, 234);

        cnv.setGenomicRange(gr);

        cnv.setPatientId(patientId);

        // Another CNV from the same patient
        CNVValueObject cnv2 = new CNVValueObject();
        cnv2.setCharacteristics(charMap);
        cnv2.setType("LOSS");
        cnv2.setGenomicRange(gr);
        cnv2.setPatientId(patientId);

        ArrayList<VariantValueObject> cnvList = new ArrayList<VariantValueObject>();
        cnvList.add(cnv);
        cnvList.add(cnv2);

        try {

            projectManager.addSubjectVariantsToProject(projectName, true, cnvList);

        } catch (Exception e) {
            log.error(e.getLocalizedMessage(), e);
            fail("projectManager.addSubjectVariantsToProject threw an exception " + e);

        }

        projectManager.alterGroupWritePermissions(projectName, groupName, true);

        TransactionTemplate tt = new TransactionTemplate(transactionManager);
        tt.execute(new TransactionCallbackWithoutResult() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {

                Project project = projectDao.findByProjectName(projectName);

                aclTestUtils.checkHasAcl(project);

                assertFalse(
                        "Project should not be viewable by user '" + aDifferentUsername + "', acl is "
                                + aclTestUtils.getAcl(project),
                        securityService.isViewableByUser(project, aDifferentUsername));

                // now to test
                List<Subject> subjects = project.getSubjects();
                assertEquals(1, subjects.size());

                Subject subject = project.getSubjects().iterator().next();

                aclTestUtils.checkHasAcl(subject);

                assertFalse(securityService.isViewableByUser(subject, aDifferentUsername));

                // equals to cnvList
                assertEquals(2, subject.getVariants().size());

                variantDao.findBySubjectPatientId(project.getId(), patientId);

                // for ( Variant v : variantCollection ) {
                // // aclTestUtils.checkHasAcl( v );
                // // assertFalse( securityService.isViewableByUser( v, aDifferentUsername ) );
                //
                // Characteristic c = v.getCharacteristics().iterator().next();
                // aclTestUtils.checkHasAcl( c );
                // assertFalse( securityService.isViewableByUser( c, aDifferentUsername ) );
                // }

            }
        });

        try {

            projectManager.deleteProject(projectName);

        } catch (Exception e) {
            log.error(e.getLocalizedMessage(), e);

        }

    }

    @Test
    public void testAlterGroupWritePermissionsForProject() {

        super.runAsAdmin();

        final String patientId = RandomStringUtils.randomAlphabetic(5);
        final String projectName = RandomStringUtils.randomAlphabetic(7);

        CharacteristicValueObject cvo = new CharacteristicValueObject();

        cvo.setKey("testChar");
        cvo.setValue("testcharvalue");

        Map<String, CharacteristicValueObject> charMap = new HashMap<String, CharacteristicValueObject>();
        charMap.put(cvo.getKey(), cvo);

        CNVValueObject cnv = new CNVValueObject();

        cnv.setCharacteristics(charMap);
        cnv.setType("GAIN");

        GenomicRange gr = new GenomicRange("X", 3, 234);

        cnv.setGenomicRange(gr);

        cnv.setPatientId(patientId);

        ArrayList<VariantValueObject> cnvList = new ArrayList<VariantValueObject>();
        cnvList.add(cnv);

        try {

            projectManager.addSubjectVariantsToProject(projectName, true, cnvList);

        } catch (Exception e) {

            fail("projectManager.addSubjectVariantsToProject threw an exception");

            e.printStackTrace();
        }

        // authorizedUsername is in groupName
        projectManager.alterGroupWritePermissions(projectName, groupName, true);

        // make sure authorizedUsername has read access to all the stuff in a project after security change
        TransactionTemplate tt = new TransactionTemplate(transactionManager);
        tt.execute(new TransactionCallbackWithoutResult() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {

                Project project = projectDao.findByProjectName(projectName);

                assertTrue(securityService.isViewableByUser(project, authorizedUsername));

                Subject subject = project.getSubjects().iterator().next();

                assertTrue(securityService.isViewableByUser(subject, authorizedUsername));

                variantDao.findBySubjectPatientId(project.getId(), patientId);

                // for ( Variant v : variantCollection ) {
                //
                // assertTrue( securityService.isViewableByUser( v, authorizedUsername ) );
                //
                // assertTrue( securityService.isViewableByUser( v.getCharacteristics().iterator().next(),
                // authorizedUsername ) );
                // }

            }
        });

        // make sure aDifferentUserName doesn't have access to stuff in project
        TransactionTemplate tt2 = new TransactionTemplate(transactionManager);
        tt2.execute(new TransactionCallbackWithoutResult() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {

                Project project = projectDao.findByProjectName(projectName);

                assertFalse(securityService.isViewableByUser(project, aDifferentUsername));

                Subject subject = project.getSubjects().iterator().next();

                assertFalse(securityService.isViewableByUser(subject, aDifferentUsername));

                variantDao.findBySubjectPatientId(project.getId(), patientId);

                // for ( Variant v : variantCollection ) {
                //
                // assertFalse( securityService.isViewableByUser( v, aDifferentUsername ) );
                //
                // assertFalse( securityService.isViewableByUser( v.getCharacteristics().iterator().next(),
                // aDifferentUsername ) );
                // }

            }
        });

        // test out a couple of dao methods

        super.runAsUser(authorizedUsername);

        long projectId = projectDao.findByProjectName(projectName).getId();

        variantDao.findBySubjectPatientId(projectId, patientId);

        super.runAsUser(aDifferentUsername);

        try {
            projectId = projectDao.findByProjectName(projectName).getId();
            fail("should have got Access Denied");
        } catch (AccessDeniedException e) {

        }

        Collection<Variant> vCollection2 = variantDao.findBySubjectPatientId(projectId, patientId);

        assertTrue(vCollection2.isEmpty());

        super.runAsAdmin();
        // test removing permissions

        // authorizedUsername is in groupName
        projectManager.alterGroupWritePermissions(projectName, groupName, false);

        // make sure authorizedUsername does not have read access to all the stuff in a project after security change
        TransactionTemplate tt3 = new TransactionTemplate(transactionManager);
        tt3.execute(new TransactionCallbackWithoutResult() {
            @Override
            public void doInTransactionWithoutResult(TransactionStatus status) {

                Project project = projectDao.findByProjectName(projectName);

                assertFalse(securityService.isViewableByUser(project, authorizedUsername));

                Subject subject = project.getSubjects().iterator().next();

                assertFalse(securityService.isViewableByUser(subject, authorizedUsername));

                variantDao.findBySubjectPatientId(project.getId(), patientId);

                // for ( Variant v : variantCollection ) {
                //
                // assertFalse( securityService.isViewableByUser( v, authorizedUsername ) );
                //
                // assertFalse( securityService.isViewableByUser( v.getCharacteristics().iterator().next(),
                // authorizedUsername ) );
                // }

            }
        });

        // test out a couple of dao methods to make sure authorizedUsername has no access
        super.runAsUser(authorizedUsername);

        try {
            projectId = projectDao.findByProjectName(projectName).getId();
            fail("should have got Access Denied");
        } catch (AccessDeniedException e) {

        }

        Collection<Variant> vCollection3 = variantDao.findBySubjectPatientId(projectId, patientId);

        assertTrue(vCollection3.isEmpty());

        super.runAsAdmin();

        try {

            projectManager.deleteProject(projectName);

        } catch (Exception e) {
            log.error(e.getLocalizedMessage(), e);

        }

    }

    @Test
    public void testCreateProject() {

        super.runAsAdmin();

        final String project_name = RandomStringUtils.randomAlphabetic(5);
        final String project_description = RandomStringUtils.randomAlphabetic(5);

        new InlineRollbackTransaction() {
            @Override
            public void instructions() {
                try {
                    Project p = projectManager.createProject(project_name, project_description);
                    aclTestUtils.checkHasAcl(p);
                } catch (Exception e) {
                    // log.error( e.getMessage() );
                    fail("projectManager.createproject threw an exception");
                }
            }
        }.execute();

    }

    @Test
    public void testDeleteProject() {

        super.runAsAdmin();

        final String patientId = RandomStringUtils.randomAlphabetic(5);
        final String projectId = RandomStringUtils.randomAlphabetic(5);

        CharacteristicValueObject cvo = new CharacteristicValueObject();

        cvo.setKey("testChar");
        cvo.setValue("testcharvalue");

        Map<String, CharacteristicValueObject> charMap = new HashMap<String, CharacteristicValueObject>();
        charMap.put(cvo.getKey(), cvo);

        CNVValueObject cnv = new CNVValueObject();

        cnv.setCharacteristics(charMap);
        cnv.setType("GAIN");

        GenomicRange gr = new GenomicRange("X", 3, 234);

        cnv.setGenomicRange(gr);

        cnv.setPatientId(patientId);

        ArrayList<VariantValueObject> cnvList = new ArrayList<VariantValueObject>();
        cnvList.add(cnv);

        try {
            // this creates a project
            projectManager.addSubjectVariantsToProject(projectId, true, cnvList);

        } catch (Exception e) {

            fail("projectManager.addSubjectVariantsToProject threw an exception");

        }

        new InlineTransaction() {
            @Override
            public void instructions() {

                Project p = projectDao.findByProjectName(projectId);
                aclTestUtils.checkHasAcl(p);

                // collect Ids
                Collection<Long> subjectIds = new HashSet<>();
                Collection<Long> variantIds = new HashSet<>();
                Collection<Long> characteristicIds = new HashSet<>();
                for (Subject s : p.getSubjects()) {
                    assertNotNull(s.getId());
                    subjectIds.add(s.getId());
                    for (Variant v : s.getVariants()) {
                        assertNotNull(v.getId());
                        variantIds.add(v.getId());
                        for (Characteristic c : v.getCharacteristics()) {
                            assertNotNull(c.getId());
                            characteristicIds.add(c.getId());
                        }
                    }
                }
                assertTrue(subjectIds.size() > 0);
                assertTrue(variantIds.size() > 0);
                assertTrue(characteristicIds.size() > 0);

                try {

                    projectManager.deleteProject(projectId);

                } catch (Exception e) {
                    log.error(e.getLocalizedMessage(), e);
                    fail("projectManager.deleteProject failed");

                }

                aclTestUtils.checkDeletedAcl(p);

                // now let's try loading the ids that should have been removed!
                assertEquals(null, projectDao.load(p.getId()));
                assertEquals(0, subjectDao.load(subjectIds).size());
                assertEquals(0, variantDao.load(variantIds).size());
                assertEquals(0, characteristicDao.load(characteristicIds).size());
            }
        }.execute();

    }

    @Test
    public void testQuickDeleteProject() {

        super.runAsAdmin();

        final String patientId = RandomStringUtils.randomAlphabetic(5);
        final String projectName = RandomStringUtils.randomAlphabetic(5);

        CharacteristicValueObject cvo = new CharacteristicValueObject();

        cvo.setKey("testChar");
        cvo.setValue("testcharvalue");

        Map<String, CharacteristicValueObject> charMap = new HashMap<String, CharacteristicValueObject>();
        charMap.put(cvo.getKey(), cvo);

        CNVValueObject cnv = new CNVValueObject();

        cnv.setCharacteristics(charMap);
        cnv.setType("GAIN");

        GenomicRange gr = new GenomicRange("X", 3, 234);

        cnv.setGenomicRange(gr);

        cnv.setPatientId(patientId);

        ArrayList<VariantValueObject> cnvList = new ArrayList<VariantValueObject>();
        cnvList.add(cnv);

        try {
            // this creates a project
            projectManager.addSubjectVariantsToProject(projectName, true, cnvList);

        } catch (Exception e) {

            fail("projectManager.addSubjectVariantsToProject threw an exception");

        }

        new InlineTransaction() {
            @Override
            public void instructions() {

                Project p = projectDao.findByProjectName(projectName);
                aclTestUtils.checkHasAcl(p);

                // collect Ids
                Collection<Long> subjectIds = new HashSet<>();
                Collection<Long> variantIds = new HashSet<>();
                Collection<Long> characteristicIds = new HashSet<>();
                for (Subject s : p.getSubjects()) {
                    assertNotNull(s.getId());
                    subjectIds.add(s.getId());
                    for (Variant v : s.getVariants()) {
                        assertNotNull(v.getId());
                        variantIds.add(v.getId());
                        for (Characteristic c : v.getCharacteristics()) {
                            assertNotNull(c.getId());
                            characteristicIds.add(c.getId());
                        }
                    }
                }
                assertTrue(subjectIds.size() > 0);
                assertTrue(variantIds.size() > 0);
                assertTrue(characteristicIds.size() > 0);
                try {

                    projectManager.quickDeleteProject(projectName);

                } catch (Exception e) {
                    log.error(e.getLocalizedMessage(), e);
                    fail("projectManager.deleteProject failed");

                }

                aclTestUtils.checkDeletedAcl(p);

                // now let's try loading the ids that should have been removed!
                assertEquals(null, projectDao.load(p.getId()));
                assertEquals(0, subjectDao.load(subjectIds).size());
                assertEquals(0, variantDao.load(variantIds).size());
                assertEquals(0, characteristicDao.load(characteristicIds).size());
            }
        }.execute();

    }

}