Merge "Always show `Download` action" into stable-3.8
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt
index 7b1baba..25fe9f3 100644
--- a/Documentation/config-project-config.txt
+++ b/Documentation/config-project-config.txt
@@ -129,9 +129,10 @@
- `Hidden`:
+
-The project is hidden and only visible to project owners. Other users
-are not able to see the project even if they have read permissions
-granted on the project.
+The project is hidden; It will not appear in any searches and is only visible
+to project owners by going directly to the repository admin page. Other users
+are not able to see the project even if they have read permissions granted on
+the project.
[[receive-section]]
diff --git a/java/com/google/gerrit/acceptance/GerritServer.java b/java/com/google/gerrit/acceptance/GerritServer.java
index e812cb7..57ac919 100644
--- a/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/java/com/google/gerrit/acceptance/GerritServer.java
@@ -61,6 +61,7 @@
import com.google.gerrit.server.experiments.ConfigExperimentFeatures.ConfigExperimentFeaturesModule;
import com.google.gerrit.server.git.receive.AsyncReceiveCommits.AsyncReceiveCommitsModule;
import com.google.gerrit.server.git.validators.CommitValidationListener;
+import com.google.gerrit.server.index.AbstractIndexModule;
import com.google.gerrit.server.index.options.AutoFlush;
import com.google.gerrit.server.schema.JdbcAccountPatchReviewStore;
import com.google.gerrit.server.ssh.NoSshModule;
@@ -425,7 +426,6 @@
if (testSshModule != null) {
daemon.addAdditionalSshModuleForTesting(testSshModule);
}
- daemon.setEnableSshd(desc.useSsh());
daemon.addAdditionalSysModuleForTesting(
new AbstractModule() {
@Override
@@ -461,7 +461,11 @@
if (desc.memory()) {
checkArgument(additionalArgs.length == 0, "cannot pass args to in-memory server");
- return startInMemory(desc, site, baseConfig, daemon, inMemoryRepoManager);
+ AbstractIndexModule testIndexModule =
+ (testSysModule instanceof AbstractIndexModule)
+ ? (AbstractIndexModule) testSysModule
+ : null;
+ return startInMemory(desc, site, baseConfig, daemon, inMemoryRepoManager, testIndexModule);
}
return startOnDisk(desc, site, daemon, serverStarted, additionalArgs);
}
@@ -471,7 +475,8 @@
Path site,
Config baseConfig,
Daemon daemon,
- @Nullable InMemoryRepositoryManager inMemoryRepoManager)
+ @Nullable InMemoryRepositoryManager inMemoryRepoManager,
+ @Nullable AbstractIndexModule testIndexModule)
throws Exception {
Config cfg = desc.buildConfig(baseConfig);
mergeTestConfig(cfg);
@@ -487,24 +492,11 @@
"accountPatchReviewDb", null, "url", JdbcAccountPatchReviewStore.TEST_IN_MEMORY_URL);
String configuredIndexBackend = cfg.getString("index", null, "type");
- IndexType indexType;
- if (configuredIndexBackend != null) {
- // Explicitly configured index backend from gerrit.config trumps any other ways to configure
- // index backends so that Reindex tests can be explicit about the backend they want to test
- // against.
- indexType = new IndexType(configuredIndexBackend);
- } else {
- // Allow configuring the index backend based on sys/env variables so that integration tests
- // can be run against different index backends.
- indexType = IndexType.fromEnvironment().orElse(new IndexType("fake"));
- }
- if (indexType.isLucene()) {
- daemon.setIndexModule(
- LuceneIndexModule.singleVersionAllLatest(
- 0, ReplicaUtil.isReplica(baseConfig), AutoFlush.ENABLED));
- } else {
- daemon.setIndexModule(FakeIndexModule.latestVersion(false));
- }
+ IndexType indexType =
+ (configuredIndexBackend != null)
+ ? new IndexType(configuredIndexBackend)
+ : IndexType.fromEnvironment().orElse(new IndexType("fake"));
+ daemon.setIndexModule(createIndexModule(indexType, baseConfig, testIndexModule));
daemon.setEnableHttpd(desc.httpd());
daemon.setInMemory(true);
@@ -524,6 +516,17 @@
return new GerritServer(desc, null, createTestInjector(daemon), daemon, null);
}
+ private static AbstractIndexModule createIndexModule(
+ IndexType indexType, Config baseConfig, @Nullable AbstractIndexModule testIndexModule) {
+ if (testIndexModule != null) {
+ return testIndexModule;
+ }
+ return indexType.isLucene()
+ ? LuceneIndexModule.singleVersionAllLatest(
+ 0, ReplicaUtil.isReplica(baseConfig), AutoFlush.ENABLED)
+ : FakeIndexModule.latestVersion(false);
+ }
+
private static GerritServer startOnDisk(
Description desc,
Path site,
diff --git a/java/com/google/gerrit/index/testing/AbstractFakeIndex.java b/java/com/google/gerrit/index/testing/AbstractFakeIndex.java
index 944f956..e4c6745 100644
--- a/java/com/google/gerrit/index/testing/AbstractFakeIndex.java
+++ b/java/com/google/gerrit/index/testing/AbstractFakeIndex.java
@@ -238,7 +238,8 @@
private final boolean skipMergable;
@Inject
- FakeChangeIndex(
+ @VisibleForTesting
+ protected FakeChangeIndex(
SitePaths sitePaths,
ChangeData.Factory changeDataFactory,
@Assisted Schema<ChangeData> schema,
diff --git a/java/com/google/gerrit/server/restapi/change/Move.java b/java/com/google/gerrit/server/restapi/change/Move.java
index c3688d6..2b0de12 100644
--- a/java/com/google/gerrit/server/restapi/change/Move.java
+++ b/java/com/google/gerrit/server/restapi/change/Move.java
@@ -286,6 +286,9 @@
.setTitle("Move change to a different branch")
.setVisible(false);
+ if (!moveEnabled) {
+ return description;
+ }
Change change = rsrc.getChange();
if (!change.isNew()) {
return description;
diff --git a/java/com/google/gerrit/server/restapi/project/CreateAccessChange.java b/java/com/google/gerrit/server/restapi/project/CreateAccessChange.java
index 65182db..458ae4d 100644
--- a/java/com/google/gerrit/server/restapi/project/CreateAccessChange.java
+++ b/java/com/google/gerrit/server/restapi/project/CreateAccessChange.java
@@ -17,6 +17,7 @@
import static com.google.gerrit.server.project.ProjectCache.illegalState;
import static com.google.gerrit.server.update.context.RefUpdateContext.RefUpdateType.CHANGE_MODIFICATION;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.entities.AccessSection;
@@ -141,7 +142,15 @@
throw new IllegalStateException(e);
}
- md.setMessage("Review access change");
+ if (!Strings.isNullOrEmpty(input.message)) {
+ if (!input.message.endsWith("\n")) {
+ input.message += "\n";
+ }
+ md.setMessage(input.message);
+ } else {
+ md.setMessage("Review access change\n");
+ }
+
md.setInsertChangeId(true);
Change.Id changeId = Change.id(seq.nextChangeId());
try (RefUpdateContext ctx = RefUpdateContext.open(CHANGE_MODIFICATION)) {
diff --git a/java/com/google/gerrit/server/restapi/project/DeleteRef.java b/java/com/google/gerrit/server/restapi/project/DeleteRef.java
index b7fe46e..4fc2b86 100644
--- a/java/com/google/gerrit/server/restapi/project/DeleteRef.java
+++ b/java/com/google/gerrit/server/restapi/project/DeleteRef.java
@@ -252,7 +252,7 @@
RefUpdate u = r.updateRef(refName);
u.setForceUpdate(true);
- u.setExpectedOldObjectId(r.exactRef(refName).getObjectId());
+ u.setExpectedOldObjectId(ref.getObjectId());
u.setNewObjectId(ObjectId.zeroId());
refDeletionValidator.validateRefOperation(
projectState.getName(),
diff --git a/java/com/google/gerrit/server/submit/RebaseSorter.java b/java/com/google/gerrit/server/submit/RebaseSorter.java
index e960284..3645d3f 100644
--- a/java/com/google/gerrit/server/submit/RebaseSorter.java
+++ b/java/com/google/gerrit/server/submit/RebaseSorter.java
@@ -40,7 +40,7 @@
private final CurrentUser caller;
private final CodeReviewRevWalk rw;
private final RevFlag canMergeFlag;
- private final Set<RevCommit> uninterestingBranchTips;
+ private final RevCommit initialTip;
private final Set<RevCommit> alreadyAccepted;
private final Provider<InternalChangeQuery> queryProvider;
private final Set<CodeReviewCommit> incoming;
@@ -48,7 +48,7 @@
public RebaseSorter(
CurrentUser caller,
CodeReviewRevWalk rw,
- Set<RevCommit> uninterestingBranchTips,
+ RevCommit initialTip,
Set<RevCommit> alreadyAccepted,
RevFlag canMergeFlag,
Provider<InternalChangeQuery> queryProvider,
@@ -56,7 +56,7 @@
this.caller = caller;
this.rw = rw;
this.canMergeFlag = canMergeFlag;
- this.uninterestingBranchTips = uninterestingBranchTips;
+ this.initialTip = initialTip;
this.alreadyAccepted = alreadyAccepted;
this.queryProvider = queryProvider;
this.incoming = incoming;
@@ -70,8 +70,8 @@
rw.resetRetain(canMergeFlag);
rw.markStart(n);
- for (RevCommit uninterestingBranchTip : uninterestingBranchTips) {
- rw.markUninteresting(uninterestingBranchTip);
+ if (initialTip != null) {
+ rw.markUninteresting(initialTip);
}
CodeReviewCommit c;
diff --git a/java/com/google/gerrit/server/submit/SubmitStrategy.java b/java/com/google/gerrit/server/submit/SubmitStrategy.java
index c7b322e..bdda3fc5 100644
--- a/java/com/google/gerrit/server/submit/SubmitStrategy.java
+++ b/java/com/google/gerrit/server/submit/SubmitStrategy.java
@@ -22,7 +22,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.SubmissionId;
@@ -218,18 +217,11 @@
projectCache.get(destBranch.project()).orElseThrow(illegalState(destBranch.project()));
this.mergeSorter =
new MergeSorter(caller, rw, alreadyAccepted, canMergeFlag, queryProvider, incoming);
- Set<RevCommit> uninterestingBranchTips;
- if (project.is(BooleanProjectConfig.CREATE_NEW_CHANGE_FOR_ALL_NOT_IN_TARGET)) {
- RevCommit initialTip = mergeTip.getInitialTip();
- uninterestingBranchTips = initialTip == null ? Set.of() : Set.of(initialTip);
- } else {
- uninterestingBranchTips = alreadyAccepted;
- }
this.rebaseSorter =
new RebaseSorter(
caller,
rw,
- uninterestingBranchTips,
+ mergeTip.getInitialTip(),
alreadyAccepted,
canMergeFlag,
queryProvider,
diff --git a/javatests/com/google/gerrit/acceptance/api/project/AccessReviewIT.java b/javatests/com/google/gerrit/acceptance/api/project/AccessReviewIT.java
new file mode 100644
index 0000000..553650a
--- /dev/null
+++ b/javatests/com/google/gerrit/acceptance/api/project/AccessReviewIT.java
@@ -0,0 +1,102 @@
+// Copyright (C) 2023 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.api.project;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.extensions.api.access.AccessSectionInfo;
+import com.google.gerrit.extensions.api.access.PermissionInfo;
+import com.google.gerrit.extensions.api.access.PermissionRuleInfo;
+import com.google.gerrit.extensions.api.access.ProjectAccessInput;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.server.group.SystemGroupBackend;
+import com.google.inject.Inject;
+import java.util.HashMap;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AccessReviewIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
+ private Project.NameKey defaultMessageProject;
+ private Project.NameKey customMessageProject;
+
+ @Before
+ public void setUp() throws Exception {
+ defaultMessageProject = projectOperations.newProject().create();
+ customMessageProject = projectOperations.newProject().create();
+ }
+
+ @Test
+ public void createPermissionsChangeWithDefaultMessage() throws Exception {
+ ProjectAccessInput in = new ProjectAccessInput();
+ in.add = new HashMap<>();
+
+ AccessSectionInfo a = new AccessSectionInfo();
+ PermissionInfo p = new PermissionInfo(null, null);
+ p.rules =
+ ImmutableMap.of(
+ SystemGroupBackend.REGISTERED_USERS.get(),
+ new PermissionRuleInfo(PermissionRuleInfo.Action.ALLOW, false));
+ a.permissions = ImmutableMap.of("read", p);
+ in.add = ImmutableMap.of("refs/heads/*", a);
+
+ RestResponse rep =
+ adminRestSession.put("/projects/" + defaultMessageProject.get() + "/access:review", in);
+ rep.assertCreated();
+
+ List<ChangeInfo> result =
+ gApi.changes()
+ .query("project:" + defaultMessageProject.get() + " AND ref:refs/meta/config")
+ .get();
+ assertThat(Iterables.getOnlyElement(result).subject).isEqualTo("Review access change");
+ }
+
+ @Test
+ public void createPermissionsChangeWithCustomMessage() throws Exception {
+ ProjectAccessInput in = new ProjectAccessInput();
+ String customMessage = "UNIT-42: Allow registered users to read 'main' branch";
+ in.add = new HashMap<>();
+
+ AccessSectionInfo a = new AccessSectionInfo();
+ PermissionInfo p = new PermissionInfo(null, null);
+ p.rules =
+ ImmutableMap.of(
+ SystemGroupBackend.REGISTERED_USERS.get(),
+ new PermissionRuleInfo(PermissionRuleInfo.Action.ALLOW, false));
+ a.permissions = ImmutableMap.of("read", p);
+ in.add = ImmutableMap.of("refs/heads/main", a);
+ in.message = customMessage;
+
+ RestResponse rep =
+ adminRestSession.put("/projects/" + customMessageProject.get() + "/access:review", in);
+ rep.assertCreated();
+
+ List<ChangeInfo> result =
+ gApi.changes()
+ .query("project:" + customMessageProject.get() + " AND ref:refs/meta/config")
+ .get();
+
+ assertThat(Iterables.getOnlyElement(result).subject).isEqualTo(customMessage);
+ }
+}
diff --git a/javatests/com/google/gerrit/acceptance/ssh/CustomIndexIT.java b/javatests/com/google/gerrit/acceptance/ssh/CustomIndexIT.java
index 434071f..fee413a 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/CustomIndexIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/CustomIndexIT.java
@@ -14,9 +14,29 @@
package com.google.gerrit.acceptance.ssh;
+import static com.google.common.truth.Truth.assertThat;
+
import com.google.gerrit.index.IndexType;
+import com.google.gerrit.index.Schema;
+import com.google.gerrit.index.project.ProjectIndex;
+import com.google.gerrit.index.testing.AbstractFakeIndex;
+import com.google.gerrit.index.testing.FakeIndexVersionManager;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.server.index.AbstractIndexModule;
+import com.google.gerrit.server.index.VersionManager;
+import com.google.gerrit.server.index.account.AccountIndex;
+import com.google.gerrit.server.index.change.ChangeIndex;
+import com.google.gerrit.server.index.change.ChangeIndexCollection;
+import com.google.gerrit.server.index.group.GroupIndex;
+import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Inject;
+import com.google.inject.Module;
+import com.google.inject.assistedinject.Assisted;
+import java.util.Map;
import org.eclipse.jgit.lib.Config;
+import org.junit.Test;
/**
* Tests for a defaulted custom index configuration. This unknown type is the opposite of {@link
@@ -24,10 +44,70 @@
*/
public class CustomIndexIT extends AbstractIndexTests {
+ @Override
+ public Module createModule() {
+ return CustomIndexModule.latestVersion(false);
+ }
+
@ConfigSuite.Default
public static Config customIndexType() {
Config config = new Config();
config.setString("index", null, "type", "custom");
return config;
}
+
+ @Inject private ChangeIndexCollection changeIndex;
+
+ @Test
+ public void customIndexModuleIsBound() throws Exception {
+ assertThat(changeIndex.getSearchIndex()).isInstanceOf(CustomModuleFakeIndexChange.class);
+ }
+}
+
+class CustomIndexModule extends AbstractIndexModule {
+
+ public static CustomIndexModule latestVersion(boolean secondary) {
+ return new CustomIndexModule(null, -1 /* direct executor */, secondary);
+ }
+
+ private CustomIndexModule(Map<String, Integer> singleVersions, int threads, boolean secondary) {
+ super(singleVersions, threads, secondary);
+ }
+
+ @Override
+ protected Class<? extends AccountIndex> getAccountIndex() {
+ return AbstractFakeIndex.FakeAccountIndex.class;
+ }
+
+ @Override
+ protected Class<? extends ChangeIndex> getChangeIndex() {
+ return CustomModuleFakeIndexChange.class;
+ }
+
+ @Override
+ protected Class<? extends GroupIndex> getGroupIndex() {
+ return AbstractFakeIndex.FakeGroupIndex.class;
+ }
+
+ @Override
+ protected Class<? extends ProjectIndex> getProjectIndex() {
+ return AbstractFakeIndex.FakeProjectIndex.class;
+ }
+
+ @Override
+ protected Class<? extends VersionManager> getVersionManager() {
+ return FakeIndexVersionManager.class;
+ }
+}
+
+class CustomModuleFakeIndexChange extends AbstractFakeIndex.FakeChangeIndex {
+
+ @com.google.inject.Inject
+ CustomModuleFakeIndexChange(
+ SitePaths sitePaths,
+ ChangeData.Factory changeDataFactory,
+ @Assisted Schema<ChangeData> schema,
+ @GerritServerConfig Config cfg) {
+ super(sitePaths, changeDataFactory, schema, cfg);
+ }
}
diff --git a/javatests/com/google/gerrit/metrics/dropwizard/BUILD b/javatests/com/google/gerrit/metrics/dropwizard/BUILD
index e236f30..42cf111 100644
--- a/javatests/com/google/gerrit/metrics/dropwizard/BUILD
+++ b/javatests/com/google/gerrit/metrics/dropwizard/BUILD
@@ -8,6 +8,7 @@
deps = [
"//java/com/google/gerrit/metrics",
"//java/com/google/gerrit/metrics/dropwizard",
+ "//java/com/google/gerrit/testing:gerrit-test-util",
"//lib/mockito",
"//lib/truth",
"@dropwizard-core//jar",
diff --git a/javatests/com/google/gerrit/metrics/dropwizard/BucketedCallbackTest.java b/javatests/com/google/gerrit/metrics/dropwizard/BucketedCallbackTest.java
new file mode 100644
index 0000000..e87a208
--- /dev/null
+++ b/javatests/com/google/gerrit/metrics/dropwizard/BucketedCallbackTest.java
@@ -0,0 +1,101 @@
+// Copyright (C) 2023 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.metrics.dropwizard;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.codahale.metrics.MetricRegistry;
+import com.google.gerrit.metrics.Description;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BucketedCallbackTest {
+
+ private MetricRegistry registry;
+
+ private DropWizardMetricMaker metrics;
+
+ private static final String CODE_NAME = "name";
+ private static final String KEY_NAME = "foo";
+ private static final String OTHER_KEY_NAME = "bar";
+ private static final String COLLIDING_KEY_NAME1 = "foo1";
+ private static final String COLLIDING_KEY_NAME2 = "foo2";
+ private static final String COLLIDING_SUBMETRIC_NAME = "foocollision";
+
+ private String metricName(String fieldValues) {
+ return CODE_NAME + "/" + fieldValues;
+ }
+
+ @Before
+ public void setup() {
+ registry = new MetricRegistry();
+ metrics = new DropWizardMetricMaker(registry, null);
+ }
+
+ @Test
+ public void shouldRegisterMetricWithNewKey() {
+ BucketedCallback<Long> bc = new CallbackMetricTestImpl();
+
+ bc.getOrCreate(KEY_NAME);
+ assertThat(registry.getNames()).containsExactly(metricName(KEY_NAME));
+
+ bc.getOrCreate(OTHER_KEY_NAME);
+ assertThat(registry.getNames())
+ .containsExactly(metricName(KEY_NAME), metricName(OTHER_KEY_NAME));
+ }
+
+ @Test
+ public void shouldNotReRegisterPreviouslyRegisteredMetric() {
+ BucketedCallback<Long> bc = new CallbackMetricTestImpl();
+ bc.getOrCreate(KEY_NAME);
+ bc.getOrCreate(KEY_NAME);
+ assertThat(registry.getNames()).containsExactly(metricName(KEY_NAME));
+ }
+
+ @Test
+ public void shouldStoreKeyValueInCellsAndRegisterSubmetricName() {
+ BucketedCallback<Long> bc = new CallbackMetricTestImpl();
+ bc.getOrCreate(COLLIDING_KEY_NAME1);
+ assertThat(bc.getCells().keySet()).containsExactly(COLLIDING_KEY_NAME1);
+ assertThat(registry.getNames()).containsExactly(metricName(COLLIDING_SUBMETRIC_NAME));
+ }
+
+ @Test
+ public void shouldErrorIfKeyIsDifferentButNameCollides() {
+ BucketedCallback<Long> bc = new CallbackMetricTestImpl();
+ bc.getOrCreate(COLLIDING_KEY_NAME1);
+
+ assertThrows(IllegalArgumentException.class, () -> bc.getOrCreate(COLLIDING_KEY_NAME2));
+ assertThat(bc.getCells().keySet()).containsExactly(COLLIDING_KEY_NAME1);
+ assertThat(registry.getNames()).containsExactly(metricName(COLLIDING_SUBMETRIC_NAME));
+ }
+
+ private class CallbackMetricTestImpl extends BucketedCallback<Long> {
+
+ CallbackMetricTestImpl() {
+ super(metrics, registry, CODE_NAME, Long.class, new Description("description"));
+ }
+
+ @Override
+ String name(Object key) {
+ if (key.equals(COLLIDING_KEY_NAME1) || key.equals(COLLIDING_KEY_NAME2)) {
+ return COLLIDING_SUBMETRIC_NAME;
+ } else {
+ return key.toString();
+ }
+ }
+ }
+}
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts
index 57f9ee6..3f99416 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.ts
@@ -117,10 +117,12 @@
return;
}
- this.restApiService.getAccountDetails(userId).then(details => {
- this._accountDetails = details ?? undefined;
- this._status = details?.status ?? '';
- });
+ this.restApiService
+ .getAccountDetails(userId, () => {})
+ .then(details => {
+ this._accountDetails = details ?? undefined;
+ this._status = details?.status ?? '';
+ });
}
_computeDetail(
diff --git a/polygerrit-ui/app/elements/gr-app-element.ts b/polygerrit-ui/app/elements/gr-app-element.ts
index 23c9e7a..a36f17a 100644
--- a/polygerrit-ui/app/elements/gr-app-element.ts
+++ b/polygerrit-ui/app/elements/gr-app-element.ts
@@ -420,7 +420,7 @@
return html`
<gr-main-header
id="mainHeader"
- .searchQuery=${(this.params as SearchViewState)?.query ?? ''}
+ .searchQuery=${(this.params as SearchViewState)?.query}
@mobile-search=${this.mobileSearchToggle}
@show-keyboard-shortcuts=${this.showKeyboardShortcuts}
.mobileSearchHidden=${!this.mobileSearch}
diff --git a/polygerrit-ui/app/elements/gr-app_test.ts b/polygerrit-ui/app/elements/gr-app_test.ts
index 6b97c85..15cfda6 100644
--- a/polygerrit-ui/app/elements/gr-app_test.ts
+++ b/polygerrit-ui/app/elements/gr-app_test.ts
@@ -30,7 +30,6 @@
GrRouter.prototype,
<any>'dispatchLocationChangeEvent'
);
-
setup(async () => {
await fixture<GrApp>(html`<gr-app id="app"></gr-app>`);
});
diff --git a/polygerrit-ui/app/utils/url-util.ts b/polygerrit-ui/app/utils/url-util.ts
index 8267638..2f9bc0c 100644
--- a/polygerrit-ui/app/utils/url-util.ts
+++ b/polygerrit-ui/app/utils/url-util.ts
@@ -34,7 +34,7 @@
) {
return customLoginUrl.startsWith('http')
? customLoginUrl
- : baseUrl + customLoginUrl;
+ : baseUrl + sanitizeRelativeUrl(customLoginUrl);
} else {
// Strip the canonical path from the path since needing canonical in
// the path is unneeded and breaks the url.
@@ -73,6 +73,10 @@
return range;
}
+function sanitizeRelativeUrl(relativeUrl: string): string {
+ return relativeUrl.startsWith('/') ? relativeUrl : `/${relativeUrl}`;
+}
+
export function prependOrigin(path: string): string {
if (path.startsWith('http')) return path;
if (path.startsWith('/')) return window.location.origin + path;
diff --git a/polygerrit-ui/app/utils/url-util_test.ts b/polygerrit-ui/app/utils/url-util_test.ts
index e36719d..e2ca617 100644
--- a/polygerrit-ui/app/utils/url-util_test.ts
+++ b/polygerrit-ui/app/utils/url-util_test.ts
@@ -76,6 +76,12 @@
authConfig.auth_type = AuthType.HTTP_LDAP;
assert.deepEqual(loginUrl(authConfig), customLoginUrl);
});
+
+ test('auth.loginUrl is sanitized when defined as a relative url', () => {
+ authConfig.login_url = 'custom';
+ authConfig.auth_type = AuthType.HTTP;
+ assert.deepEqual(loginUrl(authConfig), '/custom');
+ });
});
suite('url encoding and decoding tests', () => {