Move generating of search URLs into search.ts

We will follow this pattern also in follow-up changes:
* gr-navigation is obsolete at some point.
* router-util methods are moved to view state files.

Release-Notes: skip
Google-Bug-Id: b/244279450
Change-Id: Iabb10c69ffc159baae1062e10ee55dc8fa4ae0a7
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.ts b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.ts
index 254bc3a..f0bd520 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.ts
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.ts
@@ -7,7 +7,6 @@
 import '../../shared/gr-list-view/gr-list-view';
 import '../../shared/gr-overlay/gr-overlay';
 import '../gr-create-repo-dialog/gr-create-repo-dialog';
-import {GerritNav} from '../../core/gr-navigation/gr-navigation';
 import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
 import {
   RepoName,
@@ -24,6 +23,7 @@
 import {LitElement, PropertyValues, css, html} from 'lit';
 import {customElement, property, query, state} from 'lit/decorators.js';
 import {AdminViewState} from '../../../models/views/admin';
+import {createSearchUrl} from '../../../models/views/search';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -215,7 +215,7 @@
   }
 
   private computeChangesLink(name: string) {
-    return GerritNav.getUrlForProjectChanges(name as RepoName);
+    return createSearchUrl({project: name as RepoName});
   }
 
   private async getCreateRepoCapability() {
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.ts b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.ts
index 07f3225..29d378d 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.ts
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.ts
@@ -100,7 +100,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -120,7 +120,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -140,7 +140,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -160,7 +160,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -180,7 +180,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -200,7 +200,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -220,7 +220,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -240,7 +240,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -260,7 +260,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -280,7 +280,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -300,7 +300,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -320,7 +320,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -340,7 +340,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -360,7 +360,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -380,7 +380,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -400,7 +400,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -420,7 +420,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -440,7 +440,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -460,7 +460,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -480,7 +480,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -500,7 +500,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -520,7 +520,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -540,7 +540,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -560,7 +560,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
@@ -580,7 +580,7 @@
                     </a>
                   </td>
                   <td class="changesLink">
-                    <a href=""> view all </a>
+                    <a href="/q/project:test"> view all </a>
                   </td>
                   <td class="readOnly"></td>
                   <td class="description"></td>
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.ts b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.ts
index 1896108..8e69806 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.ts
+++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.ts
@@ -11,7 +11,6 @@
 import '../../shared/gr-select/gr-select';
 import '../../shared/gr-textarea/gr-textarea';
 import '../gr-repo-plugin-config/gr-repo-plugin-config';
-import {GerritNav} from '../../core/gr-navigation/gr-navigation';
 import {
   ConfigInfo,
   RepoName,
@@ -40,6 +39,7 @@
 import {LitElement, PropertyValues, css, html} from 'lit';
 import {customElement, property, state} from 'lit/decorators.js';
 import {subscribe} from '../../lit/subscription-controller';
+import {createSearchUrl} from '../../../models/views/search';
 
 const STATES = {
   active: {value: ProjectState.ACTIVE, label: 'Active'},
@@ -1098,7 +1098,7 @@
 
   private computeChangesUrl(name?: RepoName) {
     if (!name) return '';
-    return GerritNav.getUrlForProjectChanges(name);
+    return createSearchUrl({project: name});
   }
 
   // private but used in test
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.ts
index d50625d..effdf72 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.ts
@@ -42,6 +42,7 @@
 import {resolve} from '../../../models/dependency';
 import {subscribe} from '../../lit/subscription-controller';
 import {classMap} from 'lit/directives/class-map.js';
+import {createSearchUrl} from '../../../models/views/search';
 
 enum ChangeSize {
   XS = 10,
@@ -659,21 +660,20 @@
 
   private computeRepoUrl() {
     if (!this.change) return '';
-    return GerritNav.getUrlForProjectChanges(this.change.project, true);
+    return createSearchUrl({project: this.change.project, statuses: ['open']});
   }
 
   private computeRepoBranchURL() {
     if (!this.change) return '';
-    return GerritNav.getUrlForBranch(
-      this.change.branch,
-      this.change.project,
-      undefined
-    );
+    return createSearchUrl({
+      branch: this.change.branch,
+      project: this.change.project,
+    });
   }
 
   private computeTopicURL() {
     if (!this.change?.topic) return '';
-    return GerritNav.getUrlForTopic(this.change.topic);
+    return createSearchUrl({topic: this.change.topic});
   }
 
   private toggleCheckbox() {
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.ts
index b6d0f07..56cccb3 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.ts
@@ -308,28 +308,6 @@
     assert.equal(element.computeChangeSize(), 'XL');
   });
 
-  test('change params passed to gr-navigation', async () => {
-    const navStub = sinon.stub(GerritNav);
-    element.change = change;
-    element.usp = 'dashboard';
-    await element.updateComplete;
-
-    assert.deepEqual(navStub.getUrlForChange.lastCall.args, [
-      change,
-      {usp: 'dashboard'},
-    ]);
-    assert.deepEqual(navStub.getUrlForProjectChanges.lastCall.args, [
-      change.project,
-      true,
-    ]);
-    assert.deepEqual(navStub.getUrlForBranch.lastCall.args, [
-      change.branch,
-      change.project,
-      undefined,
-    ]);
-    assert.deepEqual(navStub.getUrlForTopic.lastCall.args, [change.topic!]);
-  });
-
   test('clicking item navigates to change', async () => {
     const navStub = sinon.stub(GerritNav);
 
@@ -378,9 +356,17 @@
         ></gr-account-label>
         <div></div>
         <span></span>
-        <a class="fullRepo" href=""> test-project </a>
-        <a class="truncatedRepo" href="" title="test-project"> test-project </a>
-        <a href=""> test-branch </a>
+        <a class="fullRepo" href="/q/project:test-project+status:open">
+          test-project
+        </a>
+        <a
+          class="truncatedRepo"
+          href="/q/project:test-project+status:open"
+          title="test-project"
+        >
+          test-project
+        </a>
+        <a href="/q/project:test-project+branch:test-branch"> test-branch </a>
         <gr-date-formatter withtooltip=""></gr-date-formatter>
         <gr-date-formatter withtooltip=""></gr-date-formatter>
         <gr-date-formatter
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-section/gr-change-list-section.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-section/gr-change-list-section.ts
index 5bdee3e..04f9f88 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-section/gr-change-list-section.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-section/gr-change-list-section.ts
@@ -7,11 +7,7 @@
 import {customElement, property, state} from 'lit/decorators.js';
 import {ChangeListSection} from '../gr-change-list/gr-change-list';
 import '../gr-change-list-action-bar/gr-change-list-action-bar';
-import {
-  CLOSED,
-  YOUR_TURN,
-  GerritNav,
-} from '../../core/gr-navigation/gr-navigation';
+import {CLOSED, YOUR_TURN} from '../../core/gr-navigation/gr-navigation';
 import {getAppContext} from '../../../services/app-context';
 import {ChangeInfo, ServerInfo, AccountInfo} from '../../../api/rest-api';
 import {changeListStyles} from '../../../styles/gr-change-list-styles';
@@ -26,6 +22,7 @@
 } from '../../../models/bulk-actions/bulk-actions-model';
 import {subscribe} from '../../lit/subscription-controller';
 import {classMap} from 'lit/directives/class-map.js';
+import {createSearchUrl} from '../../../models/views/search';
 
 const NUMBER_FIXED_COLUMNS = 4;
 const LABEL_PREFIX_INVALID_PROLOG = 'Invalid-Prolog-Rules-Label-Name--';
@@ -381,8 +378,8 @@
   }
 
   private sectionHref(query?: string) {
-    if (!query) return;
-    return GerritNav.getUrlForSearchQuery(this.processQuery(query));
+    if (!query) return '';
+    return createSearchUrl({query: this.processQuery(query)});
   }
 
   // private but used in test
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts
index 0b396f0..66569bb 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.ts
@@ -25,6 +25,7 @@
 import {LitElement, PropertyValues, html, css} from 'lit';
 import {customElement, property, state, query} from 'lit/decorators.js';
 import {ValueChangedEvent} from '../../../types/events';
+import {createSearchUrl} from '../../../models/views/search';
 
 const LOOKUP_QUERY_PATTERNS: RegExp[] = [
   /^\s*i?[0-9a-f]{7,40}\s*$/i, // CHANGE_ID
@@ -329,7 +330,7 @@
     const offset = this.offset ?? 0;
     const limit = this.limitFor(this.query, this.changesPerPage);
     const newOffset = Math.max(0, offset + limit * direction);
-    return GerritNav.getUrlForSearchQuery(this.query, newOffset);
+    return createSearchUrl({query: this.query, offset: newOffset});
   }
 
   // private but used in test
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.ts
index 3138f2a..e360899 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.ts
@@ -59,7 +59,7 @@
           <gr-change-list> </gr-change-list>
           <nav>
             Page
-            <a href="" id="prevArrow">
+            <a href="/q/" id="prevArrow">
               <gr-icon icon="chevron_left" aria-label="Older"></gr-icon>
             </a>
           </nav>
@@ -127,25 +127,19 @@
   });
 
   test('computeNavLink', () => {
-    const getUrlStub = sinon
-      .stub(GerritNav, 'getUrlForSearchQuery')
-      .returns('');
     element.query = 'status:open';
     element.offset = 0;
     element.changesPerPage = 5;
     let direction = 1;
 
-    element.computeNavLink(direction);
-    assert.equal(getUrlStub.lastCall.args[1], 5);
+    assert.equal(element.computeNavLink(direction), '/q/status:open,5');
 
     direction = -1;
-    element.computeNavLink(direction);
-    assert.equal(getUrlStub.lastCall.args[1], 0);
+    assert.equal(element.computeNavLink(direction), '/q/status:open');
 
     element.offset = 5;
     direction = 1;
-    element.computeNavLink(direction);
-    assert.equal(getUrlStub.lastCall.args[1], 10);
+    assert.equal(element.computeNavLink(direction), '/q/status:open,10');
   });
 
   test('prevArrow', async () => {
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.ts b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.ts
index 14867a7..88bf943 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.ts
@@ -52,6 +52,7 @@
 import {Shortcut} from '../../../services/shortcuts/shortcuts-config';
 import {ShortcutController} from '../../lit/shortcut-controller';
 import {DashboardViewState} from '../../../models/views/dashboard';
+import {createSearchUrl} from '../../../models/views/search';
 
 const PROJECT_PLACEHOLDER_PATTERN = /\${project}/g;
 
@@ -590,7 +591,7 @@
   }
 
   private computeDraftsLink() {
-    return GerritNav.getUrlForSearchQuery('has:draft -is:open');
+    return createSearchUrl({query: 'has:draft -is:open'});
   }
 
   private handleCreateChangeTap() {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
index 9878c99..b434699 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.ts
@@ -79,6 +79,7 @@
 import {changeMetadataStyles} from '../../../styles/gr-change-metadata-shared-styles';
 import {when} from 'lit/directives/when.js';
 import {ifDefined} from 'lit/directives/if-defined.js';
+import {createSearchUrl} from '../../../models/views/search';
 
 const HASHTAG_ADD_MESSAGE = 'Add Hashtag';
 
@@ -572,7 +573,7 @@
           () => html` <gr-linked-chip
             .text=${this.change?.topic}
             limit="40"
-            href=${GerritNav.getUrlForTopic(this.change!.topic!)}
+            href=${createSearchUrl({topic: this.change!.topic!})}
             ?removable=${!this.topicReadOnly}
             @remove=${this.handleTopicRemoved}
           ></gr-linked-chip>`
@@ -908,18 +909,19 @@
 
   private computeProjectUrl(project?: RepoName) {
     if (!project) return '';
-    return GerritNav.getUrlForProjectChanges(project);
+    return createSearchUrl({project});
   }
 
   private computeBranchUrl(project?: RepoName, branch?: BranchName) {
     if (!project || !branch || !this.change || !this.change.status) return '';
-    return GerritNav.getUrlForBranch(
+    return createSearchUrl({
       branch,
       project,
-      this.change.status === ChangeStatus.NEW
-        ? 'open'
-        : this.change.status.toLowerCase()
-    );
+      statuses:
+        this.change.status === ChangeStatus.NEW
+          ? ['open']
+          : [this.change.status.toLowerCase()],
+    });
   }
 
   private computeCherryPickOfUrl(
@@ -934,7 +936,7 @@
   }
 
   private computeHashtagUrl(hashtag: Hashtag) {
-    return GerritNav.getUrlForHashtag(hashtag);
+    return createSearchUrl({hashtag, statuses: ['open', 'merged']});
   }
 
   private async handleTopicRemoved(e: CustomEvent) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
index df778c2..7485a6d 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.ts
@@ -169,11 +169,11 @@
             Repo | Branch
           </span>
           <span class="value">
-            <a href="">
+            <a href="/q/project:test-project">
               test-project
             </a>
             |
-            <a href="">
+            <a href="/q/project:test-project+branch:test-branch+status:open">
               test-branch
             </a>
           </span>
@@ -787,7 +787,6 @@
     test('topic read only hides delete button', async () => {
       element.account = createAccountDetailWithId();
       element.change = change;
-      sinon.stub(GerritNav, 'getUrlForTopic').returns('/q/topic:test');
       await element.updateComplete;
       const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
       const button = queryAndAssert<GrButton>(chip, 'gr-button');
@@ -798,7 +797,6 @@
       element.account = createAccountDetailWithId();
       change.actions!.topic!.enabled = true;
       element.change = change;
-      sinon.stub(GerritNav, 'getUrlForTopic').returns('/q/topic:test');
       await element.updateComplete;
       const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
       const button = queryAndAssert<GrButton>(chip, 'gr-button');
@@ -853,9 +851,6 @@
     test('hashtag read only hides delete button', async () => {
       element.account = createAccountDetailWithId();
       element.change = change;
-      sinon
-        .stub(GerritNav, 'getUrlForHashtag')
-        .returns('/q/hashtag:test+(status:open%20OR%20status:merged)');
       await element.updateComplete;
       assert.isTrue(element.mutable, 'Mutable');
       assert.isFalse(
@@ -873,9 +868,6 @@
       element.account = createAccountDetailWithId();
       change.actions!.hashtags!.enabled = true;
       element.change = change;
-      sinon
-        .stub(GerritNav, 'getUrlForHashtag')
-        .returns('/q/hashtag:test+(status:open%20OR%20status:merged)');
       await element.updateComplete;
       const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
       const button = queryAndAssert<GrButton>(chip, 'gr-button');
@@ -929,7 +921,6 @@
       );
       const alertStub = sinon.stub();
       element.addEventListener(EventType.SHOW_ALERT, alertStub);
-      sinon.stub(GerritNav, 'getUrlForTopic').returns('/q/topic:the+new+topic');
       await element.updateComplete;
       const chip = queryAndAssert<GrLinkedChip>(element, 'gr-linked-chip');
       const remove = queryAndAssert<GrButton>(chip, '#remove');
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.ts b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.ts
index 9ad0e8e..c6019d0 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.ts
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.ts
@@ -12,6 +12,7 @@
 import {subscribe} from '../../lit/subscription-controller';
 import {resolve} from '../../../models/dependency';
 import {configModelToken} from '../../../models/config/config-model';
+import {createSearchUrl} from '../../../models/views/search';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -129,7 +130,7 @@
     if (webLink) return webLink;
     const hash = this._computeShortHash(change, commitInfo, serverConfig);
     if (hash === undefined) return '';
-    return GerritNav.getUrlForSearchQuery(hash);
+    return createSearchUrl({query: hash});
   }
 
   _computeShortHash(
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.ts b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.ts
index 75fb6d7..ea4b202 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.ts
@@ -34,7 +34,7 @@
       element,
       /* HTML */ `
         <div class="container">
-          <a href="" rel="noopener" target="_blank"> </a>
+          <a href="/q/" rel="noopener" target="_blank"> </a>
           <gr-copy-clipboard hastooltip="" hideinput=""> </gr-copy-clipboard>
         </div>
       `
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts
index 2b74e97..adc625a 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts
@@ -5,7 +5,6 @@
  */
 import {
   BasePatchSetNum,
-  BranchName,
   ChangeConfigInfo,
   ChangeInfo,
   CommentLinks,
@@ -13,14 +12,12 @@
   DashboardId,
   EDIT,
   GroupId,
-  Hashtag,
   NumericChangeId,
   PARENT,
   PatchSetNum,
   RepoName,
   RevisionPatchSetNum,
   ServerInfo,
-  TopicName,
   UrlEncodedCommentId,
 } from '../../../types/common';
 import {GerritView} from '../../../services/router/router-model';
@@ -31,6 +28,7 @@
 } from '../../../utils/router-util';
 import {RepoDetailView} from '../../../models/views/repo';
 import {GroupDetailView} from '../../../models/views/group';
+import {createSearchUrl} from '../../../models/views/search';
 
 // Navigation parameters object format:
 //
@@ -296,75 +294,18 @@
     return this._generateUrl(params);
   },
 
-  getUrlForSearchQuery(query: string, offset?: number) {
-    return this._getUrlFor({
-      view: GerritView.SEARCH,
-      query,
-      offset,
-    });
-  },
-
-  /**
-   * @param openOnly When true, only search open changes in the project.
-   */
-  getUrlForProjectChanges(project: RepoName, openOnly?: boolean) {
-    return this._getUrlFor({
-      view: GerritView.SEARCH,
-      project,
-      statuses: openOnly ? ['open'] : [],
-    });
-  },
-
-  /**
-   * @param status The status to search.
-   */
-  getUrlForBranch(branch: BranchName, project: RepoName, status?: string) {
-    return this._getUrlFor({
-      view: GerritView.SEARCH,
-      branch,
-      project,
-      statuses: status ? [status] : undefined,
-    });
-  },
-
-  /**
-   * @param topic The name of the topic.
-   */
-  getUrlForTopic(topic: TopicName) {
-    return this._getUrlFor({
-      view: GerritView.SEARCH,
-      topic,
-    });
-  },
-
-  /**
-   * @param hashtag The name of the hashtag.
-   */
-  getUrlForHashtag(hashtag: Hashtag) {
-    return this._getUrlFor({
-      view: GerritView.SEARCH,
-      hashtag,
-      statuses: ['open', 'merged'],
-    });
-  },
-
   /**
    * Navigate to a search for changes with the given status.
    */
   navigateToStatusSearch(status: string) {
-    this._navigate(
-      this._getUrlFor({
-        view: GerritView.SEARCH,
-        statuses: [status],
-      })
-    );
+    this._navigate(createSearchUrl({statuses: [status]}));
   },
 
   /**
    * Navigate to a search query
    */
   navigateToSearchQuery(query: string, offset?: number) {
-    this._navigate(this.getUrlForSearchQuery(query, offset));
+    this._navigate(createSearchUrl({query, offset}));
   },
 
   /**
@@ -585,16 +526,6 @@
   },
 
   /**
-   * @param owner The name of the owner.
-   */
-  getUrlForOwner(owner: string) {
-    return this._getUrlFor({
-      view: GerritView.SEARCH,
-      owner,
-    });
-  },
-
-  /**
    * @param user The name of the user.
    */
   getUrlForUserDashboard(user: string) {
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
index 2985e62..35b8c74 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.ts
@@ -21,7 +21,7 @@
 import {classMap} from 'lit/directives/class-map.js';
 import {getRemovedByIconClickReason} from '../../../utils/attention-set-util';
 import {ifDefined} from 'lit/directives/if-defined.js';
-import {GerritNav} from '../../core/gr-navigation/gr-navigation';
+import {createSearchUrl} from '../../../models/views/search';
 
 @customElement('gr-account-label')
 export class GrAccountLabel extends LitElement {
@@ -299,12 +299,13 @@
 
   private maybeRenderLink(span: TemplateResult) {
     if (!this.clickable || !this.account) return span;
-    const url = GerritNav.getUrlForOwner(
-      this.account.email ||
+    const url = createSearchUrl({
+      owner:
+        this.account.email ||
         this.account.username ||
         this.account.name ||
-        `${this.account._account_id}`
-    );
+        `${this.account._account_id}`,
+    });
     if (!url) return span;
     return html`<a class="ownerLink" href=${url} tabindex="-1">${span}</a>`;
   }
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts
index 332f2da..e7c0536 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.ts
@@ -13,7 +13,6 @@
   waitEventLoop,
 } from '../../../test/test-utils';
 import {GrAccountLabel} from './gr-account-label';
-import {GerritNav} from '../../core/gr-navigation/gr-navigation';
 import {AccountDetailInfo, ServerInfo} from '../../../types/common';
 import {
   createAccountDetailWithIdNameAndEmail,
@@ -32,7 +31,6 @@
   };
 
   setup(async () => {
-    sinon.stub(GerritNav, 'getUrlForOwner').callsFake(() => 'test');
     stubRestApi('getAccount').resolves(kermit);
     stubRestApi('getLoggedIn').resolves(false);
     stubRestApi('getConfig').resolves({
@@ -90,7 +88,7 @@
       /* HTML */ `
         <div class="container">
           <gr-hovercard-account for="hovercardTarget"></gr-hovercard-account>
-          <a class="ownerLink" href="test" tabindex="-1">
+          <a class="ownerLink" href="/q/owner:user-31%2540" tabindex="-1">
             <span class="hovercardTargetWrapper">
               <gr-avatar hidden="" imagesize="32"> </gr-avatar>
               <span
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts
index ab02f5f..3887ee5b 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.ts
@@ -6,15 +6,13 @@
 import '../gr-icon/gr-icon';
 import '../gr-tooltip-content/gr-tooltip-content';
 import '../../../styles/shared-styles';
-import {
-  GeneratedWebLink,
-  GerritNav,
-} from '../../core/gr-navigation/gr-navigation';
+import {GeneratedWebLink} from '../../core/gr-navigation/gr-navigation';
 import {ChangeInfo} from '../../../types/common';
 import {ParsedChangeInfo} from '../../../types/types';
 import {sharedStyles} from '../../../styles/shared-styles';
 import {LitElement, PropertyValues, html, css} from 'lit';
 import {customElement, property, state} from 'lit/decorators.js';
+import {createSearchUrl} from '../../../models/views/search';
 
 export enum ChangeStates {
   ABANDONED = 'Abandoned',
@@ -203,7 +201,7 @@
   // private but used in test
   getStatusLink(): string {
     if (this.revertedChange) {
-      return GerritNav.getUrlForSearchQuery(`${this.revertedChange._number}`);
+      return createSearchUrl({query: `${this.revertedChange._number}`});
     }
     if (
       this.status === ChangeStates.MERGE_CONFLICT &&
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.ts b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.ts
index 4cf7e6e..4a046e7 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.ts
@@ -4,10 +4,12 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../../../test/common-test-setup';
-import {createChange} from '../../../test/test-data-generators';
+import {
+  createChange,
+  TEST_NUMERIC_CHANGE_ID,
+} from '../../../test/test-data-generators';
 import './gr-change-status';
 import {ChangeStates, GrChangeStatus, WIP_TOOLTIP} from './gr-change-status';
-import {GerritNav} from '../../core/gr-navigation/gr-navigation';
 import {MERGE_CONFLICT_TOOLTIP} from './gr-change-status';
 import {fixture, html, assert} from '@open-wc/testing';
 import {queryAndAssert} from '../../../test/test-utils';
@@ -125,16 +127,14 @@
   });
 
   test('reverted change', () => {
-    const url = 'http://google.com';
     const status = ChangeStates.REVERT_SUBMITTED;
     const revertedChange = createChange();
-    sinon.stub(GerritNav, 'getUrlForSearchQuery').returns(url);
 
     element.revertedChange = revertedChange;
     element.resolveWeblinks = [];
     element.status = status;
     assert.isTrue(element.hasStatusLink());
-    assert.equal(element.getStatusLink(), url);
+    assert.equal(element.getStatusLink(), `/q/${TEST_NUMERIC_CHANGE_ID}`);
   });
 
   test('private', async () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts
index 9885b58..1242235 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account.ts
@@ -43,6 +43,7 @@
 import {subscribe} from '../../lit/subscription-controller';
 import {resolve} from '../../../models/dependency';
 import {configModelToken} from '../../../models/config/config-model';
+import {createSearchUrl} from '../../../models/views/search';
 
 // This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
 const base = HovercardMixin(LitElement);
@@ -361,12 +362,13 @@
 
   computeOwnerChangesLink() {
     if (!this.account) return undefined;
-    return GerritNav.getUrlForOwner(
-      this.account.email ||
+    return createSearchUrl({
+      owner:
+        this.account.email ||
         this.account.username ||
         this.account.name ||
-        `${this.account._account_id}`
-    );
+        `${this.account._account_id}`,
+    });
   }
 
   computeOwnerDashboardLink() {
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts
index 42ec66c..bafb679 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.ts
@@ -88,7 +88,9 @@
           </div>
           <div class="links">
             <gr-icon icon="link" class="linkIcon"></gr-icon>
-            <a href="">Changes</a>·<a href="">Dashboard</a>
+            <a href="/q/owner:kermit%2540gmail.com">Changes</a>·<a href=""
+              >Dashboard</a
+            >
           </div>
         </div>
       `
@@ -123,7 +125,7 @@
           </div>
           <div class="links">
             <gr-icon class="linkIcon" icon="link"> </gr-icon>
-            <a href=""> Changes </a>
+            <a href="/q/owner:kermit%2540gmail.com"> Changes </a>
             ·
             <a href=""> Dashboard </a>
           </div>
diff --git a/polygerrit-ui/app/models/views/search.ts b/polygerrit-ui/app/models/views/search.ts
index f18d2df..d932b39 100644
--- a/polygerrit-ui/app/models/views/search.ts
+++ b/polygerrit-ui/app/models/views/search.ts
@@ -3,7 +3,10 @@
  * Copyright 2022 Google LLC
  * SPDX-License-Identifier: Apache-2.0
  */
+import {RepoName, BranchName, TopicName} from '../../api/rest-api';
 import {GerritView} from '../../services/router/router-model';
+import {addQuotesWhen} from '../../utils/string-util';
+import {encodeURL} from '../../utils/url-util';
 import {Model} from '../model';
 import {ViewState} from './base';
 
@@ -13,6 +16,72 @@
   offset?: string;
 }
 
+export interface SearchUrlOptions {
+  query?: string;
+  offset?: number;
+  project?: RepoName;
+  branch?: BranchName;
+  topic?: TopicName;
+  statuses?: string[];
+  hashtag?: string;
+  owner?: string;
+}
+
+export function createSearchUrl(params: SearchUrlOptions): string {
+  let offsetExpr = '';
+  if (params.offset && params.offset > 0) {
+    offsetExpr = `,${params.offset}`;
+  }
+
+  if (params.query) {
+    return '/q/' + encodeURL(params.query, true) + offsetExpr;
+  }
+
+  const operators: string[] = [];
+  if (params.owner) {
+    operators.push('owner:' + encodeURL(params.owner, false));
+  }
+  if (params.project) {
+    operators.push('project:' + encodeURL(params.project, false));
+  }
+  if (params.branch) {
+    operators.push('branch:' + encodeURL(params.branch, false));
+  }
+  if (params.topic) {
+    operators.push(
+      'topic:' +
+        addQuotesWhen(
+          encodeURL(params.topic, false),
+          /[\s:]/.test(params.topic)
+        )
+    );
+  }
+  if (params.hashtag) {
+    operators.push(
+      'hashtag:' +
+        addQuotesWhen(
+          encodeURL(params.hashtag.toLowerCase(), false),
+          /[\s:]/.test(params.hashtag)
+        )
+    );
+  }
+  if (params.statuses) {
+    if (params.statuses.length === 1) {
+      operators.push('status:' + encodeURL(params.statuses[0], false));
+    } else if (params.statuses.length > 1) {
+      operators.push(
+        '(' +
+          params.statuses
+            .map(s => `status:${encodeURL(s, false)}`)
+            .join(' OR ') +
+          ')'
+      );
+    }
+  }
+
+  return '/q/' + operators.join('+') + offsetExpr;
+}
+
 const DEFAULT_STATE: SearchViewState = {
   view: GerritView.SEARCH,
 };
diff --git a/polygerrit-ui/app/models/views/search_test.ts b/polygerrit-ui/app/models/views/search_test.ts
new file mode 100644
index 0000000..138ce1e
--- /dev/null
+++ b/polygerrit-ui/app/models/views/search_test.ts
@@ -0,0 +1,56 @@
+/**
+ * @license
+ * Copyright 2022 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import {assert} from '@open-wc/testing';
+import {BranchName, RepoName, TopicName} from '../../api/rest-api';
+import '../../test/common-test-setup';
+import {createSearchUrl, SearchUrlOptions} from './search';
+
+suite('search view state tests', () => {
+  test('createSearchUrl', () => {
+    let options: SearchUrlOptions = {
+      owner: 'a%b',
+      project: 'c%d' as RepoName,
+      branch: 'e%f' as BranchName,
+      topic: 'g%h' as TopicName,
+      statuses: ['op%en'],
+    };
+    assert.equal(
+      createSearchUrl(options),
+      '/q/owner:a%2525b+project:c%2525d+branch:e%2525f+' +
+        'topic:g%2525h+status:op%2525en'
+    );
+
+    options.offset = 100;
+    assert.equal(
+      createSearchUrl(options),
+      '/q/owner:a%2525b+project:c%2525d+branch:e%2525f+' +
+        'topic:g%2525h+status:op%2525en,100'
+    );
+    delete options.offset;
+
+    // The presence of the query param overrides other options.
+    options.query = 'foo$bar';
+    assert.equal(createSearchUrl(options), '/q/foo%2524bar');
+
+    options.offset = 100;
+    assert.equal(createSearchUrl(options), '/q/foo%2524bar,100');
+
+    options = {statuses: ['a', 'b', 'c']};
+    assert.equal(
+      createSearchUrl(options),
+      '/q/(status:a OR status:b OR status:c)'
+    );
+
+    options = {topic: 'test' as TopicName};
+    assert.equal(createSearchUrl(options), '/q/topic:test');
+
+    options = {topic: 'test test' as TopicName};
+    assert.equal(createSearchUrl(options), '/q/topic:"test+test"');
+
+    options = {topic: 'test:test' as TopicName};
+    assert.equal(createSearchUrl(options), '/q/topic:"test:test"');
+  });
+});
diff --git a/polygerrit-ui/app/utils/router-util.ts b/polygerrit-ui/app/utils/router-util.ts
index 4c1003f..9118033 100644
--- a/polygerrit-ui/app/utils/router-util.ts
+++ b/polygerrit-ui/app/utils/router-util.ts
@@ -5,20 +5,17 @@
  */
 import {
   BasePatchSetNum,
-  BranchName,
   ChangeInfo,
   NumericChangeId,
   PARENT,
   RepoName,
   RevisionPatchSetNum,
-  TopicName,
   UrlEncodedCommentId,
 } from '../types/common';
 import {PatchRangeParams} from '../elements/core/gr-router/gr-router';
 import {encodeURL, getBaseUrl} from './url-util';
 import {assertNever} from './common-util';
 import {GerritView} from '../services/router/router-model';
-import {addQuotesWhen} from './string-util';
 import {AttemptChoice} from '../models/checks/checks-util';
 import {GroupDetailView, GroupViewState} from '../models/views/group';
 import {DashboardViewState} from '../models/views/dashboard';
@@ -34,19 +31,6 @@
   results?: ChangeInfo[];
 }
 
-export interface GenerateUrlSearchViewParameters {
-  view: GerritView.SEARCH;
-  query?: string;
-  offset?: number;
-  project?: RepoName;
-  branch?: BranchName;
-  topic?: TopicName;
-  // TODO(TS): Define more precise type (enum?)
-  statuses?: string[];
-  hashtag?: string;
-  owner?: string;
-}
-
 export interface GenerateUrlChangeViewParameters {
   view: GerritView.CHANGE;
   // TODO(TS): NumericChangeId - not sure about it, may be it can be removed
@@ -91,7 +75,6 @@
 }
 
 export type GenerateUrlParameters =
-  | GenerateUrlSearchViewParameters
   | GenerateUrlChangeViewParameters
   | RepoViewState
   | DashboardViewState
@@ -130,9 +113,7 @@
   const base = getBaseUrl();
   let url = '';
 
-  if (params.view === GerritView.SEARCH) {
-    url = generateSearchUrl(params);
-  } else if (params.view === GerritView.CHANGE) {
+  if (params.view === GerritView.CHANGE) {
     url = generateChangeUrl(params);
   } else if (params.view === GerritView.DASHBOARD) {
     url = generateDashboardUrl(params);
@@ -242,61 +223,6 @@
   }
 }
 
-function generateSearchUrl(params: GenerateUrlSearchViewParameters) {
-  let offsetExpr = '';
-  if (params.offset && params.offset > 0) {
-    offsetExpr = `,${params.offset}`;
-  }
-
-  if (params.query) {
-    return '/q/' + encodeURL(params.query, true) + offsetExpr;
-  }
-
-  const operators: string[] = [];
-  if (params.owner) {
-    operators.push('owner:' + encodeURL(params.owner, false));
-  }
-  if (params.project) {
-    operators.push('project:' + encodeURL(params.project, false));
-  }
-  if (params.branch) {
-    operators.push('branch:' + encodeURL(params.branch, false));
-  }
-  if (params.topic) {
-    operators.push(
-      'topic:' +
-        addQuotesWhen(
-          encodeURL(params.topic, false),
-          /[\s:]/.test(params.topic)
-        )
-    );
-  }
-  if (params.hashtag) {
-    operators.push(
-      'hashtag:' +
-        addQuotesWhen(
-          encodeURL(params.hashtag.toLowerCase(), false),
-          /[\s:]/.test(params.hashtag)
-        )
-    );
-  }
-  if (params.statuses) {
-    if (params.statuses.length === 1) {
-      operators.push('status:' + encodeURL(params.statuses[0], false));
-    } else if (params.statuses.length > 1) {
-      operators.push(
-        '(' +
-          params.statuses
-            .map(s => `status:${encodeURL(s, false)}`)
-            .join(' OR ') +
-          ')'
-      );
-    }
-  }
-
-  return '/q/' + operators.join('+') + offsetExpr;
-}
-
 function generateDiffOrEditUrl(
   params: GenerateUrlDiffViewParameters | GenerateUrlEditViewParameters
 ) {
diff --git a/polygerrit-ui/app/utils/router-util_test.ts b/polygerrit-ui/app/utils/router-util_test.ts
index 161725c..89f6f10 100644
--- a/polygerrit-ui/app/utils/router-util_test.ts
+++ b/polygerrit-ui/app/utils/router-util_test.ts
@@ -6,8 +6,6 @@
 import {assert} from '@open-wc/testing';
 import {
   RepoName,
-  BranchName,
-  TopicName,
   NumericChangeId,
   RevisionPatchSetNum,
   BasePatchSetNum,
@@ -25,68 +23,11 @@
   GenerateUrlChangeViewParameters,
   GenerateUrlDiffViewParameters,
   GenerateUrlEditViewParameters,
-  GenerateUrlSearchViewParameters,
   TEST_ONLY,
 } from './router-util';
 
 suite('router-util tests', () => {
   suite('generateUrl', () => {
-    test('search', () => {
-      let params: GenerateUrlSearchViewParameters = {
-        view: GerritView.SEARCH,
-        owner: 'a%b',
-        project: 'c%d' as RepoName,
-        branch: 'e%f' as BranchName,
-        topic: 'g%h' as TopicName,
-        statuses: ['op%en'],
-      };
-      assert.equal(
-        generateUrl(params),
-        '/q/owner:a%2525b+project:c%2525d+branch:e%2525f+' +
-          'topic:g%2525h+status:op%2525en'
-      );
-
-      params.offset = 100;
-      assert.equal(
-        generateUrl(params),
-        '/q/owner:a%2525b+project:c%2525d+branch:e%2525f+' +
-          'topic:g%2525h+status:op%2525en,100'
-      );
-      delete params.offset;
-
-      // The presence of the query param overrides other params.
-      params.query = 'foo$bar';
-      assert.equal(generateUrl(params), '/q/foo%2524bar');
-
-      params.offset = 100;
-      assert.equal(generateUrl(params), '/q/foo%2524bar,100');
-
-      params = {
-        view: GerritView.SEARCH,
-        statuses: ['a', 'b', 'c'],
-      };
-      assert.equal(
-        generateUrl(params),
-        '/q/(status:a OR status:b OR status:c)'
-      );
-
-      params = {
-        view: GerritView.SEARCH,
-        topic: 'test' as TopicName,
-      };
-      assert.equal(generateUrl(params), '/q/topic:test');
-      params = {
-        view: GerritView.SEARCH,
-        topic: 'test test' as TopicName,
-      };
-      assert.equal(generateUrl(params), '/q/topic:"test+test"');
-      params = {
-        view: GerritView.SEARCH,
-        topic: 'test:test' as TopicName,
-      };
-      assert.equal(generateUrl(params), '/q/topic:"test:test"');
-    });
-
     test('change', () => {
       const params: GenerateUrlChangeViewParameters = {
         view: GerritView.CHANGE,