| // 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.restapi; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.gerrit.plugins.codeowners.testing.CodeOwnerStatusInfoSubject.assertThat; |
| import static com.google.gerrit.plugins.codeowners.testing.FileCodeOwnerStatusInfoSubject.assertThat; |
| import static com.google.gerrit.plugins.codeowners.testing.PathCodeOwnerStatusInfoSubject.assertThat; |
| import static com.google.gerrit.testing.GerritJUnit.assertThrows; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.when; |
| |
| import com.google.common.collect.ImmutableSet; |
| import com.google.gerrit.entities.Change; |
| import com.google.gerrit.entities.PatchSet; |
| import com.google.gerrit.extensions.common.ChangeType; |
| import com.google.gerrit.plugins.codeowners.acceptance.AbstractCodeOwnersTest; |
| import com.google.gerrit.plugins.codeowners.api.CodeOwnerStatusInfo; |
| import com.google.gerrit.plugins.codeowners.api.FileCodeOwnerStatusInfo; |
| import com.google.gerrit.plugins.codeowners.api.PathCodeOwnerStatusInfo; |
| import com.google.gerrit.plugins.codeowners.backend.FileCodeOwnerStatus; |
| import com.google.gerrit.plugins.codeowners.backend.PathCodeOwnerStatus; |
| import com.google.gerrit.plugins.codeowners.common.ChangedFile; |
| import com.google.gerrit.plugins.codeowners.common.CodeOwnerStatus; |
| import com.google.gerrit.plugins.codeowners.testing.FileCodeOwnerStatusInfoSubject; |
| import com.google.gerrit.truth.ListSubject; |
| import java.nio.file.Paths; |
| import java.util.Optional; |
| import org.eclipse.jgit.diff.DiffEntry; |
| import org.junit.Test; |
| |
| /** Tests for {@link CodeOwnerStatusInfoJson}. */ |
| public class CodeOwnerStatusInfoJsonTest extends AbstractCodeOwnersTest { |
| @Test |
| public void cannotFormatNullPathCodeOwnerStatus() throws Exception { |
| NullPointerException npe = |
| assertThrows( |
| NullPointerException.class, |
| () -> |
| CodeOwnerStatusInfoJson.format( |
| /* pathCodeOwnerStatus= */ (PathCodeOwnerStatus) null)); |
| assertThat(npe).hasMessageThat().isEqualTo("pathCodeOwnerStatus"); |
| } |
| |
| @Test |
| public void formatPathCodeOwnerStatus() throws Exception { |
| PathCodeOwnerStatus pathCodeOwnerStatus = |
| PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED); |
| PathCodeOwnerStatusInfo pathCodeOwnerStatusInfo = |
| CodeOwnerStatusInfoJson.format(pathCodeOwnerStatus); |
| assertThat(pathCodeOwnerStatusInfo).hasPathThat().isEqualTo("foo/bar.baz"); |
| assertThat(pathCodeOwnerStatusInfo).hasStatusThat().isEqualTo(CodeOwnerStatus.APPROVED); |
| } |
| |
| @Test |
| public void cannotFormatNullFileCodeOwnerStatus() throws Exception { |
| NullPointerException npe = |
| assertThrows( |
| NullPointerException.class, |
| () -> |
| CodeOwnerStatusInfoJson.format( |
| /* fileCodeOwnerStatus= */ (FileCodeOwnerStatus) null)); |
| assertThat(npe).hasMessageThat().isEqualTo("fileCodeOwnerStatus"); |
| } |
| |
| @Test |
| public void formatFileCodeOwnerStatusForNewFile() throws Exception { |
| ChangedFile changedFile = mock(ChangedFile.class); |
| when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.ADD); |
| PathCodeOwnerStatus pathCodeOwnerStatus = |
| PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus = |
| FileCodeOwnerStatus.create(changedFile, Optional.of(pathCodeOwnerStatus), Optional.empty()); |
| FileCodeOwnerStatusInfo fileCodeOwnerStatusInfo = |
| CodeOwnerStatusInfoJson.format(fileCodeOwnerStatus); |
| assertThat(fileCodeOwnerStatusInfo).hasChangeTypeThat().isEqualTo(ChangeType.ADDED); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasNewPathStatusThat() |
| .value() |
| .hasPathThat() |
| .isEqualTo("foo/bar.baz"); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasNewPathStatusThat() |
| .value() |
| .hasStatusThat() |
| .isEqualTo(CodeOwnerStatus.APPROVED); |
| assertThat(fileCodeOwnerStatusInfo).hasOldPathStatusThat().isEmpty(); |
| } |
| |
| @Test |
| public void formatFileCodeOwnerStatusForModifiedFile() throws Exception { |
| ChangedFile changedFile = mock(ChangedFile.class); |
| when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.MODIFY); |
| PathCodeOwnerStatus pathCodeOwnerStatus = |
| PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus = |
| FileCodeOwnerStatus.create(changedFile, Optional.of(pathCodeOwnerStatus), Optional.empty()); |
| FileCodeOwnerStatusInfo fileCodeOwnerStatusInfo = |
| CodeOwnerStatusInfoJson.format(fileCodeOwnerStatus); |
| assertThat(fileCodeOwnerStatusInfo).hasChangeTypeThat().isNull(); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasNewPathStatusThat() |
| .value() |
| .hasPathThat() |
| .isEqualTo("foo/bar.baz"); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasNewPathStatusThat() |
| .value() |
| .hasStatusThat() |
| .isEqualTo(CodeOwnerStatus.APPROVED); |
| assertThat(fileCodeOwnerStatusInfo).hasOldPathStatusThat().isEmpty(); |
| } |
| |
| @Test |
| public void formatFileCodeOwnerStatusForDeletedFile() throws Exception { |
| ChangedFile changedFile = mock(ChangedFile.class); |
| when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.DELETE); |
| PathCodeOwnerStatus pathCodeOwnerStatus = |
| PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus = |
| FileCodeOwnerStatus.create(changedFile, Optional.empty(), Optional.of(pathCodeOwnerStatus)); |
| FileCodeOwnerStatusInfo fileCodeOwnerStatusInfo = |
| CodeOwnerStatusInfoJson.format(fileCodeOwnerStatus); |
| assertThat(fileCodeOwnerStatusInfo).hasChangeTypeThat().isEqualTo(ChangeType.DELETED); |
| assertThat(fileCodeOwnerStatusInfo).hasNewPathStatusThat().isEmpty(); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasOldPathStatusThat() |
| .value() |
| .hasPathThat() |
| .isEqualTo("foo/bar.baz"); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasOldPathStatusThat() |
| .value() |
| .hasStatusThat() |
| .isEqualTo(CodeOwnerStatus.APPROVED); |
| } |
| |
| @Test |
| public void formatFileCodeOwnerStatusForRenamedFile() throws Exception { |
| ChangedFile changedFile = mock(ChangedFile.class); |
| when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.RENAME); |
| PathCodeOwnerStatus newPathCodeOwnerStatus = |
| PathCodeOwnerStatus.create(Paths.get("/foo/new.baz"), CodeOwnerStatus.PENDING); |
| PathCodeOwnerStatus oldPathCodeOwnerStatus = |
| PathCodeOwnerStatus.create(Paths.get("/foo/old.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus = |
| FileCodeOwnerStatus.create( |
| changedFile, Optional.of(newPathCodeOwnerStatus), Optional.of(oldPathCodeOwnerStatus)); |
| FileCodeOwnerStatusInfo fileCodeOwnerStatusInfo = |
| CodeOwnerStatusInfoJson.format(fileCodeOwnerStatus); |
| assertThat(fileCodeOwnerStatusInfo).hasChangeTypeThat().isEqualTo(ChangeType.RENAMED); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasNewPathStatusThat() |
| .value() |
| .hasPathThat() |
| .isEqualTo("foo/new.baz"); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasNewPathStatusThat() |
| .value() |
| .hasStatusThat() |
| .isEqualTo(CodeOwnerStatus.PENDING); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasOldPathStatusThat() |
| .value() |
| .hasPathThat() |
| .isEqualTo("foo/old.baz"); |
| assertThat(fileCodeOwnerStatusInfo) |
| .hasOldPathStatusThat() |
| .value() |
| .hasStatusThat() |
| .isEqualTo(CodeOwnerStatus.APPROVED); |
| } |
| |
| @Test |
| public void cannotFormatCodeOwnerStatusInfoForNullFileCodeOwnerStatuses() throws Exception { |
| NullPointerException npe = |
| assertThrows( |
| NullPointerException.class, |
| () -> |
| CodeOwnerStatusInfoJson.format( |
| PatchSet.id(Change.id(1), 1), /* fileCodeOwnerStatuses= */ null)); |
| assertThat(npe).hasMessageThat().isEqualTo("fileCodeOwnerStatuses"); |
| } |
| |
| @Test |
| public void cannotCodeOwnerStatusInfoForNullPathSetId() throws Exception { |
| NullPointerException npe = |
| assertThrows( |
| NullPointerException.class, |
| () -> CodeOwnerStatusInfoJson.format(/* patchSetId= */ null, ImmutableSet.of())); |
| assertThat(npe).hasMessageThat().isEqualTo("patchSetId"); |
| } |
| |
| @Test |
| public void formatCodeOwnerStatusInfo() throws Exception { |
| ChangedFile changedFile = mock(ChangedFile.class); |
| when(changedFile.changeType()).thenReturn(DiffEntry.ChangeType.ADD); |
| PathCodeOwnerStatus pathCodeOwnerStatus = |
| PathCodeOwnerStatus.create(Paths.get("/foo/bar.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus = |
| FileCodeOwnerStatus.create(changedFile, Optional.of(pathCodeOwnerStatus), Optional.empty()); |
| CodeOwnerStatusInfo codeOwnerStatusInfo = |
| CodeOwnerStatusInfoJson.format( |
| PatchSet.id(Change.id(1), 1), ImmutableSet.of(fileCodeOwnerStatus)); |
| assertThat(codeOwnerStatusInfo).hasPatchSetNumberThat().isEqualTo(1); |
| FileCodeOwnerStatusInfoSubject fileCodeOwnerStatusInfoSubject = |
| assertThat(codeOwnerStatusInfo).hasFileCodeOwnerStatusesThat().onlyElement(); |
| fileCodeOwnerStatusInfoSubject.hasChangeTypeThat().isEqualTo(ChangeType.ADDED); |
| fileCodeOwnerStatusInfoSubject |
| .hasNewPathStatusThat() |
| .value() |
| .hasPathThat() |
| .isEqualTo("foo/bar.baz"); |
| fileCodeOwnerStatusInfoSubject |
| .hasNewPathStatusThat() |
| .value() |
| .hasStatusThat() |
| .isEqualTo(CodeOwnerStatus.APPROVED); |
| fileCodeOwnerStatusInfoSubject.hasOldPathStatusThat().isEmpty(); |
| } |
| |
| @Test |
| public void fileCodeOwnerStatusInfosInCodeOwnerStatusInfoAreSortedByPath() throws Exception { |
| ChangedFile changedFile1 = mock(ChangedFile.class); |
| when(changedFile1.changeType()).thenReturn(DiffEntry.ChangeType.ADD); |
| PathCodeOwnerStatus pathCodeOwnerStatus1 = |
| PathCodeOwnerStatus.create(Paths.get("/foo/a/bar.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus1 = |
| FileCodeOwnerStatus.create( |
| changedFile1, Optional.of(pathCodeOwnerStatus1), Optional.empty()); |
| |
| ChangedFile changedFile2 = mock(ChangedFile.class); |
| when(changedFile2.changeType()).thenReturn(DiffEntry.ChangeType.DELETE); |
| PathCodeOwnerStatus pathCodeOwnerStatus2 = |
| PathCodeOwnerStatus.create(Paths.get("/foo/b/bar.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus2 = |
| FileCodeOwnerStatus.create( |
| changedFile2, Optional.empty(), Optional.of(pathCodeOwnerStatus2)); |
| |
| ChangedFile changedFile3 = mock(ChangedFile.class); |
| when(changedFile3.changeType()).thenReturn(DiffEntry.ChangeType.DELETE); |
| PathCodeOwnerStatus newPathCodeOwnerStatus3 = |
| PathCodeOwnerStatus.create(Paths.get("/foo/c/new.baz"), CodeOwnerStatus.APPROVED); |
| PathCodeOwnerStatus oldPathCodeOwnerStatus3 = |
| PathCodeOwnerStatus.create(Paths.get("/foo/c/old.baz"), CodeOwnerStatus.APPROVED); |
| FileCodeOwnerStatus fileCodeOwnerStatus3 = |
| FileCodeOwnerStatus.create( |
| changedFile3, |
| Optional.of(newPathCodeOwnerStatus3), |
| Optional.of(oldPathCodeOwnerStatus3)); |
| |
| CodeOwnerStatusInfo codeOwnerStatusInfo = |
| CodeOwnerStatusInfoJson.format( |
| PatchSet.id(Change.id(1), 1), |
| ImmutableSet.of(fileCodeOwnerStatus3, fileCodeOwnerStatus2, fileCodeOwnerStatus1)); |
| ListSubject<FileCodeOwnerStatusInfoSubject, FileCodeOwnerStatusInfo> listSubject = |
| assertThat(codeOwnerStatusInfo).hasFileCodeOwnerStatusesThat(); |
| listSubject.hasSize(3); |
| listSubject.element(0).hasNewPathStatusThat().value().hasPathThat().isEqualTo("foo/a/bar.baz"); |
| listSubject.element(1).hasOldPathStatusThat().value().hasPathThat().isEqualTo("foo/b/bar.baz"); |
| listSubject.element(2).hasNewPathStatusThat().value().hasPathThat().isEqualTo("foo/c/new.baz"); |
| } |
| } |