blob: 7123d423ac8df9f3eddfc3c1333d9fd54b7f8e20 [file] [log] [blame]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gerrit.entities.converter;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static com.google.gerrit.proto.testing.SerializedClassSubject.assertThatSerializedClass;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.api.accounts.AccountInput;
import com.google.gerrit.extensions.api.changes.ApplyPatchInput;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.NotifyInfo;
import com.google.gerrit.extensions.api.changes.RecipientType;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.extensions.common.MergeInput;
import com.google.gerrit.proto.Entities;
import com.google.inject.TypeLiteral;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.junit.Test;
public class ChangeInputProtoConverterTest {
private final ChangeInputProtoConverter changeInputProtoConverter =
ChangeInputProtoConverter.INSTANCE;
private final MergeInputProtoConverter mergeInputProtoConverter =
MergeInputProtoConverter.INSTANCE;
private final AccountInputProtoConverter accountInputProtoConverter =
AccountInputProtoConverter.INSTANCE;
// Helper method that creates a MergeInput with all possible value.
private MergeInput createMergeInput() {
MergeInput mergeInput = new MergeInput();
mergeInput.source = "test-source";
mergeInput.sourceBranch = "test-source-branch";
mergeInput.strategy = "test-strategy";
mergeInput.allowConflicts = true;
return mergeInput;
}
// Helper method that creates a AccountInput with all possible value.
private AccountInput createAccountInput() {
AccountInput accountInput = new AccountInput();
accountInput.username = "test-username";
accountInput.displayName = "test-displayName";
accountInput.name = "test-name";
accountInput.email = "test-email";
accountInput.sshKey = "test-ssh-key";
accountInput.httpPassword = "test-http-password";
accountInput.groups = ImmutableList.of("test-group");
return accountInput;
}
// Helper method that creates a ChangeInput with all possible value.
private ChangeInput createChangeInput() {
ChangeInput changeInput = new ChangeInput("test-project", "test-branch", "test-subject");
changeInput.topic = "test-topic";
changeInput.status = ChangeStatus.NEW;
changeInput.isPrivate = true;
changeInput.workInProgress = true;
changeInput.baseChange = "test-base-change";
changeInput.baseCommit = "test-base-commit";
changeInput.newBranch = true;
Map<String, String> validationOptions = new HashMap<>();
validationOptions.put("test-key", "test-value");
changeInput.validationOptions = validationOptions;
Map<String, String> customKeyedValues = new HashMap<>();
customKeyedValues.put("test-key", "test-value");
changeInput.customKeyedValues = customKeyedValues;
changeInput.merge = createMergeInput();
ApplyPatchInput applyPatchInput = new ApplyPatchInput();
applyPatchInput.patch = "test-patch";
changeInput.patch = applyPatchInput;
changeInput.author = createAccountInput();
changeInput.responseFormatOptions = new ArrayList<ListChangesOption>();
changeInput.responseFormatOptions.addAll(
ImmutableList.of(ListChangesOption.LABELS, ListChangesOption.DETAILED_LABELS));
changeInput.notify = NotifyHandling.OWNER;
Map<RecipientType, NotifyInfo> notifyDetails = new HashMap<>();
NotifyInfo notifyInfo = new NotifyInfo(ImmutableList.of("account1", "account2"));
notifyDetails.put(RecipientType.TO, notifyInfo);
changeInput.notifyDetails = notifyDetails;
return changeInput;
}
private void assertAccountInputEquals(AccountInput expected, AccountInput actual) {
assertThat(
(expected == null && actual == null)
|| (Objects.equals(expected.username, actual.username)
&& Objects.equals(expected.name, actual.name)
&& Objects.equals(expected.displayName, actual.displayName)
&& Objects.equals(expected.email, actual.email)
&& Objects.equals(expected.sshKey, actual.sshKey)
&& Objects.equals(expected.httpPassword, actual.httpPassword)
&& Objects.equals(expected.groups, actual.groups)))
.isTrue();
}
private void assertMergeInputEquals(MergeInput expected, MergeInput actual) {
assertThat(
(expected == null && actual == null)
|| (Objects.equals(expected.source, actual.source)
&& Objects.equals(expected.sourceBranch, actual.sourceBranch)
&& Objects.equals(expected.strategy, actual.strategy)
&& expected.allowConflicts == actual.allowConflicts))
.isTrue();
}
private void assertChangeInputEquals(ChangeInput expected, ChangeInput actual) {
assertThat(
Objects.equals(expected.project, actual.project)
&& Objects.equals(expected.branch, actual.branch)
&& Objects.equals(expected.subject, actual.subject)
&& Objects.equals(expected.topic, actual.topic)
&& Objects.equals(expected.status, actual.status)
&& Objects.equals(expected.isPrivate, actual.isPrivate)
&& Objects.equals(expected.workInProgress, actual.workInProgress)
&& Objects.equals(expected.baseChange, actual.baseChange)
&& Objects.equals(expected.baseCommit, actual.baseCommit)
&& Objects.equals(expected.newBranch, actual.newBranch)
&& Objects.equals(expected.validationOptions, actual.validationOptions)
&& Objects.equals(expected.customKeyedValues, actual.customKeyedValues)
&& Objects.equals(expected.responseFormatOptions, actual.responseFormatOptions)
&& Objects.equals(expected.notify, actual.notify)
&& Objects.equals(expected.notifyDetails, actual.notifyDetails))
.isTrue();
assertThat(
(expected.patch == null && actual.patch == null)
|| Objects.equals(expected.patch.patch, actual.patch.patch))
.isTrue();
assertAccountInputEquals(expected.author, actual.author);
assertMergeInputEquals(expected.merge, actual.merge);
}
@Test
public void mandatoryValuesConvertedToProto() {
ChangeInput changeInput = new ChangeInput("test-project", "test-branch", "test-subject");
Entities.ChangeInput proto = changeInputProtoConverter.toProto(changeInput);
Entities.ChangeInput expectedProto =
Entities.ChangeInput.newBuilder()
.setProject("test-project")
.setBranch("test-branch")
.setSubject("test-subject")
.setNotify(Entities.NotifyHandling.ALL)
.build();
assertThat(proto).isEqualTo(expectedProto);
}
@Test
public void allValuesConvertedToProto() {
Entities.ChangeInput proto = changeInputProtoConverter.toProto(createChangeInput());
Entities.ChangeInput.Builder expectedProto =
Entities.ChangeInput.newBuilder()
.setProject("test-project")
.setBranch("test-branch")
.setSubject("test-subject")
.setTopic("test-topic")
.setStatus(Entities.ChangeStatus.NEW)
.setBaseChange("test-base-change")
.setBaseCommit("test-base-commit")
.setNewBranch(true)
.setIsPrivate(true)
.setWorkInProgress(true)
.setPatch(Entities.ApplyPatchInput.newBuilder().setPatch("test-patch").build());
Map<String, String> validationOptions = new HashMap<>();
validationOptions.put("test-key", "test-value");
expectedProto.putAllValidationOptions(validationOptions);
Map<String, String> customKeyedValues = new HashMap<>();
customKeyedValues.put("test-key", "test-value");
expectedProto.putAllCustomKeyedValues(customKeyedValues);
expectedProto.setMerge(mergeInputProtoConverter.toProto(createMergeInput()));
expectedProto.setAuthor(accountInputProtoConverter.toProto(createAccountInput()));
expectedProto.addAllResponseFormatOptions(
ImmutableList.of(
Entities.ListChangesOption.LABELS, Entities.ListChangesOption.DETAILED_LABELS));
expectedProto.setNotify(Entities.NotifyHandling.OWNER);
Map<String, Entities.NotifyInfo> notifyDetailsProto = new HashMap<>();
Entities.NotifyInfo.Builder notifyInfoBuilder =
Entities.NotifyInfo.newBuilder().addAllAccounts(ImmutableList.of("account1", "account2"));
notifyDetailsProto.put(RecipientType.TO.name(), notifyInfoBuilder.build());
expectedProto.putAllNotifyDetails(notifyDetailsProto);
assertThat(proto).isEqualTo(expectedProto.build());
}
@Test
public void mandatoryValuesConvertedToProtoAndBackAgain() {
ChangeInput changeInput = new ChangeInput("test-project", "test-branch", "test-subject");
ChangeInput convertedChangeInput =
changeInputProtoConverter.fromProto(changeInputProtoConverter.toProto(changeInput));
assertChangeInputEquals(changeInput, convertedChangeInput);
}
@Test
public void allValuesConvertedToProtoAndBackAgain() {
ChangeInput changeInput = createChangeInput();
ChangeInput convertedChangeInput =
changeInputProtoConverter.fromProto(changeInputProtoConverter.toProto(changeInput));
assertChangeInputEquals(changeInput, convertedChangeInput);
}
/** See {@link SerializedClassSubject} for background and what to do if this test fails. */
@Test
public void methodsExistAsExpected() {
assertThatSerializedClass(ChangeInput.class)
.hasFields(
ImmutableMap.<String, Type>builder()
.put("project", String.class)
.put("branch", String.class)
.put("subject", String.class)
.put("topic", String.class)
.put("status", ChangeStatus.class)
.put("isPrivate", Boolean.class)
.put("workInProgress", Boolean.class)
.put("baseChange", String.class)
.put("baseCommit", String.class)
.put("newBranch", Boolean.class)
.put("validationOptions", new TypeLiteral<Map<String, String>>() {}.getType())
.put("customKeyedValues", new TypeLiteral<Map<String, String>>() {}.getType())
.put("merge", MergeInput.class)
.put("patch", ApplyPatchInput.class)
.put("author", AccountInput.class)
.put(
"responseFormatOptions",
new TypeLiteral<List<ListChangesOption>>() {}.getType())
.put("notify", NotifyHandling.class)
.put(
"notifyDetails", new TypeLiteral<Map<RecipientType, NotifyInfo>>() {}.getType())
.build());
}
}