Make EMail computation available for DisplayUser (#1815)

Adds an internal api call to determine a email address for a DisplayUser instance
in class EMail. This was available only for the User class before, but there is no
reason, why this should be limited.

Additionally one can also set the author for the merge command as DisplayUser,
which will trigger the fallback mechanisms for the email address, if it is missing.

This is introduced to make merge commits possible for users without email addresses
in the review plugin (scm-manager/scm-review-plugin#149).
This commit is contained in:
René Pfeuffer
2021-09-30 14:32:31 +02:00
committed by GitHub
parent 922dc27c49
commit 2b85081032
4 changed files with 109 additions and 3 deletions

View File

@@ -0,0 +1,4 @@
- type: Added
description: Internal api to determine email address for DisplayUser ([#1815](https://github.com/scm-manager/scm-manager/pull/1815))
- type: Added
description: Set author for merge as DisplayUser ([#1815](https://github.com/scm-manager/scm-manager/pull/1815))

View File

@@ -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.DisplayUser;
import sonia.scm.user.EMail;
import javax.annotation.Nullable;
@@ -131,18 +132,36 @@ public class MergeCommandBuilder {
}
/**
* Use this to set the author of the merge commit manually. If this is omitted, the currently logged in user will be
* Use this to set the author of the merge commit manually. If this is omitted, the currently logged-in user will be
* used instead.
*
* This is optional and for {@link #executeMerge()} only.
*
* @return This builder instance.
* @deprecated Use {@link #setAuthor(DisplayUser)} instead to enable fallback email computation.
*/
@Deprecated
public MergeCommandBuilder setAuthor(Person author) {
request.setAuthor(author);
return this;
}
/**
* Use this to set the author of the merge commit manually. If this is omitted, the currently logged-in user will be
* used instead. If the given user object does not have an email address, we will use {@link EMail} to compute a
* fallback address.
*
* This is optional and for {@link #executeMerge()} only.
*
* @return This builder instance.
*/
public MergeCommandBuilder setAuthor(DisplayUser author) {
String mailAddress = eMail == null ? author.getMail() : eMail.getMailOrFallback(author);
Person person = new Person(author.getDisplayName(), mailAddress);
request.setAuthor(person);
return this;
}
/**
* Disables adding a verifiable signature to the merge commit.
* @return This builder instance.

View File

@@ -50,6 +50,15 @@ public class EMail {
* @return email address or fallback
*/
public String getMailOrFallback(User user) {
return getMailOrFallback(DisplayUser.from(user));
}
/**
* Returns the email address of the given user or a generated fallback address.
* @param user user to resolve address from
* @return email address or fallback
*/
public String getMailOrFallback(DisplayUser user) {
if (Strings.isNullOrEmpty(user.getMail())) {
if (isMailUsedAsId(user)) {
return user.getId();
@@ -61,11 +70,11 @@ public class EMail {
}
}
private boolean isMailUsedAsId(User user) {
private boolean isMailUsedAsId(DisplayUser user) {
return ValidationUtil.isMailAddressValid(user.getId());
}
private String createFallbackMail(User user) {
private String createFallbackMail(DisplayUser user) {
return user.getId() + "@" + scmConfiguration.getMailDomainName();
}
}

View File

@@ -0,0 +1,74 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* 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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.repository.spi.MergeCommand;
import sonia.scm.user.DisplayUser;
import sonia.scm.user.EMail;
import sonia.scm.user.User;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class MergeCommandBuilderTest {
@Mock
private MergeCommand mergeCommand;
@Mock
private EMail eMail;
@InjectMocks
private MergeCommandBuilder mergeCommandBuilder;
@BeforeEach
void prepareCommandBuilder() {
mergeCommandBuilder.setBranchToMerge("irrelevant");
mergeCommandBuilder.setTargetBranch("irrelevant");
}
@Test
void shouldUseMailAddressFromEMailFallback() {
User user = new User("dent", "Arthur Dent", null);
DisplayUser author = DisplayUser.from(user);
when(eMail.getMailOrFallback(author)).thenReturn("dent@hitchhiker.com");
mergeCommandBuilder.setAuthor(author);
mergeCommandBuilder.executeMerge();
verify(mergeCommand).merge(argThat(mergeCommandRequest -> {
assertThat(mergeCommandRequest.getAuthor().getMail()).isEqualTo("dent@hitchhiker.com");
return true;
}));
}
}