Use config model instead of calling rest api service
Release-Notes: skip
Change-Id: Ica6246fca6bab2e8028523121f7de5075a5bc808
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
index ab65b57..e614ebe 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.ts
@@ -10,9 +10,7 @@
AutocompleteSuggestion,
GrAutocomplete,
} from '../../shared/gr-autocomplete/gr-autocomplete';
-import {getDocsBaseUrl} from '../../../utils/url-util';
import {MergeabilityComputationBehavior} from '../../../constants/constants';
-import {getAppContext} from '../../../services/app-context';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, PropertyValues, html, css} from 'lit';
import {
@@ -24,6 +22,9 @@
import {Shortcut, ShortcutController} from '../../lit/shortcut-controller';
import {query as queryUtil} from '../../../utils/common-util';
import {assertIsDefined} from '../../../utils/common-util';
+import {configModelToken} from '../../../models/config/config-model';
+import {resolve} from '../../../models/dependency';
+import {subscribe} from '../../lit/subscription-controller';
// Possible static search options for auto complete, without negations.
const SEARCH_OPERATORS: ReadonlyArray<string> = [
@@ -152,9 +153,12 @@
@property({type: Object})
accountSuggestions: SuggestionProvider = () => Promise.resolve([]);
- @property({type: Object})
+ @state()
serverConfig?: ServerInfo;
+ @state()
+ mergeabilityComputationBehavior?: MergeabilityComputationBehavior;
+
@property({type: String})
label = '';
@@ -162,22 +166,32 @@
@state() inputVal = '';
// private but used in test
- @state() docBaseUrl: string | null = null;
+ @state() docsBaseUrl: string | null = null;
@state() private query: AutocompleteQuery;
@state() private threshold = 1;
- private searchOperators = new Set(SEARCH_OPERATORS_WITH_NEGATIONS_SET);
-
- private readonly restApiService = getAppContext().restApiService;
-
private readonly shortcuts = new ShortcutController(this);
+ private readonly getConfigModel = resolve(this, configModelToken);
+
constructor() {
super();
this.query = (input: string) => this.getSearchSuggestions(input);
this.shortcuts.addAbstract(Shortcut.SEARCH, () => this.handleSearch());
+ subscribe(
+ this,
+ () => this.getConfigModel().mergeabilityComputationBehavior$,
+ mergeabilityComputationBehavior => {
+ this.mergeabilityComputationBehavior = mergeabilityComputationBehavior;
+ }
+ );
+ subscribe(
+ this,
+ () => this.getConfigModel().docsBaseUrl$,
+ docsBaseUrl => (this.docsBaseUrl = docsBaseUrl)
+ );
}
static override get styles() {
@@ -236,47 +250,34 @@
}
override willUpdate(changedProperties: PropertyValues) {
- if (changedProperties.has('serverConfig')) {
- this.serverConfigChanged();
- }
-
if (changedProperties.has('value')) {
this.valueChanged();
}
}
- private serverConfigChanged() {
- const mergeability =
- this.serverConfig?.change?.mergeability_computation_behavior;
- if (
- mergeability ===
- MergeabilityComputationBehavior.API_REF_UPDATED_AND_CHANGE_REINDEX ||
- mergeability ===
- MergeabilityComputationBehavior.REF_UPDATED_AND_CHANGE_REINDEX
- ) {
- // add 'is:mergeable' to searchOperators
- this.searchOperators.add('is:mergeable');
- this.searchOperators.add('-is:mergeable');
- } else {
- this.searchOperators.delete('is:mergeable');
- this.searchOperators.delete('-is:mergeable');
- }
- if (this.serverConfig) {
- getDocsBaseUrl(this.serverConfig, this.restApiService).then(baseUrl => {
- this.docBaseUrl = baseUrl;
- });
- }
- }
-
private valueChanged() {
this.inputVal = this.value;
}
+ private searchOperators() {
+ const set = new Set(SEARCH_OPERATORS_WITH_NEGATIONS_SET);
+ if (
+ this.mergeabilityComputationBehavior ===
+ MergeabilityComputationBehavior.API_REF_UPDATED_AND_CHANGE_REINDEX ||
+ this.mergeabilityComputationBehavior ===
+ MergeabilityComputationBehavior.REF_UPDATED_AND_CHANGE_REINDEX
+ ) {
+ set.add('is:mergeable');
+ set.add('-is:mergeable');
+ }
+ return set;
+ }
+
// private but used in test
computeHelpDocLink() {
// fallback to gerrit's official doc
let baseUrl =
- this.docBaseUrl ||
+ this.docsBaseUrl ||
'https://gerrit-review.googlesource.com/documentation/';
if (baseUrl.endsWith('/')) {
baseUrl = baseUrl.substring(0, baseUrl.length - 1);
@@ -307,7 +308,7 @@
if (!this.inputVal) return;
const trimmedInput = this.inputVal.trim();
if (trimmedInput) {
- const predefinedOpOnlyQuery = [...this.searchOperators].some(
+ const predefinedOpOnlyQuery = [...this.searchOperators()].some(
op => op.endsWith(':') && op === trimmedInput
);
if (predefinedOpOnlyQuery) {
@@ -364,7 +365,7 @@
default:
return Promise.resolve(
- [...this.searchOperators]
+ [...this.searchOperators()]
.filter(operator => operator.includes(input))
.map(operator => {
return {text: operator};
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts
index 90574a2..db46c22 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.ts
@@ -8,11 +8,9 @@
import {GrSearchBar} from './gr-search-bar';
import '../../../scripts/util';
import {mockPromise, waitUntil} from '../../../test/test-utils';
-import {_testOnly_clearDocsBaseUrlCache} from '../../../utils/url-util';
import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
import {
createChangeConfig,
- createGerritInfo,
createServerInfo,
} from '../../../test/test-data-generators';
import {MergeabilityComputationBehavior} from '../../../constants/constants';
@@ -176,14 +174,8 @@
suite('getSearchSuggestions', () => {
setup(async () => {
element = basicFixture.instantiate();
- element.serverConfig = {
- ...createServerInfo(),
- change: {
- ...createChangeConfig(),
- mergeability_computation_behavior:
- 'NEVER' as MergeabilityComputationBehavior,
- },
- };
+ element.mergeabilityComputationBehavior =
+ MergeabilityComputationBehavior.NEVER;
await element.updateComplete;
});
@@ -268,28 +260,21 @@
suite('doc url', () => {
setup(async () => {
- _testOnly_clearDocsBaseUrlCache();
element = basicFixture.instantiate();
- element.serverConfig = {
- ...createServerInfo(),
- gerrit: {
- ...createGerritInfo(),
- doc_url: 'https://doc.com/',
- },
- };
- await element.updateComplete;
});
- test('compute help doc url with correct path', () => {
- assert.equal(element.docBaseUrl, 'https://doc.com/');
+ test('compute help doc url with correct path', async () => {
+ element.docsBaseUrl = 'https://doc.com/';
+ await element.updateComplete;
assert.equal(
element.computeHelpDocLink(),
'https://doc.com/user-search.html'
);
});
- test('compute help doc url fallback to gerrit url', () => {
- element.docBaseUrl = null;
+ test('compute help doc url fallback to gerrit url', async () => {
+ element.docsBaseUrl = null;
+ await element.updateComplete;
assert.equal(
element.computeHelpDocLink(),
'https://gerrit-review.googlesource.com/documentation/' +
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts
index edee3cb..bd3bd3e 100644
--- a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.ts
@@ -14,7 +14,10 @@
import {AutocompleteSuggestion} from '../../shared/gr-autocomplete/gr-autocomplete';
import {getAppContext} from '../../../services/app-context';
import {LitElement, html} from 'lit';
-import {customElement, property} from 'lit/decorators';
+import {customElement, property, state} from 'lit/decorators';
+import {subscribe} from '../../lit/subscription-controller';
+import {resolve} from '../../../models/dependency';
+import {configModelToken} from '../../../models/config/config-model';
const MAX_AUTOCOMPLETE_RESULTS = 10;
const SELF_EXPRESSION = 'self';
@@ -34,7 +37,7 @@
@property({type: String})
searchQuery = '';
- @property({type: Object})
+ @state()
serverConfig?: ServerInfo;
@property({type: String})
@@ -42,6 +45,19 @@
private readonly restApiService = getAppContext().restApiService;
+ private readonly getConfigModel = resolve(this, configModelToken);
+
+ constructor() {
+ super();
+ subscribe(
+ this,
+ () => this.getConfigModel().serverConfig$,
+ config => {
+ this.serverConfig = config;
+ }
+ );
+ }
+
override render() {
const accountSuggestions: SuggestionProvider = (predicate, expression) =>
this.fetchAccounts(predicate, expression);
@@ -57,7 +73,6 @@
.projectSuggestions=${projectSuggestions}
.groupSuggestions=${groupSuggestions}
.accountSuggestions=${accountSuggestions}
- .serverConfig=${this.serverConfig}
@handle-search=${(e: CustomEvent<SearchBarHandleSearchDetail>) => {
this.handleSearch(e);
}}
diff --git a/polygerrit-ui/app/elements/gr-app-element.ts b/polygerrit-ui/app/elements/gr-app-element.ts
index 381451f..ce2aff2 100644
--- a/polygerrit-ui/app/elements/gr-app-element.ts
+++ b/polygerrit-ui/app/elements/gr-app-element.ts
@@ -29,7 +29,7 @@
import {GerritNav} from './core/gr-navigation/gr-navigation';
import {getAppContext} from '../services/app-context';
import {GrRouter} from './core/gr-router/gr-router';
-import {AccountDetailInfo, ServerInfo} from '../types/common';
+import {AccountDetailInfo} from '../types/common';
import {
constructServerErrorMsg,
GrErrorManager,
@@ -100,8 +100,6 @@
@state() private account?: AccountDetailInfo;
- @state() private serverConfig?: ServerInfo;
-
@state() private version?: string;
@state() private showChangeListView?: boolean;
@@ -225,9 +223,6 @@
this.reporting.reportLifeCycle(LifeCycle.STARTED_AS_GUEST);
}
});
- this.restApiService.getConfig().then(config => {
- this.serverConfig = config;
- });
this.restApiService.getVersion().then(version => {
this.version = version;
this.logWelcome();
@@ -375,8 +370,7 @@
id="errorManager"
.loginUrl=${this.loginUrl}
></gr-error-manager>
- <gr-plugin-host id="plugins" .config=${this.serverConfig}>
- </gr-plugin-host>
+ <gr-plugin-host id="plugins"></gr-plugin-host>
<gr-external-style
id="externalStyleForAll"
name="app-theme"
@@ -395,7 +389,6 @@
id="search"
label="Search for changes"
.searchQuery=${(this.params as AppElementSearchParam)?.query}
- .serverConfig=${this.serverConfig}
>
</gr-smart-search>
`;
diff --git a/polygerrit-ui/app/elements/gr-app_test.ts b/polygerrit-ui/app/elements/gr-app_test.ts
index 06fce4d..2b84344 100644
--- a/polygerrit-ui/app/elements/gr-app_test.ts
+++ b/polygerrit-ui/app/elements/gr-app_test.ts
@@ -16,7 +16,6 @@
createServerInfo,
} from '../test/test-data-generators';
import {GrAppElement} from './gr-app-element';
-import {GrPluginHost} from './plugins/gr-plugin-host/gr-plugin-host';
import {GrRouter} from './core/gr-router/gr-router';
suite('gr-app tests', () => {
@@ -48,12 +47,6 @@
sinon.assert.callOrder(appStartedStub, routerStartStub);
});
- test('passes config to gr-plugin-host', () => {
- const grAppElement = queryAndAssert<GrAppElement>(grApp, '#app-element');
- const pluginHost = queryAndAssert<GrPluginHost>(grAppElement, '#plugins');
- assert.deepEqual(pluginHost.config, config);
- });
-
test('_paramsChanged sets search page', () => {
const grAppElement = queryAndAssert<GrAppElement>(grApp, '#app-element');
diff --git a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.ts b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.ts
index 9b62743..dfdf12c 100644
--- a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.ts
+++ b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.ts
@@ -3,27 +3,37 @@
* Copyright 2017 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
-import {LitElement, PropertyValues} from 'lit';
-import {customElement, property} from 'lit/decorators';
+import {LitElement} from 'lit';
+import {customElement, state} from 'lit/decorators';
import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {ServerInfo} from '../../../types/common';
+import {subscribe} from '../../lit/subscription-controller';
+import {resolve} from '../../../models/dependency';
+import {configModelToken} from '../../../models/config/config-model';
@customElement('gr-plugin-host')
export class GrPluginHost extends LitElement {
- @property({type: Object})
+ @state()
config?: ServerInfo;
- _configChanged(config: ServerInfo) {
- const jsPlugins = config.plugin?.js_resource_paths ?? [];
- const themes: string[] = config.default_theme ? [config.default_theme] : [];
- const instanceId = config.gerrit?.instance_id;
- getPluginLoader().loadPlugins([...themes, ...jsPlugins], instanceId);
- }
+ // visible for testing
+ readonly getConfigModel = resolve(this, configModelToken);
- override updated(changedProperties: PropertyValues<GrPluginHost>) {
- if (changedProperties.has('config') && this.config) {
- this._configChanged(this.config);
- }
+ constructor() {
+ super();
+ subscribe(
+ this,
+ () => this.getConfigModel().serverConfig$,
+ config => {
+ if (!config) return;
+ const jsPlugins = config?.plugin?.js_resource_paths ?? [];
+ const themes: string[] = config?.default_theme
+ ? [config.default_theme]
+ : [];
+ const instanceId = config?.gerrit?.instance_id;
+ getPluginLoader().loadPlugins([...themes, ...jsPlugins], instanceId);
+ }
+ );
}
}
diff --git a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.ts b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.ts
index 945af72..756221e 100644
--- a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.ts
+++ b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.ts
@@ -8,28 +8,32 @@
import {getPluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader';
import {GrPluginHost} from './gr-plugin-host';
import {fixture, html} from '@open-wc/testing-helpers';
-import {ServerInfo} from '../../../api/rest-api';
+import {SinonStub} from 'sinon';
+import {createServerInfo} from '../../../test/test-data-generators';
suite('gr-plugin-host tests', () => {
let element: GrPluginHost;
+ let loadPluginsStub: SinonStub;
setup(async () => {
+ loadPluginsStub = sinon.stub(getPluginLoader(), 'loadPlugins');
element = await fixture<GrPluginHost>(html`
<gr-plugin-host></gr-plugin-host>
`);
+ await element.updateComplete;
sinon.stub(document.body, 'appendChild');
});
test('load plugins should be called', async () => {
- const loadPluginsStub = sinon.stub(getPluginLoader(), 'loadPlugins');
- element.config = {
+ loadPluginsStub.reset();
+ element.getConfigModel().updateServerConfig({
+ ...createServerInfo(),
plugin: {
has_avatars: false,
js_resource_paths: ['plugins/42', 'plugins/foo/bar', 'plugins/baz'],
},
- } as ServerInfo;
- await flush();
+ });
assert.isTrue(loadPluginsStub.calledOnce);
assert.isTrue(
loadPluginsStub.calledWith([
@@ -41,15 +45,15 @@
});
test('theme plugins should be loaded if enabled', async () => {
- const loadPluginsStub = sinon.stub(getPluginLoader(), 'loadPlugins');
- element.config = {
+ loadPluginsStub.reset();
+ element.getConfigModel().updateServerConfig({
+ ...createServerInfo(),
default_theme: 'gerrit-theme.js',
plugin: {
has_avatars: false,
js_resource_paths: ['plugins/42', 'plugins/foo/bar', 'plugins/baz'],
},
- } as ServerInfo;
- await flush();
+ });
assert.isTrue(loadPluginsStub.calledOnce);
assert.isTrue(
loadPluginsStub.calledWith([
@@ -60,4 +64,13 @@
])
);
});
+
+ test('plugins loaded with instanceId ', async () => {
+ loadPluginsStub.reset();
+ const config = createServerInfo();
+ config.gerrit.instance_id = 'test-id';
+ element.getConfigModel().updateServerConfig(config);
+ assert.isTrue(loadPluginsStub.calledOnce);
+ assert.isTrue(loadPluginsStub.calledWith([], 'test-id'));
+ });
});
diff --git a/polygerrit-ui/app/models/config/config-model.ts b/polygerrit-ui/app/models/config/config-model.ts
index dd26182..6861348 100644
--- a/polygerrit-ui/app/models/config/config-model.ts
+++ b/polygerrit-ui/app/models/config/config-model.ts
@@ -12,6 +12,7 @@
import {select} from '../../utils/observable-util';
import {Model} from '../model';
import {define} from '../dependency';
+import {getDocsBaseUrl} from '../../utils/url-util';
export interface ConfigState {
repoConfig?: ConfigInfo;
@@ -35,6 +36,20 @@
configState => configState.serverConfig
);
+ public mergeabilityComputationBehavior$ = select(
+ this.serverConfig$,
+ serverConfig => serverConfig?.change?.mergeability_computation_behavior
+ );
+
+ public docsBaseUrl$ = select(
+ this.serverConfig$.pipe(
+ switchMap(serverConfig =>
+ from(getDocsBaseUrl(serverConfig, this.restApiService))
+ )
+ ),
+ url => url
+ );
+
private subscriptions: Subscription[];
constructor(
@@ -59,11 +74,12 @@
];
}
- updateRepoConfig(repoConfig?: ConfigInfo) {
+ private updateRepoConfig(repoConfig?: ConfigInfo) {
const current = this.subject$.getValue();
this.subject$.next({...current, repoConfig});
}
+ // visible for testing
updateServerConfig(serverConfig?: ServerInfo) {
const current = this.subject$.getValue();
this.subject$.next({...current, serverConfig});