blob: 456e609acfed6c53ee44b326a4434c7c4eee4891 [file] [log] [blame]
// 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");
}
}