diff --git a/scm-test/src/main/java/sonia/scm/repository/RepositoryManagerTestBase.java b/scm-test/src/main/java/sonia/scm/repository/RepositoryManagerTestBase.java deleted file mode 100644 index bd12ab67be..0000000000 --- a/scm-test/src/main/java/sonia/scm/repository/RepositoryManagerTestBase.java +++ /dev/null @@ -1,577 +0,0 @@ -/** - * Copyright (c) 2010, Sebastian Sdorra - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of SCM-Manager; nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * http://bitbucket.org/sdorra/scm-manager - * - */ - - - -package sonia.scm.repository; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.github.legman.Subscribe; -import com.github.sdorra.shiro.SubjectAware; - -import org.apache.shiro.subject.Subject; - -import org.junit.Before; -import org.junit.Test; - -import sonia.scm.HandlerEventType; -import sonia.scm.Manager; -import sonia.scm.ManagerTestBase; -import sonia.scm.event.ScmEventBus; -import sonia.scm.repository.api.HookContext; - -import static org.junit.Assert.*; - -//~--- JDK imports ------------------------------------------------------------ - -import java.io.IOException; - -import java.util.Collection; - -/** - * - * @author Sebastian Sdorra - */ -public abstract class RepositoryManagerTestBase extends ManagerTestBase -{ - - /** - * Method description - * - * - * @param repository - * - * @return - */ - public abstract HookContext createHookContext(Repository repository); - - /** - * Method description - * - * - * @param archiveEnabled - * - * @return - */ - protected abstract RepositoryManager createRepositoryManager( - boolean archiveEnabled); - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testCreate() throws RepositoryException, IOException - { - Repository heartOfGold = createTestRepository(); - Repository dbRepo = manager.get(heartOfGold.getId()); - - assertNotNull(dbRepo); - assertRepositoriesEquals(dbRepo, heartOfGold); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test(expected = RepositoryAlreadyExistsException.class) - public void testCreateExisting() throws RepositoryException, IOException - { - createTestRepository(); - createTestRepository(); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testDelete() throws RepositoryException, IOException - { - delete(manager, createTestRepository()); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test(expected = RepositoryIsNotArchivedException.class) - public void testDeleteNonArchived() throws RepositoryException, IOException - { - delete(createRepositoryManager(true), createTestRepository()); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test(expected = RepositoryNotFoundException.class) - public void testDeleteNotFound() throws RepositoryException, IOException - { - manager.delete(createRepositoryWithId()); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testDeleteWithEnabledArchive() - throws RepositoryException, IOException - { - Repository repository = createTestRepository(); - - repository.setArchived(true); - RepositoryManager drm = createRepositoryManager(true); - drm.init(contextProvider); - delete(drm, repository); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testGet() throws RepositoryException, IOException - { - Repository heartOfGold = createTestRepository(); - String id = heartOfGold.getId(); - String description = heartOfGold.getDescription(); - - assertNotNull(description); - - // test for reference - heartOfGold.setDescription("prototype ship"); - heartOfGold = manager.get(id); - assertNotNull(heartOfGold); - assertEquals(description, heartOfGold.getDescription()); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testGetAll() throws RepositoryException, IOException - { - Repository heartOfGold = createTestRepository(); - Repository happyVerticalPeopleTransporter = createSecondTestRepository(); - boolean foundHeart = false; - boolean foundTransporter = false; - Collection repositories = manager.getAll(); - - assertNotNull(repositories); - assertFalse(repositories.isEmpty()); - assertTrue(repositories.size() >= 2); - - Repository heartReference = null; - - for (Repository repository : repositories) - { - if (repository.getId().equals(heartOfGold.getId())) - { - assertRepositoriesEquals(heartOfGold, repository); - foundHeart = true; - heartReference = repository; - } - else if ( - repository.getId().equals(happyVerticalPeopleTransporter.getId())) - { - assertRepositoriesEquals(happyVerticalPeopleTransporter, repository); - foundTransporter = true; - } - } - - assertTrue(foundHeart); - assertTrue(foundTransporter); - - // test for reference - assertNotSame(heartOfGold, heartReference); - heartReference.setDescription("prototype ship"); - assertFalse( - heartOfGold.getDescription().equals(heartReference.getDescription())); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testListener() throws RepositoryException, IOException - { - RepositoryManager repoManager = createRepositoryManager(false); - repoManager.init(contextProvider); - TestListener listener = new TestListener(); - - ScmEventBus.getInstance().register(listener); - - Repository repository = RepositoryTestData.create42Puzzle(); - - repoManager.create(repository); - assertRepositoriesEquals(repository, listener.preRepository); - assertSame(HandlerEventType.BEFORE_CREATE, listener.preEvent); - assertRepositoriesEquals(repository, listener.postRepository); - assertSame(HandlerEventType.CREATE, listener.postEvent); - - repository.setDescription("changed description"); - repoManager.modify(repository); - assertRepositoriesEquals(repository, listener.preRepository); - assertSame(HandlerEventType.BEFORE_MODIFY, listener.preEvent); - assertRepositoriesEquals(repository, listener.postRepository); - assertSame(HandlerEventType.MODIFY, listener.postEvent); - - repoManager.delete(repository); - - assertRepositoriesEquals(repository, listener.preRepository); - assertSame(HandlerEventType.BEFORE_DELETE, listener.preEvent); - assertRepositoriesEquals(repository, listener.postRepository); - assertSame(HandlerEventType.DELETE, listener.postEvent); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testModify() throws RepositoryException, IOException - { - Repository heartOfGold = createTestRepository(); - - heartOfGold.setDescription("prototype ship"); - manager.modify(heartOfGold); - - Repository hearReference = manager.get(heartOfGold.getId()); - - assertNotNull(hearReference); - assertEquals(hearReference.getDescription(), "prototype ship"); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test(expected = RepositoryNotFoundException.class) - public void testModifyNotFound() throws RepositoryException, IOException - { - manager.modify(createRepositoryWithId()); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testRefresh() throws RepositoryException, IOException - { - Repository heartOfGold = createTestRepository(); - String description = heartOfGold.getDescription(); - - heartOfGold.setDescription("prototype ship"); - manager.refresh(heartOfGold); - assertEquals(description, heartOfGold.getDescription()); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test(expected = RepositoryNotFoundException.class) - public void testRefreshNotFound() throws RepositoryException, IOException - { - manager.refresh(createRepositoryWithId()); - } - - /** - * Method description - * - * - * @throws IOException - * @throws RepositoryException - */ - @Test - public void testRepositoryHook() throws RepositoryException, IOException - { - CountingReceiveHook hook = new CountingReceiveHook(); - RepositoryManager repoManager = createRepositoryManager(false); - - ScmEventBus.getInstance().register(hook); - - assertEquals(0, hook.eventsReceived); - - Repository repository = createTestRepository(); - HookContext ctx = createHookContext(repository); - - repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, - RepositoryHookType.POST_RECEIVE)); - assertEquals(1, hook.eventsReceived); - repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, - RepositoryHookType.POST_RECEIVE)); - assertEquals(2, hook.eventsReceived); - } - - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param repo - * @param other - */ - private void assertRepositoriesEquals(Repository repo, Repository other) - { - assertEquals(repo.getId(), other.getId()); - assertEquals(repo.getName(), other.getName()); - assertEquals(repo.getDescription(), other.getDescription()); - assertEquals(repo.getContact(), other.getContact()); - assertEquals(repo.getCreationDate(), other.getCreationDate()); - assertEquals(repo.getLastModified(), other.getLastModified()); - } - - /** - * Method description - * - * - * - * @param repository - * @return - * - * @throws IOException - * @throws RepositoryException - */ - private Repository createRepository(Repository repository) - throws RepositoryException, IOException - { - manager.create(repository); - assertNotNull(repository.getId()); - assertNotNull(manager.get(repository.getId())); - assertTrue(repository.getCreationDate() > 0); - - return repository; - } - - /** - * Method description - * - * - * @return - */ - private Repository createRepositoryWithId() - { - Repository repository = RepositoryTestData.createHeartOfGold(); - - repository.setId("abc"); - - return repository; - } - - /** - * Method description - * - * - * @return - * - * @throws IOException - * @throws RepositoryException - */ - private Repository createSecondTestRepository() - throws RepositoryException, IOException - { - return createRepository( - RepositoryTestData.createHappyVerticalPeopleTransporter()); - } - - /** - * Method description - * - * - * @return - * - * @throws IOException - * @throws RepositoryException - */ - private Repository createTestRepository() - throws RepositoryException, IOException - { - return createRepository(RepositoryTestData.createHeartOfGold()); - } - - /** - * Method description - * - * - * @param manager - * @param repository - * - * @throws IOException - * @throws RepositoryException - */ - private void delete(Manager manager, - Repository repository) - throws RepositoryException, IOException - { - String id = repository.getId(); - - manager.delete(repository); - assertNull(manager.get(id)); - } - - //~--- inner classes -------------------------------------------------------- - - /** - * Class description - * - * - * @version Enter version here..., 13/01/29 - * @author Enter your name here... - */ - private static class CountingReceiveHook - { - - /** - * Method description - * - * - * @param event - */ - @Subscribe(async = false) - public void onEvent(PostReceiveRepositoryHookEvent event) - { - eventsReceived++; - } - - /** - * Method description - * - * - * @param event - */ - @Subscribe(async = false) - public void onEvent(PreReceiveRepositoryHookEvent event) - { - eventsReceived++; - } - - //~--- fields ------------------------------------------------------------- - - /** Field description */ - private int eventsReceived = 0; - } - - - /** - * Class description - * - * - * @version Enter version here..., 13/01/29 - * @author Enter your name here... - */ - private static class TestListener - { - - /** - * Method description - * - * - * @param repository - * @param event - */ - @Subscribe(async = false) - public void onEvent(RepositoryEvent event) - { - if (event.getEventType().isPost()) - { - this.postRepository = event.getItem(); - this.postEvent = event.getEventType(); - } - else if (event.getEventType().isPre()) - { - this.preRepository = event.getItem(); - this.preEvent = event.getEventType(); - } - } - - //~--- fields ------------------------------------------------------------- - - /** Field description */ - private HandlerEventType postEvent; - - /** Field description */ - private Repository postRepository; - - /** Field description */ - private HandlerEventType preEvent; - - /** Field description */ - private Repository preRepository; - } -} diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java index 4de03b3f11..7dc982470e 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java @@ -28,13 +28,10 @@ * http://bitbucket.org/sdorra/scm-manager * */ - - - package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- - +import com.github.legman.Subscribe; import com.github.sdorra.shiro.ShiroRule; import com.github.sdorra.shiro.SubjectAware; import com.google.common.collect.ImmutableSet; @@ -53,65 +50,446 @@ import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.StoreFactory; import static org.junit.Assert.*; - import static org.mockito.Mockito.*; +import static org.hamcrest.Matchers.*; //~--- JDK imports ------------------------------------------------------------ - import java.io.IOException; +import java.util.Collection; import java.util.HashSet; import java.util.Set; +import java.util.Stack; +import org.apache.shiro.authz.UnauthorizedException; import org.junit.Rule; +import org.junit.rules.ExpectedException; +import org.mockito.invocation.InvocationOnMock; +import sonia.scm.HandlerEventType; +import sonia.scm.Manager; +import sonia.scm.ManagerTestBase; +import sonia.scm.event.ScmEventBus; +import sonia.scm.security.KeyGenerator; /** - * + * Unit tests for {@link DefaultRepositoryManager}. + * * @author Sebastian Sdorra */ @SubjectAware( - username = "trillian", - password = "secret", - configuration = "classpath:sonia/scm/repository/shiro.ini" + username = "trillian", + password = "secret", + configuration = "classpath:sonia/scm/repository/shiro.ini" ) -public class DefaultRepositoryManagerTest extends RepositoryManagerTestBase -{ +public class DefaultRepositoryManagerTest extends ManagerTestBase { @Rule public ShiroRule shiro = new ShiroRule(); - - /** - * Method description - * - * - * @param repository - * - * @return - */ - @Override - public HookContext createHookContext(Repository repository) - { - PreProcessorUtil ppu = mock(PreProcessorUtil.class); - HookContextProvider provider = mock(HookContextProvider.class); - Set features = ImmutableSet.of(); - when(provider.getSupportedFeatures()).thenReturn(features); - - return new HookContextFactory(ppu).createContext(provider, repository); - } - - //~--- get methods ---------------------------------------------------------- + @Rule + public ExpectedException thrown = ExpectedException.none(); /** - * Method description - * + * Tests {@link RepositoryManager#create(sonia.scm.repository.Repository)}. * * @throws IOException * @throws RepositoryException */ @Test - public void getRepositoryFromRequestUriTest() - throws RepositoryException, IOException - { + public void testCreate() throws RepositoryException, IOException { + Repository heartOfGold = createTestRepository(); + Repository dbRepo = manager.get(heartOfGold.getId()); + + assertNotNull(dbRepo); + assertRepositoriesEquals(dbRepo, heartOfGold); + } + + /** + * Tests {@link RepositoryManager#create(sonia.scm.repository.Repository)} without the required permissions. + * + * @throws IOException + * @throws RepositoryException + */ + @SubjectAware( + username = "unpriv" + ) + @Test(expected = UnauthorizedException.class) + public void testCreateWithoutPrivileges() throws RepositoryException, IOException { + createTestRepository(); + } + + /** + * Tests {@link RepositoryManager#create(sonia.scm.repository.Repository)} with a already existing repository. + * + * @throws IOException + * @throws RepositoryException + */ + @Test(expected = RepositoryAlreadyExistsException.class) + public void testCreateExisting() throws RepositoryException, IOException { + createTestRepository(); + createTestRepository(); + } + + /** + * Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)}. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testDelete() throws RepositoryException, IOException { + delete(manager, createTestRepository()); + } + + /** + * Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} without the required permissions. + * + * @throws IOException + * @throws RepositoryException + */ + @SubjectAware( + username = "unpriv" + ) + @Test(expected = UnauthorizedException.class) + public void testDeleteWithoutPrivileges() throws RepositoryException, IOException { + delete(manager, createTestRepository()); + } + + /** + * Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} with a non archived repository and with + * enabled archive mode. + * + * @throws IOException + * @throws RepositoryException + */ + @Test(expected = RepositoryIsNotArchivedException.class) + public void testDeleteNonArchived() throws RepositoryException, IOException { + delete(createRepositoryManager(true), createTestRepository()); + } + + /** + * Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} with a non existing repository. + * + * @throws IOException + * @throws RepositoryException + */ + @Test(expected = RepositoryNotFoundException.class) + public void testDeleteNotFound() throws RepositoryException, IOException { + manager.delete(createRepositoryWithId()); + } + + /** + * Tests {@link RepositoryManager#delete(sonia.scm.repository.Repository)} with enabled archive mode. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testDeleteWithEnabledArchive() + throws RepositoryException, IOException { + Repository repository = createTestRepository(); + + repository.setArchived(true); + RepositoryManager drm = createRepositoryManager(true); + drm.init(contextProvider); + delete(drm, repository); + } + + /** + * Tests {@link RepositoryManager#get(java.lang.String)} . + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGet() throws RepositoryException, IOException { + Repository heartOfGold = createTestRepository(); + String id = heartOfGold.getId(); + String description = heartOfGold.getDescription(); + + assertNotNull(description); + + // test for reference + heartOfGold.setDescription("prototype ship"); + heartOfGold = manager.get(id); + assertNotNull(heartOfGold); + assertEquals(description, heartOfGold.getDescription()); + } + + /** + * Tests {@link RepositoryManager#get(java.lang.String)} without required privileges. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + @SubjectAware( + username = "crato" + ) + public void testGetWithoutRequiredPrivileges() throws RepositoryException, IOException { + Repository heartOfGold = RepositoryTestData.createHeartOfGold(); + manager.create(heartOfGold); + + thrown.expect(UnauthorizedException.class); + manager.get(heartOfGold.getId()); + } + + /** + * Tests {@link RepositoryManager#getAll()}. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testGetAll() throws RepositoryException, IOException { + Repository heartOfGold = createTestRepository(); + Repository happyVerticalPeopleTransporter = createSecondTestRepository(); + boolean foundHeart = false; + boolean foundTransporter = false; + Collection repositories = manager.getAll(); + + assertNotNull(repositories); + assertFalse(repositories.isEmpty()); + assertTrue(repositories.size() >= 2); + + Repository heartReference = null; + + for (Repository repository : repositories) { + if (repository.getId().equals(heartOfGold.getId())) { + assertRepositoriesEquals(heartOfGold, repository); + foundHeart = true; + heartReference = repository; + } + else if (repository.getId().equals(happyVerticalPeopleTransporter.getId())) { + assertRepositoriesEquals(happyVerticalPeopleTransporter, repository); + foundTransporter = true; + } + } + + assertTrue(foundHeart); + assertTrue(foundTransporter); + + // test for reference + assertNotSame(heartOfGold, heartReference); + heartReference.setDescription("prototype ship"); + assertFalse( + heartOfGold.getDescription().equals(heartReference.getDescription())); + } + + /** + * Tests {@link RepositoryManager#getAll()} with permission for 2 of 3 repositories. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + @SubjectAware(username = "dent") + public void testGetAllWithPermissions() throws RepositoryException, IOException { + // mock key generator + KeyGenerator keyGenerator = mock(KeyGenerator.class); + Stack keys = new Stack<>(); + keys.push("rateotu"); + keys.push("p42"); + keys.push("hof"); + + when(keyGenerator.createKey()).then((InvocationOnMock invocation) -> { + return keys.pop(); + }); + + // create repository manager + RepositoryManager repositoryManager = createRepositoryManager(false, keyGenerator); + + // create first test repository + Repository heartOfGold = RepositoryTestData.createHeartOfGold(); + repositoryManager.create(heartOfGold); + assertEquals("hof", heartOfGold.getId()); + + // create second test repository + Repository puzzle42 = RepositoryTestData.create42Puzzle(); + repositoryManager.create(puzzle42); + assertEquals("p42", puzzle42.getId()); + + // create third test repository + Repository restaurant = RepositoryTestData.createRestaurantAtTheEndOfTheUniverse(); + repositoryManager.create(restaurant); + assertEquals("rateotu", restaurant.getId()); + + // assert returned repositories + Collection repositories = repositoryManager.getAll(); + assertEquals(2, repositories.size()); + assertThat(repositories, + containsInAnyOrder( + hasProperty("id", is("p42")), + hasProperty("id", is("hof")) + ) + ); + } + + /** + * Tests repository manager events. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testEvents() throws RepositoryException, IOException { + RepositoryManager repoManager = createRepositoryManager(false); + repoManager.init(contextProvider); + TestListener listener = new TestListener(); + + ScmEventBus.getInstance().register(listener); + + Repository repository = RepositoryTestData.create42Puzzle(); + + repoManager.create(repository); + assertRepositoriesEquals(repository, listener.preRepository); + assertSame(HandlerEventType.BEFORE_CREATE, listener.preEvent); + assertRepositoriesEquals(repository, listener.postRepository); + assertSame(HandlerEventType.CREATE, listener.postEvent); + + repository.setDescription("changed description"); + repoManager.modify(repository); + assertRepositoriesEquals(repository, listener.preRepository); + assertSame(HandlerEventType.BEFORE_MODIFY, listener.preEvent); + assertRepositoriesEquals(repository, listener.postRepository); + assertSame(HandlerEventType.MODIFY, listener.postEvent); + + repoManager.delete(repository); + + assertRepositoriesEquals(repository, listener.preRepository); + assertSame(HandlerEventType.BEFORE_DELETE, listener.preEvent); + assertRepositoriesEquals(repository, listener.postRepository); + assertSame(HandlerEventType.DELETE, listener.postEvent); + } + + /** + * Tests {@link RepositoryManager#modify(sonia.scm.repository.Repository)}. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testModify() throws RepositoryException, IOException { + Repository heartOfGold = createTestRepository(); + + heartOfGold.setDescription("prototype ship"); + manager.modify(heartOfGold); + + Repository hearReference = manager.get(heartOfGold.getId()); + + assertNotNull(hearReference); + assertEquals(hearReference.getDescription(), "prototype ship"); + } + + /** + * Tests {@link RepositoryManager#modify(sonia.scm.repository.Repository)} without + * the required permissions. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + @SubjectAware(username = "crato") + public void testModifyWithoutRequiredPermissions() throws RepositoryException, IOException { + Repository heartOfGold = RepositoryTestData.createHeartOfGold(); + manager.create(heartOfGold); + heartOfGold.setDescription("prototype ship"); + + thrown.expect(UnauthorizedException.class); + manager.modify(heartOfGold); + } + + /** + * Tests {@link RepositoryManager#modify(sonia.scm.repository.Repository)} with a non + * existing repository. + * + * @throws IOException + * @throws RepositoryException + */ + @Test(expected = RepositoryNotFoundException.class) + public void testModifyNotFound() throws RepositoryException, IOException { + manager.modify(createRepositoryWithId()); + } + + /** + * Tests {@link RepositoryManager#refresh(sonia.scm.repository.Repository)}. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testRefresh() throws RepositoryException, IOException { + Repository heartOfGold = createTestRepository(); + String description = heartOfGold.getDescription(); + + heartOfGold.setDescription("prototype ship"); + manager.refresh(heartOfGold); + assertEquals(description, heartOfGold.getDescription()); + } + + /** + * Tests {@link RepositoryManager#refresh(sonia.scm.repository.Repository)} without + * required permissions. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + @SubjectAware(username = "crato") + public void testRefreshWithoutRequiredPermissions() throws RepositoryException, IOException { + Repository heartOfGold = RepositoryTestData.createHeartOfGold(); + manager.create(heartOfGold); + heartOfGold.setDescription("prototype ship"); + + thrown.expect(UnauthorizedException.class); + manager.refresh(heartOfGold); + } + + /** + * Tests {@link RepositoryManager#refresh(sonia.scm.repository.Repository)} with a non existing + * repository. + * + * @throws IOException + * @throws RepositoryException + */ + @Test(expected = RepositoryNotFoundException.class) + public void testRefreshNotFound() throws RepositoryException, IOException { + manager.refresh(createRepositoryWithId()); + } + + /** + * Tests repository hooks. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void testRepositoryHook() throws RepositoryException, IOException { + CountingReceiveHook hook = new CountingReceiveHook(); + RepositoryManager repoManager = createRepositoryManager(false); + + ScmEventBus.getInstance().register(hook); + + assertEquals(0, hook.eventsReceived); + + Repository repository = createTestRepository(); + HookContext ctx = createHookContext(repository); + + repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, + RepositoryHookType.POST_RECEIVE)); + assertEquals(1, hook.eventsReceived); + repoManager.fireHookEvent(new RepositoryHookEvent(ctx, repository, + RepositoryHookType.POST_RECEIVE)); + assertEquals(2, hook.eventsReceived); + } + + /** + * Tests {@link RepositoryManager#getFromTypeAndUri(String, String)}. + * + * @throws IOException + * @throws RepositoryException + */ + @Test + public void getRepositoryFromRequestUriTest() throws RepositoryException, IOException { RepositoryManager m = createManager(); m.init(contextProvider); @@ -130,49 +508,31 @@ public class DefaultRepositoryManagerTest extends RepositoryManagerTestBase } //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ + @Override - protected DefaultRepositoryManager createManager() - { + protected DefaultRepositoryManager createManager() { return createRepositoryManager(false); } - /** - * Method description - * - * - * @param archiveEnabled - * - * @return - */ - @Override - protected DefaultRepositoryManager createRepositoryManager( - boolean archiveEnabled) - { + private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled) { + return createRepositoryManager(archiveEnabled, new DefaultKeyGenerator()); + } + + private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled, KeyGenerator keyGenerator) { Set handlerSet = new HashSet<>(); StoreFactory factory = new JAXBStoreFactory(); factory.init(contextProvider); handlerSet.add(new DummyRepositoryHandler(factory)); - handlerSet.add(new DummyRepositoryHandler(factory) - { + handlerSet.add(new DummyRepositoryHandler(factory) { @Override - public Type getType() - { + public Type getType() { return new Type("hg", "Mercurial"); } }); - handlerSet.add(new DummyRepositoryHandler(factory) - { + handlerSet.add(new DummyRepositoryHandler(factory) { @Override - public Type getType() - { + public Type getType() { return new Type("git", "Git"); } }); @@ -184,22 +544,102 @@ public class DefaultRepositoryManagerTest extends RepositoryManagerTestBase configuration.setEnableRepositoryArchive(archiveEnabled); return new DefaultRepositoryManager(configuration, contextProvider, - new DefaultKeyGenerator(), repositoryDAO, handlerSet); + keyGenerator, repositoryDAO, handlerSet); } - - /** - * Method description - * - * - * @param m - * @param repository - * - * @throws IOException - * @throws RepositoryException - */ + private void createRepository(RepositoryManager m, Repository repository) - throws RepositoryException, IOException - { + throws RepositoryException, IOException { m.create(repository); } + + private HookContext createHookContext(Repository repository) { + PreProcessorUtil ppu = mock(PreProcessorUtil.class); + HookContextProvider provider = mock(HookContextProvider.class); + Set features = ImmutableSet.of(); + + when(provider.getSupportedFeatures()).thenReturn(features); + + return new HookContextFactory(ppu).createContext(provider, repository); + } + + private void assertRepositoriesEquals(Repository repo, Repository other) { + assertEquals(repo.getId(), other.getId()); + assertEquals(repo.getName(), other.getName()); + assertEquals(repo.getDescription(), other.getDescription()); + assertEquals(repo.getContact(), other.getContact()); + assertEquals(repo.getCreationDate(), other.getCreationDate()); + assertEquals(repo.getLastModified(), other.getLastModified()); + } + + private Repository createRepository(Repository repository) throws RepositoryException, IOException { + manager.create(repository); + assertNotNull(repository.getId()); + assertNotNull(manager.get(repository.getId())); + assertTrue(repository.getCreationDate() > 0); + + return repository; + } + + private Repository createRepositoryWithId() { + Repository repository = RepositoryTestData.createHeartOfGold(); + repository.setId("abc"); + return repository; + } + + private Repository createSecondTestRepository() throws RepositoryException, IOException { + return createRepository( + RepositoryTestData.createHappyVerticalPeopleTransporter()); + } + + private Repository createTestRepository() throws RepositoryException, IOException { + return createRepository(RepositoryTestData.createHeartOfGold()); + } + + private void delete(Manager manager, Repository repository) + throws RepositoryException, IOException { + + String id = repository.getId(); + + manager.delete(repository); + assertNull(manager.get(id)); + } + + private static class CountingReceiveHook { + + private int eventsReceived = 0; + + @Subscribe(async = false) + public void onEvent(PostReceiveRepositoryHookEvent event) { + eventsReceived++; + } + + @Subscribe(async = false) + public void onEvent(PreReceiveRepositoryHookEvent event) { + eventsReceived++; + } + } + + private class TestListener { + + private HandlerEventType postEvent; + + private Repository postRepository; + + private HandlerEventType preEvent; + + private Repository preRepository; + + @Subscribe(async = false) + public void onEvent(RepositoryEvent event) { + if (event.getEventType().isPost()) { + this.postRepository = event.getItem(); + this.postEvent = event.getEventType(); + } + else if (event.getEventType().isPre()) { + this.preRepository = event.getItem(); + this.preEvent = event.getEventType(); + } + } + } + } diff --git a/scm-webapp/src/test/resources/sonia/scm/repository/shiro.ini b/scm-webapp/src/test/resources/sonia/scm/repository/shiro.ini index ac6822a96d..5073bf398d 100644 --- a/scm-webapp/src/test/resources/sonia/scm/repository/shiro.ini +++ b/scm-webapp/src/test/resources/sonia/scm/repository/shiro.ini @@ -1,5 +1,11 @@ [users] trillian = secret, admin +dent = secret, creator, heartOfGold, puzzle42 +unpriv = secret +crato = secret, creator [roles] admin = * +creator = repository:create +heartOfGold = "repository:read,modify,delete:hof" +puzzle42 = "repository:read,write:p42"