| // Copyright (C) 2020 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.plugins.codeowners.backend.config; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.gerrit.server.project.ProjectCache.illegalState; |
| import static com.google.gerrit.testing.GerritJUnit.assertThrows; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.gerrit.entities.Change; |
| import com.google.gerrit.entities.LabelType; |
| import com.google.gerrit.entities.LabelValue; |
| import com.google.gerrit.entities.PatchSet; |
| import com.google.gerrit.entities.PatchSetApproval; |
| import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest; |
| import com.google.gerrit.server.project.ProjectState; |
| import com.google.gerrit.server.util.time.TimeUtil; |
| import java.util.Arrays; |
| import org.junit.Test; |
| |
| /** Tests for {@link com.google.gerrit.plugins.codeowners.backend.config.RequiredApproval}. */ |
| public class RequiredApprovalTest extends AbstractCodeOwnersTest { |
| @Test |
| public void cannotCheckIsCodeOwnerApprovalForNullPatchSetApproval() throws Exception { |
| LabelType labelType = createLabelType("Foo", -2, -1, 0, 1, 2); |
| RequiredApproval requiredApproval = RequiredApproval.create(labelType, (short) 1); |
| NullPointerException npe = |
| assertThrows(NullPointerException.class, () -> requiredApproval.isApprovedBy(null)); |
| assertThat(npe).hasMessageThat().isEqualTo("patchSetApproval"); |
| } |
| |
| @Test |
| public void isCodeOwnerApproval() throws Exception { |
| LabelType labelType = createLabelType("Foo", -2, -1, 0, 1, 2); |
| RequiredApproval requiredApproval = RequiredApproval.create(labelType, (short) 1); |
| assertThat(requiredApproval.isApprovedBy(createApproval(labelType, -2))).isFalse(); |
| assertThat(requiredApproval.isApprovedBy(createApproval(labelType, -1))).isFalse(); |
| assertThat(requiredApproval.isApprovedBy(createApproval(labelType, 0))).isFalse(); |
| assertThat(requiredApproval.isApprovedBy(createApproval(labelType, 1))).isTrue(); |
| assertThat(requiredApproval.isApprovedBy(createApproval(labelType, 2))).isTrue(); |
| } |
| |
| @Test |
| public void cannotParseNullAsRequiredApproval() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| NullPointerException npe = |
| assertThrows(NullPointerException.class, () -> RequiredApproval.parse(projectState, null)); |
| assertThat(npe).hasMessageThat().isEqualTo("requiredApprovalString"); |
| } |
| |
| @Test |
| public void parseRequiresProjectState() throws Exception { |
| NullPointerException npe = |
| assertThrows( |
| NullPointerException.class, () -> RequiredApproval.parse(null, "Code-Review+1")); |
| assertThat(npe).hasMessageThat().isEqualTo("projectState"); |
| } |
| |
| @Test |
| public void parse() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| RequiredApproval requiredApproval = RequiredApproval.parse(projectState, "Code-Review+1"); |
| assertThat(requiredApproval.labelType().getName()).isEqualTo("Code-Review"); |
| assertThat(requiredApproval.value()).isEqualTo(1); |
| } |
| |
| @Test |
| public void cannotParseInvalidString() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| IllegalArgumentException exception = |
| assertThrows( |
| IllegalArgumentException.class, () -> RequiredApproval.parse(projectState, "invalid")); |
| assertThat(exception) |
| .hasMessageThat() |
| .isEqualTo("Invalid format, expected '<label-name>+<label-value>'."); |
| } |
| |
| @Test |
| public void cannotParseStringWithInvalidValue() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| String invalidVotingValue = "not-a-number"; |
| IllegalArgumentException exception = |
| assertThrows( |
| IllegalArgumentException.class, |
| () -> RequiredApproval.parse(projectState, "Code-Review+" + invalidVotingValue)); |
| assertThat(exception) |
| .hasMessageThat() |
| .isEqualTo(String.format("Invalid voting value: %s", invalidVotingValue)); |
| } |
| |
| @Test |
| public void cannotParseStringWithNegativeValue() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| IllegalArgumentException exception = |
| assertThrows( |
| IllegalArgumentException.class, |
| () -> RequiredApproval.parse(projectState, "Code-Review+-1")); |
| assertThat(exception) |
| .hasMessageThat() |
| .isEqualTo(String.format("Voting value must be positive: -1")); |
| } |
| |
| @Test |
| public void parseRequiresThatLabelExists() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| String nonExistingLabel = "Non-Existing"; |
| IllegalStateException exception = |
| assertThrows( |
| IllegalStateException.class, |
| () -> RequiredApproval.parse(projectState, nonExistingLabel + "+1")); |
| assertThat(exception) |
| .hasMessageThat() |
| .isEqualTo( |
| String.format( |
| "Label %s doesn't exist for project %s.", nonExistingLabel, project.get())); |
| } |
| |
| @Test |
| public void parseRequiresThatLabelValueExists() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| IllegalStateException exception = |
| assertThrows( |
| IllegalStateException.class, |
| () -> RequiredApproval.parse(projectState, "Code-Review+3")); |
| assertThat(exception) |
| .hasMessageThat() |
| .isEqualTo( |
| String.format("Label Code-Review on project %s doesn't allow value 3.", project.get())); |
| } |
| |
| @Test |
| public void createDefaultRequiresProjectState() throws Exception { |
| NullPointerException npe = |
| assertThrows( |
| NullPointerException.class, |
| () -> RequiredApproval.createDefault(null, "Code-Owners", (short) 1)); |
| assertThat(npe).hasMessageThat().isEqualTo("projectState"); |
| } |
| |
| @Test |
| public void createDefaultRequiresDefaultLabel() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| NullPointerException npe = |
| assertThrows( |
| NullPointerException.class, |
| () -> RequiredApproval.createDefault(projectState, null, (short) 1)); |
| assertThat(npe).hasMessageThat().isEqualTo("defaultLabel"); |
| } |
| |
| @Test |
| public void createDefault() throws Exception { |
| String labelName = "Code-Review"; |
| short labelValue = 2; |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| RequiredApproval requiredApproval = |
| RequiredApproval.createDefault(projectState, labelName, labelValue); |
| assertThat(requiredApproval.labelType().getName()).isEqualTo(labelName); |
| assertThat(requiredApproval.value()).isEqualTo(labelValue); |
| } |
| |
| @Test |
| public void createDefaultRequiresThatLabelExists() throws Exception { |
| String nonExistingLabel = "Non-Existing"; |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| IllegalStateException exception = |
| assertThrows( |
| IllegalStateException.class, |
| () -> RequiredApproval.createDefault(projectState, nonExistingLabel, (short) 1)); |
| assertThat(exception) |
| .hasMessageThat() |
| .isEqualTo( |
| String.format( |
| "Default label %s doesn't exist for project %s.", nonExistingLabel, project.get())); |
| } |
| |
| @Test |
| public void createDefaultRequiresThatLabelValueExists() throws Exception { |
| ProjectState projectState = projectCache.get(project).orElseThrow(illegalState(project)); |
| IllegalStateException exception = |
| assertThrows( |
| IllegalStateException.class, |
| () -> RequiredApproval.createDefault(projectState, "Code-Review", (short) 3)); |
| assertThat(exception) |
| .hasMessageThat() |
| .isEqualTo( |
| String.format( |
| "Label Code-Review on project %s doesn't allow default value 3.", project.get())); |
| } |
| |
| private static LabelType createLabelType(String labelName, int firstValue, int... furtherValues) { |
| ImmutableList.Builder<LabelValue> labelValues = ImmutableList.builder(); |
| labelValues.add(LabelValue.create((short) firstValue, "Value " + firstValue)); |
| Arrays.stream(furtherValues) |
| .forEach(value -> labelValues.add(LabelValue.create((short) value, "Value " + value))); |
| return LabelType.builder(labelName, labelValues.build()).build(); |
| } |
| |
| private PatchSetApproval createApproval(LabelType labelType, int value) { |
| return PatchSetApproval.builder() |
| .key(PatchSetApproval.key(PatchSet.id(Change.id(1), 1), admin.id(), labelType.getLabelId())) |
| .value(value) |
| .granted(TimeUtil.now()) |
| .build(); |
| } |
| } |