mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-02-22 22:50:11 +01:00
Use email util to compute fallback mail address
This commit is contained in:
@@ -30,6 +30,7 @@ import sonia.scm.repository.spi.MergeCommand;
|
||||
import sonia.scm.repository.spi.MergeCommandRequest;
|
||||
import sonia.scm.repository.spi.MergeConflictResult;
|
||||
import sonia.scm.repository.util.AuthorUtil;
|
||||
import sonia.scm.user.EMail;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@@ -75,11 +76,14 @@ import java.util.Set;
|
||||
*/
|
||||
public class MergeCommandBuilder {
|
||||
|
||||
private final EMail eMail;
|
||||
|
||||
private final MergeCommand mergeCommand;
|
||||
private final MergeCommandRequest request = new MergeCommandRequest();
|
||||
|
||||
MergeCommandBuilder(MergeCommand mergeCommand) {
|
||||
MergeCommandBuilder(MergeCommand mergeCommand, EMail eMail) {
|
||||
this.mergeCommand = mergeCommand;
|
||||
this.eMail = eMail;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +213,7 @@ public class MergeCommandBuilder {
|
||||
* @return The result of the merge.
|
||||
*/
|
||||
public MergeCommandResult executeMerge() {
|
||||
AuthorUtil.setAuthorIfNotAvailable(request);
|
||||
AuthorUtil.setAuthorIfNotAvailable(request, eMail);
|
||||
Preconditions.checkArgument(request.isValid(), "revision to merge and target revision is required");
|
||||
return mergeCommand.merge(request);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import sonia.scm.repository.spi.ModifyCommand;
|
||||
import sonia.scm.repository.spi.ModifyCommandRequest;
|
||||
import sonia.scm.repository.util.AuthorUtil;
|
||||
import sonia.scm.repository.work.WorkdirProvider;
|
||||
import sonia.scm.user.EMail;
|
||||
import sonia.scm.util.IOUtil;
|
||||
|
||||
import java.io.File;
|
||||
@@ -72,14 +73,17 @@ public class ModifyCommandBuilder {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ModifyCommandBuilder.class);
|
||||
|
||||
private final EMail eMail;
|
||||
|
||||
private final ModifyCommand command;
|
||||
private final File workdir;
|
||||
|
||||
private final ModifyCommandRequest request = new ModifyCommandRequest();
|
||||
|
||||
ModifyCommandBuilder(ModifyCommand command, WorkdirProvider workdirProvider) {
|
||||
ModifyCommandBuilder(ModifyCommand command, WorkdirProvider workdirProvider, EMail eMail) {
|
||||
this.command = command;
|
||||
this.workdir = workdirProvider.createNewWorkdir();
|
||||
this.eMail = eMail;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,7 +128,7 @@ public class ModifyCommandBuilder {
|
||||
* @return The revision of the new commit.
|
||||
*/
|
||||
public String execute() {
|
||||
AuthorUtil.setAuthorIfNotAvailable(request);
|
||||
AuthorUtil.setAuthorIfNotAvailable(request, eMail);
|
||||
try {
|
||||
Preconditions.checkArgument(request.isValid(), "commit message and at least one request are required");
|
||||
return command.execute(request);
|
||||
|
||||
@@ -34,6 +34,7 @@ import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.repository.work.WorkdirProvider;
|
||||
import sonia.scm.user.EMail;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
@@ -87,6 +88,7 @@ public final class RepositoryService implements Closeable {
|
||||
@SuppressWarnings("rawtypes")
|
||||
private final Set<ScmProtocolProvider> protocolProviders;
|
||||
private final WorkdirProvider workdirProvider;
|
||||
private final EMail eMail;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link RepositoryService}. This constructor should only
|
||||
@@ -94,20 +96,22 @@ public final class RepositoryService implements Closeable {
|
||||
* @param cacheManager cache manager
|
||||
* @param provider implementation for {@link RepositoryServiceProvider}
|
||||
* @param repository the repository
|
||||
* @param workdirProvider
|
||||
* @param workdirProvider provider for workdirs
|
||||
* @param eMail utility to compute email addresses if missing
|
||||
*/
|
||||
RepositoryService(CacheManager cacheManager,
|
||||
RepositoryServiceProvider provider, Repository repository,
|
||||
PreProcessorUtil preProcessorUtil,
|
||||
@SuppressWarnings("rawtypes") Set<ScmProtocolProvider> protocolProviders,
|
||||
WorkdirProvider workdirProvider
|
||||
) {
|
||||
WorkdirProvider workdirProvider,
|
||||
EMail eMail) {
|
||||
this.cacheManager = cacheManager;
|
||||
this.provider = provider;
|
||||
this.repository = repository;
|
||||
this.preProcessorUtil = preProcessorUtil;
|
||||
this.protocolProviders = protocolProviders;
|
||||
this.workdirProvider = workdirProvider;
|
||||
this.eMail = eMail;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,7 +401,7 @@ public final class RepositoryService implements Closeable {
|
||||
LOG.debug("create merge command for repository {}",
|
||||
repository.getNamespaceAndName());
|
||||
|
||||
return new MergeCommandBuilder(provider.getMergeCommand());
|
||||
return new MergeCommandBuilder(provider.getMergeCommand(), eMail);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -418,7 +422,7 @@ public final class RepositoryService implements Closeable {
|
||||
LOG.debug("create modify command for repository {}",
|
||||
repository.getNamespaceAndName());
|
||||
|
||||
return new ModifyCommandBuilder(provider.getModifyCommand(), workdirProvider);
|
||||
return new ModifyCommandBuilder(provider.getModifyCommand(), workdirProvider, eMail);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,9 +40,7 @@ import sonia.scm.HandlerEventType;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.cache.Cache;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.repository.BranchCreatedEvent;
|
||||
import sonia.scm.repository.ClearRepositoryCacheEvent;
|
||||
import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.PostReceiveRepositoryHookEvent;
|
||||
@@ -58,6 +56,7 @@ import sonia.scm.repository.work.WorkdirProvider;
|
||||
import sonia.scm.security.PublicKeyCreatedEvent;
|
||||
import sonia.scm.security.PublicKeyDeletedEvent;
|
||||
import sonia.scm.security.ScmSecurityException;
|
||||
import sonia.scm.user.EMail;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@@ -117,47 +116,9 @@ public final class RepositoryServiceFactory {
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a new {@link RepositoryServiceFactory}. This constructor
|
||||
* should not be called manually, it should only be used by the injection
|
||||
* container.
|
||||
*
|
||||
* @param configuration configuration
|
||||
* @param cacheManager cache manager
|
||||
* @param repositoryManager manager for repositories
|
||||
* @param resolvers a set of {@link RepositoryServiceResolver}
|
||||
* @param preProcessorUtil helper object for pre processor handling
|
||||
* @param protocolProviders
|
||||
* @param workdirProvider
|
||||
* @since 1.21
|
||||
*/
|
||||
@Inject
|
||||
public RepositoryServiceFactory(ScmConfiguration configuration,
|
||||
CacheManager cacheManager, RepositoryManager repositoryManager,
|
||||
Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil,
|
||||
@SuppressWarnings("rawtypes") Set<ScmProtocolProvider> protocolProviders, WorkdirProvider workdirProvider) {
|
||||
this(
|
||||
configuration, cacheManager, repositoryManager, resolvers,
|
||||
preProcessorUtil, protocolProviders, workdirProvider, ScmEventBus.getInstance()
|
||||
);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
RepositoryServiceFactory(ScmConfiguration configuration,
|
||||
CacheManager cacheManager, RepositoryManager repositoryManager,
|
||||
Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil,
|
||||
Set<ScmProtocolProvider> protocolProviders, WorkdirProvider workdirProvider,
|
||||
ScmEventBus eventBus) {
|
||||
this.configuration = configuration;
|
||||
this.cacheManager = cacheManager;
|
||||
this.repositoryManager = repositoryManager;
|
||||
this.resolvers = resolvers;
|
||||
this.preProcessorUtil = preProcessorUtil;
|
||||
this.protocolProviders = protocolProviders;
|
||||
this.workdirProvider = workdirProvider;
|
||||
|
||||
eventBus.register(new CacheClearHook(cacheManager));
|
||||
}
|
||||
private final EMail eMail;
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Set<ScmProtocolProvider> protocolProviders;
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
@@ -216,47 +177,27 @@ public final class RepositoryServiceFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new RepositoryService for the given repository.
|
||||
* Constructs a new {@link RepositoryServiceFactory}. This constructor
|
||||
* should not be called manually, it should only be used by the injection
|
||||
* container.
|
||||
*
|
||||
* @param repository the repository
|
||||
* @return a implementation of RepositoryService
|
||||
* for the given type of repository
|
||||
* @throws RepositoryServiceNotFoundException if no repository service
|
||||
* implementation for this kind of repository is available
|
||||
* @throws NullPointerException if the repository is null
|
||||
* @throws ScmSecurityException if current user has not read permissions
|
||||
* for that repository
|
||||
* @param cacheManager cache manager
|
||||
* @param repositoryManager manager for repositories
|
||||
* @param resolvers a set of {@link RepositoryServiceResolver}
|
||||
* @param preProcessorUtil helper object for pre processor handling
|
||||
* @param protocolProviders
|
||||
* @param workdirProvider
|
||||
* @since 1.21
|
||||
*/
|
||||
public RepositoryService create(Repository repository) {
|
||||
Preconditions.checkNotNull(repository, "repository is required");
|
||||
|
||||
// check for read permissions of current user
|
||||
RepositoryPermissions.read(repository).check();
|
||||
|
||||
RepositoryService service = null;
|
||||
|
||||
for (RepositoryServiceResolver resolver : resolvers) {
|
||||
RepositoryServiceProvider provider = resolver.resolve(repository);
|
||||
|
||||
if (provider != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"create new repository service for repository {} of type {}",
|
||||
repository.getName(), repository.getType());
|
||||
}
|
||||
|
||||
service = new RepositoryService(cacheManager, provider, repository,
|
||||
preProcessorUtil, protocolProviders, workdirProvider);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (service == null) {
|
||||
throw new RepositoryServiceNotFoundException(repository);
|
||||
}
|
||||
|
||||
return service;
|
||||
@Inject
|
||||
public RepositoryServiceFactory(CacheManager cacheManager, RepositoryManager repositoryManager,
|
||||
Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil,
|
||||
@SuppressWarnings("rawtypes") Set<ScmProtocolProvider> protocolProviders,
|
||||
WorkdirProvider workdirProvider, EMail eMail) {
|
||||
this(
|
||||
cacheManager, repositoryManager, resolvers,
|
||||
preProcessorUtil, protocolProviders, workdirProvider, eMail, ScmEventBus.getInstance()
|
||||
);
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
@@ -355,11 +296,6 @@ public final class RepositoryServiceFactory {
|
||||
*/
|
||||
private final CacheManager cacheManager;
|
||||
|
||||
/**
|
||||
* scm-manager configuration
|
||||
*/
|
||||
private final ScmConfiguration configuration;
|
||||
|
||||
/**
|
||||
* pre processor util
|
||||
*/
|
||||
@@ -375,7 +311,65 @@ public final class RepositoryServiceFactory {
|
||||
*/
|
||||
private final Set<RepositoryServiceResolver> resolvers;
|
||||
|
||||
private Set<ScmProtocolProvider> protocolProviders;
|
||||
@VisibleForTesting
|
||||
RepositoryServiceFactory(CacheManager cacheManager, RepositoryManager repositoryManager,
|
||||
Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil,
|
||||
@SuppressWarnings("rawtypes") Set<ScmProtocolProvider> protocolProviders,
|
||||
WorkdirProvider workdirProvider, EMail eMail, ScmEventBus eventBus) {
|
||||
this.cacheManager = cacheManager;
|
||||
this.repositoryManager = repositoryManager;
|
||||
this.resolvers = resolvers;
|
||||
this.preProcessorUtil = preProcessorUtil;
|
||||
this.protocolProviders = protocolProviders;
|
||||
this.workdirProvider = workdirProvider;
|
||||
this.eMail = eMail;
|
||||
|
||||
eventBus.register(new CacheClearHook(cacheManager));
|
||||
}
|
||||
|
||||
private final WorkdirProvider workdirProvider;
|
||||
|
||||
/**
|
||||
* Creates a new RepositoryService for the given repository.
|
||||
*
|
||||
* @param repository the repository
|
||||
* @return a implementation of RepositoryService
|
||||
* for the given type of repository
|
||||
* @throws RepositoryServiceNotFoundException if no repository service
|
||||
* implementation for this kind of repository is available
|
||||
* @throws NullPointerException if the repository is null
|
||||
* @throws ScmSecurityException if current user has not read permissions
|
||||
* for that repository
|
||||
*/
|
||||
public RepositoryService create(Repository repository) {
|
||||
Preconditions.checkNotNull(repository, "repository is required");
|
||||
|
||||
// check for read permissions of current user
|
||||
RepositoryPermissions.read(repository).check();
|
||||
|
||||
RepositoryService service = null;
|
||||
|
||||
for (RepositoryServiceResolver resolver : resolvers) {
|
||||
RepositoryServiceProvider provider = resolver.resolve(repository);
|
||||
|
||||
if (provider != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"create new repository service for repository {} of type {}",
|
||||
repository.getName(), repository.getType());
|
||||
}
|
||||
|
||||
service = new RepositoryService(cacheManager, provider, repository,
|
||||
preProcessorUtil, protocolProviders, workdirProvider, eMail);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (service == null) {
|
||||
throw new RepositoryServiceNotFoundException(repository);
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,28 +21,29 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository.util;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import sonia.scm.repository.Person;
|
||||
import sonia.scm.user.EMail;
|
||||
import sonia.scm.user.User;
|
||||
|
||||
public class AuthorUtil {
|
||||
|
||||
public static void setAuthorIfNotAvailable(CommandWithAuthor request) {
|
||||
public static void setAuthorIfNotAvailable(CommandWithAuthor request, EMail eMail) {
|
||||
if (request.getAuthor() == null) {
|
||||
request.setAuthor(createAuthorFromSubject());
|
||||
request.setAuthor(createAuthorFromSubject(eMail));
|
||||
}
|
||||
}
|
||||
|
||||
private static Person createAuthorFromSubject() {
|
||||
private static Person createAuthorFromSubject(EMail eMail) {
|
||||
Subject subject = SecurityUtils.getSubject();
|
||||
User user = subject.getPrincipals().oneByType(User.class);
|
||||
String name = user.getDisplayName();
|
||||
String email = user.getMail();
|
||||
return new Person(name, email);
|
||||
String mailAddress = eMail.createFallbackMailAddress(user);
|
||||
return new Person(name, mailAddress);
|
||||
}
|
||||
|
||||
public interface CommandWithAuthor {
|
||||
|
||||
@@ -25,7 +25,12 @@
|
||||
package sonia.scm.repository.api;
|
||||
|
||||
import com.google.common.io.ByteSource;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -34,10 +39,12 @@ import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import sonia.scm.repository.Person;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.spi.ModifyCommand;
|
||||
import sonia.scm.repository.spi.ModifyCommandRequest;
|
||||
import sonia.scm.repository.work.WorkdirProvider;
|
||||
import sonia.scm.user.EMail;
|
||||
import sonia.scm.user.User;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
@@ -50,15 +57,19 @@ import java.util.List;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ModifyCommandBuilderTest {
|
||||
|
||||
private static final ScmConfiguration SCM_CONFIGURATION = new ScmConfiguration();
|
||||
|
||||
@Mock
|
||||
ModifyCommand command;
|
||||
@Mock
|
||||
@@ -73,7 +84,7 @@ class ModifyCommandBuilderTest {
|
||||
void initWorkdir(@TempDir Path temp) throws IOException {
|
||||
workdir = Files.createDirectory(temp.resolve("workdir"));
|
||||
lenient().when(workdirProvider.createNewWorkdir()).thenReturn(workdir.toFile());
|
||||
commandBuilder = new ModifyCommandBuilder(command, workdirProvider);
|
||||
commandBuilder = new ModifyCommandBuilder(command, workdirProvider, new EMail(SCM_CONFIGURATION));
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
@@ -89,136 +100,27 @@ class ModifyCommandBuilderTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnTargetRevisionFromCommit() {
|
||||
String targetRevision = initCommand()
|
||||
.deleteFile("toBeDeleted")
|
||||
.execute();
|
||||
|
||||
assertThat(targetRevision).isEqualTo("target");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteDelete() throws IOException {
|
||||
initCommand()
|
||||
.deleteFile("toBeDeleted")
|
||||
.execute();
|
||||
|
||||
verify(worker).delete("toBeDeleted");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithByteSourceContent() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), anyBoolean());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithInputStreamContent() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), anyBoolean());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").withData(new ByteArrayInputStream("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithOverwriteFalseAsDefault() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<Boolean> overwriteCaptor = ArgumentCaptor.forClass(Boolean.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), overwriteCaptor.capture());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").withData(new ByteArrayInputStream("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(overwriteCaptor.getValue()).isFalse();
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithOverwriteIfSet() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<Boolean> overwriteCaptor = ArgumentCaptor.forClass(Boolean.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), overwriteCaptor.capture());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").setOverwrite(true).withData(new ByteArrayInputStream("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(overwriteCaptor.getValue()).isTrue();
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateMultipleTimes() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), anyBoolean());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated_1").withData(new ByteArrayInputStream("content_1".getBytes()))
|
||||
.createFile("toBeCreated_2").withData(new ByteArrayInputStream("content_2".getBytes()))
|
||||
.execute();
|
||||
|
||||
List<String> createdNames = nameCaptor.getAllValues();
|
||||
assertThat(createdNames.get(0)).isEqualTo("toBeCreated_1");
|
||||
assertThat(createdNames.get(1)).isEqualTo("toBeCreated_2");
|
||||
assertThat(contentCaptor).contains("content_1", "content_2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteModify() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).modify(nameCaptor.capture(), any());
|
||||
|
||||
initCommand()
|
||||
.modifyFile("toBeModified").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeModified");
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
private ModifyCommandBuilder initCommand() {
|
||||
return commandBuilder
|
||||
.setBranch("branch")
|
||||
.setCommitMessage("message")
|
||||
.setAuthor(new Person());
|
||||
.setCommitMessage("message");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDeleteTemporaryFiles(@TempDir Path temp) throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<File> fileCaptor = ArgumentCaptor.forClass(File.class);
|
||||
doNothing().when(worker).modify(nameCaptor.capture(), fileCaptor.capture());
|
||||
private void mockLoggedInUser(User loggedInUser) {
|
||||
Subject subject = mock(Subject.class);
|
||||
ThreadContext.bind(subject);
|
||||
PrincipalCollection principals = mock(PrincipalCollection.class);
|
||||
when(subject.getPrincipals()).thenReturn(principals);
|
||||
when(principals.oneByType(User.class)).thenReturn(loggedInUser);
|
||||
}
|
||||
|
||||
initCommand()
|
||||
.modifyFile("toBeModified").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(Files.list(temp)).isEmpty();
|
||||
@AfterEach
|
||||
void unbindSubjec() {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
private static class ExtractContent implements Answer {
|
||||
|
||||
private final List<String> contentCaptor;
|
||||
|
||||
public ExtractContent(List<String> contentCaptor) {
|
||||
@@ -230,4 +132,171 @@ class ModifyCommandBuilderTest {
|
||||
return contentCaptor.add(Files.readAllLines(((File) invocation.getArgument(1)).toPath()).get(0));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class WithUserWithMail {
|
||||
|
||||
@BeforeEach
|
||||
void initSubject() {
|
||||
User loggedInUser = new User("dent", "Arthur", "dent@hitchhiker.com");
|
||||
mockLoggedInUser(loggedInUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnTargetRevisionFromCommit() {
|
||||
String targetRevision = initCommand()
|
||||
.deleteFile("toBeDeleted")
|
||||
.execute();
|
||||
|
||||
assertThat(targetRevision).isEqualTo("target");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteDelete() throws IOException {
|
||||
initCommand()
|
||||
.deleteFile("toBeDeleted")
|
||||
.execute();
|
||||
|
||||
verify(worker).delete("toBeDeleted");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithByteSourceContent() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), anyBoolean());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithInputStreamContent() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), anyBoolean());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").withData(new ByteArrayInputStream("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithOverwriteFalseAsDefault() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<Boolean> overwriteCaptor = ArgumentCaptor.forClass(Boolean.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), overwriteCaptor.capture());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").withData(new ByteArrayInputStream("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(overwriteCaptor.getValue()).isFalse();
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateWithOverwriteIfSet() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<Boolean> overwriteCaptor = ArgumentCaptor.forClass(Boolean.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), overwriteCaptor.capture());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated").setOverwrite(true).withData(new ByteArrayInputStream("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeCreated");
|
||||
assertThat(overwriteCaptor.getValue()).isTrue();
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteCreateMultipleTimes() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).create(nameCaptor.capture(), any(), anyBoolean());
|
||||
|
||||
initCommand()
|
||||
.createFile("toBeCreated_1").withData(new ByteArrayInputStream("content_1".getBytes()))
|
||||
.createFile("toBeCreated_2").withData(new ByteArrayInputStream("content_2".getBytes()))
|
||||
.execute();
|
||||
|
||||
List<String> createdNames = nameCaptor.getAllValues();
|
||||
assertThat(createdNames.get(0)).isEqualTo("toBeCreated_1");
|
||||
assertThat(createdNames.get(1)).isEqualTo("toBeCreated_2");
|
||||
assertThat(contentCaptor).contains("content_1", "content_2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExecuteModify() throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
List<String> contentCaptor = new ArrayList<>();
|
||||
doAnswer(new ExtractContent(contentCaptor)).when(worker).modify(nameCaptor.capture(), any());
|
||||
|
||||
initCommand()
|
||||
.modifyFile("toBeModified").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(nameCaptor.getValue()).isEqualTo("toBeModified");
|
||||
assertThat(contentCaptor).contains("content");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDeleteTemporaryFiles(@TempDir Path temp) throws IOException {
|
||||
ArgumentCaptor<String> nameCaptor = ArgumentCaptor.forClass(String.class);
|
||||
ArgumentCaptor<File> fileCaptor = ArgumentCaptor.forClass(File.class);
|
||||
doNothing().when(worker).modify(nameCaptor.capture(), fileCaptor.capture());
|
||||
|
||||
initCommand()
|
||||
.modifyFile("toBeModified").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
assertThat(Files.list(temp)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseMailFromUser() throws IOException {
|
||||
initCommand()
|
||||
.modifyFile("toBeModified").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
verify(command).execute(argThat(modifyCommandRequest -> {
|
||||
assertThat(modifyCommandRequest.getAuthor().getMail()).isEqualTo("dent@hitchhiker.com");
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class WithUserWithoutMail {
|
||||
|
||||
@BeforeEach
|
||||
void initSubject() {
|
||||
User loggedInUser = new User("dent", "Arthur", null);
|
||||
mockLoggedInUser(loggedInUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseMailFromUser() throws IOException {
|
||||
SCM_CONFIGURATION.setMailHost("heart-of-gold.local");
|
||||
initCommand()
|
||||
.modifyFile("toBeModified").withData(ByteSource.wrap("content".getBytes()))
|
||||
.execute();
|
||||
|
||||
verify(command).execute(argThat(modifyCommandRequest -> {
|
||||
assertThat(modifyCommandRequest.getAuthor().getMail()).isEqualTo("dent@heart-of-gold.local");
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.repository.spi.RepositoryServiceResolver;
|
||||
import sonia.scm.repository.work.WorkdirProvider;
|
||||
import sonia.scm.user.EMail;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
@@ -56,9 +57,6 @@ import static org.mockito.Mockito.when;
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class RepositoryServiceFactoryTest {
|
||||
|
||||
@Mock
|
||||
private ScmConfiguration configuration;
|
||||
|
||||
@Mock(answer = Answers.RETURNS_MOCKS)
|
||||
private CacheManager cacheManager;
|
||||
|
||||
@@ -94,8 +92,9 @@ class RepositoryServiceFactoryTest {
|
||||
builder.add(repositoryServiceResolver);
|
||||
}
|
||||
return new RepositoryServiceFactory(
|
||||
configuration, cacheManager, repositoryManager, builder.build(),
|
||||
preProcessorUtil, ImmutableSet.of(), workdirProvider, eventBus
|
||||
cacheManager, repositoryManager, builder.build(),
|
||||
preProcessorUtil, ImmutableSet.of(), workdirProvider,
|
||||
new EMail(new ScmConfiguration()), eventBus
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,15 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository.api;
|
||||
|
||||
import org.junit.Test;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.spi.HttpScmProtocol;
|
||||
import sonia.scm.repository.spi.RepositoryServiceProvider;
|
||||
import sonia.scm.user.EMail;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -46,9 +48,11 @@ public class RepositoryServiceTest {
|
||||
private final RepositoryServiceProvider provider = mock(RepositoryServiceProvider.class);
|
||||
private final Repository repository = new Repository("", "git", "space", "repo");
|
||||
|
||||
private final EMail eMail = new EMail(new ScmConfiguration());
|
||||
|
||||
@Test
|
||||
public void shouldReturnMatchingProtocolsFromProvider() {
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null);
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
Stream<ScmProtocol> supportedProtocols = repositoryService.getSupportedProtocols();
|
||||
|
||||
assertThat(sizeOf(supportedProtocols.collect(Collectors.toList()))).isEqualTo(1);
|
||||
@@ -56,7 +60,7 @@ public class RepositoryServiceTest {
|
||||
|
||||
@Test
|
||||
public void shouldFindKnownProtocol() {
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null);
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
|
||||
HttpScmProtocol protocol = repositoryService.getProtocol(HttpScmProtocol.class);
|
||||
|
||||
@@ -65,11 +69,9 @@ public class RepositoryServiceTest {
|
||||
|
||||
@Test
|
||||
public void shouldFailForUnknownProtocol() {
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null);
|
||||
RepositoryService repositoryService = new RepositoryService(null, provider, repository, null, Collections.singleton(new DummyScmProtocolProvider()), null, eMail);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
repositoryService.getProtocol(UnknownScmProtocol.class);
|
||||
});
|
||||
assertThrows(IllegalArgumentException.class, () -> repositoryService.getProtocol(UnknownScmProtocol.class));
|
||||
}
|
||||
|
||||
private static class DummyHttpProtocol extends HttpScmProtocol {
|
||||
|
||||
Reference in New Issue
Block a user