/**
* Copy a diff from another issue
*/
- private static Optional<FieldDiffs> copyFieldDiffOfIssueFromOtherBranch(String issueKey, FieldDiffs c) {
+ private static Optional<FieldDiffs> copyFieldDiffOfIssueFromOtherBranch(String issueKey, FieldDiffs source) {
FieldDiffs result = new FieldDiffs();
result.setIssueKey(issueKey);
- result.setUserUuid(c.userUuid());
- result.setCreationDate(c.creationDate());
+ source.userUuid().ifPresent(result::setUserUuid);
+ source.webhookSource().ifPresent(result::setWebhookSource);
+ source.externalUser().ifPresent(result::setExternalUser);
+ result.setCreationDate(source.creationDate());
// Don't copy "file" changelogs as they refer to file uuids that might later be purged
- c.diffs().entrySet().stream()
+ source.diffs().entrySet().stream()
.filter(e -> !e.getKey().equals(IssueFieldsSetter.FILE))
.forEach(e -> result.setDiff(e.getKey(), e.getValue().oldValue(), e.getValue().newValue()));
if (result.diffs().isEmpty()) {
IssueCache.FieldDiffs.Builder builder = IssueCache.FieldDiffs.newBuilder()
.setCreationDate(fieldDiffs.creationDate().getTime());
- if (fieldDiffs.issueKey() != null) {
- builder.setIssueKey(fieldDiffs.issueKey());
- }
-
- String userUuid = fieldDiffs.userUuid();
- if (userUuid != null) {
- builder.setUserUuid(userUuid);
- }
+ fieldDiffs.issueKey().ifPresent(builder::setIssueKey);
+ fieldDiffs.userUuid().ifPresent(builder::setUserUuid);
for (Map.Entry<String, FieldDiffs.Diff> e : fieldDiffs.diffs().entrySet()) {
IssueCache.Diff.Builder diffBuilder = IssueCache.Diff.newBuilder();
.containsOnly(tuple("raw", commentDate, "user_uuid", "A comment"));
assertThat(raw.changes()).hasSize(2);
assertThat(raw.changes().get(0).creationDate()).isEqualTo(diffDate);
- assertThat(raw.changes().get(0).userUuid()).isEqualTo("user_uuid");
- assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw");
+ assertThat(raw.changes().get(0).userUuid()).contains("user_uuid");
+ assertThat(raw.changes().get(0).issueKey()).contains("raw");
assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity");
- assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid");
+ assertThat(raw.changes().get(1).userUuid()).contains("default_user_uuid");
assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_BRANCH);
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).oldValue()).isEqualTo("#2");
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).newValue()).isEqualTo("master");
.containsOnly(tuple("raw", commentDate, "user_uuid", "A comment"));
assertThat(raw.changes()).hasSize(2);
assertThat(raw.changes().get(0).creationDate()).isEqualTo(diffDate);
- assertThat(raw.changes().get(0).userUuid()).isEqualTo("user_uuid");
- assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw");
+ assertThat(raw.changes().get(0).userUuid()).contains("user_uuid");
+ assertThat(raw.changes().get(0).issueKey()).contains("raw");
assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity");
- assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid");
+ assertThat(raw.changes().get(1).userUuid()).contains("default_user_uuid");
assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_BRANCH);
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).oldValue()).isEqualTo("sourceBranch-1");
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).newValue()).isEqualTo("#1");
}
+ @Test
+ public void copyExistingIssuesFromSourceBranchOfPullRequest_copyFieldDiffsCorrectly() {
+ String pullRequestKey = "1";
+ Branch branch = mock(Branch.class);
+ when(branch.getType()).thenReturn(BranchType.PULL_REQUEST);
+ when(branch.getName()).thenReturn("sourceBranch-1");
+ when(branch.getPullRequestKey()).thenReturn(pullRequestKey);
+ analysisMetadataHolder.setBranch(branch);
+ analysisMetadataHolder.setPullRequestKey(pullRequestKey);
+ DefaultIssue destIssue = new DefaultIssue()
+ .setKey("raw");
+ DefaultIssue sourceIssue = new DefaultIssue()
+ .setKey("issue");
+ sourceIssue.setResolution("resolution");
+ sourceIssue.setStatus("status");
+
+ FieldDiffs sourceFieldDiffs = new FieldDiffs();
+ sourceIssue.addChange(sourceFieldDiffs
+ .setCreationDate(new Date())
+ .setIssueKey("short")
+ .setUserUuid("user_uuid")
+ .setExternalUser("toto")
+ .setWebhookSource("github")
+ .setDiff("severity", "MINOR", "MAJOR"));
+
+ underTest.copyExistingIssueFromSourceBranchToPullRequest(destIssue, sourceIssue);
+
+ FieldDiffs actualFieldDiffs = destIssue.changes().iterator().next();
+ assertThat(actualFieldDiffs.issueKey()).contains(destIssue.key());
+ assertThat(actualFieldDiffs).usingRecursiveComparison().ignoringFields("issueKey").isEqualTo(sourceFieldDiffs);
+ }
+
@Test
public void copyExistingIssuesFromSourceBranchOfPullRequest_only_works_for_pull_requests() {
DefaultIssue raw = new DefaultIssue()
IssueChangeDto dto = newDto(issueKey);
dto.setChangeType(IssueChangeDto.TYPE_FIELD_CHANGE);
dto.setChangeData(diffs.toEncodedString());
- dto.setUserUuid(diffs.userUuid());
+ dto.setUserUuid(diffs.userUuid().orElse(null));
Date createdAt = requireNonNull(diffs.creationDate(), "Diffs created at must not be null");
dto.setIssueChangeCreationDate(createdAt.getTime());
dto.setProjectUuid(projectUuid);
.setIssueChangeCreationDate(System2.INSTANCE.now());
FieldDiffs diffs = changeDto.toFieldDiffs();
- assertThat(diffs.userUuid()).isEqualTo("user_uuid");
- assertThat(diffs.issueKey()).isEqualTo("ABCDE");
+ assertThat(diffs.userUuid()).contains("user_uuid");
+ assertThat(diffs.issueKey()).contains("ABCDE");
assertThat(diffs.creationDate()).isNotNull();
}
.setCreatedAt(System2.INSTANCE.now());
FieldDiffs diffs = changeDto.toFieldDiffs();
- assertThat(diffs.userUuid()).isEqualTo("user_uuid");
- assertThat(diffs.issueKey()).isEqualTo("ABCDE");
+ assertThat(diffs.userUuid()).contains("user_uuid");
+ assertThat(diffs.issueKey()).contains("ABCDE");
assertThat(diffs.creationDate()).isNotNull();
}
@Test
public void broadcastOnIssueChange_has_no_effect_when_issues_are_empty() {
underTest.broadcastOnIssueChange(emptyList(), singletonList(component1QGChangeEvent), false);
-
verifyNoInteractions(listener1, listener2, listener3);
}
private Map<String, UserDto> loadUsers(DbSession dbSession, Map<String, List<FieldDiffs>> changesByRuleKey,
Map<String, List<IssueChangeDto>> commentsByIssueKey, Set<UserDto> preloadedUsers) {
Set<String> userUuids = Stream.concat(
- changesByRuleKey.values().stream()
- .flatMap(Collection::stream)
- .map(FieldDiffs::userUuid),
- commentsByIssueKey.values().stream()
- .flatMap(Collection::stream)
- .map(IssueChangeDto::getUserUuid))
+ changesByRuleKey.values().stream()
+ .flatMap(Collection::stream)
+ .map(FieldDiffs::userUuid)
+ .filter(Optional::isPresent)
+ .map(Optional::get),
+ commentsByIssueKey.values().stream()
+ .flatMap(Collection::stream)
+ .map(IssueChangeDto::getUserUuid)
+ )
.filter(Objects::nonNull)
.collect(toSet());
if (userUuids.isEmpty()) {
}
return Stream.concat(
- preloadedUsers.stream(),
- dbClient.userDao().selectByUuids(dbSession, missingUsersUuids).stream())
+ preloadedUsers.stream(),
+ dbClient.userDao().selectByUuids(dbSession, missingUsersUuids).stream())
.filter(t -> userUuids.contains(t.getUuid()))
.collect(uniqueIndex(UserDto::getUuid, userUuids.size()));
}
}
return Stream.concat(
- preloadedComponents.stream(),
- dbClient.componentDao().selectByUuids(dbSession, missingFileUuids).stream())
+ preloadedComponents.stream(),
+ dbClient.componentDao().selectByUuids(dbSession, missingFileUuids).stream())
.filter(t -> fileUuids.contains(t.uuid()))
.collect(uniqueIndex(ComponentDto::uuid, fileUuids.size()));
}
private Function<FieldDiffs, Common.Changelog> toWsChangelog(FormattingContext formattingContext) {
return change -> {
- String userUUuid = change.userUuid();
Common.Changelog.Builder changelogBuilder = Common.Changelog.newBuilder();
changelogBuilder.setCreationDate(formatDateTime(change.creationDate()));
- formattingContext.getUserByUuid(userUUuid)
+ change.userUuid().flatMap(formattingContext::getUserByUuid)
.ifPresent(user -> {
changelogBuilder.setUser(user.getLogin());
changelogBuilder.setIsUserActive(user.isActive());
ofNullable(user.getName()).ifPresent(changelogBuilder::setUserName);
ofNullable(emptyToNull(user.getEmail())).ifPresent(email -> changelogBuilder.setAvatar(avatarFactory.create(user)));
});
+ change.externalUser().ifPresent(changelogBuilder::setExternalUser);
+ change.webhookSource().ifPresent(changelogBuilder::setWebhookSource);
change.diffs().entrySet().stream()
.map(toWsDiff(formattingContext))
.forEach(changelogBuilder::addDiffs);
"Requires the 'Browse' permission on the project of the specified issue.")
.setSince("4.1")
.setChangelog(
+ new Change("9.7", "'externalUser' and 'webhookSource' information added to the answer"),
new Change("6.3", "changes on effort is expressed with the raw value in minutes (instead of the duration previously)"))
.setHandler(this)
.setResponseExample(Resources.getResource(IssuesWs.class, "changelog-example.json"));
import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
+import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.db.component.BranchType.PULL_REQUEST;
public class IssueUpdater {
if (context.refreshMeasures()) {
List<DefaultIssue> changedIssues = result.getIssues().stream().map(IssueDto::toDefaultIssue).collect(MoreCollectors.toList(result.getIssues().size()));
- issueChangePostProcessor.process(dbSession, changedIssues, singleton(component), context.fromAlm());
+ boolean isChangeFromWebhook = isNotEmpty(context.getWebhookSource());
+ issueChangePostProcessor.process(dbSession, changedIssues, singleton(component), isChangeFromWebhook);
}
return result;
"isUserActive": true,
"avatar": "b0d8c6e5ea589e6fc3d3e08afb1873bb",
"creationDate": "2014-03-04T23:03:44+0100",
+ "externalUser": "toto",
+ "webhookSource": "github",
"diffs": [
{
"key": "severity",
package org.sonar.server.issue;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.MoreCollectors;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
assertThat(wsChangelog.getDiffsList().get(3).getNewValue()).isEqualTo("e");
}
+ @Test
+ public void formatChangelog_handlesCorrectlyExternalUserAndWebhookSource() {
+ IssueDto issue = dbTester.issues().insertIssue();
+
+ IssueChangeDto issueChangeDto = newFieldChange(issue)
+ .setChangeData(new FieldDiffs()
+ .setDiff("f_change_" + 1, null, null)
+ .setExternalUser("toto")
+ .setWebhookSource("github")
+ .toEncodedString());
+
+ dbTester.issues().insertChange(issueChangeDto);
+
+ FormattingContext formattingContext = underTest.newFormattingContext(dbTester.getSession(), singleton(issue), Load.CHANGE_LOG);
+
+ Changelog changeLog = underTest.formatChangelog(issue, formattingContext).collect(MoreCollectors.onlyElement());
+ assertThat(changeLog.getExternalUser()).isEqualTo("toto");
+ assertThat(changeLog.getWebhookSource()).isEqualTo("github");
+ }
+
@Test
@UseDataProvider("loadAllOrChangelog")
public void formatChangelog_returns_user_details_if_exists(Load load) {
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.Common;
import org.sonarqube.ws.Common.Changelog.Diff;
import org.sonarqube.ws.Issues.ChangelogWsResponse;
public class ChangelogActionTest {
-
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
IssueDto issueDto = insertNewIssue();
userSession.logIn("john")
.addProjectPermission(USER, project, file);
- db.issues().insertFieldDiffs(issueDto, new FieldDiffs().setUserUuid(user.getUuid()).setDiff("severity", "MAJOR", "BLOCKER").setCreationDate(new Date()));
+ FieldDiffs fieldDiffs = createFieldDiffs(user);
+ db.issues().insertFieldDiffs(issueDto, fieldDiffs);
ChangelogWsResponse result = call(issueDto.getKey());
assertThat(result.getChangelogList()).hasSize(1);
- assertThat(result.getChangelogList().get(0).getUser()).isNotNull().isEqualTo(user.getLogin());
- assertThat(result.getChangelogList().get(0).getUserName()).isNotNull().isEqualTo(user.getName());
- assertThat(result.getChangelogList().get(0).getIsUserActive()).isTrue();
- assertThat(result.getChangelogList().get(0).getAvatar()).isNotNull().isEqualTo("93942e96f5acd83e2e047ad8fe03114d");
- assertThat(result.getChangelogList().get(0).getCreationDate()).isNotEmpty();
- assertThat(result.getChangelogList().get(0).getDiffsList()).extracting(Diff::getKey, Diff::getOldValue, Diff::getNewValue).containsOnly(tuple("severity", "MAJOR", "BLOCKER"));
+ Common.Changelog changelog = result.getChangelogList().get(0);
+ assertThat(changelog.getUser()).isNotNull().isEqualTo(user.getLogin());
+ assertThat(changelog.getUserName()).isNotNull().isEqualTo(user.getName());
+ assertThat(changelog.getIsUserActive()).isTrue();
+ assertThat(changelog.getAvatar()).isNotNull().isEqualTo("93942e96f5acd83e2e047ad8fe03114d");
+ assertThat(changelog.getCreationDate()).isNotEmpty();
+ assertThat(changelog.getExternalUser()).isEqualTo(fieldDiffs.externalUser().orElse(null));
+ assertThat(changelog.getWebhookSource()).isEqualTo(fieldDiffs.webhookSource().orElse(null));
+ assertThat(changelog.getDiffsList()).extracting(Diff::getKey, Diff::getOldValue, Diff::getNewValue).containsOnly(tuple("severity", "MAJOR", "BLOCKER"));
+ }
+
+ private static FieldDiffs createFieldDiffs(UserDto user) {
+ return new FieldDiffs()
+ .setUserUuid(user.getUuid())
+ .setDiff("severity", "MAJOR", "BLOCKER")
+ .setCreationDate(new Date())
+ .setExternalUser("toto")
+ .setWebhookSource("github");
}
@Test
.addProjectPermission(USER, project, file);
db.issues().insertFieldDiffs(issueDto, new FieldDiffs()
.setUserUuid(user.getUuid())
- .setDiff("severity", "MAJOR", "BLOCKER").setCreationDate(new Date())
+ .setDiff("severity", "MAJOR", "BLOCKER")
+ .setWebhookSource("github")
+ .setExternalUser("toto")
+ .setCreationDate(new Date())
.setCreationDate(DateUtils.parseDateTime("2014-03-04T23:03:44+0100")));
String result = tester.newRequest().setParam("issue", issueDto.getKey()).execute().getInput();
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import java.util.Optional;
+import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
currentChange = new FieldDiffs();
currentChange.setUserUuid(context.userUuid());
currentChange.setCreationDate(context.date());
+ currentChange.setWebhookSource(context.getWebhookSource());
+ currentChange.setExternalUser(context.getExternalUser());
}
currentChange.setDiff(field, oldValue, newValue);
}
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.base.Strings.isNullOrEmpty;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+import static org.apache.commons.lang.StringUtils.trimToNull;
/**
* PLUGINS MUST NOT USE THIS CLASS, EXCEPT FOR UNIT TESTING.
*/
public class FieldDiffs implements Serializable {
private static final String CHAR_TO_ESCAPE = "|,{}=:";
- public static final String ASSIGNEE = "assignee";
- public static final String ENCODING_PREFIX = "{base64:";
- public static final String ENCODING_SUFFIX = "}";
+ private static final String ASSIGNEE = "assignee";
+ private static final String ENCODING_PREFIX = "{base64:";
+ private static final String ENCODING_SUFFIX = "}";
+ private static final String WEBHOOK_SOURCE = "webhookSource";
+ private static final String EXTERNAL_USER_KEY = "externalUser";
private final Map<String, Diff> diffs = new LinkedHashMap<>();
- private String issueKey;
- private String userUuid;
- private Date creationDate;
+ private String issueKey = null;
+ private String userUuid = null;
+ private Date creationDate = null;
+ private String externalUser = null;
+ private String webhookSource = null;
public Map<String, Diff> diffs() {
if (diffs.containsKey(ASSIGNEE)) {
return diffs.get(field);
}
- @CheckForNull
- public String userUuid() {
- return userUuid;
+ public Optional<String> userUuid() {
+ return Optional.ofNullable(userUuid);
}
public FieldDiffs setUserUuid(@Nullable String s) {
return this;
}
- @CheckForNull
- public String issueKey() {
- return issueKey;
+ public Optional<String> issueKey() {
+ return Optional.ofNullable(issueKey);
}
public FieldDiffs setIssueKey(@Nullable String issueKey) {
return this;
}
+ public Optional<String> externalUser() {
+ return Optional.ofNullable(externalUser);
+ }
+
+ public FieldDiffs setExternalUser(@Nullable String externalUser) {
+ this.externalUser = externalUser;
+ return this;
+ }
+
+ public Optional<String> webhookSource() {
+ return Optional.ofNullable(webhookSource);
+ }
+
+ public FieldDiffs setWebhookSource(@Nullable String webhookSource) {
+ this.webhookSource = webhookSource;
+ return this;
+ }
+
@SuppressWarnings("unchecked")
public FieldDiffs setDiff(String field, @Nullable Serializable oldValue, @Nullable Serializable newValue) {
Diff diff = diffs.get(field);
}
private String serialize(boolean shouldEncode) {
- StringBuilder sb = new StringBuilder();
- boolean notFirst = false;
- for (Map.Entry<String, Diff> entry : diffs.entrySet()) {
- if (notFirst) {
- sb.append(',');
- } else {
- notFirst = true;
- }
- sb.append(entry.getKey());
- sb.append('=');
- if (shouldEncode) {
- sb.append(entry.getValue().toEncodedString());
- } else {
- sb.append(entry.getValue().toString());
- }
+ List<String> serializedStrings = new ArrayList<>();
+ if (isNotBlank(webhookSource)) {
+ serializedStrings.add(WEBHOOK_SOURCE + "=" + webhookSource);
}
- return sb.toString();
+ if (isNotBlank(externalUser)) {
+ serializedStrings.add(EXTERNAL_USER_KEY + "=" + externalUser);
+ }
+ diffs.entrySet().stream()
+ .map(entry -> serializeKeyValuePair(shouldEncode, entry.getKey(), entry.getValue()))
+ .forEach(serializedStrings::add);
+ return StringUtils.join(serializedStrings, ",");
+ }
+
+ private static String serializeKeyValuePair(boolean shouldEncode, String key, Diff values) {
+ String serializedValues = shouldEncode ? values.toEncodedString() : values.toString();
+ return key + "=" + serializedValues;
}
public static FieldDiffs parse(@Nullable String s) {
}
String[] keyValues = field.split("=", 2);
+ String key = keyValues[0];
if (keyValues.length == 2) {
String values = keyValues[1];
- int split = values.indexOf('|');
- if (split > -1) {
- diffs.setDiff(keyValues[0], emptyToNull(values.substring(0, split)), emptyToNull(values.substring(split + 1)));
+ if (EXTERNAL_USER_KEY.equals(key)) {
+ diffs.setExternalUser(trimToNull(values));
+ } else if (WEBHOOK_SOURCE.equals(key)) {
+ diffs.setWebhookSource(trimToNull(values));
} else {
- diffs.setDiff(keyValues[0], null, emptyToNull(values));
+ addDiff(diffs, key, values);
}
} else {
- diffs.setDiff(keyValues[0], null, null);
+ diffs.setDiff(key, null, null);
}
}
return diffs;
}
+ private static void addDiff(FieldDiffs diffs, String key, String values) {
+ int split = values.indexOf('|');
+ if (split > -1) {
+ diffs.setDiff(key, emptyToNull(values.substring(0, split)), emptyToNull(values.substring(split + 1)));
+ } else {
+ diffs.setDiff(key, null, emptyToNull(values));
+ }
+ }
+
@SuppressWarnings("unchecked")
Diff decode(Diff encoded) {
return new Diff(
private final Date date;
private final boolean scan;
private final boolean refreshMeasures;
- private final boolean fromAlm;
+ private final String externalUser;
+ private final String webhookSource;
- private IssueChangeContext(@Nullable String userUuid, Date date, boolean scan, boolean refreshMeasures, boolean fromAlm) {
+ private IssueChangeContext(Date date, boolean scan, boolean refreshMeasures, @Nullable String userUuid, @Nullable String externalUser,
+ @Nullable String webhookSource) {
this.userUuid = userUuid;
this.date = requireNonNull(date);
this.scan = scan;
this.refreshMeasures = refreshMeasures;
- this.fromAlm = fromAlm;
+ this.externalUser = externalUser;
+ this.webhookSource = webhookSource;
}
@CheckForNull
return refreshMeasures;
}
- public boolean fromAlm() {
- return fromAlm;
+ @Nullable
+ public String getExternalUser() {
+ return externalUser;
+ }
+
+ @Nullable
+ public String getWebhookSource() {
+ return webhookSource;
}
@Override
return false;
}
IssueChangeContext that = (IssueChangeContext) o;
- return scan == that.scan &&
- Objects.equals(userUuid, that.userUuid) &&
- Objects.equals(date, that.date) &&
- refreshMeasures == that.refreshMeasures;
+ return scan == that.scan && refreshMeasures == that.refreshMeasures && Objects.equals(userUuid, that.userUuid) && date.equals(that.date)
+ && Objects.equals(externalUser, that.getExternalUser()) && Objects.equals(webhookSource, that.getWebhookSource());
}
@Override
public int hashCode() {
- return Objects.hash(userUuid, date, scan, refreshMeasures, fromAlm);
- }
-
- @Override
- public String toString() {
- return "IssueChangeContext{" +
- "userUuid='" + userUuid + '\'' +
- ", date=" + date +
- ", scan=" + scan +
- ", refreshMeasures=" + refreshMeasures +
- ", fromAlm=" + fromAlm +
- '}';
+ return Objects.hash(userUuid, date, scan, refreshMeasures, externalUser, webhookSource);
}
public static IssueChangeContextBuilder newBuilder() {
private Date date;
private boolean scan = false;
private boolean refreshMeasures = false;
- private boolean fromAlm = false;
+ private String externalUser;
+ private String webhookSource;
private IssueChangeContextBuilder() {
}
return this;
}
- public IssueChangeContextBuilder withFromAlm() {
- this.fromAlm = true;
+ public IssueChangeContextBuilder setExternalUser(@Nullable String externalUser) {
+ this.externalUser = externalUser;
+ return this;
+ }
+
+ public IssueChangeContextBuilder setWebhookSource(@Nullable String webhookSource) {
+ this.webhookSource = webhookSource;
return this;
}
public IssueChangeContext build() {
- return new IssueChangeContext(userUuid, date, scan, refreshMeasures, fromAlm);
+ return new IssueChangeContext(date, scan, refreshMeasures, userUuid, externalUser, webhookSource);
}
}
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class DefaultIssueTest {
@Test
public void all_changes_contain_current_change() {
IssueChangeContext issueChangeContext = mock(IssueChangeContext.class);
- DefaultIssue issue = new DefaultIssue().setKey("AAA").setFieldChange(issueChangeContext, "actionPlan", "1.0", "1.1");
+ when(issueChangeContext.getExternalUser()).thenReturn("toto");
+ when(issueChangeContext.getWebhookSource()).thenReturn("github");
+
+ DefaultIssue issue = new DefaultIssue()
+ .setKey("AAA")
+ .setFieldChange(issueChangeContext, "actionPlan", "1.0", "1.1");
assertThat(issue.changes()).hasSize(1);
+ FieldDiffs actualDiffs = issue.changes().iterator().next();
+ assertThat(actualDiffs.externalUser()).contains(issueChangeContext.getExternalUser());
+ assertThat(actualDiffs.webhookSource()).contains(issueChangeContext.getWebhookSource());
}
@Test
@Test
public void test_toString() {
+ diffs.setWebhookSource("github");
+ diffs.setExternalUser("toto");
diffs.setDiff("severity", "BLOCKER", "INFO");
diffs.setDiff("resolution", "OPEN", "FIXED");
- assertThat(diffs.toString()).isEqualTo("severity=BLOCKER|INFO,resolution=OPEN|FIXED");
+ assertThat(diffs).hasToString("webhookSource=github,externalUser=toto,severity=BLOCKER|INFO,resolution=OPEN|FIXED");
}
@Test
diffs.setDiff("severity", null, "INFO");
diffs.setDiff("assignee", "user1", null);
- assertThat(diffs.toString()).isEqualTo("severity=INFO,assignee=user1|");
+ assertThat(diffs).hasToString("severity=INFO,assignee=user1|");
}
@Test
public void test_parse() {
- diffs = FieldDiffs.parse("severity=BLOCKER|INFO,resolution=OPEN|FIXED,donut=|new,gambas=miam,acme=old|");
+ diffs = FieldDiffs.parse("severity=BLOCKER|INFO,webhookSource=github,resolution=OPEN|FIXED,donut=|new,gambas=miam,acme=old|,externalUser=charlie");
assertThat(diffs.diffs()).hasSize(5);
+ assertThat(diffs.webhookSource()).contains("github");
+ assertThat(diffs.externalUser()).contains("charlie");
+
FieldDiffs.Diff diff = diffs.diffs().get("severity");
assertThat(diff.oldValue()).isEqualTo("BLOCKER");
assertThat(diff.newValue()).isEqualTo("INFO");
@Test
public void test_parse_empty_values() {
- diffs = FieldDiffs.parse("severity=INFO,resolution=");
+ diffs = FieldDiffs.parse("severity=INFO,resolution=,webhookSource=,externalUser=");
+
+ assertThat(diffs.externalUser()).isEmpty();
+ assertThat(diffs.webhookSource()).isEmpty();
assertThat(diffs.diffs()).hasSize(2);
FieldDiffs.Diff diff = diffs.diffs().get("severity");
private static final Date NOW = new Date();
private static final String USER_UUID = "user_uuid";
+ private static final String EXTERNAL_USER = "toto@tata.com";
+ private static final String WEBHOOK_SOURCE = "github";
private IssueChangeContext context;
public void test_issueChangeContextByScanBuilder() {
context = issueChangeContextByScanBuilder(NOW).build();
- verifyContext(null, true, false, false);
+ verifyContext(true, false, null, null, null);
}
@Test
public void test_issueChangeContextByUserBuilder() {
context = issueChangeContextByUserBuilder(NOW, USER_UUID).build();
- verifyContext(USER_UUID, false, false, false);
+ verifyContext(false, false, USER_UUID, null, null);
}
@Test
.withRefreshMeasures()
.setUserUuid(USER_UUID)
.setDate(NOW)
- .withFromAlm()
+ .setExternalUser(EXTERNAL_USER)
+ .setWebhookSource(WEBHOOK_SOURCE)
.build();
- verifyContext(USER_UUID, true, true, true);
+ verifyContext(true, true, USER_UUID, EXTERNAL_USER, WEBHOOK_SOURCE);
}
@Test
public void test_equal() {
- context = IssueChangeContext.newBuilder().setUserUuid(USER_UUID).setDate(NOW).build();
- IssueChangeContext equalContext = IssueChangeContext.newBuilder().setUserUuid(USER_UUID).setDate(NOW).build();
+ context = IssueChangeContext.newBuilder()
+ .setUserUuid(USER_UUID)
+ .setDate(NOW)
+ .setExternalUser(EXTERNAL_USER)
+ .setWebhookSource(WEBHOOK_SOURCE)
+ .build();
+ IssueChangeContext equalContext = IssueChangeContext.newBuilder()
+ .setUserUuid(USER_UUID)
+ .setDate(NOW)
+ .setExternalUser(EXTERNAL_USER)
+ .setWebhookSource(WEBHOOK_SOURCE)
+ .build();
IssueChangeContext notEqualContext = IssueChangeContext.newBuilder().setUserUuid("other_user_uuid").setDate(NOW).build();
assertThat(context).isEqualTo(context)
public void test_hashCode() {
context = IssueChangeContext.newBuilder().setUserUuid(USER_UUID).setDate(NOW).build();
- assertThat(context.hashCode()).isEqualTo(Objects.hash(USER_UUID, NOW, false, false, false));
+ assertThat(context.hashCode()).isEqualTo(Objects.hash(USER_UUID, NOW, false, false, null, null));
}
- @Test
- public void test_toString() {
- context = IssueChangeContext.newBuilder().setUserUuid(USER_UUID).setDate(NOW).build();
- String expected = "IssueChangeContext{userUuid='user_uuid', date=" + NOW + ", scan=false, refreshMeasures=false, fromAlm=false}";
-
- assertThat(context).hasToString(expected);
- }
-
- private void verifyContext(@Nullable String userUuid, boolean scan, boolean refreshMeasures, boolean fromAlm) {
+ private void verifyContext(boolean scan, boolean refreshMeasures, @Nullable String userUuid, @Nullable String externalUser,
+ @Nullable String webhookSource) {
assertThat(context.userUuid()).isEqualTo(userUuid);
assertThat(context.date()).isEqualTo(NOW);
assertThat(context.scan()).isEqualTo(scan);
assertThat(context.refreshMeasures()).isEqualTo(refreshMeasures);
- assertThat(context.fromAlm()).isEqualTo(fromAlm);
+ assertThat(context.getExternalUser()).isEqualTo(externalUser);
+ assertThat(context.getWebhookSource()).isEqualTo(webhookSource);
}
-
}
repeated Diff diffs = 5;
optional string avatar = 6;
optional bool isUserActive = 7;
+ optional string externalUser = 8;
+ optional string webhookSource = 9;
message Diff {
optional string key = 1;