| /* |
| * 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()); |
| } |
| } |