Add REST endpoint to get a label definition of a project

Bug: Issue 11522
Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: I41e5c015d6067653c5794595df5ba7b97ca679a3
This commit is contained in:
Edwin Kempin
2019-10-25 08:40:24 +02:00
parent b527526e2a
commit aa56f445d3
16 changed files with 510 additions and 67 deletions

View File

@@ -3093,6 +3093,52 @@ Labels that belong to the same project are sorted by label name.
]
----
[[get-label]]
=== Get Label
--
'GET /projects/link:#project-name[\{project-name\}]/labels/link:#label-name[\{label-name\}]'
--
Retrieves the definition of a label that is defined in this project.
The calling user must have read access to the `refs/meta/config` branch of the
project.
.Request
----
GET /projects/All-Projects/labels/Code-Review HTTP/1.0
----
As response a link:#label-definition-info[LabelDefinitionInfo] entity is
returned that describes the label.
.Response
----
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json; charset=UTF-8
)]}'
{
"name": "Code-Review",
"project": "All-Projects",
"function": "MaxWithBlock",
"values": {
" 0": "No score",
"-1": "I would prefer this is not merged as is",
"-2": "This shall not be merged",
"+1": "Looks good to me, but someone else must approve",
"+2": "Looks good to me, approved"
},
"default_value": 0,
"can_override": true,
"copy_min_score": true,
"copy_all_scores_if_no_change": true,
"copy_all_scores_on_trivial_rebase": true,
"allow_post_submit": true
}
----
[[ids]]
== IDs
@@ -3117,6 +3163,10 @@ The ID of a dashboard in the format '<ref>:<path>'.
A special dashboard ID is `default` which represents the default
dashboard of a project.
[[label-name]]
=== \{label-name\}
The name of a review label.
[[project-name]]
=== \{project-name\}
The name of the project.

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2019 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.extensions.api.projects;
import com.google.gerrit.extensions.common.LabelDefinitionInfo;
import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.gerrit.extensions.restapi.RestApiException;
public interface LabelApi {
LabelDefinitionInfo get() throws RestApiException;
/**
* A default implementation which allows source compatibility when adding new methods to the
* interface.
*/
class NotImplemented implements LabelApi {
@Override
public LabelDefinitionInfo get() throws RestApiException {
throw new NotImplementedException();
}
}
}

View File

@@ -218,6 +218,8 @@ public interface ProjectApi {
}
}
LabelApi label(String labelName) throws RestApiException;
/**
* A default implementation which allows source compatibility when adding new methods to the
* interface.
@@ -397,5 +399,10 @@ public interface ProjectApi {
public ListLabelsRequest labels() throws RestApiException {
throw new NotImplementedException();
}
@Override
public LabelApi label(String labelName) throws RestApiException {
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2019 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.server.api.projects;
import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
import com.google.gerrit.extensions.api.projects.LabelApi;
import com.google.gerrit.extensions.common.LabelDefinitionInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.project.LabelResource;
import com.google.gerrit.server.restapi.project.GetLabel;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
public class LabelApiImpl implements LabelApi {
interface Factory {
LabelApiImpl create(LabelResource rsrc);
}
private final GetLabel getLabel;
private final LabelResource rsrc;
@Inject
LabelApiImpl(GetLabel getLabel, @Assisted LabelResource rsrc) {
this.getLabel = getLabel;
this.rsrc = rsrc;
}
@Override
public LabelDefinitionInfo get() throws RestApiException {
try {
return getLabel.apply(rsrc).value();
} catch (Exception e) {
throw asRestApiException("Cannot get label", e);
}
}
}

View File

@@ -28,5 +28,6 @@ public class Module extends FactoryModule {
factory(ChildProjectApiImpl.Factory.class);
factory(CommitApiImpl.Factory.class);
factory(DashboardApiImpl.Factory.class);
factory(LabelApiImpl.Factory.class);
}
}

View File

@@ -37,6 +37,7 @@ import com.google.gerrit.extensions.api.projects.DeleteTagsInput;
import com.google.gerrit.extensions.api.projects.DescriptionInput;
import com.google.gerrit.extensions.api.projects.HeadInput;
import com.google.gerrit.extensions.api.projects.IndexProjectInput;
import com.google.gerrit.extensions.api.projects.LabelApi;
import com.google.gerrit.extensions.api.projects.ParentInput;
import com.google.gerrit.extensions.api.projects.ProjectApi;
import com.google.gerrit.extensions.api.projects.ProjectInput;
@@ -72,6 +73,7 @@ import com.google.gerrit.server.restapi.project.GetHead;
import com.google.gerrit.server.restapi.project.GetParent;
import com.google.gerrit.server.restapi.project.Index;
import com.google.gerrit.server.restapi.project.IndexChanges;
import com.google.gerrit.server.restapi.project.LabelsCollection;
import com.google.gerrit.server.restapi.project.ListBranches;
import com.google.gerrit.server.restapi.project.ListDashboards;
import com.google.gerrit.server.restapi.project.ListLabels;
@@ -130,6 +132,8 @@ public class ProjectApiImpl implements ProjectApi {
private final Index index;
private final IndexChanges indexChanges;
private final Provider<ListLabels> listLabels;
private final LabelsCollection labels;
private final LabelApiImpl.Factory labelApi;
@AssistedInject
ProjectApiImpl(
@@ -166,6 +170,8 @@ public class ProjectApiImpl implements ProjectApi {
Index index,
IndexChanges indexChanges,
Provider<ListLabels> listLabels,
LabelApiImpl.Factory labelApi,
LabelsCollection labels,
@Assisted ProjectResource project) {
this(
permissionBackend,
@@ -202,6 +208,8 @@ public class ProjectApiImpl implements ProjectApi {
index,
indexChanges,
listLabels,
labelApi,
labels,
null);
}
@@ -240,6 +248,8 @@ public class ProjectApiImpl implements ProjectApi {
Index index,
IndexChanges indexChanges,
Provider<ListLabels> listLabels,
LabelApiImpl.Factory labelApi,
LabelsCollection labels,
@Assisted String name) {
this(
permissionBackend,
@@ -276,6 +286,8 @@ public class ProjectApiImpl implements ProjectApi {
index,
indexChanges,
listLabels,
labelApi,
labels,
name);
}
@@ -314,6 +326,8 @@ public class ProjectApiImpl implements ProjectApi {
Index index,
IndexChanges indexChanges,
Provider<ListLabels> listLabels,
LabelApiImpl.Factory labelApi,
LabelsCollection labels,
String name) {
this.permissionBackend = permissionBackend;
this.createProject = createProject;
@@ -350,6 +364,8 @@ public class ProjectApiImpl implements ProjectApi {
this.index = index;
this.indexChanges = indexChanges;
this.listLabels = listLabels;
this.labelApi = labelApi;
this.labels = labels;
}
@Override
@@ -695,4 +711,13 @@ public class ProjectApiImpl implements ProjectApi {
}
};
}
@Override
public LabelApi label(String labelName) throws RestApiException {
try {
return labelApi.create(labels.parse(checkExists(), IdString.fromDecoded(labelName)));
} catch (Exception e) {
throw asRestApiException("Cannot parse label", e);
}
}
}

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2019 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.server.project;
import static java.util.stream.Collectors.toMap;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.common.LabelDefinitionInfo;
public class LabelDefinitionJson {
public static LabelDefinitionInfo format(Project.NameKey projectName, LabelType labelType) {
LabelDefinitionInfo label = new LabelDefinitionInfo();
label.name = labelType.getName();
label.projectName = projectName.get();
label.function = labelType.getFunction().getFunctionName();
label.values =
labelType.getValues().stream().collect(toMap(LabelValue::formatValue, LabelValue::getText));
label.defaultValue = labelType.getDefaultValue();
label.branches = labelType.getRefPatterns() != null ? labelType.getRefPatterns() : null;
label.canOverride = toBoolean(labelType.canOverride());
label.copyAnyScore = toBoolean(labelType.isCopyAnyScore());
label.copyMinScore = toBoolean(labelType.isCopyMinScore());
label.copyMaxScore = toBoolean(labelType.isCopyMaxScore());
label.copyAllScoresIfNoChange = toBoolean(labelType.isCopyAllScoresIfNoChange());
label.copyAllScoresIfNoCodeChange = toBoolean(labelType.isCopyAllScoresIfNoCodeChange());
label.copyAllScoresOnTrivialRebase = toBoolean(labelType.isCopyAllScoresOnTrivialRebase());
label.copyAllScoresOnMergeFirstParentUpdate =
toBoolean(labelType.isCopyAllScoresOnMergeFirstParentUpdate());
label.allowPostSubmit = toBoolean(labelType.allowPostSubmit());
label.ignoreSelfApproval = toBoolean(labelType.ignoreSelfApproval());
return label;
}
private static Boolean toBoolean(boolean v) {
return v ? v : null;
}
private LabelDefinitionJson() {}
}

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2019 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.server.restapi.project;
import com.google.gerrit.extensions.common.LabelDefinitionInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.project.LabelDefinitionJson;
import com.google.gerrit.server.project.LabelResource;
import com.google.inject.Singleton;
@Singleton
public class GetLabel implements RestReadView<LabelResource> {
@Override
public Response<LabelDefinitionInfo> apply(LabelResource rsrc)
throws AuthException, BadRequestException {
return Response.ok(
LabelDefinitionJson.format(rsrc.getProject().getNameKey(), rsrc.getLabelType()));
}
}

View File

@@ -14,13 +14,17 @@
package com.google.gerrit.server.restapi.project;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ChildCollection;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.server.project.LabelResource;
import com.google.gerrit.server.project.ProjectResource;
import com.google.inject.Inject;
@@ -31,11 +35,16 @@ import com.google.inject.Singleton;
public class LabelsCollection implements ChildCollection<ProjectResource, LabelResource> {
private final Provider<ListLabels> list;
private final DynamicMap<RestView<LabelResource>> views;
private final PermissionBackend permissionBackend;
@Inject
LabelsCollection(Provider<ListLabels> list, DynamicMap<RestView<LabelResource>> views) {
LabelsCollection(
Provider<ListLabels> list,
DynamicMap<RestView<LabelResource>> views,
PermissionBackend permissionBackend) {
this.list = list;
this.views = views;
this.permissionBackend = permissionBackend;
}
@Override
@@ -45,8 +54,16 @@ public class LabelsCollection implements ChildCollection<ProjectResource, LabelR
@Override
public LabelResource parse(ProjectResource parent, IdString id)
throws ResourceNotFoundException, Exception {
throw new MethodNotAllowedException();
throws AuthException, ResourceNotFoundException, PermissionBackendException {
permissionBackend
.currentUser()
.project(parent.getNameKey())
.check(ProjectPermission.READ_CONFIG);
LabelType labelType = parent.getProjectState().getConfig().getLabelSections().get(id.get());
if (labelType == null) {
throw new ResourceNotFoundException(id);
}
return new LabelResource(parent, labelType);
}
@Override

View File

@@ -14,10 +14,7 @@
package com.google.gerrit.server.restapi.project;
import static java.util.stream.Collectors.toMap;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.extensions.common.LabelDefinitionInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.Response;
@@ -25,6 +22,7 @@ import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.server.project.LabelDefinitionJson;
import com.google.gerrit.server.project.ProjectResource;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
@@ -77,33 +75,9 @@ public class ListLabels implements RestReadView<ProjectResource> {
Collection<LabelType> labelTypes = projectState.getConfig().getLabelSections().values();
List<LabelDefinitionInfo> labels = new ArrayList<>(labelTypes.size());
for (LabelType labelType : labelTypes) {
LabelDefinitionInfo label = new LabelDefinitionInfo();
label.name = labelType.getName();
label.projectName = projectState.getName();
label.function = labelType.getFunction().getFunctionName();
label.values =
labelType.getValues().stream()
.collect(toMap(LabelValue::formatValue, LabelValue::getText));
label.defaultValue = labelType.getDefaultValue();
label.branches = labelType.getRefPatterns() != null ? labelType.getRefPatterns() : null;
label.canOverride = toBoolean(labelType.canOverride());
label.copyAnyScore = toBoolean(labelType.isCopyAnyScore());
label.copyMinScore = toBoolean(labelType.isCopyMinScore());
label.copyMaxScore = toBoolean(labelType.isCopyMaxScore());
label.copyAllScoresIfNoChange = toBoolean(labelType.isCopyAllScoresIfNoChange());
label.copyAllScoresIfNoCodeChange = toBoolean(labelType.isCopyAllScoresIfNoCodeChange());
label.copyAllScoresOnTrivialRebase = toBoolean(labelType.isCopyAllScoresOnTrivialRebase());
label.copyAllScoresOnMergeFirstParentUpdate =
toBoolean(labelType.isCopyAllScoresOnMergeFirstParentUpdate());
label.allowPostSubmit = toBoolean(labelType.allowPostSubmit());
label.ignoreSelfApproval = toBoolean(labelType.ignoreSelfApproval());
labels.add(label);
labels.add(LabelDefinitionJson.format(projectState.getNameKey(), labelType));
}
labels.sort(Comparator.comparing(l -> l.name));
return labels;
}
private static Boolean toBoolean(boolean v) {
return v ? v : null;
}
}

View File

@@ -68,6 +68,7 @@ public class Module extends RestApiModule {
get(CHILD_PROJECT_KIND).to(GetChildProject.class);
child(PROJECT_KIND, "labels").to(LabelsCollection.class);
get(LABEL_KIND).to(GetLabel.class);
get(PROJECT_KIND, "HEAD").to(GetHead.class);
put(PROJECT_KIND, "HEAD").to(SetHead.class);

View File

@@ -29,6 +29,7 @@ import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.rest.util.RestApiCallHelper;
import com.google.gerrit.acceptance.rest.util.RestCall;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.changes.ReviewInput;
@@ -160,6 +161,13 @@ public class ProjectsRestApiBindingsIT extends AbstractDaemonTest {
private static final ImmutableList<RestCall> COMMIT_FILE_ENDPOINTS =
ImmutableList.of(RestCall.get("/projects/%s/commits/%s/files/%s/content"));
/**
* Label REST endpoints to be tested, each URL contains placeholders for the project identifier
* and the label name.
*/
private static final ImmutableList<RestCall> LABEL_ENDPOINTS =
ImmutableList.of(RestCall.get("/projects/%s/labels/%s"));
private static final String FILENAME = "test.txt";
@Inject private ProjectOperations projectOperations;
@@ -214,6 +222,13 @@ public class ProjectsRestApiBindingsIT extends AbstractDaemonTest {
adminRestSession, COMMIT_FILE_ENDPOINTS, project.get(), commit, FILENAME);
}
@Test
public void labelEndpoints() throws Exception {
String label = "Foo-Review";
configLabel(label, LabelFunction.NO_OP);
RestApiCallHelper.execute(adminRestSession, LABEL_ENDPOINTS, project.get(), label);
}
private String createAndSubmitChange(String filename) throws Exception {
RevCommit c =
testRepo

View File

@@ -6,6 +6,7 @@ load("//javatests/com/google/gerrit/acceptance:tests.bzl", "acceptance_tests")
group = f[:f.index(".")],
labels = ["rest"],
deps = [
":labelassert",
":project",
":push_tag_util",
":refassert",
@@ -13,6 +14,19 @@ load("//javatests/com/google/gerrit/acceptance:tests.bzl", "acceptance_tests")
],
) for f in glob(["*IT.java"])]
java_library(
name = "labelassert",
srcs = [
"LabelAssert.java",
],
deps = [
"//java/com/google/gerrit/common:server",
"//java/com/google/gerrit/extensions:api",
"//java/com/google/gerrit/server",
"//lib/truth",
],
)
java_library(
name = "refassert",
srcs = [

View File

@@ -0,0 +1,144 @@
// Copyright (C) 2019 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.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.common.LabelDefinitionInfo;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.inject.Inject;
import org.junit.Test;
@NoHttpd
public class GetLabelIT extends AbstractDaemonTest {
@Inject private RequestScopeOperations requestScopeOperations;
@Test
public void notAllowed() throws Exception {
requestScopeOperations.setApiUser(user.id());
AuthException thrown =
assertThrows(
AuthException.class,
() -> gApi.projects().name(allProjects.get()).label("Code-Review").get());
assertThat(thrown).hasMessageThat().contains("read refs/meta/config not permitted");
}
@Test
public void notFound() throws Exception {
ResourceNotFoundException thrown =
assertThrows(
ResourceNotFoundException.class,
() -> gApi.projects().name(project.get()).label("Foo-Review").get());
assertThat(thrown).hasMessageThat().contains("Not found: Foo-Review");
}
@Test
public void allProjectsCodeReviewLabel() throws Exception {
LabelDefinitionInfo codeReviewLabel =
gApi.projects().name(allProjects.get()).label("Code-Review").get();
LabelAssert.assertCodeReviewLabel(codeReviewLabel);
}
@Test
public void labelWithDefaultValue() throws Exception {
configLabel("foo", LabelFunction.NO_OP);
// set default value
try (ProjectConfigUpdate u = updateProject(project)) {
LabelType labelType = u.getConfig().getLabelSections().get("foo");
labelType.setDefaultValue((short) 1);
u.getConfig().getLabelSections().put(labelType.getName(), labelType);
u.save();
}
LabelDefinitionInfo fooLabel = gApi.projects().name(project.get()).label("foo").get();
assertThat(fooLabel.defaultValue).isEqualTo(1);
}
@Test
public void labelLimitedToBranches() throws Exception {
configLabel(
"foo", LabelFunction.NO_OP, ImmutableList.of("refs/heads/master", "^refs/heads/stable-.*"));
LabelDefinitionInfo fooLabel = gApi.projects().name(project.get()).label("foo").get();
assertThat(fooLabel.branches).containsExactly("refs/heads/master", "^refs/heads/stable-.*");
}
@Test
public void labelWithoutRules() throws Exception {
configLabel("foo", LabelFunction.NO_OP);
// unset rules which are enabled by default
try (ProjectConfigUpdate u = updateProject(project)) {
LabelType labelType = u.getConfig().getLabelSections().get("foo");
labelType.setCanOverride(false);
labelType.setCopyAllScoresIfNoChange(false);
labelType.setAllowPostSubmit(false);
u.getConfig().getLabelSections().put(labelType.getName(), labelType);
u.save();
}
LabelDefinitionInfo fooLabel = gApi.projects().name(project.get()).label("foo").get();
assertThat(fooLabel.canOverride).isNull();
assertThat(fooLabel.copyAnyScore).isNull();
assertThat(fooLabel.copyMinScore).isNull();
assertThat(fooLabel.copyMaxScore).isNull();
assertThat(fooLabel.copyAllScoresIfNoChange).isNull();
assertThat(fooLabel.copyAllScoresIfNoCodeChange).isNull();
assertThat(fooLabel.copyAllScoresOnTrivialRebase).isNull();
assertThat(fooLabel.copyAllScoresOnMergeFirstParentUpdate).isNull();
assertThat(fooLabel.allowPostSubmit).isNull();
assertThat(fooLabel.ignoreSelfApproval).isNull();
}
@Test
public void labelWithAllRules() throws Exception {
configLabel("foo", LabelFunction.NO_OP);
// set rules which are not enabled by default
try (ProjectConfigUpdate u = updateProject(project)) {
LabelType labelType = u.getConfig().getLabelSections().get("foo");
labelType.setCopyAnyScore(true);
labelType.setCopyMinScore(true);
labelType.setCopyMaxScore(true);
labelType.setCopyAllScoresIfNoCodeChange(true);
labelType.setCopyAllScoresOnTrivialRebase(true);
labelType.setCopyAllScoresOnMergeFirstParentUpdate(true);
labelType.setIgnoreSelfApproval(true);
u.getConfig().getLabelSections().put(labelType.getName(), labelType);
u.save();
}
LabelDefinitionInfo fooLabel = gApi.projects().name(project.get()).label("foo").get();
assertThat(fooLabel.canOverride).isTrue();
assertThat(fooLabel.copyAnyScore).isTrue();
assertThat(fooLabel.copyMinScore).isTrue();
assertThat(fooLabel.copyMaxScore).isTrue();
assertThat(fooLabel.copyAllScoresIfNoChange).isTrue();
assertThat(fooLabel.copyAllScoresIfNoCodeChange).isTrue();
assertThat(fooLabel.copyAllScoresOnTrivialRebase).isTrue();
assertThat(fooLabel.copyAllScoresOnMergeFirstParentUpdate).isTrue();
assertThat(fooLabel.allowPostSubmit).isTrue();
assertThat(fooLabel.ignoreSelfApproval).isTrue();
}
}

View File

@@ -0,0 +1,55 @@
// Copyright (C) 2019 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.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.extensions.common.LabelDefinitionInfo;
import com.google.gerrit.server.config.AllProjectsNameProvider;
public class LabelAssert {
public static void assertCodeReviewLabel(LabelDefinitionInfo codeReviewLabel) {
assertThat(codeReviewLabel.name).isEqualTo("Code-Review");
assertThat(codeReviewLabel.projectName).isEqualTo(AllProjectsNameProvider.DEFAULT);
assertThat(codeReviewLabel.function).isEqualTo(LabelFunction.MAX_WITH_BLOCK.getFunctionName());
assertThat(codeReviewLabel.values)
.containsExactly(
"+2",
"Looks good to me, approved",
"+1",
"Looks good to me, but someone else must approve",
" 0",
"No score",
"-1",
"I would prefer this is not merged as is",
"-2",
"This shall not be merged");
assertThat(codeReviewLabel.defaultValue).isEqualTo(0);
assertThat(codeReviewLabel.branches).isNull();
assertThat(codeReviewLabel.canOverride).isTrue();
assertThat(codeReviewLabel.copyAnyScore).isNull();
assertThat(codeReviewLabel.copyMinScore).isTrue();
assertThat(codeReviewLabel.copyMaxScore).isNull();
assertThat(codeReviewLabel.copyAllScoresIfNoChange).isTrue();
assertThat(codeReviewLabel.copyAllScoresIfNoCodeChange).isNull();
assertThat(codeReviewLabel.copyAllScoresOnTrivialRebase).isTrue();
assertThat(codeReviewLabel.copyAllScoresOnMergeFirstParentUpdate).isNull();
assertThat(codeReviewLabel.allowPostSubmit).isTrue();
assertThat(codeReviewLabel.ignoreSelfApproval).isNull();
}
private LabelAssert() {}
}

View File

@@ -61,7 +61,7 @@ public class ListLabelsIT extends AbstractDaemonTest {
assertThat(labelNames(labels)).containsExactly("Code-Review");
LabelDefinitionInfo codeReviewLabel = Iterables.getOnlyElement(labels);
assertCodeReviewLabel(codeReviewLabel);
LabelAssert.assertCodeReviewLabel(codeReviewLabel);
}
@Test
@@ -199,7 +199,7 @@ public class ListLabelsIT extends AbstractDaemonTest {
assertThat(labelNames(labels)).containsExactly("Code-Review");
LabelDefinitionInfo codeReviewLabel = Iterables.getOnlyElement(labels);
assertCodeReviewLabel(codeReviewLabel);
LabelAssert.assertCodeReviewLabel(codeReviewLabel);
}
@Test
@@ -212,7 +212,7 @@ public class ListLabelsIT extends AbstractDaemonTest {
gApi.projects().name(project.get()).labels().withInherited(true).get();
assertThat(labelNames(labels)).containsExactly("Code-Review", "bar", "baz", "foo").inOrder();
assertCodeReviewLabel(labels.get(0));
LabelAssert.assertCodeReviewLabel(labels.get(0));
assertThat(labels.get(1).name).isEqualTo("bar");
assertThat(labels.get(1).projectName).isEqualTo(project.get());
assertThat(labels.get(2).name).isEqualTo("baz");
@@ -229,7 +229,7 @@ public class ListLabelsIT extends AbstractDaemonTest {
gApi.projects().name(project.get()).labels().withInherited(true).get();
assertThat(labelNames(labels)).containsExactly("Code-Review", "Code-Review");
assertCodeReviewLabel(labels.get(0));
LabelAssert.assertCodeReviewLabel(labels.get(0));
assertThat(labels.get(1).name).isEqualTo("Code-Review");
assertThat(labels.get(1).projectName).isEqualTo(project.get());
assertThat(labels.get(1).function).isEqualTo(LabelFunction.NO_OP.getFunctionName());
@@ -247,43 +247,13 @@ public class ListLabelsIT extends AbstractDaemonTest {
gApi.projects().name(childProject.get()).labels().withInherited(true).get();
assertThat(labelNames(labels)).containsExactly("Code-Review", "foo", "bar").inOrder();
assertCodeReviewLabel(labels.get(0));
LabelAssert.assertCodeReviewLabel(labels.get(0));
assertThat(labels.get(1).name).isEqualTo("foo");
assertThat(labels.get(1).projectName).isEqualTo(project.get());
assertThat(labels.get(2).name).isEqualTo("bar");
assertThat(labels.get(2).projectName).isEqualTo(childProject.get());
}
private void assertCodeReviewLabel(LabelDefinitionInfo codeReviewLabel) {
assertThat(codeReviewLabel.name).isEqualTo("Code-Review");
assertThat(codeReviewLabel.projectName).isEqualTo(allProjects.get());
assertThat(codeReviewLabel.function).isEqualTo(LabelFunction.MAX_WITH_BLOCK.getFunctionName());
assertThat(codeReviewLabel.values)
.containsExactly(
"+2",
"Looks good to me, approved",
"+1",
"Looks good to me, but someone else must approve",
" 0",
"No score",
"-1",
"I would prefer this is not merged as is",
"-2",
"This shall not be merged");
assertThat(codeReviewLabel.defaultValue).isEqualTo(0);
assertThat(codeReviewLabel.branches).isNull();
assertThat(codeReviewLabel.canOverride).isTrue();
assertThat(codeReviewLabel.copyAnyScore).isNull();
assertThat(codeReviewLabel.copyMinScore).isTrue();
assertThat(codeReviewLabel.copyMaxScore).isNull();
assertThat(codeReviewLabel.copyAllScoresIfNoChange).isTrue();
assertThat(codeReviewLabel.copyAllScoresIfNoCodeChange).isNull();
assertThat(codeReviewLabel.copyAllScoresOnTrivialRebase).isTrue();
assertThat(codeReviewLabel.copyAllScoresOnMergeFirstParentUpdate).isNull();
assertThat(codeReviewLabel.allowPostSubmit).isTrue();
assertThat(codeReviewLabel.ignoreSelfApproval).isNull();
}
private static List<String> labelNames(List<LabelDefinitionInfo> labels) {
return labels.stream().map(l -> l.name).collect(toList());
}