add co-authors if available to changeset view

refactor ChangesetAuthor.tsx

get interfaces right / fix unit test / cleanup

fix table layout

use Set constructor injection to bind the implementation for the new changesetTrailers API

cleanup / update CHANGELOG.md

cleanup

fix formatting
This commit is contained in:
Eduard Heimbuch
2020-05-28 11:45:15 +02:00
committed by René Pfeuffer
parent a712c89f6a
commit ec57aa88fa
15 changed files with 208 additions and 80 deletions

View File

@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- ClassLoader and Adapter parameters to typed store apis ([#1111](https://github.com/scm-manager/scm-manager/pull/1111))
- Native packaging for Debian, Red Hat, Windows, Unix, Docker and Kubernetes ([#1165](https://github.com/scm-manager/scm-manager/pull/1165))
- Cache for working directories ([#1166](https://github.com/scm-manager/scm-manager/pull/1166))
- Show commit trailers in table on changeset details view ([#1169](https://github.com/scm-manager/scm-manager/pull/1169))
### Fixed
- Correctly resolve Links in markdown files ([#1152](https://github.com/scm-manager/scm-manager/pull/1152))

View File

@@ -24,12 +24,12 @@
package sonia.scm.repository;
import sonia.scm.api.v2.resources.TrailerPersonDto;
import sonia.scm.plugin.ExtensionPoint;
import java.util.List;
@ExtensionPoint
public interface ChangesetTrailerTypes {
List<String> getTrailerTypes();
public interface ChangesetTrailers {
List<TrailerPersonDto> getTrailers(Repository repository, Changeset changeset);
}

View File

@@ -23,7 +23,6 @@
*/
import React from "react";
import { Changeset } from "@scm-manager/ui-types";
import { ExtensionPoint } from "@scm-manager/ui-extensions";
import { WithTranslation, withTranslation } from "react-i18next";
type Props = WithTranslation & {
@@ -53,15 +52,27 @@ class ChangesetAuthor extends React.Component<Props> {
);
}
checkIfCoAuthorsExists() {
console.log(this.props.changeset.trailerPersons.filter(p => p.trailerType === "Co-authored-by").length > 0);
return this.props.changeset.trailerPersons.filter(p => p.trailerType === "Co-authored-by").length > 0;
getCoAuthorsFromChangeset() {
return this.props.changeset.trailerPersons.filter(p => p.trailerType === "Co-authored-by");
}
renderCoAuthors() {
const { t } = this.props;
const coAuthors = this.getCoAuthorsFromChangeset();
return <>{t("changeset.author.prefix")}</>;
if (coAuthors.length > 0) {
const authorLabel = t("changeset.coAuthor.label", { count: coAuthors.length });
return (
<>
{" " + t("changeset.coAuthor.prefix") + " "}
<a title={authorLabel + ":\n" + coAuthors.map(person => "- " + person.name).join("\n")}>
{coAuthors.length + " " + authorLabel}
</a>
</>
);
}
return null;
}
withExtensionPoint(child: any) {
@@ -69,14 +80,7 @@ class ChangesetAuthor extends React.Component<Props> {
return (
<>
{t("changeset.author.prefix")} {child}
{this.checkIfCoAuthorsExists() ? this.renderCoAuthors() : null}
<ExtensionPoint
name="changesets.author.suffix"
props={{
changeset: this.props.changeset
}}
renderAll={true}
/>
{this.renderCoAuthors()}
</>
);
}

View File

@@ -89,11 +89,26 @@
"diffNotSupported": "Diff des Changesets wird von diesem Repositorytyp nicht unterstützt",
"author": {
"prefix": "Verfasst von",
"mailto": "Mail senden an"
"mailto": "Mail senden an",
"label": "Autor"
},
"coAuthor": {
"prefix": "und",
"label": "Co-Autor",
"label_plural": "Co-Autoren"
},
"buttons": {
"details": "Details",
"sources": "Sources"
},
"trailer": {
"type": {
"Reviewed-by": "Reviewer",
"Co-authored-by": "Co-Autoren",
"Committed-by": "Committed von",
"Signed-off-by": "Signiert von",
"Pushed-by": "Pushed by"
}
}
},
"repositoryForm": {

View File

@@ -89,11 +89,27 @@
"diffNotSupported": "Diff of changesets is not supported by the type of repository",
"author": {
"prefix": "Authored by",
"mailto": "Send mail to"
"mailto": "Send mail to",
"label": "Author"
},
"coAuthor": {
"prefix": "and",
"label": "Co-author",
"label_plural": "Co-authors"
},
"buttons": {
"details": "Details",
"sources": "Sources"
},
"trailer": {
"type": {
"Reviewed-by": "Reviewers",
"Co-authored-by": "Co-Authors",
"Committed-by": "Commit by",
"Signed-off-by": "Signed-off",
"Pushed-by": "Pushed by"
},
"person": "Person"
}
},
"repositoryForm": {

View File

@@ -31,7 +31,6 @@ import {
AvatarImage,
AvatarWrapper,
Button,
ChangesetAuthor,
ChangesetDiff,
ChangesetId,
changesets,
@@ -39,6 +38,7 @@ import {
DateFromNow,
Level
} from "@scm-manager/ui-components";
import { TrailerPerson } from "@scm-manager/ui-types/src/Changesets";
type Props = WithTranslation & {
changeset: Changeset;
@@ -63,6 +63,10 @@ const BottomMarginLevel = styled(Level)`
margin-bottom: 1rem !important;
`;
const SizedTd = styled.td`
width: 10rem;
`;
class ChangesetDetails extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
@@ -71,6 +75,29 @@ class ChangesetDetails extends React.Component<Props, State> {
};
}
collectAvailableTrailerTypes() {
const { changeset } = this.props;
// @ts-ignore
return [...new Set(changeset.trailerPersons.map(person => person.trailerType))];
}
getTrailersByType(type: string) {
const { changeset } = this.props;
return changeset.trailerPersons?.filter(person => person.trailerType === type);
}
getTrailerPersonsByType() {
const availableTrailerTypes: string[] = this.collectAvailableTrailerTypes();
let type;
let trailerPersons = [];
for (type of availableTrailerTypes) {
trailerPersons.push({ type, persons: this.getTrailersByType(type) });
}
return trailerPersons;
}
render() {
const { changeset, repository, t } = this.props;
const { collapsed } = this.state;
@@ -79,6 +106,35 @@ class ChangesetDetails extends React.Component<Props, State> {
const id = <ChangesetId repository={repository} changeset={changeset} link={false} />;
const date = <DateFromNow date={changeset.date} />;
const trailerPersons = this.getTrailerPersonsByType();
const trailerTable = (
<table>
<tr>
<SizedTd>{t("changeset.author.label") + ":"}</SizedTd>
<td>
<a title={changeset?.author?.mail} href={"mailto:" + changeset?.author?.mail}>
{changeset?.author?.name}
</a>
</td>
</tr>
{trailerPersons.map(p => (
<tr>
<SizedTd>{t("changeset.trailer.type." + p.type) + ":"}</SizedTd>
<td className="shorten-text is-marginless">
{p.persons
.map(person => (
<a title={person.mail} href={"mailto:" + person.mail}>
{person.name}
</a>
))
.reduce((prev, curr) => [prev, ", ", curr])}
</td>
</tr>
))}
</table>
);
return (
<>
<div className={classNames("content", "is-marginless")}>
@@ -101,9 +157,7 @@ class ChangesetDetails extends React.Component<Props, State> {
</RightMarginP>
</AvatarWrapper>
<div className="media-content">
<p>
<ChangesetAuthor changeset={changeset} />
</p>
{trailerTable}
<p>
<Trans i18nKey="repos:changeset.summary" components={[id, date]} />
</p>

View File

@@ -25,7 +25,10 @@
package sonia.scm.api.v2.resources;
import com.google.common.collect.ImmutableList;
import sonia.scm.repository.ChangesetTrailerTypes;
import sonia.scm.plugin.Extension;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetTrailers;
import sonia.scm.repository.Repository;
import javax.inject.Inject;
import java.util.ArrayList;
@@ -33,24 +36,24 @@ import java.util.List;
import java.util.Scanner;
import java.util.regex.Pattern;
public class ChangesetTrailerExtractor {
@Extension
public class ChangesetDescriptionTrailers implements ChangesetTrailers {
private final ChangesetTrailerTypes changesetTrailerTypes;
private static final List<String> types = ImmutableList.of("Co-authored-by", "Reviewed-by", "Signed-off-by", "Committed-by");
@Inject
public ChangesetTrailerExtractor(ChangesetTrailerTypes changesetTrailerTypes) {
this.changesetTrailerTypes = changesetTrailerTypes;
}
public ChangesetDescriptionTrailers() {}
List<TrailerPersonDto> extractTrailersFromCommitMessage(String commitMessage) {
@Override
public List<TrailerPersonDto> getTrailers(Repository repository, Changeset changeset) {
List<TrailerPersonDto> persons = new ArrayList<>();
try (Scanner scanner = new Scanner(commitMessage)) {
scanner.useDelimiter(Pattern.compile("[\\n;]"));
try (Scanner scanner = new Scanner(changeset.getDescription())) {
scanner.useDelimiter(Pattern.compile("[\\n]"));
while (scanner.hasNext()) {
String line = scanner.next();
for (String trailerType : changesetTrailerTypes.getTrailerTypes()) {
for (String trailerType : types) {
if (line.contains(trailerType)) {
TrailerPersonDto personDto = createPersonDtoFromUser(line);
personDto.setTrailerType(trailerType);
@@ -59,7 +62,6 @@ public class ChangesetTrailerExtractor {
}
}
}
return persons;
}
@@ -77,12 +79,4 @@ public class ChangesetTrailerExtractor {
return personDto;
}
static class TrailerTypes implements ChangesetTrailerTypes {
@Override
public List<String> getTrailerTypes() {
return ImmutableList.of("Co-authored-by", "Reviewed-by", "Signed-off-by", "Committed-by");
}
}
}

View File

@@ -26,9 +26,15 @@ package sonia.scm.api.v2.resources;
import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.Links;
import org.mapstruct.*;
import org.mapstruct.AfterMapping;
import org.mapstruct.Context;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.ObjectFactory;
import sonia.scm.repository.Branch;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetTrailers;
import sonia.scm.repository.Repository;
import sonia.scm.repository.Tag;
import sonia.scm.repository.api.Command;
@@ -37,8 +43,12 @@ import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.web.EdisonHalAppender;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static de.otto.edison.hal.Embedded.embeddedBuilder;
@@ -46,7 +56,7 @@ import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
@Mapper
public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMapper implements InstantAttributeMapper, ChangesetToChangesetDtoMapper{
public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMapper implements InstantAttributeMapper, ChangesetToChangesetDtoMapper {
@Inject
private RepositoryServiceFactory serviceFactory;
@@ -64,14 +74,32 @@ public abstract class DefaultChangesetToChangesetDtoMapper extends HalAppenderMa
private TagCollectionToDtoMapper tagCollectionToDtoMapper;
@Inject
private ChangesetTrailerExtractor changesetTrailerExtractor;
private Set<ChangesetTrailers> changesetTrailersSet;
@Mapping(target = "attributes", ignore = true) // We do not map HAL attributes
public abstract ChangesetDto map(Changeset changeset, @Context Repository repository);
@AfterMapping
void appendTrailerPersons(Changeset changeset, @MappingTarget ChangesetDto target) {
target.setTrailerPersons(changesetTrailerExtractor.extractTrailersFromCommitMessage(changeset.getDescription()));
void appendTrailerPersons(Changeset changeset, @MappingTarget ChangesetDto target, @Context Repository repository) {
List<TrailerPersonDto> collectedTrailers = new ArrayList<>();
changesetTrailersSet.forEach(changesetTrailers -> collectedTrailers.addAll(changesetTrailers.getTrailers(repository, changeset)));
target.setTrailerPersons(collectedTrailers);
}
@AfterMapping
void removeTrailerFromChangesetDescription(@MappingTarget ChangesetDto target) {
StringBuilder builder = new StringBuilder();
try (Scanner scanner = new Scanner(target.getDescription())) {
scanner.useDelimiter(Pattern.compile("[\\n]"));
while (scanner.hasNext()) {
String line = scanner.next();
if (!line.contains("-by:")) {
builder.append(line).append("\n");
}
}
}
target.setDescription(builder.toString());
}
@ObjectFactory

View File

@@ -27,7 +27,6 @@ package sonia.scm.api.v2.resources;
import com.google.inject.AbstractModule;
import com.google.inject.servlet.ServletScopes;
import org.mapstruct.factory.Mappers;
import sonia.scm.repository.ChangesetTrailerTypes;
import sonia.scm.web.api.RepositoryToHalMapper;
public class MapperModule extends AbstractModule {
@@ -78,7 +77,6 @@ public class MapperModule extends AbstractModule {
bind(MeDtoFactory.class);
bind(UIPluginDtoMapper.class);
bind(UIPluginDtoCollectionMapper.class);
bind(ChangesetTrailerTypes.class).to(ChangesetTrailerExtractor.TrailerTypes.class);
bind(ScmPathInfoStore.class).in(ServletScopes.REQUEST);

View File

@@ -111,7 +111,6 @@ import sonia.scm.web.security.DefaultAdministrationContext;
import javax.net.ssl.SSLContext;
/**
*
* @author Sebastian Sdorra
*/
class ScmServletModule extends ServletModule {

View File

@@ -45,6 +45,7 @@ import sonia.scm.repository.Branch;
import sonia.scm.repository.Branches;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.ChangesetTrailers;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Person;
import sonia.scm.repository.Repository;
@@ -61,6 +62,7 @@ import java.net.URI;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -113,6 +115,9 @@ public class BranchRootResourceTest extends RepositoryTestBase {
@Mock
private TagCollectionToDtoMapper tagCollectionToDtoMapper;
@Mock
private Set<ChangesetTrailers> changesetTrailers;
@InjectMocks
private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;

View File

@@ -24,11 +24,12 @@
package sonia.scm.api.v2.resources;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.api.v2.resources.ChangesetTrailerExtractor.TrailerTypes;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.user.DisplayUser;
import sonia.scm.user.User;
@@ -37,21 +38,17 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class ChangesetTrailerExtractorTest {
class ChangesetDescriptionTrailersTest {
private ChangesetTrailerExtractor extractor;
private static final Repository REPOSITORY = RepositoryTestData.createHeartOfGold();
@BeforeEach
void initExtractor() {
TrailerTypes trailerTypes = new TrailerTypes();
extractor = new ChangesetTrailerExtractor(trailerTypes);
}
private final ChangesetDescriptionTrailers changesetDescriptionTrailers = new ChangesetDescriptionTrailers();
@Test
void shouldReturnEmptyList() {
String commitMessage = "zaphod beetlebrox";
Changeset changeset = createChangeset("zaphod beeblebrox");
List<TrailerPersonDto> trailerPersons = extractor.extractTrailersFromCommitMessage(commitMessage);
List<TrailerPersonDto> trailerPersons = changesetDescriptionTrailers.getTrailers(REPOSITORY, changeset);
assertThat(trailerPersons).isNotNull();
assertThat(trailerPersons).isEmpty();
@@ -60,26 +57,26 @@ class ChangesetTrailerExtractorTest {
@Test
void shouldReturnTrailerPersonsWithCoAuthors() {
DisplayUser displayUser = createDisplayUser("Arthur Dent", "dent@hitchhiker.org");
String commitMessage = "zaphod beetlebrox\n\nCo-authored-by: Arthur Dent <dent@hitchhiker.org>";
Changeset changeset = createChangeset("zaphod beeblebrox\n\nCo-authored-by: Arthur Dent <dent@hitchhiker.org>");
PersonDto personDto = createPersonDto(displayUser);
List<TrailerPersonDto> trailerPersons = extractor.extractTrailersFromCommitMessage(commitMessage);
List<TrailerPersonDto> trailerPersons = changesetDescriptionTrailers.getTrailers(REPOSITORY, changeset);
TrailerPersonDto trailerPersonDto = trailerPersons.get(0);
assertThat(trailerPersonDto.getTrailerType()).isEqualTo("Co-authored-by");
assertThat(trailerPersonDto.getName()).isEqualTo(personDto.getName());
assertThat(trailerPersonDto.getMail()).isEqualTo(personDto.getMail());
TrailerPersonDto trailerPerson = trailerPersons.get(0);
assertThat(trailerPerson.getTrailerType()).isEqualTo("Co-authored-by");
assertThat(trailerPerson.getName()).isEqualTo(personDto.getName());
assertThat(trailerPerson.getMail()).isEqualTo(personDto.getMail());
}
@Test
void shouldReturnTrailerPersonsWithReviewers() {
DisplayUser displayUser = createDisplayUser("Tricia McMillan", "trillian@hitchhiker.org");
String commitMessage = "zaphod beetlebrox\nReviewed-by: Tricia McMillan <trillian@hitchhiker.org>";
Changeset changeset = createChangeset("zaphod beeblebrox\nReviewed-by: Tricia McMillan <trillian@hitchhiker.org>");
PersonDto personDto = createPersonDto(displayUser);
List<TrailerPersonDto> trailerPersons = extractor.extractTrailersFromCommitMessage(commitMessage);
List<TrailerPersonDto> trailerPersons = changesetDescriptionTrailers.getTrailers(REPOSITORY, changeset);
TrailerPersonDto trailerPersonDto = trailerPersons.get(0);
@@ -91,11 +88,11 @@ class ChangesetTrailerExtractorTest {
@Test
void shouldReturnTrailerPersonsWithSigner() {
DisplayUser displayUser = createDisplayUser("Tricia McMillan", "trillian@hitchhiker.org");
String commitMessage = "zaphod beetlebrox\nSigned-off-by: Tricia McMillan <trillian@hitchhiker.org>";
Changeset changeset = createChangeset("zaphod beeblebrox\nSigned-off-by: Tricia McMillan <trillian@hitchhiker.org>");
PersonDto personDto = createPersonDto(displayUser);
List<TrailerPersonDto> trailerPersons = extractor.extractTrailersFromCommitMessage(commitMessage);
List<TrailerPersonDto> trailerPersons = changesetDescriptionTrailers.getTrailers(REPOSITORY, changeset);
TrailerPersonDto trailerPersonDto = trailerPersons.get(0);
@@ -107,11 +104,11 @@ class ChangesetTrailerExtractorTest {
@Test
void shouldReturnTrailerPersonsWithCommitter() {
DisplayUser displayUser = createDisplayUser("Tricia McMillan", "trillian@hitchhiker.org");
String commitMessage = "zaphod beetlebrox\nCommitted-by: Tricia McMillan <trillian@hitchhiker.org>";
Changeset changeset = createChangeset("zaphod beeblebrox\nCommitted-by: Tricia McMillan <trillian@hitchhiker.org>");
PersonDto personDto = createPersonDto(displayUser);
List<TrailerPersonDto> trailerPersons = extractor.extractTrailersFromCommitMessage(commitMessage);
List<TrailerPersonDto> trailerPersons = changesetDescriptionTrailers.getTrailers(REPOSITORY, changeset);
TrailerPersonDto trailerPersonDto = trailerPersons.get(0);
@@ -120,9 +117,14 @@ class ChangesetTrailerExtractorTest {
assertThat(trailerPersonDto.getMail()).isEqualTo(personDto.getMail());
}
private Changeset createChangeset(String commitMessage) {
Changeset changeset = new Changeset();
changeset.setDescription(commitMessage);
return changeset;
}
private DisplayUser createDisplayUser(String name, String mail) {
DisplayUser displayUser = DisplayUser.from(new User(name, name, mail));
return displayUser;
return DisplayUser.from(new User(name, name, mail));
}
private PersonDto createPersonDto(DisplayUser displayUser) {

View File

@@ -43,6 +43,7 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.ChangesetTrailers;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Person;
import sonia.scm.repository.Repository;
@@ -56,6 +57,7 @@ import java.net.URI;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -68,7 +70,6 @@ import static org.mockito.Mockito.when;
@Slf4j
public class ChangesetRootResourceTest extends RepositoryTestBase {
public static final String CHANGESET_PATH = "space/repo/changesets/";
public static final String CHANGESET_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + CHANGESET_PATH;
@@ -86,6 +87,10 @@ public class ChangesetRootResourceTest extends RepositoryTestBase {
@Mock
private LogCommandBuilder logCommandBuilder;
@Mock
private Set<ChangesetTrailers> changesetTrailers;
@InjectMocks
private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
@InjectMocks
@@ -93,11 +98,9 @@ public class ChangesetRootResourceTest extends RepositoryTestBase {
private ChangesetRootResource changesetRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@Before
public void prepareEnvironment() {
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);

View File

@@ -44,6 +44,7 @@ import sonia.scm.ContextEntry;
import sonia.scm.NotFoundException;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.ChangesetTrailers;
import sonia.scm.repository.InternalRepositoryException;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Person;
@@ -59,6 +60,7 @@ import java.net.URISyntaxException;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -89,6 +91,9 @@ public class FileHistoryResourceTest extends RepositoryTestBase {
private FileHistoryCollectionToDtoMapper fileHistoryCollectionToDtoMapper;
@Mock
private Set<ChangesetTrailers> changesetTrailers;
@InjectMocks
private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;

View File

@@ -45,6 +45,7 @@ import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.NotFoundException;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.ChangesetTrailers;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Person;
import sonia.scm.repository.Repository;
@@ -64,6 +65,7 @@ import java.net.URISyntaxException;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Set;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.assertEquals;
@@ -78,7 +80,6 @@ import static sonia.scm.repository.api.DiffFormat.NATIVE;
@Slf4j
public class IncomingRootResourceTest extends RepositoryTestBase {
public static final String INCOMING_PATH = "space/repo/incoming/";
public static final String INCOMING_CHANGESETS_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + INCOMING_PATH;
public static final String INCOMING_DIFF_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + INCOMING_PATH;
@@ -108,6 +109,9 @@ public class IncomingRootResourceTest extends RepositoryTestBase {
private IncomingChangesetCollectionToDtoMapper incomingChangesetCollectionToDtoMapper;
@Mock
private Set<ChangesetTrailers> changesetTrailers;
@InjectMocks
private DefaultChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;