Merge pull request #551 from vttranlina/JAMES_3544

[JAMES-3544] UploadRepository contract & InMemory implementationtemp
diff --git a/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java b/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java
index 1cb9130..3c29347 100644
--- a/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java
+++ b/server/data/data-cassandra/src/test/java/org/apache/james/user/cassandra/CassandraUsersRepositoryTest.java
@@ -19,9 +19,13 @@
 
 package org.apache.james.user.cassandra;
 
+import java.util.Optional;
+
 import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.core.Username;
 import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.lib.UsersRepositoryContract;
 import org.apache.james.user.lib.UsersRepositoryImpl;
 import org.apache.james.user.lib.model.Algorithm;
@@ -39,17 +43,24 @@
         @RegisterExtension
         UserRepositoryExtension extension = UserRepositoryExtension.withVirtualHost();
 
-        private UsersRepositoryImpl usersRepository;
+        private UsersRepositoryImpl<CassandraUsersDAO> usersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) throws Exception {
-            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting());
+            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), Optional.empty());
+            this.testSystem = testSystem;
         }
 
         @Override
-        public UsersRepositoryImpl testee() {
+        public UsersRepositoryImpl<CassandraUsersDAO> testee() {
             return usersRepository;
         }
+
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            return getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), administrator);
+        }
     }
 
     @Nested
@@ -57,25 +68,33 @@
         @RegisterExtension
         UserRepositoryExtension extension = UserRepositoryExtension.withoutVirtualHosting();
 
-        private UsersRepositoryImpl usersRepository;
+        private UsersRepositoryImpl<CassandraUsersDAO> usersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) throws Exception {
-            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting());
+            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), Optional.empty());
+            this.testSystem = testSystem;
         }
 
         @Override
-        public UsersRepositoryImpl testee() {
+        public UsersRepositoryImpl<CassandraUsersDAO> testee() {
             return usersRepository;
         }
+
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            return getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), administrator);
+        }
     }
 
-    private static UsersRepositoryImpl getUsersRepository(DomainList domainList, boolean enableVirtualHosting) throws Exception {
+    private static UsersRepositoryImpl<CassandraUsersDAO> getUsersRepository(DomainList domainList, boolean enableVirtualHosting, Optional<Username> administrator) throws Exception {
         CassandraUsersDAO usersDAO = new CassandraUsersDAO(new Algorithm.DefaultFactory(), cassandraCluster.getCassandraCluster().getConf());
         BaseHierarchicalConfiguration configuration = new BaseHierarchicalConfiguration();
         configuration.addProperty("enableVirtualHosting", String.valueOf(enableVirtualHosting));
+        administrator.ifPresent(username -> configuration.addProperty("administratorId", username.asString()));
 
-        UsersRepositoryImpl usersRepository = new UsersRepositoryImpl(domainList, usersDAO);
+        UsersRepositoryImpl<CassandraUsersDAO> usersRepository = new UsersRepositoryImpl<>(domainList, usersDAO);
         usersRepository.configure(configuration);
         return usersRepository;
     }
diff --git a/server/data/data-jpa/src/test/java/org/apache/james/user/jpa/JpaUsersRepositoryTest.java b/server/data/data-jpa/src/test/java/org/apache/james/user/jpa/JpaUsersRepositoryTest.java
index 9ef1078..55355b0 100644
--- a/server/data/data-jpa/src/test/java/org/apache/james/user/jpa/JpaUsersRepositoryTest.java
+++ b/server/data/data-jpa/src/test/java/org/apache/james/user/jpa/JpaUsersRepositoryTest.java
@@ -18,12 +18,15 @@
  ****************************************************************/
 package org.apache.james.user.jpa;
 
+import java.util.Optional;
+
 import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
 import org.apache.james.backends.jpa.JpaTestCluster;
+import org.apache.james.core.Username;
 import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.jpa.model.JPAUser;
 import org.apache.james.user.lib.UsersRepositoryContract;
-import org.apache.james.user.lib.UsersRepositoryImpl;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
@@ -39,16 +42,23 @@
         UserRepositoryExtension extension = UserRepositoryExtension.withVirtualHost();
 
         private JPAUsersRepository usersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) throws Exception {
-            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting());
+            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), Optional.empty());
+            this.testSystem = testSystem;
         }
 
         @Override
-        public UsersRepositoryImpl testee() {
+        public UsersRepository testee() {
             return usersRepository;
         }
+
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            return getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), administrator);
+        }
     }
 
     @Nested
@@ -57,16 +67,23 @@
         UserRepositoryExtension extension = UserRepositoryExtension.withoutVirtualHosting();
 
         private JPAUsersRepository usersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) throws Exception {
-            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting());
+            usersRepository = getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), Optional.empty());
+            this.testSystem = testSystem;
         }
 
         @Override
-        public UsersRepositoryImpl testee() {
+        public UsersRepository testee() {
             return usersRepository;
         }
+
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            return getUsersRepository(testSystem.getDomainList(), extension.isSupportVirtualHosting(), administrator);
+        }
     }
 
     @AfterEach
@@ -74,11 +91,12 @@
         JPA_TEST_CLUSTER.clear("JAMES_USER");
     }
 
-    private static JPAUsersRepository getUsersRepository(DomainList domainList, boolean enableVirtualHosting) throws Exception {
+    private static JPAUsersRepository getUsersRepository(DomainList domainList, boolean enableVirtualHosting, Optional<Username> administrator) throws Exception {
         JPAUsersRepository repos = new JPAUsersRepository(domainList);
         repos.setEntityManagerFactory(JPA_TEST_CLUSTER.getEntityManagerFactory());
         BaseHierarchicalConfiguration configuration = new BaseHierarchicalConfiguration();
         configuration.addProperty("enableVirtualHosting", String.valueOf(enableVirtualHosting));
+        administrator.ifPresent(username -> configuration.addProperty("administratorId", username.asString()));
         repos.configure(configuration);
         return repos;
     }
diff --git a/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java
index 9638dbf..a24c698 100644
--- a/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java
+++ b/server/data/data-ldap/src/test/java/org/apache/james/user/ldap/ReadOnlyUsersLDAPRepositoryTest.java
@@ -28,6 +28,8 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.util.Optional;
+
 import org.apache.commons.configuration2.HierarchicalConfiguration;
 import org.apache.commons.configuration2.ex.ConversionException;
 import org.apache.commons.configuration2.plist.PropertyListConfiguration;
@@ -35,6 +37,7 @@
 import org.apache.james.core.Username;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.domainlist.api.mock.SimpleDomainList;
+import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.lib.UsersRepositoryContract;
 import org.apache.james.user.lib.UsersRepositoryImpl;
 import org.junit.jupiter.api.AfterAll;
@@ -142,10 +145,12 @@
         UserRepositoryExtension extension = UserRepositoryExtension.withVirtualHost();
 
         private ReadOnlyUsersLDAPRepository usersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) throws Exception {
             usersRepository = startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting(ldapContainer), testSystem.getDomainList());
+            this.testSystem = testSystem;
         }
 
         @Override
@@ -153,6 +158,11 @@
             return usersRepository;
         }
 
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            return startUsersRepository(ldapRepositoryConfigurationWithVirtualHosting(ldapContainer, administrator), testSystem.getDomainList());
+        }
+
         @Test
         void isAdministratorShouldReturnTrueWhenConfiguredAndUserIsAdmin(TestSystem testSystem) throws Exception {
             assertThat(testee().isAdministrator(testSystem.getAdmin())).isTrue();
@@ -241,10 +251,12 @@
         UserRepositoryExtension extension = UserRepositoryExtension.withoutVirtualHosting();
 
         private ReadOnlyUsersLDAPRepository usersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) throws Exception {
             usersRepository = startUsersRepository(ldapRepositoryConfiguration(ldapContainer), testSystem.getDomainList());
+            this.testSystem = testSystem;
         }
 
         @Override
@@ -252,6 +264,11 @@
             return usersRepository;
         }
 
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            return startUsersRepository(ldapRepositoryConfiguration(ldapContainer, administrator), testSystem.getDomainList());
+        }
+
         @Test
         void knownUserShouldBeAbleToLogInWhenPasswordIsCorrect() throws Exception {
             assertThat(usersRepository.test(JAMES_USER, PASSWORD)).isTrue();
@@ -371,17 +388,25 @@
     }
 
     static HierarchicalConfiguration<ImmutableNode> ldapRepositoryConfiguration(LdapGenericContainer ldapContainer) {
+        return ldapRepositoryConfiguration(ldapContainer, Optional.of(Username.of(ADMIN_LOCAL_PART)));
+    }
+
+    static HierarchicalConfiguration<ImmutableNode> ldapRepositoryConfiguration(LdapGenericContainer ldapContainer,  Optional<Username> administrator) {
         PropertyListConfiguration configuration = baseConfiguration(ldapContainer);
         configuration.addProperty("[@userIdAttribute]", "uid");
-        configuration.addProperty("[@administratorId]", ADMIN_LOCAL_PART);
+        administrator.ifPresent(username -> configuration.addProperty("[@administratorId]", username.asString()));
         return configuration;
     }
 
     static HierarchicalConfiguration<ImmutableNode> ldapRepositoryConfigurationWithVirtualHosting(LdapGenericContainer ldapContainer) {
+        return ldapRepositoryConfigurationWithVirtualHosting(ldapContainer, Optional.of(ADMIN));
+    }
+
+    static HierarchicalConfiguration<ImmutableNode> ldapRepositoryConfigurationWithVirtualHosting(LdapGenericContainer ldapContainer, Optional<Username> administrator) {
         PropertyListConfiguration configuration = baseConfiguration(ldapContainer);
         configuration.addProperty("[@userIdAttribute]", "mail");
         configuration.addProperty("supportsVirtualHosting", true);
-        configuration.addProperty("[@administratorId]", ADMIN.asString());
+        administrator.ifPresent(username -> configuration.addProperty("[@administratorId]", username.asString()));
         return configuration;
     }
 
diff --git a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java
index 15e0173..d499e74 100644
--- a/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java
+++ b/server/data/data-library/src/main/java/org/apache/james/user/lib/UsersRepositoryImpl.java
@@ -40,7 +40,6 @@
 import org.apache.james.user.api.model.User;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.CharMatcher;
 
 public class UsersRepositoryImpl<T extends UsersDAO> implements UsersRepository, Configurable {
@@ -164,10 +163,6 @@
         return virtualHosting;
     }
 
-    @VisibleForTesting void setAdministratorId(Optional<Username> username) {
-        this.administratorId = username;
-    }
-
     @Override
     public boolean isAdministrator(Username username) throws UsersRepositoryException {
         assertValid(username);
diff --git a/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java b/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
index eabe6db..000b84a 100644
--- a/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
+++ b/server/data/data-library/src/test/java/org/apache/james/user/lib/UsersRepositoryContract.java
@@ -34,6 +34,7 @@
 import org.apache.james.domainlist.api.mock.SimpleDomainList;
 import org.apache.james.user.api.AlreadyExistInUsersRepositoryException;
 import org.apache.james.user.api.InvalidUsernameException;
+import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
 import org.apache.james.user.lib.model.Algorithm;
@@ -53,15 +54,12 @@
 
     class UserRepositoryExtension implements BeforeEachCallback, ParameterResolver {
 
-        private static final boolean ENABLE_VIRTUAL_HOSTING = true;
-        private static final boolean DISABLE_VIRTUAL_HOSTING = !ENABLE_VIRTUAL_HOSTING;
-
         public static UserRepositoryExtension withVirtualHost() {
-            return new UserRepositoryExtension(ENABLE_VIRTUAL_HOSTING);
+            return new UserRepositoryExtension(true);
         }
 
         public static UserRepositoryExtension withoutVirtualHosting() {
-            return new UserRepositoryExtension(DISABLE_VIRTUAL_HOSTING);
+            return new UserRepositoryExtension(false);
         }
 
         private final boolean supportVirtualHosting;
@@ -93,7 +91,7 @@
 
     class TestSystem {
         static final Domain DOMAIN = Domain.of("james.org");
-        static final Domain UNKNOW_DOMAIN = Domain.of("unknown.org");
+        static final Domain UNKNOWN_DOMAIN = Domain.of("unknown.org");
 
         private final boolean supportVirtualHosting;
         private final SimpleDomainList domainList;
@@ -103,7 +101,7 @@
         private final Username user3;
         private final Username admin;
         private final Username adminCaseVariation;
-        private final Username userWithUnknowDomain;
+        private final Username userWithUnknownDomain;
         private final Username invalidUsername;
 
         TestSystem(boolean supportVirtualHosting) throws Exception {
@@ -116,7 +114,7 @@
             user1CaseVariation = toUsername("uSeRnaMe");
             admin = toUsername("admin");
             adminCaseVariation = toUsername("adMin");
-            userWithUnknowDomain = toUsername("unknown", UNKNOW_DOMAIN);
+            userWithUnknownDomain = toUsername("unknown", UNKNOWN_DOMAIN);
             invalidUsername = toUsername("userContains)*(");
         }
 
@@ -140,12 +138,15 @@
             return admin;
         }
 
-        public Username getUserWithUnknowDomain() {
-            return userWithUnknowDomain;
+        public Username getUserWithUnknownDomain() {
+            return userWithUnknownDomain;
         }
     }
 
-    UsersRepositoryImpl testee();
+    UsersRepository testee();
+
+    UsersRepository testee(Optional<Username> administrator) throws Exception;
+
 
     interface ReadOnlyContract extends UsersRepositoryContract {
         @Test
@@ -169,9 +170,9 @@
         }
 
         @Test
-        default void isAdministratorShouldBeCaseInsentive(TestSystem testSystem) throws Exception {
-            testee().setAdministratorId(Optional.of(testSystem.admin));
-            assertThat(testee().isAdministrator(testSystem.adminCaseVariation))
+        default void isAdministratorShouldBeCaseInsensitive(TestSystem testSystem) throws Exception {
+            UsersRepository testee = testee(Optional.of(testSystem.admin));
+            assertThat(testee.isAdministrator(testSystem.adminCaseVariation))
                 .isTrue();
         }
 
@@ -255,14 +256,14 @@
         }
 
         @Test
-        default void containsShouldBeCaseInsentive(TestSystem testSystem) throws UsersRepositoryException {
+        default void containsShouldBeCaseInsensitive(TestSystem testSystem) throws UsersRepositoryException {
             testee().addUser(testSystem.user1CaseVariation, "password2");
 
             assertThat(testee().contains(testSystem.user1)).isTrue();
         }
 
         @Test
-        default void containsShouldBeCaseInsentiveWhenOriginalValueLowerCased(TestSystem testSystem) throws UsersRepositoryException {
+        default void containsShouldBeCaseInsensitiveWhenOriginalValueLowerCased(TestSystem testSystem) throws UsersRepositoryException {
             testee().addUser(testSystem.user1, "password2");
 
             assertThat(testee().contains(testSystem.user1CaseVariation)).isTrue();
@@ -294,7 +295,7 @@
         }
 
         @Test
-        default void removeUserShouldBeCaseInsentiveOnCaseVariationUser(TestSystem testSystem) throws UsersRepositoryException {
+        default void removeUserShouldBeCaseInsensitiveOnCaseVariationUser(TestSystem testSystem) throws UsersRepositoryException {
             testee().addUser(testSystem.user1CaseVariation, "password2");
 
             testee().removeUser(testSystem.user1);
@@ -305,7 +306,7 @@
         }
 
         @Test
-        default void removeUserShouldBeCaseInsentive(TestSystem testSystem) throws UsersRepositoryException {
+        default void removeUserShouldBeCaseInsensitive(TestSystem testSystem) throws UsersRepositoryException {
             testee().addUser(testSystem.user1, "password2");
 
             testee().removeUser(testSystem.user1CaseVariation);
@@ -316,7 +317,7 @@
         }
 
         @Test
-        default void getUserByNameShouldBeCaseInsentive(TestSystem testSystem) throws UsersRepositoryException {
+        default void getUserByNameShouldBeCaseInsensitive(TestSystem testSystem) throws UsersRepositoryException {
             testee().addUser(testSystem.user1, "password2");
 
             assertThat(testee().getUserByName(testSystem.user1CaseVariation).getUserName())
@@ -333,7 +334,7 @@
 
 
         @Test
-        default void testShouldBeCaseInsentiveOnCaseVariationUser(TestSystem testSystem) throws UsersRepositoryException {
+        default void testShouldBeCaseInsensitiveOnCaseVariationUser(TestSystem testSystem) throws UsersRepositoryException {
             String password = "password2";
             testee().addUser(testSystem.user1CaseVariation, password);
 
@@ -342,7 +343,7 @@
         }
 
         @Test
-        default void testShouldBeCaseInsentive(TestSystem testSystem) throws UsersRepositoryException {
+        default void testShouldBeCaseInsensitive(TestSystem testSystem) throws UsersRepositoryException {
             String password = "password2";
             testee().addUser(testSystem.user1, password);
 
@@ -516,23 +517,23 @@
 
         @Test
         default void isAdministratorShouldReturnFalseWhenNotConfigured(TestSystem testSystem) throws Exception {
-            testee().setAdministratorId(Optional.empty());
+            UsersRepository testee = testee(Optional.empty());
 
-            assertThat(testee().isAdministrator(testSystem.admin)).isFalse();
+            assertThat(testee.isAdministrator(testSystem.admin)).isFalse();
         }
 
         @Test
         default void isAdministratorShouldReturnTrueWhenConfiguredAndUserIsAdmin(TestSystem testSystem) throws Exception {
-            testee().setAdministratorId(Optional.of(testSystem.admin));
+            UsersRepository testee = testee(Optional.of(testSystem.admin));
 
-            assertThat(testee().isAdministrator(testSystem.admin)).isTrue();
+            assertThat(testee.isAdministrator(testSystem.admin)).isTrue();
         }
 
         @Test
         default void isAdministratorShouldReturnFalseWhenConfiguredAndUserIsNotAdmin(TestSystem testSystem) throws Exception {
-            testee().setAdministratorId(Optional.of(testSystem.admin));
+            UsersRepository testee = testee(Optional.of(testSystem.admin));
 
-            assertThat(testee().isAdministrator(testSystem.user1)).isFalse();
+            assertThat(testee.isAdministrator(testSystem.user1)).isFalse();
         }
     }
 
@@ -552,7 +553,7 @@
 
         @Test
         default void addUserShouldThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatThrownBy(() -> testee().addUser(testSystem.userWithUnknowDomain, "password"))
+            assertThatThrownBy(() -> testee().addUser(testSystem.userWithUnknownDomain, "password"))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Domain does not exist in DomainList");
         }
@@ -566,7 +567,7 @@
 
         @Test
         default void updateUserShouldThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatThrownBy(() -> testee().updateUser(new DefaultUser(testSystem.userWithUnknowDomain, Algorithm.DEFAULT_FACTORY.of("hasAlg"))))
+            assertThatThrownBy(() -> testee().updateUser(new DefaultUser(testSystem.userWithUnknownDomain, Algorithm.DEFAULT_FACTORY.of("hasAlg"))))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Domain does not exist in DomainList");
         }
@@ -579,7 +580,7 @@
 
         @Test
         default void removeUserShouldThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatThrownBy(() -> testee().removeUser(testSystem.userWithUnknowDomain))
+            assertThatThrownBy(() -> testee().removeUser(testSystem.userWithUnknownDomain))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Domain does not exist in DomainList");
         }
@@ -595,25 +596,25 @@
 
         @Test
         default void getUserByNameShouldNotThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatCode(() -> testee().getUserByName(testSystem.userWithUnknowDomain))
+            assertThatCode(() -> testee().getUserByName(testSystem.userWithUnknownDomain))
                 .doesNotThrowAnyException();
         }
 
         @Test
         default void containsShouldNotThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatCode(() -> testee().contains(testSystem.userWithUnknowDomain))
+            assertThatCode(() -> testee().contains(testSystem.userWithUnknownDomain))
                 .doesNotThrowAnyException();
         }
 
         @Test
         default void testShouldNotThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatCode(() -> testee().test(testSystem.userWithUnknowDomain, "password"))
+            assertThatCode(() -> testee().test(testSystem.userWithUnknownDomain, "password"))
                 .doesNotThrowAnyException();
         }
 
         @Test
         default void isAdministratorShouldThrowWhenUserDoesNotBelongToDomainList(TestSystem testSystem) {
-            assertThatThrownBy(() -> testee().isAdministrator(testSystem.userWithUnknowDomain))
+            assertThatThrownBy(() -> testee().isAdministrator(testSystem.userWithUnknownDomain))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Domain does not exist in DomainList");
         }
@@ -646,14 +647,14 @@
         default void assertDomainPartValidShouldThrowWhenDomainPartIsMissing() throws Exception {
             Username withoutDomainPart = Username.fromLocalPartWithoutDomain("localPartOnly");
 
-            assertThatThrownBy(() -> testee().assertDomainPartValid(withoutDomainPart))
+            assertThatThrownBy(() -> testee().assertValid(withoutDomainPart))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Given Username needs to contain a @domainpart");
         }
 
         @Test
         default void assertDomainPartValidShouldThrowWhenDomainPartIsNotManaged(TestSystem testSystem) {
-            assertThatThrownBy(() -> testee().assertDomainPartValid(testSystem.userWithUnknowDomain))
+            assertThatThrownBy(() -> testee().assertValid(testSystem.userWithUnknownDomain))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Domain does not exist in DomainList");
         }
@@ -664,7 +665,7 @@
                 "localPart",
                 TestSystem.DOMAIN);
 
-            assertThatCode(() -> testee().assertDomainPartValid(userWithManagedDomain))
+            assertThatCode(() -> testee().assertValid(userWithManagedDomain))
                 .doesNotThrowAnyException();
         }
     }
@@ -700,7 +701,7 @@
                 "localPart",
                 TestSystem.DOMAIN);
 
-            assertThatThrownBy(() -> testee().assertDomainPartValid(withDomainPart))
+            assertThatThrownBy(() -> testee().assertValid(withDomainPart))
                 .isInstanceOf(InvalidUsernameException.class)
                 .hasMessage("Given Username contains a @domainpart but virtualhosting support is disabled");
         }
@@ -709,7 +710,7 @@
         default void assertDomainPartValidShouldNotThrowWhenDomainPartIsMissing() {
             Username withOutDomainPart = Username.fromLocalPartWithoutDomain("localPartOnly");
 
-            assertThatCode(() -> testee().assertDomainPartValid(withOutDomainPart))
+            assertThatCode(() -> testee().assertValid(withOutDomainPart))
                 .doesNotThrowAnyException();
         }
     }
diff --git a/server/data/data-memory/src/test/java/org/apache/james/user/memory/MemoryUsersRepositoryTest.java b/server/data/data-memory/src/test/java/org/apache/james/user/memory/MemoryUsersRepositoryTest.java
index b77b437..28d8f32 100644
--- a/server/data/data-memory/src/test/java/org/apache/james/user/memory/MemoryUsersRepositoryTest.java
+++ b/server/data/data-memory/src/test/java/org/apache/james/user/memory/MemoryUsersRepositoryTest.java
@@ -22,14 +22,19 @@
 import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 
+import java.util.Optional;
+
+import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
+import org.apache.commons.configuration2.HierarchicalConfiguration;
+import org.apache.commons.configuration2.tree.ImmutableNode;
 import org.apache.james.core.Domain;
 import org.apache.james.core.Username;
 import org.apache.james.dnsservice.api.InMemoryDNSService;
 import org.apache.james.domainlist.lib.DomainListConfiguration;
 import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.lib.UsersRepositoryContract;
-import org.apache.james.user.lib.UsersRepositoryImpl;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -46,14 +51,23 @@
         UserRepositoryExtension extension = UserRepositoryExtension.withVirtualHost();
 
         private MemoryUsersRepository memoryUsersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) {
             memoryUsersRepository = MemoryUsersRepository.withVirtualHosting(testSystem.getDomainList());
+            this.testSystem = testSystem;
         }
 
         @Override
-        public UsersRepositoryImpl testee() {
+        public UsersRepository testee() {
+            return memoryUsersRepository;
+        }
+
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            MemoryUsersRepository memoryUsersRepository = MemoryUsersRepository.withVirtualHosting(testSystem.getDomainList());
+            memoryUsersRepository.configure(configuration(administrator, true));
             return memoryUsersRepository;
         }
 
@@ -103,14 +117,23 @@
         UserRepositoryExtension extension = UserRepositoryExtension.withoutVirtualHosting();
 
         private MemoryUsersRepository memoryUsersRepository;
+        private TestSystem testSystem;
 
         @BeforeEach
         void setUp(TestSystem testSystem) {
             memoryUsersRepository = MemoryUsersRepository.withoutVirtualHosting(testSystem.getDomainList());
+            this.testSystem = testSystem;
         }
 
         @Override
-        public UsersRepositoryImpl testee() {
+        public UsersRepository testee() {
+            return memoryUsersRepository;
+        }
+
+        @Override
+        public UsersRepository testee(Optional<Username> administrator) throws Exception {
+            MemoryUsersRepository memoryUsersRepository = MemoryUsersRepository.withVirtualHosting(testSystem.getDomainList());
+            memoryUsersRepository.configure(configuration(administrator, false));
             return memoryUsersRepository;
         }
 
@@ -130,4 +153,12 @@
                 .doesNotThrowAnyException();
         }
     }
+
+    private HierarchicalConfiguration<ImmutableNode> configuration(Optional<Username> administrator, boolean enableVirtualHosting) {
+        BaseHierarchicalConfiguration configuration = new BaseHierarchicalConfiguration();
+        administrator.ifPresent(username -> configuration.addProperty("administratorId", username.asString()));
+
+        configuration.addProperty("enableVirtualHosting", enableVirtualHosting);
+        return configuration;
+    }
 }