Repository: focus-shift/jollyday
Pull request #432 (2024-01-16 16:51:54)

Add tests for  configuration provider and improve packages
<!--

Thanks for contributing.
Please review the following notes before submitting you pull request.

Please look for other issues or pull requests which already work on this topic. Is somebody already on it? Do you need to synchronize?

# Security Vulnerabilities

🛑 STOP! 🛑 If your contribution fixes a security vulnerability, please do not submit it.
Instead, please write an E-Mail to to one of the maintainer with all the information
to recreate the security vulnerability.

# Describing Your Changes

If, having reviewed the notes above, you're ready to submit your pull request, please
provide a brief description of the proposed changes.

If they:
 🐞 fix a bug, please describe the broken behaviour and how the changes fix it.
    Please label with 'type: bug' and 'status: new'
    
 🎁 make an enhancement, please describe the new functionality and why you believe it's useful.
    Please label with 'type: enhancement' and 'status: new'
 
If your pull request relates to any existing issues,
please reference them by using the issue number prefixed with #.

-->



Patch:
diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ClasspathConfigurationProvider.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ClasspathConfigurationProvider.java
new file mode 100644
index 00000000..11ec95f9
--- /dev/null
+++ b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ClasspathConfigurationProvider.java
@@ -0,0 +1,54 @@
+package de.focus_shift.jollyday.core.configuration;
+
+import de.focus_shift.jollyday.core.util.ResourceUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * An {@link ConfigurationProvider} implementation which reads the
+ * 'jollyday.properties' default configuration file from the classpath
+ * and provides the configuration.
+ */
+class ClasspathConfigurationProvider implements ConfigurationProvider {
+
+  private final ResourceUtil resourceUtil = new ResourceUtil();
+
+  private static final String DEFAULT_CONFIGURATION_FILE_NAME = "jollyday.properties";
+  private URL configurationFile;
+
+  public ClasspathConfigurationProvider() {
+    this.configurationFile = getConfigurationFile(DEFAULT_CONFIGURATION_FILE_NAME);
+  }
+
+  @Override
+  public Properties getProperties() {
+    return mapConfigurationFromUrl(configurationFile);
+  }
+
+  public void overrideConfigurationFileName(final String configurationFile) {
+    this.configurationFile = getConfigurationFile(configurationFile);
+  }
+
+  private Properties mapConfigurationFromUrl(final URL url) {
+    final Properties properties = new Properties();
+
+    try (final InputStream inputStream = url.openStream()) {
+      properties.load(inputStream);
+    } catch (IOException e) {
+      throw new IllegalStateException("Could not load default configuration from classpath.", e);
+    }
+
+    return properties;
+  }
+
+  private URL getConfigurationFile(final String configurationFileName) {
+    final URL configuration = resourceUtil.getResource(configurationFileName);
+    if (configuration == null) {
+      throw new IllegalStateException("Configuration file '" + configurationFileName + "' not found on classpath.");
+    }
+    return configuration;
+  }
+}
diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProvider.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProvider.java
index cb473d1f..01151d76 100644
--- a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProvider.java
+++ b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProvider.java
@@ -3,9 +3,7 @@ package de.focus_shift.jollyday.core.configuration;
 import java.util.Properties;
 
 /**
- * The interface for jollyday configuration provider.
- *
- * @author sven
+ * Interface for the configuration providers
  */
 public interface ConfigurationProvider {
 
@@ -15,6 +13,7 @@ public interface ConfigurationProvider {
    * configuration.
    */
   String CONFIG_PROVIDERS_PROPERTY = "config.providers";
+
   /**
    * System property to define URLs to overriding jollyday configuration
    * files.
@@ -25,5 +24,4 @@ public interface ConfigurationProvider {
    * @return the configuration properties for jollyday.
    */
   Properties getProperties();
-
 }
diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManager.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManager.java
index d7334069..7574dd4b 100644
--- a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManager.java
+++ b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManager.java
@@ -1,30 +1,24 @@
 package de.focus_shift.jollyday.core.configuration;
 
 import de.focus_shift.jollyday.core.ManagerParameter;
-import de.focus_shift.jollyday.core.configuration.impl.DefaultConfigurationProvider;
-import de.focus_shift.jollyday.core.configuration.impl.URLConfigurationProvider;
 import de.focus_shift.jollyday.core.util.ClassLoadingUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-
 /**
- * Manages the configuration provider implementations and thus delivering the
- * jollyday configuration.
- *
- * @author Sven Diedrichsen
+ * Manages the configuration provider implementations and thus delivering the jollyday configuration.
  */
 public class ConfigurationProviderManager {
 
   private static final Logger LOG = LoggerFactory.getLogger(ConfigurationProviderManager.class);
 
-  private ConfigurationProvider defaultConfigurationProvider = new DefaultConfigurationProvider();
+  private ConfigurationProvider classpathConfigurationProvider = new ClasspathConfigurationProvider();
   private ConfigurationProvider urlConfigurationProvider = new URLConfigurationProvider();
   private final ClassLoadingUtil classLoadingUtil = new ClassLoadingUtil();
 
   /**
    * Reads the jollyday configuration from the
-   * {@link DefaultConfigurationProvider}, the
+   * {@link ClasspathConfigurationProvider}, the
    * {@link URLConfigurationProvider} and any configuration provider specified
    * by the system property 'config.providers'.
    *
@@ -37,7 +31,7 @@ public class ConfigurationProviderManager {
 
   private void addInternalConfigurationProviderProperties(ManagerParameter parameter) {
     parameter.mergeProperties(urlConfigurationProvider.getProperties());
-    parameter.mergeProperties(defaultConfigurationProvider.getProperties());
+    parameter.mergeProperties(classpathConfigurationProvider.getProperties());
   }
 
   private void addCustomConfigurationProviderProperties(ManagerParameter parameter) {
@@ -45,7 +39,7 @@ public class ConfigurationProviderManager {
     if (providersStrList != null) {
       final String[] providersClassNames = providersStrList.split(",");
       for (String providerClassName : providersClassNames) {
-        if (providerClassName == null || "".equals(providerClassName))
+        if (providerClassName == null || providerClassName.isEmpty())
           continue;
         try {
           final Class<?> providerClass = Class.forName(providerClassName.trim(), true, classLoadingUtil.getClassloader());
diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/URLConfigurationProvider.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/URLConfigurationProvider.java
new file mode 100644
index 00000000..07b79ce5
--- /dev/null
+++ b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/URLConfigurationProvider.java
@@ -0,0 +1,64 @@
+package de.focus_shift.jollyday.core.configuration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Objects;
+import java.util.Properties;
+
+import static java.util.Arrays.stream;
+import static java.util.function.Predicate.not;
+
+/**
+ * An {@link ConfigurationProvider} implementation which reads a list of URLs
+ * provided by the system property 'config.urls' in order they are
+ * provided into a {@link Properties} instance.
+ */
+class URLConfigurationProvider implements ConfigurationProvider {
+
+  private static final Logger LOG = LoggerFactory.getLogger(URLConfigurationProvider.class);
+
+  /**
+   * Returns the properties by reading from the URLs provided by the system
+   * property 'config.urls'.
+   */
+  @Override
+  public Properties getProperties() {
+    final Properties properties = new Properties();
+    final String configURLs = System.getProperty(CONFIG_URLS_PROPERTY);
+
+    if (configURLs != null) {
+        stream(configURLs.split(","))
+        .filter(Objects::nonNull)
+        .filter(not(String::isEmpty))
+        .map(String::trim)
+        .map(this::createUrl)
+        .filter(Objects::nonNull)
+        .forEach(url -> readPropertiesFromURL(properties, url));
+    }
+
+    return properties;
+  }
+
+  private void readPropertiesFromURL(final Properties properties, final URL url) {
+    try (final InputStream inputStream = url.openStream()) {
+      properties.load(inputStream);
+    } catch (IOException e) {
+      throw new IllegalStateException("Could not load default properties from classpath.", e);
+    }
+  }
+
+  private URL createUrl(final String stringUrl) {
+    URL url = null;
+    try {
+      url = new URL(stringUrl);
+    } catch (MalformedURLException e) {
+      LOG.warn("Cannot read configuration from '{}' with message '{}'.", stringUrl, e.getMessage());
+    }
+    return url;
+  }
+}
diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/impl/DefaultConfigurationProvider.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/impl/DefaultConfigurationProvider.java
deleted file mode 100644
index 87fa69a9..00000000
--- a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/impl/DefaultConfigurationProvider.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package de.focus_shift.jollyday.core.configuration.impl;
-
-import de.focus_shift.jollyday.core.configuration.ConfigurationProvider;
-import de.focus_shift.jollyday.core.util.ResourceUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Properties;
-
-/**
- * Provider which adds jollydays default configuration file
- * 'jollyday.properties' by reading it from the classpath by using the currents
- * threads classloader.
- *
- * @author Sven Diedrichsen
- */
-public class DefaultConfigurationProvider implements ConfigurationProvider {
-
-  private static final Logger LOG = LoggerFactory.getLogger(DefaultConfigurationProvider.class);
-
-  /**
-   * The name of the configuration file.
-   */
-  private static final String CONFIG_FILE = "jollyday.properties";
-  /**
-   * The utility to load resources.
-   */
-  private final ResourceUtil resourceUtil = new ResourceUtil();
-
-  /*
-   * (non-Javadoc)
-   *
-   * @see
-   * de.focus_shift.jollyday.core.configuration.ConfigurationProvider#addConfiguration(java.util.Properties)
-   */
-  @Override
-  public Properties getProperties() {
-    final Properties properties = new Properties();
-    try {
-      final URL config = resourceUtil.getResource(CONFIG_FILE);
-      if (config == null) {
-        throw new IllegalStateException("Properties file " + CONFIG_FILE + " not found on classpath.");
-      }
-      try (InputStream stream = config.openStream()) {
-        if (stream != null) {
-          properties.load(stream);
-        } else {
-          LOG.warn("Could not load default properties file '{}' from classpath.", CONFIG_FILE);
-        }
-      }
-      return properties;
-    } catch (IOException e) {
-      throw new IllegalStateException("Could not load default properties from classpath.", e);
-    }
-  }
-}
diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/impl/URLConfigurationProvider.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/impl/URLConfigurationProvider.java
deleted file mode 100644
index b90d2a25..00000000
--- a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/configuration/impl/URLConfigurationProvider.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package de.focus_shift.jollyday.core.configuration.impl;
-
-import de.focus_shift.jollyday.core.configuration.ConfigurationProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Properties;
-
-/**
- * An {@link ConfigurationProvider} implementation which reads a list of URLs
- * provided by the system property 'config.urls' in order they are
- * provided into a {@link Properties} instance.
- *
- * @author Sven Diedrichsen
- */
-public class URLConfigurationProvider implements ConfigurationProvider {
-
-  private static final Logger LOG = LoggerFactory.getLogger(URLConfigurationProvider.class);
-
-  /**
-   * Returns the properties by reading from the URLs provided by the system
-   * property 'config.urls'.
-   */
-  @Override
-  public Properties getProperties() {
-    final Properties properties = new Properties();
-    final String configURLs = System.getProperty(CONFIG_URLS_PROPERTY);
-    if (configURLs != null) {
-      final String[] strConfigURLs = configURLs.split(",");
-      for (String strURL : strConfigURLs) {
-        readPropertiesFromURL(properties, strURL);
-      }
-    }
-    return properties;
-  }
-
-  private void readPropertiesFromURL(Properties properties, String strURL) {
-    if (strURL == null || "".equals(strURL)) {
-      return;
-    }
-
-    InputStream inputStream = null;
-    try {
-      final URL configURL = new URL(strURL.trim());
-      inputStream = configURL.openStream();
-      properties.load(inputStream);
-    } catch (Exception e) {
-      LOG.warn("Cannot read configuration from '{}' with message '{}'.", strURL, e.getMessage());
-    } finally {
-      closeStreamFromURL(strURL, inputStream);
-    }
-  }
-
-  private void closeStreamFromURL(String strURL, InputStream inputStream) {
-    if (inputStream != null) {
-      try {
-        inputStream.close();
-      } catch (Exception e) {
-        LOG.warn("Cannot close stream for configuration URL {}.", strURL);
-      }
-    }
-  }
-}
diff --git a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/util/ResourceUtil.java b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/util/ResourceUtil.java
index 6d589e64..9e647dd5 100644
--- a/jollyday-core/src/main/java/de/focus_shift/jollyday/core/util/ResourceUtil.java
+++ b/jollyday-core/src/main/java/de/focus_shift/jollyday/core/util/ResourceUtil.java
@@ -173,7 +173,7 @@ public class ResourceUtil {
    */
   public URL getResource(String resourceName) {
     try {
-      URL resource = classLoadingUtil.getClassloader().getResource(resourceName);
+      final URL resource = classLoadingUtil.getClassloader().getResource(resourceName);
       return resource == null ? this.getClass().getClassLoader().getResource(resourceName) : resource;
     } catch (Exception e) {
       throw new IllegalStateException("Cannot load resource: " + resourceName, e);


Test patch:
diff --git a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/ClasspathConfigurationProviderContentTest.java b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/ClasspathConfigurationProviderContentTest.java
new file mode 100644
index 00000000..2e84fb6a
--- /dev/null
+++ b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/ClasspathConfigurationProviderContentTest.java
@@ -0,0 +1,50 @@
+package de.focus_shift.jollyday.core.configuration;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.entry;
+
+class ClasspathConfigurationProviderContentTest {
+
+  @Test
+  void ensureToOnlyContainKnownKeys() {
+    final ClasspathConfigurationProvider sut = new ClasspathConfigurationProvider();
+    final Properties properties = sut.getProperties();
+    assertThat(properties).containsOnlyKeys(
+      "manager.impl",
+      "manager.impl.jp",
+      "parser.impl.de.focus_shift.jollyday.core.spi.Fixed",
+      "parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth",
+      "parser.impl.de.focus_shift.jollyday.core.spi.IslamicHoliday",
+      "parser.impl.de.focus_shift.jollyday.core.spi.ChristianHoliday",
+      "parser.impl.de.focus_shift.jollyday.core.spi.RelativeToFixed",
+      "parser.impl.de.focus_shift.jollyday.core.spi.RelativeToWeekdayInMonth",
+      "parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed",
+      "parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayRelativeToFixed",
+      "parser.impl.de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday",
+      "parser.impl.de.focus_shift.jollyday.core.spi.RelativeToEasterSunday"
+    );
+  }
+
+  @Test
+  void ensureToConfigureDifferentConfigurationFile() {
+    final ClasspathConfigurationProvider sut = new ClasspathConfigurationProvider();
+    sut.overrideConfigurationFileName("alternative-jollyday.properties");
+    final Properties properties = sut.getProperties();
+    assertThat(properties).contains(entry("manager.impl", "de.focus_shift.jollyday.core.impl.JapaneseHolidayManager"));
+  }
+
+  @Test
+  void ensureToThrowIllegalStateExceptionIfConfigurationFileNotFoundOnClasspath() {
+    final ClasspathConfigurationProvider sut = new ClasspathConfigurationProvider();
+
+    assertThatThrownBy(() -> sut.overrideConfigurationFileName("notAvailableFileName.properties"))
+      .isInstanceOf(IllegalStateException.class)
+      .hasMessageContaining("Configuration file 'notAvailableFileName.properties' not found on classpath.");
+  }
+}
diff --git a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManagerTest.java b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManagerTest.java
index 97a01e0c..c70ecf11 100644
--- a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManagerTest.java
+++ b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/ConfigurationProviderManagerTest.java
@@ -9,6 +9,8 @@ import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
+import java.util.Properties;
+
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.verify;
 
@@ -16,12 +18,12 @@ import static org.mockito.Mockito.verify;
 class ConfigurationProviderManagerTest {
 
   @Mock
-  private ConfigurationProvider defaultConfigurationProvider;
+  private ClasspathConfigurationProvider classpathConfigurationProvider;
   @Mock
-  private ConfigurationProvider urlConfigurationProvider;
+  private URLConfigurationProvider urlConfigurationProvider;
 
   @InjectMocks
-  private final ConfigurationProviderManager configurationProviderManager = new ConfigurationProviderManager();
+  private final ConfigurationProviderManager sut = new ConfigurationProviderManager();
 
   private final ManagerParameter managerParameter = ManagerParameters.create((String) null);
 
@@ -33,21 +35,21 @@ class ConfigurationProviderManagerTest {
   @Test
   void testGetPropertiesWithEmptyProvidersList() {
     System.setProperty(ConfigurationProvider.CONFIG_PROVIDERS_PROPERTY, "");
-    configurationProviderManager.mergeConfigurationProperties(managerParameter);
+    sut.mergeConfigurationProperties(managerParameter);
     assertResult(managerParameter);
   }
 
   @Test
   void testGetPropertiesWithWrongClass() {
     System.setProperty(ConfigurationProvider.CONFIG_PROVIDERS_PROPERTY, "java.lang.String");
-    configurationProviderManager.mergeConfigurationProperties(managerParameter);
+    sut.mergeConfigurationProperties(managerParameter);
     assertResult(managerParameter);
   }
 
   @Test
   void testGetPropertiesWithCorrectClass() {
     System.setProperty(ConfigurationProvider.CONFIG_PROVIDERS_PROPERTY, "de.focus_shift.jollyday.core.configuration.TestProvider");
-    configurationProviderManager.mergeConfigurationProperties(managerParameter);
+    sut.mergeConfigurationProperties(managerParameter);
     assertResult(managerParameter);
     assertThat(managerParameter.getProperty("key")).isEqualTo("value");
   }
@@ -55,7 +57,7 @@ class ConfigurationProviderManagerTest {
   @Test
   void testGetPropertiesWithWrongAndCorrectClass() {
     System.setProperty(ConfigurationProvider.CONFIG_PROVIDERS_PROPERTY, "de.focus_shift.jollyday.core.configuration.TestProvider, java.lang.String");
-    configurationProviderManager.mergeConfigurationProperties(managerParameter);
+    sut.mergeConfigurationProperties(managerParameter);
     assertResult(managerParameter);
     assertThat(managerParameter.getProperty("key")).isEqualTo("value");
   }
@@ -65,7 +67,7 @@ class ConfigurationProviderManagerTest {
     managerParameter.setProperty("MANUAL_KEY", "MANUAL_VALUE");
     managerParameter.setProperty("manager.impl", "NewImpl");
 
-    configurationProviderManager.mergeConfigurationProperties(managerParameter);
+    sut.mergeConfigurationProperties(managerParameter);
 
     assertResult(managerParameter);
     assertThat(managerParameter.getProperty("MANUAL_KEY")).isEqualTo("MANUAL_VALUE");
@@ -74,7 +76,7 @@ class ConfigurationProviderManagerTest {
 
   private void assertResult(ManagerParameter parameter) {
     assertThat(parameter).isNotNull();
-    verify(defaultConfigurationProvider).getProperties();
+    verify(classpathConfigurationProvider).getProperties();
     verify(urlConfigurationProvider).getProperties();
   }
 }
diff --git a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/TestProvider.java b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/TestProvider.java
index 29617c72..be191cff 100644
--- a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/TestProvider.java
+++ b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/TestProvider.java
@@ -2,6 +2,9 @@ package de.focus_shift.jollyday.core.configuration;
 
 import java.util.Properties;
 
+/**
+ * This provider is used in {@link ConfigurationProviderManagerTest}
+ */
 public class TestProvider implements ConfigurationProvider {
 
   private final Properties properties = new Properties();
diff --git a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/impl/URLConfigurationProviderTest.java b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/URLConfigurationProviderTest.java
similarity index 65%
rename from jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/impl/URLConfigurationProviderTest.java
rename to jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/URLConfigurationProviderTest.java
index a3fe3942..e7662780 100644
--- a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/impl/URLConfigurationProviderTest.java
+++ b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/URLConfigurationProviderTest.java
@@ -1,20 +1,20 @@
-package de.focus_shift.jollyday.core.configuration.impl;
+package de.focus_shift.jollyday.core.configuration;
 
-import de.focus_shift.jollyday.core.configuration.ConfigurationProvider;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
 import java.util.Properties;
 
+import static de.focus_shift.jollyday.core.configuration.ConfigurationProvider.CONFIG_URLS_PROPERTY;
 import static org.assertj.core.api.Assertions.assertThat;
 
 class URLConfigurationProviderTest {
 
-  private final ConfigurationProvider sut = new URLConfigurationProvider();
+  private final URLConfigurationProvider sut = new URLConfigurationProvider();
 
   @AfterEach
   void teardown() {
-    System.clearProperty(ConfigurationProvider.CONFIG_URLS_PROPERTY);
+    System.clearProperty(CONFIG_URLS_PROPERTY);
   }
 
   @Test
@@ -25,21 +25,21 @@ class URLConfigurationProviderTest {
 
   @Test
   void testPutConfigurationWithPropertySetEmpty() {
-    System.setProperty(ConfigurationProvider.CONFIG_URLS_PROPERTY, "");
+    System.setProperty(CONFIG_URLS_PROPERTY, "");
     final Properties props = sut.getProperties();
     assertThat(props).isEmpty();
   }
 
   @Test
   void testPutConfigurationWithPropertyWithIllegalURL() {
-    System.setProperty(ConfigurationProvider.CONFIG_URLS_PROPERTY, "TestIllegalData");
+    System.setProperty(CONFIG_URLS_PROPERTY, "TestIllegalData");
     final Properties props = sut.getProperties();
     assertThat(props).isEmpty();
   }
 
   @Test
   void testPutConfigurationWithPropertyWithCorrectURL() {
-    System.setProperty(ConfigurationProvider.CONFIG_URLS_PROPERTY, "file:./src/test/resources/url.load.properties");
+    System.setProperty(CONFIG_URLS_PROPERTY, "file:./src/test/resources/url.load.properties");
     final Properties props = sut.getProperties();
     assertThat(props).isNotEmpty();
     assertThat(props.getProperty("manager.impl.test")).isEqualTo("de.jollyday.impl.DefaultHolidayManager");
diff --git a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/impl/DefaultConfigurationProviderContentTest.java b/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/impl/DefaultConfigurationProviderContentTest.java
deleted file mode 100644
index 9f5e48f6..00000000
--- a/jollyday-core/src/test/java/de/focus_shift/jollyday/core/configuration/impl/DefaultConfigurationProviderContentTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package de.focus_shift.jollyday.core.configuration.impl;
-
-import org.junit.jupiter.api.Test;
-
-import java.util.Properties;
-import java.util.Set;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-class DefaultConfigurationProviderContentTest {
-
-  private static final Set<String> KEYS_DEFAULT_CONFIG = Set.of(
-    "manager.impl",
-    "manager.impl.jp",
-    "parser.impl.de.focus_shift.jollyday.core.spi.Fixed",
-    "parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth",
-    "parser.impl.de.focus_shift.jollyday.core.spi.IslamicHoliday",
-    "parser.impl.de.focus_shift.jollyday.core.spi.ChristianHoliday",
-    "parser.impl.de.focus_shift.jollyday.core.spi.RelativeToFixed",
-    "parser.impl.de.focus_shift.jollyday.core.spi.RelativeToWeekdayInMonth",
-    "parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed",
-    "parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayRelativeToFixed",
-    "parser.impl.de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday",
-    "parser.impl.de.focus_shift.jollyday.core.spi.RelativeToEasterSunday"
-  );
-
-  private final DefaultConfigurationProvider sut = new DefaultConfigurationProvider();
-
-  @Test
-  void testPutConfiguration() {
-    final Properties p = sut.getProperties();
-    assertThat(p).containsOnlyKeys(KEYS_DEFAULT_CONFIG);
-  }
-}
diff --git a/jollyday-core/src/test/resources/alternative-jollyday.properties b/jollyday-core/src/test/resources/alternative-jollyday.properties
new file mode 100644
index 00000000..d49d36f2
--- /dev/null
+++ b/jollyday-core/src/test/resources/alternative-jollyday.properties
@@ -0,0 +1,12 @@
+manager.impl=de.focus_shift.jollyday.core.impl.JapaneseHolidayManager
+manager.impl.jp=de.focus_shift.jollyday.core.impl.JapaneseHolidayManager
+parser.impl.de.focus_shift.jollyday.core.spi.Fixed=de.focus_shift.jollyday.core.parser.impl.FixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth=de.focus_shift.jollyday.core.parser.impl.FixedWeekdayInMonthParser
+parser.impl.de.focus_shift.jollyday.core.spi.IslamicHoliday=de.focus_shift.jollyday.core.parser.impl.IslamicHolidayParser
+parser.impl.de.focus_shift.jollyday.core.spi.ChristianHoliday=de.focus_shift.jollyday.core.parser.impl.ChristianHolidayParser
+parser.impl.de.focus_shift.jollyday.core.spi.RelativeToFixed=de.focus_shift.jollyday.core.parser.impl.RelativeToFixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.RelativeToWeekdayInMonth=de.focus_shift.jollyday.core.parser.impl.RelativeToWeekdayInMonthParser
+parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed=de.focus_shift.jollyday.core.parser.impl.FixedWeekdayBetweenFixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayRelativeToFixed=de.focus_shift.jollyday.core.parser.impl.FixedWeekdayRelativeToFixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday=de.focus_shift.jollyday.core.parser.impl.EthiopianOrthodoxHolidayParser
+parser.impl.de.focus_shift.jollyday.core.spi.RelativeToEasterSunday=de.focus_shift.jollyday.core.parser.impl.RelativeToEasterSundayParser
diff --git a/jollyday-core/src/test/resources/jollyday.properties b/jollyday-core/src/test/resources/jollyday.properties
new file mode 100644
index 00000000..a25e94c2
--- /dev/null
+++ b/jollyday-core/src/test/resources/jollyday.properties
@@ -0,0 +1,12 @@
+manager.impl=de.focus_shift.jollyday.core.impl.DefaultHolidayManager
+manager.impl.jp=de.focus_shift.jollyday.core.impl.JapaneseHolidayManager
+parser.impl.de.focus_shift.jollyday.core.spi.Fixed=de.focus_shift.jollyday.core.parser.impl.FixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayInMonth=de.focus_shift.jollyday.core.parser.impl.FixedWeekdayInMonthParser
+parser.impl.de.focus_shift.jollyday.core.spi.IslamicHoliday=de.focus_shift.jollyday.core.parser.impl.IslamicHolidayParser
+parser.impl.de.focus_shift.jollyday.core.spi.ChristianHoliday=de.focus_shift.jollyday.core.parser.impl.ChristianHolidayParser
+parser.impl.de.focus_shift.jollyday.core.spi.RelativeToFixed=de.focus_shift.jollyday.core.parser.impl.RelativeToFixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.RelativeToWeekdayInMonth=de.focus_shift.jollyday.core.parser.impl.RelativeToWeekdayInMonthParser
+parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayBetweenFixed=de.focus_shift.jollyday.core.parser.impl.FixedWeekdayBetweenFixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.FixedWeekdayRelativeToFixed=de.focus_shift.jollyday.core.parser.impl.FixedWeekdayRelativeToFixedParser
+parser.impl.de.focus_shift.jollyday.core.spi.EthiopianOrthodoxHoliday=de.focus_shift.jollyday.core.parser.impl.EthiopianOrthodoxHolidayParser
+parser.impl.de.focus_shift.jollyday.core.spi.RelativeToEasterSunday=de.focus_shift.jollyday.core.parser.impl.RelativeToEasterSundayParser