From 7c50ad07ec5d8b19ca2e776135961f39f0fd2742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Mon, 3 Jun 2019 15:24:19 +0200 Subject: [PATCH] Extract common code --- .../group}/XmlGroupV1UpdateStep.java | 17 +---- .../scm/update/properties/V1Properties.java | 14 ++++ .../scm/update/properties/V1Property.java | 10 +++ .../repository}/BaseMigrationStrategy.java | 2 +- .../repository}/CopyMigrationStrategy.java | 2 +- .../repository}/InlineMigrationStrategy.java | 2 +- .../repository}/MigrationStrategy.java | 2 +- .../repository}/MigrationStrategyDao.java | 2 +- .../repository}/MoveMigrationStrategy.java | 2 +- .../repository}/RepositoryMigrationPlan.java | 2 +- .../XmlRepositoryFileNameUpdateStep.java | 2 +- .../XmlRepositoryV1UpdateStep.java | 16 +---- .../security}/XmlSecurityV1UpdateStep.java | 2 +- .../user}/XmlUserV1UpdateStep.java | 16 +---- .../sonia/scm/update/UpdateStepTestUtil.java | 63 ++++++++++++++++++ .../group}/XmlGroupV1UpdateStepTest.java | 36 +++------- .../CopyMigrationStrategyTest.java | 2 +- .../InlineMigrationStrategyTest.java | 2 +- .../repository}/MigrationStrategyDaoTest.java | 6 +- .../repository}/MigrationStrategyMock.java | 4 +- .../MoveMigrationStrategyTest.java | 2 +- .../repository}/V1RepositoryFileSystem.java | 4 +- .../XmlRepositoryFileNameUpdateStepTest.java | 4 +- .../XmlRepositoryV1UpdateStepTest.java | 10 +-- .../XmlSecurityV1UpdateStepTest.java | 5 +- .../user}/XmlUserV1UpdateStepTest.java | 40 +++-------- .../scm/repository/update/scm-home.v1.zip | Bin 13412 -> 0 bytes .../{group/update => update/group}/groups.xml | 0 .../repository}/formerV2RepositoryFile.xml | 0 .../scm/update/repository/scm-home.v1.zip | Bin 0 -> 13593 bytes .../update => update/security}/config.xml | 0 .../{user/update => update/user}/users.xml | 0 32 files changed, 143 insertions(+), 126 deletions(-) rename scm-webapp/src/main/java/sonia/scm/{group/update => update/group}/XmlGroupV1UpdateStep.java (92%) create mode 100644 scm-webapp/src/main/java/sonia/scm/update/properties/V1Properties.java create mode 100644 scm-webapp/src/main/java/sonia/scm/update/properties/V1Property.java rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/BaseMigrationStrategy.java (97%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/CopyMigrationStrategy.java (97%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/InlineMigrationStrategy.java (97%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/MigrationStrategy.java (93%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/MigrationStrategyDao.java (95%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/MoveMigrationStrategy.java (98%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/RepositoryMigrationPlan.java (98%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/XmlRepositoryFileNameUpdateStep.java (98%) rename scm-webapp/src/main/java/sonia/scm/{repository/update => update/repository}/XmlRepositoryV1UpdateStep.java (96%) rename scm-webapp/src/main/java/sonia/scm/{security/update => update/security}/XmlSecurityV1UpdateStep.java (99%) rename scm-webapp/src/main/java/sonia/scm/{user/update => update/user}/XmlUserV1UpdateStep.java (94%) create mode 100644 scm-webapp/src/test/java/sonia/scm/update/UpdateStepTestUtil.java rename scm-webapp/src/test/java/sonia/scm/{group/update => update/group}/XmlGroupV1UpdateStepTest.java (66%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/CopyMigrationStrategyTest.java (98%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/InlineMigrationStrategyTest.java (97%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/MigrationStrategyDaoTest.java (90%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/MigrationStrategyMock.java (85%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/MoveMigrationStrategyTest.java (98%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/V1RepositoryFileSystem.java (96%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/XmlRepositoryFileNameUpdateStepTest.java (93%) rename scm-webapp/src/test/java/sonia/scm/{repository/update => update/repository}/XmlRepositoryV1UpdateStepTest.java (96%) rename scm-webapp/src/test/java/sonia/scm/{security/update => update/security}/XmlSecurityV1UpdateStepTest.java (95%) rename scm-webapp/src/test/java/sonia/scm/{user/update => update/user}/XmlUserV1UpdateStepTest.java (69%) delete mode 100644 scm-webapp/src/test/resources/sonia/scm/repository/update/scm-home.v1.zip rename scm-webapp/src/test/resources/sonia/scm/{group/update => update/group}/groups.xml (100%) rename scm-webapp/src/test/resources/sonia/scm/{repository/update => update/repository}/formerV2RepositoryFile.xml (100%) create mode 100644 scm-webapp/src/test/resources/sonia/scm/update/repository/scm-home.v1.zip rename scm-webapp/src/test/resources/sonia/scm/{security/update => update/security}/config.xml (100%) rename scm-webapp/src/test/resources/sonia/scm/{user/update => update/user}/users.xml (100%) diff --git a/scm-webapp/src/main/java/sonia/scm/group/update/XmlGroupV1UpdateStep.java b/scm-webapp/src/main/java/sonia/scm/update/group/XmlGroupV1UpdateStep.java similarity index 92% rename from scm-webapp/src/main/java/sonia/scm/group/update/XmlGroupV1UpdateStep.java rename to scm-webapp/src/main/java/sonia/scm/update/group/XmlGroupV1UpdateStep.java index 7589fe5db7..3f3b25352d 100644 --- a/scm-webapp/src/main/java/sonia/scm/group/update/XmlGroupV1UpdateStep.java +++ b/scm-webapp/src/main/java/sonia/scm/update/group/XmlGroupV1UpdateStep.java @@ -1,4 +1,4 @@ -package sonia.scm.group.update; +package sonia.scm.update.group; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,6 +11,7 @@ import sonia.scm.plugin.Extension; import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory; import sonia.scm.store.StoreConstants; +import sonia.scm.update.properties.V1Properties; import sonia.scm.version.Version; import javax.inject.Inject; @@ -25,7 +26,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; -import java.util.Map; import java.util.Optional; import static java.util.Optional.empty; @@ -140,19 +140,6 @@ public class XmlGroupV1UpdateStep implements UpdateStep { } } - @XmlAccessorType(XmlAccessType.FIELD) - private static class V1Property { - private String key; - private String value; - } - - @XmlAccessorType(XmlAccessType.FIELD) - @XmlRootElement(name = "properties") - private static class V1Properties { - @XmlElement(name = "item") - private List properties; - } - private static class GroupList { @XmlElement(name = "group") private List groups; diff --git a/scm-webapp/src/main/java/sonia/scm/update/properties/V1Properties.java b/scm-webapp/src/main/java/sonia/scm/update/properties/V1Properties.java new file mode 100644 index 0000000000..3c8555a76e --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/update/properties/V1Properties.java @@ -0,0 +1,14 @@ +package sonia.scm.update.properties; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "properties") +public class V1Properties { + @XmlElement(name = "item") + private List properties; +} diff --git a/scm-webapp/src/main/java/sonia/scm/update/properties/V1Property.java b/scm-webapp/src/main/java/sonia/scm/update/properties/V1Property.java new file mode 100644 index 0000000000..c92c15188d --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/update/properties/V1Property.java @@ -0,0 +1,10 @@ +package sonia.scm.update.properties; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +@XmlAccessorType(XmlAccessType.FIELD) +public class V1Property { + private String key; + private String value; +} diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/BaseMigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/BaseMigrationStrategy.java similarity index 97% rename from scm-webapp/src/main/java/sonia/scm/repository/update/BaseMigrationStrategy.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/BaseMigrationStrategy.java index 3ac0a6fd68..adb903af51 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/BaseMigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/BaseMigrationStrategy.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import sonia.scm.SCMContextProvider; import sonia.scm.migration.UpdateException; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/CopyMigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/CopyMigrationStrategy.java similarity index 97% rename from scm-webapp/src/main/java/sonia/scm/repository/update/CopyMigrationStrategy.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/CopyMigrationStrategy.java index c5550b29af..060ed6704e 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/CopyMigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/CopyMigrationStrategy.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import sonia.scm.SCMContextProvider; import sonia.scm.repository.RepositoryDirectoryHandler; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/InlineMigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/InlineMigrationStrategy.java similarity index 97% rename from scm-webapp/src/main/java/sonia/scm/repository/update/InlineMigrationStrategy.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/InlineMigrationStrategy.java index ace6a63ab8..62dd67d86a 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/InlineMigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/InlineMigrationStrategy.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import sonia.scm.SCMContextProvider; import sonia.scm.repository.RepositoryDirectoryHandler; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/MigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/MigrationStrategy.java similarity index 93% rename from scm-webapp/src/main/java/sonia/scm/repository/update/MigrationStrategy.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/MigrationStrategy.java index 6ff631208c..c7bb2cba86 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/MigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/MigrationStrategy.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import com.google.inject.Injector; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/MigrationStrategyDao.java b/scm-webapp/src/main/java/sonia/scm/update/repository/MigrationStrategyDao.java similarity index 95% rename from scm-webapp/src/main/java/sonia/scm/repository/update/MigrationStrategyDao.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/MigrationStrategyDao.java index f98e697468..15c931bf31 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/MigrationStrategyDao.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/MigrationStrategyDao.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import sonia.scm.store.ConfigurationStore; import sonia.scm.store.ConfigurationStoreFactory; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/MoveMigrationStrategy.java b/scm-webapp/src/main/java/sonia/scm/update/repository/MoveMigrationStrategy.java similarity index 98% rename from scm-webapp/src/main/java/sonia/scm/repository/update/MoveMigrationStrategy.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/MoveMigrationStrategy.java index e42d4138bb..08d71dd376 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/MoveMigrationStrategy.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/MoveMigrationStrategy.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/RepositoryMigrationPlan.java b/scm-webapp/src/main/java/sonia/scm/update/repository/RepositoryMigrationPlan.java similarity index 98% rename from scm-webapp/src/main/java/sonia/scm/repository/update/RepositoryMigrationPlan.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/RepositoryMigrationPlan.java index 126bca8a23..f2b2dc9788 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/RepositoryMigrationPlan.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/RepositoryMigrationPlan.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/XmlRepositoryFileNameUpdateStep.java b/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryFileNameUpdateStep.java similarity index 98% rename from scm-webapp/src/main/java/sonia/scm/repository/update/XmlRepositoryFileNameUpdateStep.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryFileNameUpdateStep.java index 765f3c6317..62902713f0 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/XmlRepositoryFileNameUpdateStep.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryFileNameUpdateStep.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/scm-webapp/src/main/java/sonia/scm/repository/update/XmlRepositoryV1UpdateStep.java b/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStep.java similarity index 96% rename from scm-webapp/src/main/java/sonia/scm/repository/update/XmlRepositoryV1UpdateStep.java rename to scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStep.java index 813d42818f..a3b511a06b 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/update/XmlRepositoryV1UpdateStep.java +++ b/scm-webapp/src/main/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStep.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import com.google.inject.Injector; import org.slf4j.Logger; @@ -13,6 +13,7 @@ import sonia.scm.repository.xml.XmlRepositoryDAO; import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory; import sonia.scm.store.StoreConstants; +import sonia.scm.update.properties.V1Properties; import sonia.scm.version.Version; import javax.inject.Inject; @@ -199,19 +200,6 @@ public class XmlRepositoryV1UpdateStep implements UpdateStep { private String type; } - @XmlAccessorType(XmlAccessType.FIELD) - private static class V1Property { - private String key; - private String value; - } - - @XmlAccessorType(XmlAccessType.FIELD) - @XmlRootElement(name = "properties") - private static class V1Properties { - @XmlElement(name = "item") - private List properties; - } - @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "repositories") private static class V1Repository { diff --git a/scm-webapp/src/main/java/sonia/scm/security/update/XmlSecurityV1UpdateStep.java b/scm-webapp/src/main/java/sonia/scm/update/security/XmlSecurityV1UpdateStep.java similarity index 99% rename from scm-webapp/src/main/java/sonia/scm/security/update/XmlSecurityV1UpdateStep.java rename to scm-webapp/src/main/java/sonia/scm/update/security/XmlSecurityV1UpdateStep.java index 52bf8124e3..f62b81b5df 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/update/XmlSecurityV1UpdateStep.java +++ b/scm-webapp/src/main/java/sonia/scm/update/security/XmlSecurityV1UpdateStep.java @@ -1,4 +1,4 @@ -package sonia.scm.security.update; +package sonia.scm.update.security; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/scm-webapp/src/main/java/sonia/scm/user/update/XmlUserV1UpdateStep.java b/scm-webapp/src/main/java/sonia/scm/update/user/XmlUserV1UpdateStep.java similarity index 94% rename from scm-webapp/src/main/java/sonia/scm/user/update/XmlUserV1UpdateStep.java rename to scm-webapp/src/main/java/sonia/scm/update/user/XmlUserV1UpdateStep.java index d02de8067d..9878304585 100644 --- a/scm-webapp/src/main/java/sonia/scm/user/update/XmlUserV1UpdateStep.java +++ b/scm-webapp/src/main/java/sonia/scm/update/user/XmlUserV1UpdateStep.java @@ -1,4 +1,4 @@ -package sonia.scm.user.update; +package sonia.scm.update.user; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,6 +10,7 @@ import sonia.scm.security.AssignedPermission; import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory; import sonia.scm.store.StoreConstants; +import sonia.scm.update.properties.V1Properties; import sonia.scm.user.User; import sonia.scm.user.xml.XmlUserDAO; import sonia.scm.version.Version; @@ -125,19 +126,6 @@ public class XmlUserV1UpdateStep implements UpdateStep { return new File(contextProvider.getBaseDirectory(), StoreConstants.CONFIG_DIRECTORY_NAME).toPath(); } - @XmlAccessorType(XmlAccessType.FIELD) - private static class V1Property { - private String key; - private String value; - } - - @XmlAccessorType(XmlAccessType.FIELD) - @XmlRootElement(name = "properties") - private static class V1Properties { - @XmlElement(name = "item") - private List properties; - } - @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "user") private static class V1User { diff --git a/scm-webapp/src/test/java/sonia/scm/update/UpdateStepTestUtil.java b/scm-webapp/src/test/java/sonia/scm/update/UpdateStepTestUtil.java new file mode 100644 index 0000000000..f077d783b3 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/update/UpdateStepTestUtil.java @@ -0,0 +1,63 @@ +package sonia.scm.update; + +import com.google.common.io.Resources; +import org.mockito.Mockito; +import sonia.scm.SCMContextProvider; +import sonia.scm.security.AssignedPermission; +import sonia.scm.security.DefaultKeyGenerator; +import sonia.scm.store.ConfigurationEntryStore; +import sonia.scm.store.ConfigurationEntryStoreFactory; +import sonia.scm.store.JAXBConfigurationEntryStoreFactory; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.mockito.Mockito.when; + +public class UpdateStepTestUtil { + +private final SCMContextProvider contextProvider; + + private final Path tempDir; + private final ConfigurationEntryStoreFactory storeFactory; + + public UpdateStepTestUtil(Path tempDir) { + this.tempDir = tempDir; + contextProvider = Mockito.mock(SCMContextProvider.class); + storeFactory = new JAXBConfigurationEntryStoreFactory(contextProvider, null, new DefaultKeyGenerator()); + when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile()); + } + + public SCMContextProvider getContextProvider() { + return contextProvider; + } + + public ConfigurationEntryStoreFactory getStoreFactory() { + return storeFactory; + } + + public void copyConfigFile(String fileName) throws IOException { + Path configDir = tempDir.resolve("config"); + Files.createDirectories(configDir); + copyTestDatabaseFile(configDir, fileName); + } + + public ConfigurationEntryStore getStoreForConfigFile(String name) { + return storeFactory + .withType(AssignedPermission.class) + .withName(name) + .build(); + } + + public Path getFile(String name) { + return tempDir.resolve("config").resolve(name); + } + + private void copyTestDatabaseFile(Path configDir, String fileName) throws IOException { + URL url = Resources.getResource(fileName); + Files.copy(url.openStream(), configDir.resolve(Paths.get(fileName).getFileName())); + } +} diff --git a/scm-webapp/src/test/java/sonia/scm/group/update/XmlGroupV1UpdateStepTest.java b/scm-webapp/src/test/java/sonia/scm/update/group/XmlGroupV1UpdateStepTest.java similarity index 66% rename from scm-webapp/src/test/java/sonia/scm/group/update/XmlGroupV1UpdateStepTest.java rename to scm-webapp/src/test/java/sonia/scm/update/group/XmlGroupV1UpdateStepTest.java index ab82771304..394dc44109 100644 --- a/scm-webapp/src/test/java/sonia/scm/group/update/XmlGroupV1UpdateStepTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/group/XmlGroupV1UpdateStepTest.java @@ -1,6 +1,5 @@ -package sonia.scm.group.update; +package sonia.scm.update.group; -import com.google.common.io.Resources; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -10,17 +9,12 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import sonia.scm.SCMContextProvider; import sonia.scm.group.Group; import sonia.scm.group.xml.XmlGroupDAO; -import sonia.scm.security.DefaultKeyGenerator; -import sonia.scm.store.ConfigurationEntryStoreFactory; -import sonia.scm.store.JAXBConfigurationEntryStoreFactory; +import sonia.scm.update.UpdateStepTestUtil; import javax.xml.bind.JAXBException; import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; @@ -31,14 +25,11 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @ExtendWith(TempDirectory.class) class XmlGroupV1UpdateStepTest { - @Mock - SCMContextProvider contextProvider; @Mock XmlGroupDAO groupDAO; @@ -47,13 +38,13 @@ class XmlGroupV1UpdateStepTest { XmlGroupV1UpdateStep updateStep; - ConfigurationEntryStoreFactory storeFactory; + private UpdateStepTestUtil testUtil; + @BeforeEach void mockScmHome(@TempDirectory.TempDir Path tempDir) { - when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile()); - storeFactory = new JAXBConfigurationEntryStoreFactory(contextProvider, null, new DefaultKeyGenerator()); - updateStep = new XmlGroupV1UpdateStep(contextProvider, groupDAO, storeFactory); + testUtil = new UpdateStepTestUtil(tempDir); + updateStep = new XmlGroupV1UpdateStep(testUtil.getContextProvider(), groupDAO, testUtil.getStoreFactory()); } @Nested @@ -65,10 +56,8 @@ class XmlGroupV1UpdateStepTest { } @BeforeEach - void createGroupV1XML(@TempDirectory.TempDir Path tempDir) throws IOException { - Path configDir = tempDir.resolve("config"); - Files.createDirectories(configDir); - copyTestDatabaseFile(configDir, "groups.xml"); + void createGroupV1XML() throws IOException { + testUtil.copyConfigFile("sonia/scm/update/group/groups.xml"); } @Test @@ -92,9 +81,9 @@ class XmlGroupV1UpdateStepTest { } @Test - void shouldExtractProperties(@TempDirectory.TempDir Path tempDir) throws JAXBException { + void shouldExtractProperties() throws JAXBException { updateStep.doUpdate(); - Path propertiesFile = tempDir.resolve("config").resolve("group-properties-v1.xml"); + Path propertiesFile = testUtil.getFile("group-properties-v1.xml"); assertThat(propertiesFile) .exists(); assertThat(linesOf(propertiesFile.toFile())) @@ -110,11 +99,6 @@ class XmlGroupV1UpdateStepTest { } } - private void copyTestDatabaseFile(Path configDir, String groupsFileName) throws IOException { - URL url = Resources.getResource("sonia/scm/group/update/" + groupsFileName); - Files.copy(url.openStream(), configDir.resolve(groupsFileName)); - } - @Test void shouldNotFailForMissingConfigDir() throws JAXBException { updateStep.doUpdate(); diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/CopyMigrationStrategyTest.java b/scm-webapp/src/test/java/sonia/scm/update/repository/CopyMigrationStrategyTest.java similarity index 98% rename from scm-webapp/src/test/java/sonia/scm/repository/update/CopyMigrationStrategyTest.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/CopyMigrationStrategyTest.java index d7217bec48..b40283ae79 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/CopyMigrationStrategyTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/CopyMigrationStrategyTest.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/InlineMigrationStrategyTest.java b/scm-webapp/src/test/java/sonia/scm/update/repository/InlineMigrationStrategyTest.java similarity index 97% rename from scm-webapp/src/test/java/sonia/scm/repository/update/InlineMigrationStrategyTest.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/InlineMigrationStrategyTest.java index ed0d7eeb40..6abddae3fb 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/InlineMigrationStrategyTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/InlineMigrationStrategyTest.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/MigrationStrategyDaoTest.java b/scm-webapp/src/test/java/sonia/scm/update/repository/MigrationStrategyDaoTest.java similarity index 90% rename from scm-webapp/src/test/java/sonia/scm/repository/update/MigrationStrategyDaoTest.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/MigrationStrategyDaoTest.java index a7365ce656..e3fd4457b6 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/MigrationStrategyDaoTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/MigrationStrategyDaoTest.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -11,13 +11,15 @@ import org.mockito.junit.jupiter.MockitoExtension; import sonia.scm.SCMContextProvider; import sonia.scm.store.ConfigurationStoreFactory; import sonia.scm.store.JAXBConfigurationStoreFactory; +import sonia.scm.update.repository.MigrationStrategy; +import sonia.scm.update.repository.MigrationStrategyDao; import javax.xml.bind.JAXBException; import java.nio.file.Path; import java.util.Optional; import static org.mockito.Mockito.when; -import static sonia.scm.repository.update.MigrationStrategy.INLINE; +import static sonia.scm.update.repository.MigrationStrategy.INLINE; @ExtendWith(MockitoExtension.class) @ExtendWith(TempDirectory.class) diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/MigrationStrategyMock.java b/scm-webapp/src/test/java/sonia/scm/update/repository/MigrationStrategyMock.java similarity index 85% rename from scm-webapp/src/test/java/sonia/scm/repository/update/MigrationStrategyMock.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/MigrationStrategyMock.java index e0ee39880f..e0018f584f 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/MigrationStrategyMock.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/MigrationStrategyMock.java @@ -1,7 +1,7 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import com.google.inject.Injector; -import sonia.scm.repository.update.MigrationStrategy.Instance; +import sonia.scm.update.repository.MigrationStrategy.Instance; import java.util.HashMap; import java.util.Map; diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/MoveMigrationStrategyTest.java b/scm-webapp/src/test/java/sonia/scm/update/repository/MoveMigrationStrategyTest.java similarity index 98% rename from scm-webapp/src/test/java/sonia/scm/repository/update/MoveMigrationStrategyTest.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/MoveMigrationStrategyTest.java index ce894516df..b55315d85f 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/MoveMigrationStrategyTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/MoveMigrationStrategyTest.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/V1RepositoryFileSystem.java b/scm-webapp/src/test/java/sonia/scm/update/repository/V1RepositoryFileSystem.java similarity index 96% rename from scm-webapp/src/test/java/sonia/scm/repository/update/V1RepositoryFileSystem.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/V1RepositoryFileSystem.java index 146953d790..5baf5200fc 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/V1RepositoryFileSystem.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/V1RepositoryFileSystem.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import sonia.scm.repository.spi.ZippedRepositoryTestBase; @@ -62,6 +62,6 @@ class V1RepositoryFileSystem { * */ static void createV1Home(Path tempDir) throws IOException { - ZippedRepositoryTestBase.extract(tempDir.toFile(), "sonia/scm/repository/update/scm-home.v1.zip"); + ZippedRepositoryTestBase.extract(tempDir.toFile(), "sonia/scm/update/repository/scm-home.v1.zip"); } } diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/XmlRepositoryFileNameUpdateStepTest.java b/scm-webapp/src/test/java/sonia/scm/update/repository/XmlRepositoryFileNameUpdateStepTest.java similarity index 93% rename from scm-webapp/src/test/java/sonia/scm/repository/update/XmlRepositoryFileNameUpdateStepTest.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/XmlRepositoryFileNameUpdateStepTest.java index 6314e02783..51be47fc82 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/XmlRepositoryFileNameUpdateStepTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/XmlRepositoryFileNameUpdateStepTest.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import com.google.common.io.Resources; import org.junit.jupiter.api.BeforeEach; @@ -31,7 +31,7 @@ class XmlRepositoryFileNameUpdateStepTest { @Test void shouldCopyRepositoriesFileToRepositoryPathsFile(@TempDirectory.TempDir Path tempDir) throws JAXBException, IOException { XmlRepositoryFileNameUpdateStep updateStep = new XmlRepositoryFileNameUpdateStep(contextProvider); - URL url = Resources.getResource("sonia/scm/repository/update/formerV2RepositoryFile.xml"); + URL url = Resources.getResource("sonia/scm/update/repository/formerV2RepositoryFile.xml"); Path configDir = tempDir.resolve("config"); Files.createDirectories(configDir); Files.copy(url.openStream(), configDir.resolve("repositories.xml")); diff --git a/scm-webapp/src/test/java/sonia/scm/repository/update/XmlRepositoryV1UpdateStepTest.java b/scm-webapp/src/test/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStepTest.java similarity index 96% rename from scm-webapp/src/test/java/sonia/scm/repository/update/XmlRepositoryV1UpdateStepTest.java rename to scm-webapp/src/test/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStepTest.java index 773d7bd447..438a54b70d 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/update/XmlRepositoryV1UpdateStepTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/repository/XmlRepositoryV1UpdateStepTest.java @@ -1,4 +1,4 @@ -package sonia.scm.repository.update; +package sonia.scm.update.repository; import com.google.common.io.Resources; import com.google.inject.Injector; @@ -36,9 +36,9 @@ import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static sonia.scm.repository.update.MigrationStrategy.COPY; -import static sonia.scm.repository.update.MigrationStrategy.INLINE; -import static sonia.scm.repository.update.MigrationStrategy.MOVE; +import static sonia.scm.update.repository.MigrationStrategy.COPY; +import static sonia.scm.update.repository.MigrationStrategy.INLINE; +import static sonia.scm.update.repository.MigrationStrategy.MOVE; @ExtendWith(MockitoExtension.class) @ExtendWith(TempDirectory.class) @@ -226,7 +226,7 @@ class XmlRepositoryV1UpdateStepTest { } private void createFormerV2RepositoriesFile(@TempDirectory.TempDir Path tempDir) throws IOException { - URL url = Resources.getResource("sonia/scm/repository/update/formerV2RepositoryFile.xml"); + URL url = Resources.getResource("sonia/scm/update/repository/formerV2RepositoryFile.xml"); Path configDir = tempDir.resolve("config"); Files.createDirectories(configDir); Files.copy(url.openStream(), configDir.resolve("repositories.xml")); diff --git a/scm-webapp/src/test/java/sonia/scm/security/update/XmlSecurityV1UpdateStepTest.java b/scm-webapp/src/test/java/sonia/scm/update/security/XmlSecurityV1UpdateStepTest.java similarity index 95% rename from scm-webapp/src/test/java/sonia/scm/security/update/XmlSecurityV1UpdateStepTest.java rename to scm-webapp/src/test/java/sonia/scm/update/security/XmlSecurityV1UpdateStepTest.java index 62e82ce168..f8949d73a5 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/update/XmlSecurityV1UpdateStepTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/security/XmlSecurityV1UpdateStepTest.java @@ -1,4 +1,4 @@ -package sonia.scm.security.update; +package sonia.scm.update.security; import com.google.common.io.Resources; import org.junit.jupiter.api.BeforeEach; @@ -14,6 +14,7 @@ import sonia.scm.store.ConfigurationEntryStore; import sonia.scm.store.ConfigurationEntryStoreFactory; import sonia.scm.store.InMemoryConfigurationEntryStore; import sonia.scm.store.InMemoryConfigurationEntryStoreFactory; +import sonia.scm.update.security.XmlSecurityV1UpdateStep; import javax.xml.bind.JAXBException; import java.io.IOException; @@ -82,7 +83,7 @@ class XmlSecurityV1UpdateStepTest { } private void copyTestDatabaseFile(Path configDir, String fileName) throws IOException { - URL url = Resources.getResource("sonia/scm/security/update/" + fileName); + URL url = Resources.getResource("sonia/scm/update/security/" + fileName); Files.copy(url.openStream(), configDir.resolve(fileName)); } diff --git a/scm-webapp/src/test/java/sonia/scm/user/update/XmlUserV1UpdateStepTest.java b/scm-webapp/src/test/java/sonia/scm/update/user/XmlUserV1UpdateStepTest.java similarity index 69% rename from scm-webapp/src/test/java/sonia/scm/user/update/XmlUserV1UpdateStepTest.java rename to scm-webapp/src/test/java/sonia/scm/update/user/XmlUserV1UpdateStepTest.java index 0d0920620c..19d37d542d 100644 --- a/scm-webapp/src/test/java/sonia/scm/user/update/XmlUserV1UpdateStepTest.java +++ b/scm-webapp/src/test/java/sonia/scm/update/user/XmlUserV1UpdateStepTest.java @@ -1,6 +1,5 @@ -package sonia.scm.user.update; +package sonia.scm.update.user; -import com.google.common.io.Resources; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -10,18 +9,13 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import sonia.scm.SCMContextProvider; import sonia.scm.security.AssignedPermission; -import sonia.scm.security.DefaultKeyGenerator; -import sonia.scm.store.ConfigurationEntryStoreFactory; -import sonia.scm.store.JAXBConfigurationEntryStoreFactory; +import sonia.scm.update.UpdateStepTestUtil; import sonia.scm.user.User; import sonia.scm.user.xml.XmlUserDAO; import javax.xml.bind.JAXBException; import java.io.IOException; -import java.net.URL; -import java.nio.file.Files; import java.nio.file.Path; import java.util.Optional; @@ -31,14 +25,11 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @ExtendWith(TempDirectory.class) class XmlUserV1UpdateStepTest { - @Mock - SCMContextProvider contextProvider; @Mock XmlUserDAO userDAO; @@ -47,13 +38,12 @@ class XmlUserV1UpdateStepTest { XmlUserV1UpdateStep updateStep; - ConfigurationEntryStoreFactory storeFactory; + private UpdateStepTestUtil testUtil; @BeforeEach void mockScmHome(@TempDirectory.TempDir Path tempDir) { - when(contextProvider.getBaseDirectory()).thenReturn(tempDir.toFile()); - storeFactory = new JAXBConfigurationEntryStoreFactory(contextProvider, null, new DefaultKeyGenerator()); - updateStep = new XmlUserV1UpdateStep(contextProvider, userDAO, storeFactory); + testUtil = new UpdateStepTestUtil(tempDir); + updateStep = new XmlUserV1UpdateStep(testUtil.getContextProvider(), userDAO, testUtil.getStoreFactory()); } @Nested @@ -65,20 +55,15 @@ class XmlUserV1UpdateStepTest { } @BeforeEach - void createUserV1XML(@TempDirectory.TempDir Path tempDir) throws IOException { - Path configDir = tempDir.resolve("config"); - Files.createDirectories(configDir); - copyTestDatabaseFile(configDir, "users.xml"); + void createUserV1XML() throws IOException { + testUtil.copyConfigFile("sonia/scm/update/user/users.xml"); } @Test void shouldCreateNewPermissionsForV1AdminUser() throws JAXBException { updateStep.doUpdate(); Optional assignedPermission = - storeFactory - .withType(AssignedPermission.class) - .withName("security") - .build() + testUtil.getStoreForConfigFile("security") .getAll() .values() .stream() @@ -111,9 +96,9 @@ class XmlUserV1UpdateStepTest { } @Test - void shouldExtractProperties(@TempDirectory.TempDir Path tempDir) throws JAXBException { + void shouldExtractProperties() throws JAXBException { updateStep.doUpdate(); - Path propertiesFile = tempDir.resolve("config").resolve("user-properties-v1.xml"); + Path propertiesFile = testUtil.getFile("user-properties-v1.xml"); assertThat(propertiesFile) .exists(); assertThat(linesOf(propertiesFile.toFile())) @@ -133,11 +118,6 @@ class XmlUserV1UpdateStepTest { } } - private void copyTestDatabaseFile(Path configDir, String usersFileName) throws IOException { - URL url = Resources.getResource("sonia/scm/user/update/" + usersFileName); - Files.copy(url.openStream(), configDir.resolve(usersFileName)); - } - @Test void shouldNotFailForMissingConfigDir() throws JAXBException { updateStep.doUpdate(); diff --git a/scm-webapp/src/test/resources/sonia/scm/repository/update/scm-home.v1.zip b/scm-webapp/src/test/resources/sonia/scm/repository/update/scm-home.v1.zip deleted file mode 100644 index 0d43f2f4d6a0b5f595e58cda18933e1565bbc083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13412 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 j3U~NwsfS7$ce)SA3YaDk%xMgsilZcEjpIVcAWT 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