You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rc...@apache.org on 2020/08/17 09:11:36 UTC

[james-project] 25/26: [Refactoring] Migrate AbstractSieveRepositoryTest to SieveRepositoryContract JUnit5

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit a5f5e57526afe4d8017d00a34a40b9170001c61e
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Thu Aug 13 17:13:02 2020 +0700

    [Refactoring] Migrate AbstractSieveRepositoryTest to SieveRepositoryContract JUnit5
---
 .../cassandra/CassandraSieveRepositoryTest.java    |  41 +--
 .../file/SieveFileRepositoryTest.java              |  39 ++-
 .../james/sieve/jpa/JpaSieveRepositoryTest.java    |  27 +-
 .../lib/AbstractSieveRepositoryTest.java           | 361 --------------------
 .../lib/SieveRepositoryContract.java               | 371 +++++++++++++++++++++
 5 files changed, 420 insertions(+), 419 deletions(-)

diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/sieve/cassandra/CassandraSieveRepositoryTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/sieve/cassandra/CassandraSieveRepositoryTest.java
index c28d7ba..d0954d7 100644
--- a/server/data/data-cassandra/src/test/java/org/apache/james/sieve/cassandra/CassandraSieveRepositoryTest.java
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/sieve/cassandra/CassandraSieveRepositoryTest.java
@@ -20,37 +20,28 @@
 package org.apache.james.sieve.cassandra;
 
 import org.apache.james.backends.cassandra.CassandraCluster;
-import org.apache.james.backends.cassandra.DockerCassandraRule;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
 import org.apache.james.sieverepository.api.SieveRepository;
-import org.apache.james.sieverepository.lib.AbstractSieveRepositoryTest;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
+import org.apache.james.sieverepository.lib.SieveRepositoryContract;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.RegisterExtension;
 
-public class CassandraSieveRepositoryTest extends AbstractSieveRepositoryTest {
+class CassandraSieveRepositoryTest implements SieveRepositoryContract {
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new CassandraClusterExtension(CassandraSieveRepositoryModule.MODULE);
 
-    @Rule
-    public DockerCassandraRule cassandraServer = new DockerCassandraRule();
-    
-    private CassandraCluster cassandra;
+    SieveRepository sieveRepository;
 
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        cassandra = CassandraCluster.create(CassandraSieveRepositoryModule.MODULE, cassandraServer.getHost());
-        super.setUp();
-    }
-    
-    @After
-    public void tearDown() {
-        cassandra.close();
-    }
-
-    @Override
-    protected SieveRepository createSieveRepository() {
-        return new CassandraSieveRepository(
+    @BeforeEach
+    void setUp(CassandraCluster cassandra) {
+        sieveRepository = new CassandraSieveRepository(
             new CassandraSieveDAO(cassandra.getConf()),
             new CassandraSieveQuotaDAO(cassandra.getConf()),
             new CassandraActiveScriptDAO(cassandra.getConf()));
     }
+
+    @Override
+    public SieveRepository sieveRepository() {
+        return sieveRepository;
+    }
 }
\ No newline at end of file
diff --git a/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java b/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java
index dd194f5..42b9b70 100644
--- a/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java
+++ b/server/data/data-file/src/test/java/org/apache/james/sieverepository/file/SieveFileRepositoryTest.java
@@ -4,29 +4,28 @@ package org.apache.james.sieverepository.file;
 
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.james.filesystem.api.FileSystem;
 import org.apache.james.sieverepository.api.SieveRepository;
-import org.apache.james.sieverepository.lib.AbstractSieveRepositoryTest;
-import org.junit.After;
-import org.junit.Before;
+import org.apache.james.sieverepository.lib.SieveRepositoryContract;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
 
-public class SieveFileRepositoryTest extends AbstractSieveRepositoryTest {
+class SieveFileRepositoryTest implements SieveRepositoryContract {
 
-    private static final String SIEVE_ROOT = FileSystem.FILE_PROTOCOL + "sieve";
+    static final String SIEVE_ROOT = FileSystem.FILE_PROTOCOL + "sieve";
 
-    private FileSystem fileSystem;
+    FileSystem fileSystem;
+    SieveRepository sieveRepository;
 
-    @Override
-    @Before
-    public void setUp() throws Exception {
+    @BeforeEach
+    void setUp() throws Exception {
         this.fileSystem = new FileSystem() {
             @Override
-            public File getBasedir() throws FileNotFoundException {
+            public File getBasedir() {
                 return new File(System.getProperty("java.io.tmpdir"));
             }
             
@@ -36,24 +35,24 @@ public class SieveFileRepositoryTest extends AbstractSieveRepositoryTest {
             }
             
             @Override
-            public File getFile(String fileURL) throws FileNotFoundException {
+            public File getFile(String fileURL) {
                 return new File(getBasedir(), fileURL.substring(FileSystem.FILE_PROTOCOL.length()));
             }
         };
-        super.setUp();
-    }
-
-    @Override
-    protected SieveRepository createSieveRepository() throws Exception {
-        return new SieveFileRepository(fileSystem);
+        sieveRepository = new SieveFileRepository(fileSystem);
     }
 
-    @After
-    public void tearDown() throws Exception {
+    @AfterEach
+    void tearDown() throws Exception {
         File root = fileSystem.getFile(SIEVE_ROOT);
         // Remove files from the previous test, if any
         if (root.exists()) {
             FileUtils.forceDelete(root);
         }
     }
+
+    @Override
+    public SieveRepository sieveRepository() {
+        return sieveRepository;
+    }
 }
diff --git a/server/data/data-jpa/src/test/java/org/apache/james/sieve/jpa/JpaSieveRepositoryTest.java b/server/data/data-jpa/src/test/java/org/apache/james/sieve/jpa/JpaSieveRepositoryTest.java
index e79de07..ab59dc6 100644
--- a/server/data/data-jpa/src/test/java/org/apache/james/sieve/jpa/JpaSieveRepositoryTest.java
+++ b/server/data/data-jpa/src/test/java/org/apache/james/sieve/jpa/JpaSieveRepositoryTest.java
@@ -23,27 +23,28 @@ import org.apache.james.backends.jpa.JpaTestCluster;
 import org.apache.james.sieve.jpa.model.JPASieveQuota;
 import org.apache.james.sieve.jpa.model.JPASieveScript;
 import org.apache.james.sieverepository.api.SieveRepository;
-import org.apache.james.sieverepository.lib.AbstractSieveRepositoryTest;
-import org.junit.After;
-import org.junit.Before;
+import org.apache.james.sieverepository.lib.SieveRepositoryContract;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
 
-public class JpaSieveRepositoryTest extends AbstractSieveRepositoryTest {
+class JpaSieveRepositoryTest implements SieveRepositoryContract {
 
-    private static final JpaTestCluster JPA_TEST_CLUSTER = JpaTestCluster.create(JPASieveScript.class, JPASieveQuota.class);
+    final JpaTestCluster JPA_TEST_CLUSTER = JpaTestCluster.create(JPASieveScript.class, JPASieveQuota.class);
 
-    @Override
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
+    SieveRepository sieveRepository;
+
+    @BeforeEach
+    void setUp() {
+        sieveRepository = new JPASieveRepository(JPA_TEST_CLUSTER.getEntityManagerFactory());
     }
 
-    @After
-    public void tearDown() throws Exception {
+    @AfterEach
+    void tearDown() {
         JPA_TEST_CLUSTER.clear("JAMES_SIEVE_SCRIPT", "JAMES_SIEVE_QUOTA");
     }
 
     @Override
-    protected SieveRepository createSieveRepository() throws Exception {
-        return new JPASieveRepository(JPA_TEST_CLUSTER.getEntityManagerFactory());
+    public SieveRepository sieveRepository() {
+        return sieveRepository;
     }
 }
diff --git a/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/AbstractSieveRepositoryTest.java b/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/AbstractSieveRepositoryTest.java
deleted file mode 100644
index 4482d97..0000000
--- a/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/AbstractSieveRepositoryTest.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you under the Apache License, Version 2.0 (the            *
- * "License"); you may not use this file except in compliance   *
- * with the License.  You may obtain a copy of the License at   *
- *                                                              *
- *   http://www.apache.org/licenses/LICENSE-2.0                 *
- *                                                              *
- * Unless required by applicable law or agreed to in writing,   *
- * software distributed under the License is distributed on an  *
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
- * KIND, either express or implied.  See the License for the    *
- * specific language governing permissions and limitations      *
- * under the License.                                           *
- ****************************************************************/
-package org.apache.james.sieverepository.lib;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.james.core.Username;
-import org.apache.james.core.quota.QuotaSizeLimit;
-import org.apache.james.sieverepository.api.ScriptContent;
-import org.apache.james.sieverepository.api.ScriptName;
-import org.apache.james.sieverepository.api.ScriptSummary;
-import org.apache.james.sieverepository.api.SieveRepository;
-import org.apache.james.sieverepository.api.exception.DuplicateException;
-import org.apache.james.sieverepository.api.exception.IsActiveException;
-import org.apache.james.sieverepository.api.exception.QuotaExceededException;
-import org.apache.james.sieverepository.api.exception.QuotaNotFoundException;
-import org.apache.james.sieverepository.api.exception.ScriptNotFoundException;
-import org.junit.Test;
-
-public abstract class AbstractSieveRepositoryTest {
-
-    protected static final Username USERNAME = Username.of("test");
-    protected static final ScriptName SCRIPT_NAME = new ScriptName("script");
-    protected static final ScriptContent SCRIPT_CONTENT = new ScriptContent("Hello World");
-
-    private static final ScriptName OTHER_SCRIPT_NAME = new ScriptName("other_script");
-    private static final ScriptContent OTHER_SCRIPT_CONTENT = new ScriptContent("Other script content");
-    private static final QuotaSizeLimit DEFAULT_QUOTA = QuotaSizeLimit.size(Long.MAX_VALUE - 1L);
-    private static final QuotaSizeLimit USER_QUOTA = QuotaSizeLimit.size(Long.MAX_VALUE / 2);
-
-    protected SieveRepository sieveRepository;
-
-    public void setUp() throws Exception {
-        sieveRepository = createSieveRepository();
-    }
-
-    @Test(expected = ScriptNotFoundException.class)
-    public void getScriptShouldThrowIfUnableToFindScript() throws Exception {
-        sieveRepository.getScript(USERNAME, SCRIPT_NAME);
-    }
-
-    @Test
-    public void getScriptShouldReturnCorrectContent() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        assertThat(getScriptContent(sieveRepository.getScript(USERNAME, SCRIPT_NAME))).isEqualTo(SCRIPT_CONTENT);
-    }
-
-    @Test
-    public void getActivationDateForActiveScriptShouldReturnNonNullAndNonZeroResult() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        assertThat(sieveRepository.getActivationDateForActiveScript(USERNAME)).isNotNull();
-        assertThat(sieveRepository.getActivationDateForActiveScript(USERNAME)).isNotEqualTo(ZonedDateTime.ofInstant(Instant.ofEpochMilli(0L), ZoneOffset.UTC));
-    }
-
-    @Test(expected = ScriptNotFoundException.class)
-    public void getActivationDateForActiveScriptShouldThrowOnMissingActiveScript() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.getActivationDateForActiveScript(USERNAME);
-    }
-
-    @Test
-    public void haveSpaceShouldNotThrowWhenUserDoesNotHaveQuota() throws Exception {
-        sieveRepository.haveSpace(USERNAME, SCRIPT_NAME, DEFAULT_QUOTA.asLong() + 1L);
-    }
-
-    @Test
-    public void haveSpaceShouldNotThrowWhenQuotaIsNotReached() throws Exception {
-        sieveRepository.setDefaultQuota(DEFAULT_QUOTA);
-        sieveRepository.haveSpace(USERNAME, SCRIPT_NAME, DEFAULT_QUOTA.asLong());
-    }
-
-    @Test(expected = QuotaExceededException.class)
-    public void haveSpaceShouldThrowWhenQuotaIsExceed() throws Exception {
-        sieveRepository.setDefaultQuota(DEFAULT_QUOTA);
-        sieveRepository.haveSpace(USERNAME, SCRIPT_NAME, DEFAULT_QUOTA.asLong() + 1);
-    }
-
-    @Test
-    public void haveSpaceShouldNotThrowWhenAttemptToReplaceOtherScript() throws Exception {
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.haveSpace(USERNAME, SCRIPT_NAME, USER_QUOTA.asLong());
-    }
-
-    @Test(expected = QuotaExceededException.class)
-    public void haveSpaceShouldThrowWhenAttemptToReplaceOtherScriptWithTooLargeScript() throws Exception {
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.haveSpace(USERNAME, SCRIPT_NAME, USER_QUOTA.asLong() + 1);
-    }
-
-    @Test(expected = QuotaExceededException.class)
-    public void haveSpaceShouldTakeAlreadyExistingScriptsIntoAccount() throws Exception {
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.haveSpace(USERNAME, OTHER_SCRIPT_NAME, USER_QUOTA.asLong() - 1);
-    }
-
-    @Test
-    public void haveSpaceShouldNotThrowAfterActivatingAScript() throws Exception {
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.haveSpace(USERNAME, SCRIPT_NAME, USER_QUOTA.asLong());
-    }
-
-    @Test
-    public void listScriptsShouldReturnAnEmptyListIfUserNotFound() throws Exception {
-        assertThat(sieveRepository.listScripts(USERNAME)).isEmpty();
-    }
-
-    @Test
-    public void listScriptsShouldReturnEmptyListWhenThereIsNoScript() throws Exception {
-        assertThat(sieveRepository.listScripts(USERNAME)).isEmpty();
-    }
-
-    @Test
-    public void putScriptShouldWork() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        assertThat(sieveRepository.listScripts(USERNAME)).containsOnly(new ScriptSummary(SCRIPT_NAME, false));
-    }
-
-    @Test
-    public void setActiveShouldWork() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        assertThat(sieveRepository.listScripts(USERNAME)).containsOnly(new ScriptSummary(SCRIPT_NAME, true));
-    }
-
-    @Test
-    public void listScriptShouldCombineActiveAndPassiveScripts() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.putScript(USERNAME, OTHER_SCRIPT_NAME, OTHER_SCRIPT_CONTENT);
-        assertThat(sieveRepository.listScripts(USERNAME)).containsOnly(new ScriptSummary(SCRIPT_NAME, true), new ScriptSummary(OTHER_SCRIPT_NAME, false));
-    }
-
-    @Test(expected = QuotaExceededException.class)
-    public void putScriptShouldThrowWhenScriptTooBig() throws Exception {
-        sieveRepository.setDefaultQuota(QuotaSizeLimit.size(SCRIPT_CONTENT.length() - 1));
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-    }
-
-    @Test(expected = QuotaExceededException.class)
-    public void putScriptShouldThrowWhenQuotaChangedInBetween() throws Exception {
-        sieveRepository.setDefaultQuota(QuotaSizeLimit.size(SCRIPT_CONTENT.length()));
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setDefaultQuota(QuotaSizeLimit.size(SCRIPT_CONTENT.length() - 1));
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-    }
-
-    @Test(expected = ScriptNotFoundException.class)
-    public void setActiveScriptShouldThrowOnNonExistentScript() throws Exception {
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-    }
-
-    @Test
-    public void setActiveScriptShouldWork() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        assertThat(getScriptContent(sieveRepository.getActive(USERNAME))).isEqualTo(SCRIPT_CONTENT);
-    }
-
-    @Test
-    public void setActiveSwitchScriptShouldWork() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.putScript(USERNAME, OTHER_SCRIPT_NAME, OTHER_SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, OTHER_SCRIPT_NAME);
-        assertThat(getScriptContent(sieveRepository.getActive(USERNAME))).isEqualTo(OTHER_SCRIPT_CONTENT);
-    }
-
-    @Test(expected = ScriptNotFoundException.class)
-    public void switchOffActiveScriptShouldWork() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.setActive(USERNAME, SieveRepository.NO_SCRIPT_NAME);
-        sieveRepository.getActive(USERNAME);
-    }
-
-    @Test
-    public void switchOffActiveScriptShouldNotThrow() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.setActive(USERNAME, SieveRepository.NO_SCRIPT_NAME);
-    }
-
-    @Test(expected = ScriptNotFoundException.class)
-    public void getActiveShouldThrowWhenNoActiveScript() throws Exception {
-        sieveRepository.getActive(USERNAME);
-    }
-
-    @Test(expected = ScriptNotFoundException.class)
-    public void deleteActiveScriptShouldThrowIfScriptDoNotExist() throws Exception {
-        sieveRepository.deleteScript(USERNAME, SCRIPT_NAME);
-    }
-
-    @Test(expected = IsActiveException.class)
-    public void deleteActiveScriptShouldThrow() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.deleteScript(USERNAME, SCRIPT_NAME);
-    }
-
-    @Test(expected = IsActiveException.class)
-    public void deleteScriptShouldWork() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.deleteScript(USERNAME, SCRIPT_NAME);
-        sieveRepository.getScript(USERNAME, SCRIPT_NAME);
-    }
-
-    @Test(expected = ScriptNotFoundException.class)
-    public void renameScriptShouldThrowIfScriptNotFound() throws Exception {
-        sieveRepository.renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME);
-    }
-
-    @Test
-    public void renameScriptShouldWork() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME);
-        assertThat(getScriptContent(sieveRepository.getScript(USERNAME, OTHER_SCRIPT_NAME))).isEqualTo(SCRIPT_CONTENT);
-    }
-
-    @Test
-    public void renameScriptShouldPropagateActiveScript() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.setActive(USERNAME, SCRIPT_NAME);
-        sieveRepository.renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME);
-        assertThat(getScriptContent(sieveRepository.getActive(USERNAME))).isEqualTo(SCRIPT_CONTENT);
-    }
-
-    @Test(expected = DuplicateException.class)
-    public void renameScriptShouldNotOverwriteExistingScript() throws Exception {
-        sieveRepository.putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
-        sieveRepository.putScript(USERNAME, OTHER_SCRIPT_NAME, OTHER_SCRIPT_CONTENT);
-        sieveRepository.renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME);
-    }
-
-    @Test(expected = QuotaNotFoundException.class)
-    public void getQuotaShouldThrowIfQuotaNotFound() throws Exception {
-        sieveRepository.getDefaultQuota();
-    }
-
-    @Test
-    public void getQuotaShouldWork() throws Exception {
-        sieveRepository.setDefaultQuota(DEFAULT_QUOTA);
-        assertThat(sieveRepository.getDefaultQuota()).isEqualTo(DEFAULT_QUOTA);
-    }
-
-    @Test
-    public void getQuotaShouldWorkOnUsers() throws Exception {
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        assertThat(sieveRepository.getQuota(USERNAME)).isEqualTo(USER_QUOTA);
-    }
-
-    @Test
-    public void hasQuotaShouldReturnFalseWhenRepositoryDoesNotHaveQuota() throws Exception {
-        assertThat(sieveRepository.hasDefaultQuota()).isFalse();
-    }
-
-    @Test
-    public void hasQuotaShouldReturnTrueWhenRepositoryHaveQuota() throws Exception {
-        sieveRepository.setDefaultQuota(DEFAULT_QUOTA);
-        assertThat(sieveRepository.hasDefaultQuota()).isTrue();
-    }
-
-    @Test
-    public void hasQuotaShouldReturnFalseWhenUserDoesNotHaveQuota() throws Exception {
-        assertThat(sieveRepository.hasDefaultQuota()).isFalse();
-    }
-
-    @Test
-    public void hasQuotaShouldReturnTrueWhenUserHaveQuota() throws Exception {
-        sieveRepository.setQuota(USERNAME, DEFAULT_QUOTA);
-        assertThat(sieveRepository.hasQuota(USERNAME)).isTrue();
-    }
-
-    @Test
-    public void removeQuotaShouldNotThrowIfRepositoryDoesNotHaveQuota() throws Exception {
-        sieveRepository.removeQuota();
-    }
-
-    @Test
-    public void removeUserQuotaShouldNotThrowWhenAbsent() throws Exception {
-        sieveRepository.removeQuota(USERNAME);
-    }
-
-    @Test
-    public void removeQuotaShouldWorkOnRepositories() throws Exception {
-        sieveRepository.setDefaultQuota(DEFAULT_QUOTA);
-        sieveRepository.removeQuota();
-        assertThat(sieveRepository.hasDefaultQuota()).isFalse();
-    }
-
-    @Test
-    public void removeQuotaShouldWorkOnUsers() throws Exception {
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        sieveRepository.removeQuota(USERNAME);
-        assertThat(sieveRepository.hasQuota(USERNAME)).isFalse();
-    }
-
-    @Test(expected = QuotaNotFoundException.class)
-    public void removeQuotaShouldWorkOnUsersWithGlobalQuota() throws Exception {
-        sieveRepository.setDefaultQuota(DEFAULT_QUOTA);
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        sieveRepository.removeQuota(USERNAME);
-        sieveRepository.getQuota(USERNAME);
-    }
-
-    @Test
-    public void setQuotaShouldWork() throws Exception {
-        sieveRepository.setDefaultQuota(DEFAULT_QUOTA);
-        assertThat(sieveRepository.getDefaultQuota()).isEqualTo(DEFAULT_QUOTA);
-    }
-
-    @Test
-    public void setQuotaShouldWorkOnUsers() throws Exception {
-        sieveRepository.setQuota(USERNAME, DEFAULT_QUOTA);
-        assertThat(sieveRepository.getQuota(USERNAME)).isEqualTo(DEFAULT_QUOTA);
-    }
-
-    @Test
-    public void setQuotaShouldOverrideExistingQuota() throws Exception {
-        sieveRepository.setQuota(USERNAME, USER_QUOTA);
-        sieveRepository.setQuota(USERNAME, QuotaSizeLimit.size(USER_QUOTA.asLong() - 1));
-        assertThat(sieveRepository.getQuota(USERNAME)).isEqualTo(QuotaSizeLimit.size(USER_QUOTA.asLong() - 1));
-    }
-
-    protected ScriptContent getScriptContent(InputStream inputStream) throws IOException {
-        return new ScriptContent(IOUtils.toString(inputStream, StandardCharsets.UTF_8));
-    }
-
-    protected abstract SieveRepository createSieveRepository() throws Exception;
-
-}
diff --git a/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/SieveRepositoryContract.java b/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/SieveRepositoryContract.java
new file mode 100644
index 0000000..a3e55e7
--- /dev/null
+++ b/server/data/data-library/src/test/java/org/apache/james/sieverepository/lib/SieveRepositoryContract.java
@@ -0,0 +1,371 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.sieverepository.lib;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.core.Username;
+import org.apache.james.core.quota.QuotaSizeLimit;
+import org.apache.james.sieverepository.api.ScriptContent;
+import org.apache.james.sieverepository.api.ScriptName;
+import org.apache.james.sieverepository.api.ScriptSummary;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.sieverepository.api.exception.DuplicateException;
+import org.apache.james.sieverepository.api.exception.IsActiveException;
+import org.apache.james.sieverepository.api.exception.QuotaExceededException;
+import org.apache.james.sieverepository.api.exception.QuotaNotFoundException;
+import org.apache.james.sieverepository.api.exception.ScriptNotFoundException;
+import org.junit.jupiter.api.Test;
+
+public interface SieveRepositoryContract {
+
+    Username USERNAME = Username.of("test");
+    ScriptName SCRIPT_NAME = new ScriptName("script");
+    ScriptContent SCRIPT_CONTENT = new ScriptContent("Hello World");
+
+    ScriptName OTHER_SCRIPT_NAME = new ScriptName("other_script");
+    ScriptContent OTHER_SCRIPT_CONTENT = new ScriptContent("Other script content");
+    QuotaSizeLimit DEFAULT_QUOTA = QuotaSizeLimit.size(Long.MAX_VALUE - 1L);
+    QuotaSizeLimit USER_QUOTA = QuotaSizeLimit.size(Long.MAX_VALUE / 2);
+
+    SieveRepository sieveRepository();
+
+    @Test
+    default void getScriptShouldThrowIfUnableToFindScript() {
+        assertThatThrownBy(() -> sieveRepository().getScript(USERNAME, SCRIPT_NAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void getScriptShouldReturnCorrectContent() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        assertThat(getScriptContent(sieveRepository().getScript(USERNAME, SCRIPT_NAME))).isEqualTo(SCRIPT_CONTENT);
+    }
+
+    @Test
+    default void getActivationDateForActiveScriptShouldReturnNonNullAndNonZeroResult() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        assertThat(sieveRepository().getActivationDateForActiveScript(USERNAME)).isNotNull();
+        assertThat(sieveRepository().getActivationDateForActiveScript(USERNAME)).isNotEqualTo(ZonedDateTime.ofInstant(Instant.ofEpochMilli(0L), ZoneOffset.UTC));
+    }
+
+    @Test
+    default void getActivationDateForActiveScriptShouldThrowOnMissingActiveScript() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        assertThatThrownBy(() -> sieveRepository().getActivationDateForActiveScript(USERNAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void haveSpaceShouldNotThrowWhenUserDoesNotHaveQuota() throws Exception {
+        sieveRepository().haveSpace(USERNAME, SCRIPT_NAME, DEFAULT_QUOTA.asLong() + 1L);
+    }
+
+    @Test
+    default void haveSpaceShouldNotThrowWhenQuotaIsNotReached() throws Exception {
+        sieveRepository().setDefaultQuota(DEFAULT_QUOTA);
+        sieveRepository().haveSpace(USERNAME, SCRIPT_NAME, DEFAULT_QUOTA.asLong());
+    }
+
+    @Test
+    default void haveSpaceShouldThrowWhenQuotaIsExceed() throws Exception {
+        sieveRepository().setDefaultQuota(DEFAULT_QUOTA);
+        assertThatThrownBy(() -> sieveRepository().haveSpace(USERNAME, SCRIPT_NAME, DEFAULT_QUOTA.asLong() + 1))
+            .isInstanceOf(QuotaExceededException.class);
+    }
+
+    @Test
+    default void haveSpaceShouldNotThrowWhenAttemptToReplaceOtherScript() throws Exception {
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().haveSpace(USERNAME, SCRIPT_NAME, USER_QUOTA.asLong());
+    }
+
+    @Test
+    default void haveSpaceShouldThrowWhenAttemptToReplaceOtherScriptWithTooLargeScript() throws Exception {
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        assertThatThrownBy(() -> sieveRepository().haveSpace(USERNAME, SCRIPT_NAME, USER_QUOTA.asLong() + 1))
+            .isInstanceOf(QuotaExceededException.class);
+    }
+
+    @Test
+    default void haveSpaceShouldTakeAlreadyExistingScriptsIntoAccount() throws Exception {
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        assertThatThrownBy(() -> sieveRepository().haveSpace(USERNAME, OTHER_SCRIPT_NAME, USER_QUOTA.asLong() - 1))
+            .isInstanceOf(QuotaExceededException.class);
+    }
+
+    @Test
+    default void haveSpaceShouldNotThrowAfterActivatingAScript() throws Exception {
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        sieveRepository().haveSpace(USERNAME, SCRIPT_NAME, USER_QUOTA.asLong());
+    }
+
+    @Test
+    default void listScriptsShouldReturnAnEmptyListIfUserNotFound() throws Exception {
+        assertThat(sieveRepository().listScripts(USERNAME)).isEmpty();
+    }
+
+    @Test
+    default void listScriptsShouldReturnEmptyListWhenThereIsNoScript() throws Exception {
+        assertThat(sieveRepository().listScripts(USERNAME)).isEmpty();
+    }
+
+    @Test
+    default void putScriptShouldWork() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        assertThat(sieveRepository().listScripts(USERNAME)).containsOnly(new ScriptSummary(SCRIPT_NAME, false));
+    }
+
+    @Test
+    default void setActiveShouldWork() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        assertThat(sieveRepository().listScripts(USERNAME)).containsOnly(new ScriptSummary(SCRIPT_NAME, true));
+    }
+
+    @Test
+    default void listScriptShouldCombineActiveAndPassiveScripts() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        sieveRepository().putScript(USERNAME, OTHER_SCRIPT_NAME, OTHER_SCRIPT_CONTENT);
+        assertThat(sieveRepository().listScripts(USERNAME)).containsOnly(new ScriptSummary(SCRIPT_NAME, true), new ScriptSummary(OTHER_SCRIPT_NAME, false));
+    }
+
+    @Test
+    default void putScriptShouldThrowWhenScriptTooBig() throws Exception {
+        sieveRepository().setDefaultQuota(QuotaSizeLimit.size(SCRIPT_CONTENT.length() - 1));
+        assertThatThrownBy(() -> sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT))
+            .isInstanceOf(QuotaExceededException.class);
+    }
+
+    @Test
+    default void putScriptShouldThrowWhenQuotaChangedInBetween() throws Exception {
+        sieveRepository().setDefaultQuota(QuotaSizeLimit.size(SCRIPT_CONTENT.length()));
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setDefaultQuota(QuotaSizeLimit.size(SCRIPT_CONTENT.length() - 1));
+        assertThatThrownBy(() -> sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT))
+            .isInstanceOf(QuotaExceededException.class);
+    }
+
+    @Test
+    default void setActiveScriptShouldThrowOnNonExistentScript() {
+        assertThatThrownBy(() -> sieveRepository().setActive(USERNAME, SCRIPT_NAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void setActiveScriptShouldWork() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        assertThat(getScriptContent(sieveRepository().getActive(USERNAME))).isEqualTo(SCRIPT_CONTENT);
+    }
+
+    @Test
+    default void setActiveSwitchScriptShouldWork() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        sieveRepository().putScript(USERNAME, OTHER_SCRIPT_NAME, OTHER_SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, OTHER_SCRIPT_NAME);
+        assertThat(getScriptContent(sieveRepository().getActive(USERNAME))).isEqualTo(OTHER_SCRIPT_CONTENT);
+    }
+
+    @Test
+    default void switchOffActiveScriptShouldWork() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        sieveRepository().setActive(USERNAME, SieveRepository.NO_SCRIPT_NAME);
+        assertThatThrownBy(() -> sieveRepository().getActive(USERNAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void switchOffActiveScriptShouldNotThrow() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        sieveRepository().setActive(USERNAME, SieveRepository.NO_SCRIPT_NAME);
+    }
+
+    @Test
+    default void getActiveShouldThrowWhenNoActiveScript() {
+        assertThatThrownBy(() -> sieveRepository().getActive(USERNAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void deleteActiveScriptShouldThrowIfScriptDoNotExist() {
+        assertThatThrownBy(() -> sieveRepository().deleteScript(USERNAME, SCRIPT_NAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void deleteActiveScriptShouldThrow() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        assertThatThrownBy(() -> sieveRepository().deleteScript(USERNAME, SCRIPT_NAME))
+            .isInstanceOf(IsActiveException.class);
+    }
+
+    @Test
+    default void deleteScriptShouldWork() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().deleteScript(USERNAME, SCRIPT_NAME);
+        assertThatThrownBy(() -> sieveRepository().getScript(USERNAME, SCRIPT_NAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void renameScriptShouldThrowIfScriptNotFound() {
+        assertThatThrownBy(() -> sieveRepository().renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME))
+            .isInstanceOf(ScriptNotFoundException.class);
+    }
+
+    @Test
+    default void renameScriptShouldWork() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME);
+        assertThat(getScriptContent(sieveRepository().getScript(USERNAME, OTHER_SCRIPT_NAME))).isEqualTo(SCRIPT_CONTENT);
+    }
+
+    @Test
+    default void renameScriptShouldPropagateActiveScript() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().setActive(USERNAME, SCRIPT_NAME);
+        sieveRepository().renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME);
+        assertThat(getScriptContent(sieveRepository().getActive(USERNAME))).isEqualTo(SCRIPT_CONTENT);
+    }
+
+    @Test
+    default void renameScriptShouldNotOverwriteExistingScript() throws Exception {
+        sieveRepository().putScript(USERNAME, SCRIPT_NAME, SCRIPT_CONTENT);
+        sieveRepository().putScript(USERNAME, OTHER_SCRIPT_NAME, OTHER_SCRIPT_CONTENT);
+        assertThatThrownBy(() -> sieveRepository().renameScript(USERNAME, SCRIPT_NAME, OTHER_SCRIPT_NAME))
+            .isInstanceOf(DuplicateException.class);
+    }
+
+    @Test
+    default void getQuotaShouldThrowIfQuotaNotFound() {
+        assertThatThrownBy(() -> sieveRepository().getDefaultQuota())
+            .isInstanceOf(QuotaNotFoundException.class);
+    }
+
+    @Test
+    default void getQuotaShouldWork() throws Exception {
+        sieveRepository().setDefaultQuota(DEFAULT_QUOTA);
+        assertThat(sieveRepository().getDefaultQuota()).isEqualTo(DEFAULT_QUOTA);
+    }
+
+    @Test
+    default void getQuotaShouldWorkOnUsers() throws Exception {
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        assertThat(sieveRepository().getQuota(USERNAME)).isEqualTo(USER_QUOTA);
+    }
+
+    @Test
+    default void hasQuotaShouldReturnFalseWhenRepositoryDoesNotHaveQuota() throws Exception {
+        assertThat(sieveRepository().hasDefaultQuota()).isFalse();
+    }
+
+    @Test
+    default void hasQuotaShouldReturnTrueWhenRepositoryHaveQuota() throws Exception {
+        sieveRepository().setDefaultQuota(DEFAULT_QUOTA);
+        assertThat(sieveRepository().hasDefaultQuota()).isTrue();
+    }
+
+    @Test
+    default void hasQuotaShouldReturnFalseWhenUserDoesNotHaveQuota() throws Exception {
+        assertThat(sieveRepository().hasDefaultQuota()).isFalse();
+    }
+
+    @Test
+    default void hasQuotaShouldReturnTrueWhenUserHaveQuota() throws Exception {
+        sieveRepository().setQuota(USERNAME, DEFAULT_QUOTA);
+        assertThat(sieveRepository().hasQuota(USERNAME)).isTrue();
+    }
+
+    @Test
+    default void removeQuotaShouldNotThrowIfRepositoryDoesNotHaveQuota() throws Exception {
+        sieveRepository().removeQuota();
+    }
+
+    @Test
+    default void removeUserQuotaShouldNotThrowWhenAbsent() throws Exception {
+        sieveRepository().removeQuota(USERNAME);
+    }
+
+    @Test
+    default void removeQuotaShouldWorkOnRepositories() throws Exception {
+        sieveRepository().setDefaultQuota(DEFAULT_QUOTA);
+        sieveRepository().removeQuota();
+        assertThat(sieveRepository().hasDefaultQuota()).isFalse();
+    }
+
+    @Test
+    default void removeQuotaShouldWorkOnUsers() throws Exception {
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        sieveRepository().removeQuota(USERNAME);
+        assertThat(sieveRepository().hasQuota(USERNAME)).isFalse();
+    }
+
+    @Test
+    default void removeQuotaShouldWorkOnUsersWithGlobalQuota() throws Exception {
+        sieveRepository().setDefaultQuota(DEFAULT_QUOTA);
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        sieveRepository().removeQuota(USERNAME);
+        assertThatThrownBy(() -> sieveRepository().getQuota(USERNAME))
+            .isInstanceOf(QuotaNotFoundException.class);
+    }
+
+    @Test
+    default void setQuotaShouldWork() throws Exception {
+        sieveRepository().setDefaultQuota(DEFAULT_QUOTA);
+        assertThat(sieveRepository().getDefaultQuota()).isEqualTo(DEFAULT_QUOTA);
+    }
+
+    @Test
+    default void setQuotaShouldWorkOnUsers() throws Exception {
+        sieveRepository().setQuota(USERNAME, DEFAULT_QUOTA);
+        assertThat(sieveRepository().getQuota(USERNAME)).isEqualTo(DEFAULT_QUOTA);
+    }
+
+    @Test
+    default void setQuotaShouldOverrideExistingQuota() throws Exception {
+        sieveRepository().setQuota(USERNAME, USER_QUOTA);
+        sieveRepository().setQuota(USERNAME, QuotaSizeLimit.size(USER_QUOTA.asLong() - 1));
+        assertThat(sieveRepository().getQuota(USERNAME)).isEqualTo(QuotaSizeLimit.size(USER_QUOTA.asLong() - 1));
+    }
+
+    default ScriptContent getScriptContent(InputStream inputStream) throws IOException {
+        return new ScriptContent(IOUtils.toString(inputStream, StandardCharsets.UTF_8));
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org