Move RouterModel to be dependency injected

Release-Notes: skip
Change-Id: I6a2dc54159ebb36c97c39d188b9165edb97de288
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.ts b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.ts
index 088002c..85be2d5 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.ts
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.ts
@@ -34,7 +34,10 @@
 } from '../../../types/common';
 import {GroupNameChangedDetail} from '../gr-group/gr-group';
 import {getAppContext} from '../../../services/app-context';
-import {GerritView} from '../../../services/router/router-model';
+import {
+  GerritView,
+  routerModelToken,
+} from '../../../services/router/router-model';
 import {menuPageStyles} from '../../../styles/gr-menu-page-styles';
 import {pageNavStyles} from '../../../styles/gr-page-nav-styles';
 import {sharedStyles} from '../../../styles/shared-styles';
@@ -120,7 +123,7 @@
 
   private readonly getRepoViewModel = resolve(this, repoViewModelToken);
 
-  private readonly routerModel = getAppContext().routerModel;
+  private readonly getRouterModel = resolve(this, routerModelToken);
 
   private readonly getNavigation = resolve(this, navigationToken);
 
@@ -152,7 +155,7 @@
     );
     subscribe(
       this,
-      () => this.routerModel.routerView$,
+      () => this.getRouterModel().routerView$,
       view => {
         this.view = view;
         if (this.needsReload()) this.reload();
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
index 98b0b23..136ae3c 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
@@ -135,7 +135,10 @@
   fireReload,
   fireTitleChange,
 } from '../../../utils/event-util';
-import {GerritView} from '../../../services/router/router-model';
+import {
+  GerritView,
+  routerModelToken,
+} from '../../../services/router/router-model';
 import {
   debounce,
   DelayedTask,
@@ -540,7 +543,7 @@
 
   private readonly getChangeModel = resolve(this, changeModelToken);
 
-  private readonly routerModel = getAppContext().routerModel;
+  private readonly getRouterModel = resolve(this, routerModelToken);
 
   private readonly getCommentsModel = resolve(this, commentsModelToken);
 
@@ -715,14 +718,14 @@
     );
     subscribe(
       this,
-      () => this.routerModel.routerView$,
+      () => this.getRouterModel().routerView$,
       view => {
         this.isViewCurrent = view === GerritView.CHANGE;
       }
     );
     subscribe(
       this,
-      () => this.routerModel.routerPatchNum$,
+      () => this.getRouterModel().routerPatchNum$,
       patchNum => {
         this.routerPatchNum = patchNum;
       }
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
index 9a8a9ab..4c9164f 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
@@ -85,7 +85,10 @@
   ValueChangedEvent,
 } from '../../../types/events';
 import {fireAlert, fireEvent, fireTitleChange} from '../../../utils/event-util';
-import {GerritView} from '../../../services/router/router-model';
+import {
+  GerritView,
+  routerModelToken,
+} from '../../../services/router/router-model';
 import {assertIsDefined} from '../../../utils/common-util';
 import {Key, toggleClass} from '../../../utils/dom-util';
 import {CursorMoveResult} from '../../../api/core';
@@ -288,8 +291,7 @@
 
   private readonly restApiService = getAppContext().restApiService;
 
-  // Private but used in tests.
-  readonly routerModel = getAppContext().routerModel;
+  private readonly getRouterModel = resolve(this, routerModelToken);
 
   private readonly getUserModel = resolve(this, userModelToken);
 
@@ -472,7 +474,7 @@
           switchMap(() =>
             combineLatest([
               this.getChangeModel().patchNum$,
-              this.routerModel.routerView$,
+              this.getRouterModel().routerView$,
               this.getUserModel().diffPreferences$,
               this.getChangeModel().reviewedFiles$,
             ]).pipe(
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
index 2141224..f403a39 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
@@ -24,7 +24,10 @@
   waitUntil,
 } from '../../../test/test-utils';
 import {ChangeComments} from '../gr-comment-api/gr-comment-api';
-import {GerritView} from '../../../services/router/router-model';
+import {
+  GerritView,
+  routerModelToken,
+} from '../../../services/router/router-model';
 import {
   createRevisions,
   createComment as createCommentGeneric,
@@ -1569,7 +1572,7 @@
           loadingStatus: LoadingStatus.LOADED,
         });
 
-        element.routerModel.setState({
+        testResolver(routerModelToken).setState({
           changeNum: TEST_NUMERIC_CHANGE_ID,
           view: GerritView.DIFF,
           patchNum: 2 as RevisionPatchSetNum,
@@ -1611,7 +1614,7 @@
         loadingStatus: LoadingStatus.LOADED,
       });
 
-      element.routerModel.setState({
+      testResolver(routerModelToken).setState({
         changeNum: TEST_NUMERIC_CHANGE_ID,
         view: GerritView.DIFF,
         patchNum: 22 as RevisionPatchSetNum,
@@ -1642,7 +1645,7 @@
 
       userModel.setDiffPreferences(createDefaultDiffPrefs());
 
-      element.routerModel.setState({
+      testResolver(routerModelToken).setState({
         changeNum: TEST_NUMERIC_CHANGE_ID,
         view: GerritView.DIFF,
         patchNum: 2 as RevisionPatchSetNum,
diff --git a/polygerrit-ui/app/elements/gr-app-element.ts b/polygerrit-ui/app/elements/gr-app-element.ts
index 27d2857..646727f 100644
--- a/polygerrit-ui/app/elements/gr-app-element.ts
+++ b/polygerrit-ui/app/elements/gr-app-element.ts
@@ -53,7 +53,7 @@
   RpcLogEvent,
   TitleChangeEventDetail,
 } from '../types/events';
-import {GerritView} from '../services/router/router-model';
+import {GerritView, routerModelToken} from '../services/router/router-model';
 import {Execution, LifeCycle} from '../constants/reporting';
 import {fireIronAnnounce} from '../utils/event-util';
 import {resolve} from '../models/dependency';
@@ -164,7 +164,7 @@
 
   private readonly getUserModel = resolve(this, userModelToken);
 
-  private readonly routerModel = getAppContext().routerModel;
+  private readonly getRouterModel = resolve(this, routerModelToken);
 
   constructor() {
     super();
@@ -219,7 +219,7 @@
     );
     subscribe(
       this,
-      () => this.routerModel.routerView$,
+      () => this.getRouterModel().routerView$,
       view => {
         this.view = view;
         if (view) this.errorView?.classList.remove('show');
diff --git a/polygerrit-ui/app/embed/gr-diff-app-context-init.ts b/polygerrit-ui/app/embed/gr-diff-app-context-init.ts
index e762985..9f54347 100644
--- a/polygerrit-ui/app/embed/gr-diff-app-context-init.ts
+++ b/polygerrit-ui/app/embed/gr-diff-app-context-init.ts
@@ -72,9 +72,6 @@
     accountsModel: (_ctx: Partial<AppContext>) => {
       throw new Error('accountsModel is not implemented');
     },
-    routerModel: (_ctx: Partial<AppContext>) => {
-      throw new Error('routerModel is not implemented');
-    },
     pluginsModel: (_ctx: Partial<AppContext>) => {
       throw new Error('pluginsModel is not implemented');
     },
diff --git a/polygerrit-ui/app/models/change/change-model.ts b/polygerrit-ui/app/models/change/change-model.ts
index 20a24e8..8282a3f 100644
--- a/polygerrit-ui/app/models/change/change-model.ts
+++ b/polygerrit-ui/app/models/change/change-model.ts
@@ -257,9 +257,9 @@
   );
 
   constructor(
-    readonly routerModel: RouterModel,
-    readonly restApiService: RestApiService,
-    readonly userModel: UserModel
+    private readonly routerModel: RouterModel,
+    private readonly restApiService: RestApiService,
+    private readonly userModel: UserModel
   ) {
     super(initialState);
     this.subscriptions = [
diff --git a/polygerrit-ui/app/models/change/change-model_test.ts b/polygerrit-ui/app/models/change/change-model_test.ts
index ce699dc..a2fc7c9 100644
--- a/polygerrit-ui/app/models/change/change-model_test.ts
+++ b/polygerrit-ui/app/models/change/change-model_test.ts
@@ -28,7 +28,7 @@
 } from '../../types/common';
 import {ParsedChangeInfo} from '../../types/types';
 import {getAppContext} from '../../services/app-context';
-import {GerritView} from '../../services/router/router-model';
+import {GerritView, routerModelToken} from '../../services/router/router-model';
 import {ChangeState, LoadingStatus, updateChangeWithEdit} from './change-model';
 import {ChangeModel} from './change-model';
 import {assert} from '@open-wc/testing';
@@ -83,7 +83,7 @@
 
   setup(() => {
     changeModel = new ChangeModel(
-      getAppContext().routerModel,
+      testResolver(routerModelToken),
       getAppContext().restApiService,
       testResolver(userModelToken)
     );
@@ -121,7 +121,7 @@
     assert.equal(stub.callCount, 0);
     assert.isUndefined(state?.change);
 
-    changeModel.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -140,7 +140,7 @@
     const promise = mockPromise<ParsedChangeInfo | undefined>();
     const stub = stubRestApi('getChangeDetail').callsFake(() => promise);
     let state: ChangeState;
-    changeModel.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -164,7 +164,7 @@
     let promise = mockPromise<ParsedChangeInfo | undefined>();
     const stub = stubRestApi('getChangeDetail').callsFake(() => promise);
     let state: ChangeState;
-    changeModel.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -178,7 +178,7 @@
       _number: 123 as NumericChangeId,
     };
     promise = mockPromise<ParsedChangeInfo | undefined>();
-    changeModel.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: otherChange._number,
     });
@@ -197,7 +197,7 @@
     let promise = mockPromise<ParsedChangeInfo | undefined>();
     const stub = stubRestApi('getChangeDetail').callsFake(() => promise);
     let state: ChangeState;
-    changeModel.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -208,7 +208,7 @@
 
     promise = mockPromise<ParsedChangeInfo | undefined>();
     promise.resolve(undefined);
-    changeModel.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: undefined,
     });
@@ -220,7 +220,7 @@
 
     promise = mockPromise<ParsedChangeInfo | undefined>();
     promise.resolve(knownChange);
-    changeModel.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: knownChange._number,
     });
@@ -299,7 +299,9 @@
     assert.equal(spy.lastCall.firstArg, PARENT);
 
     // test update
-    changeModel.routerModel.updateState({basePatchNum: 1 as PatchSetNumber});
+    testResolver(routerModelToken).updateState({
+      basePatchNum: 1 as PatchSetNumber,
+    });
     assert.equal(spy.callCount, 2);
     assert.equal(spy.lastCall.firstArg, 1 as PatchSetNumber);
 
diff --git a/polygerrit-ui/app/models/checks/checks-model.ts b/polygerrit-ui/app/models/checks/checks-model.ts
index c2b7bf3..e201b88 100644
--- a/polygerrit-ui/app/models/checks/checks-model.ts
+++ b/polygerrit-ui/app/models/checks/checks-model.ts
@@ -52,7 +52,6 @@
 import {ReportingService} from '../../services/gr-reporting/gr-reporting';
 import {Execution, Interaction, Timing} from '../../constants/reporting';
 import {fireAlert, fireEvent} from '../../utils/event-util';
-import {RouterModel} from '../../services/router/router-model';
 import {Model} from '../model';
 import {define} from '../dependency';
 import {
@@ -373,11 +372,10 @@
   );
 
   constructor(
-    readonly routerModel: RouterModel,
-    readonly changeViewModel: ChangeViewModel,
-    readonly changeModel: ChangeModel,
-    readonly reporting: ReportingService,
-    readonly pluginsModel: PluginsModel
+    private readonly changeViewModel: ChangeViewModel,
+    private readonly changeModel: ChangeModel,
+    private readonly reporting: ReportingService,
+    private readonly pluginsModel: PluginsModel
   ) {
     super({
       pluginStateLatest: {},
diff --git a/polygerrit-ui/app/models/checks/checks-model_test.ts b/polygerrit-ui/app/models/checks/checks-model_test.ts
index a19db6b..dc2ad4b 100644
--- a/polygerrit-ui/app/models/checks/checks-model_test.ts
+++ b/polygerrit-ui/app/models/checks/checks-model_test.ts
@@ -69,7 +69,6 @@
 
   setup(() => {
     model = new ChecksModel(
-      getAppContext().routerModel,
       testResolver(changeViewModelToken),
       testResolver(changeModelToken),
       getAppContext().reportingService,
@@ -84,7 +83,7 @@
 
   test('register and fetch', async () => {
     let change: ParsedChangeInfo | undefined = undefined;
-    model.changeModel.change$.subscribe(c => (change = c));
+    testResolver(changeModelToken).change$.subscribe(c => (change = c));
     const provider = createProvider();
     const fetchSpy = sinon.spy(provider, 'fetch');
 
@@ -96,7 +95,7 @@
     await waitUntil(() => change === undefined);
 
     const testChange = createParsedChange();
-    model.changeModel.updateStateChange(testChange);
+    testResolver(changeModelToken).updateStateChange(testChange);
     await waitUntil(() => change === testChange);
     await waitUntilCalled(fetchSpy, 'fetch');
 
@@ -111,7 +110,7 @@
   test('fetch throttle', async () => {
     const clock = sinon.useFakeTimers();
     let change: ParsedChangeInfo | undefined = undefined;
-    model.changeModel.change$.subscribe(c => (change = c));
+    testResolver(changeModelToken).change$.subscribe(c => (change = c));
     const provider = createProvider();
     const fetchSpy = sinon.spy(provider, 'fetch');
 
@@ -123,7 +122,7 @@
     await waitUntil(() => change === undefined);
 
     const testChange = createParsedChange();
-    model.changeModel.updateStateChange(testChange);
+    testResolver(changeModelToken).updateStateChange(testChange);
     await waitUntil(() => change === testChange);
 
     model.reload('test-plugin');
@@ -283,7 +282,7 @@
   test('polls for changes', async () => {
     const clock = sinon.useFakeTimers();
     let change: ParsedChangeInfo | undefined = undefined;
-    model.changeModel.change$.subscribe(c => (change = c));
+    testResolver(changeModelToken).change$.subscribe(c => (change = c));
     const provider = createProvider();
     const fetchSpy = sinon.spy(provider, 'fetch');
 
@@ -295,7 +294,7 @@
     await waitUntil(() => change === undefined);
     clock.tick(1);
     const testChange = createParsedChange();
-    model.changeModel.updateStateChange(testChange);
+    testResolver(changeModelToken).updateStateChange(testChange);
     await waitUntil(() => change === testChange);
     clock.tick(600); // need to wait for 500ms throttle
     await waitUntilCalled(fetchSpy, 'fetch');
@@ -310,7 +309,7 @@
   test('does not poll when config specifies 0 seconds', async () => {
     const clock = sinon.useFakeTimers();
     let change: ParsedChangeInfo | undefined = undefined;
-    model.changeModel.change$.subscribe(c => (change = c));
+    testResolver(changeModelToken).change$.subscribe(c => (change = c));
     const provider = createProvider();
     const fetchSpy = sinon.spy(provider, 'fetch');
 
@@ -322,7 +321,7 @@
     await waitUntil(() => change === undefined);
     clock.tick(1);
     const testChange = createParsedChange();
-    model.changeModel.updateStateChange(testChange);
+    testResolver(changeModelToken).updateStateChange(testChange);
     await waitUntil(() => change === testChange);
     clock.tick(600); // need to wait for 500ms throttle
     await waitUntilCalled(fetchSpy, 'fetch');
diff --git a/polygerrit-ui/app/models/comments/comments-model.ts b/polygerrit-ui/app/models/comments/comments-model.ts
index 76453b0..a7b43ca 100644
--- a/polygerrit-ui/app/models/comments/comments-model.ts
+++ b/polygerrit-ui/app/models/comments/comments-model.ts
@@ -384,11 +384,11 @@
   private discardedDrafts: DraftInfo[] = [];
 
   constructor(
-    readonly routerModel: RouterModel,
-    readonly changeModel: ChangeModel,
-    readonly accountsModel: AccountsModel,
-    readonly restApiService: RestApiService,
-    readonly reporting: ReportingService
+    private readonly routerModel: RouterModel,
+    private readonly changeModel: ChangeModel,
+    private readonly accountsModel: AccountsModel,
+    private readonly restApiService: RestApiService,
+    private readonly reporting: ReportingService
   ) {
     super(initialState);
     this.subscriptions.push(
diff --git a/polygerrit-ui/app/models/comments/comments-model_test.ts b/polygerrit-ui/app/models/comments/comments-model_test.ts
index 32ea1bc..a3b3219 100644
--- a/polygerrit-ui/app/models/comments/comments-model_test.ts
+++ b/polygerrit-ui/app/models/comments/comments-model_test.ts
@@ -23,7 +23,7 @@
 } from '../../test/test-data-generators';
 import {stubRestApi, waitUntil, waitUntilCalled} from '../../test/test-utils';
 import {getAppContext} from '../../services/app-context';
-import {GerritView} from '../../services/router/router-model';
+import {GerritView, routerModelToken} from '../../services/router/router-model';
 import {PathToCommentsInfoMap} from '../../types/common';
 import {changeModelToken} from '../change/change-model';
 import {assert} from '@open-wc/testing';
@@ -69,7 +69,7 @@
 
   test('loads comments', async () => {
     const model = new CommentsModel(
-      getAppContext().routerModel,
+      testResolver(routerModelToken),
       testResolver(changeModelToken),
       getAppContext().accountsModel,
       getAppContext().restApiService,
@@ -97,11 +97,11 @@
       model.portedComments$.subscribe(c => (portedComments = c ?? {}))
     );
 
-    model.routerModel.setState({
+    testResolver(routerModelToken).setState({
       view: GerritView.CHANGE,
       changeNum: TEST_NUMERIC_CHANGE_ID,
     });
-    model.changeModel.updateStateChange(createParsedChange());
+    testResolver(changeModelToken).updateStateChange(createParsedChange());
 
     await waitUntilCalled(diffCommentsSpy, 'diffCommentsSpy');
     await waitUntilCalled(diffRobotCommentsSpy, 'diffRobotCommentsSpy');
@@ -130,7 +130,7 @@
     };
     stubRestApi('getAccountDetails').returns(Promise.resolve(account));
     const model = new CommentsModel(
-      getAppContext().routerModel,
+      testResolver(routerModelToken),
       testResolver(changeModelToken),
       getAppContext().accountsModel,
       getAppContext().restApiService,
@@ -158,7 +158,7 @@
     };
     stubRestApi('getAccountDetails').returns(Promise.resolve(account));
     const model = new CommentsModel(
-      getAppContext().routerModel,
+      testResolver(routerModelToken),
       testResolver(changeModelToken),
       getAppContext().accountsModel,
       getAppContext().restApiService,
diff --git a/polygerrit-ui/app/services/app-context-init.ts b/polygerrit-ui/app/services/app-context-init.ts
index ee6ca0e..1115f11 100644
--- a/polygerrit-ui/app/services/app-context-init.ts
+++ b/polygerrit-ui/app/services/app-context-init.ts
@@ -21,7 +21,7 @@
   CommentsModel,
   commentsModelToken,
 } from '../models/comments/comments-model';
-import {RouterModel} from './router/router-model';
+import {RouterModel, routerModelToken} from './router/router-model';
 import {
   ShortcutsService,
   shortcutsServiceToken,
@@ -64,7 +64,6 @@
  */
 export function createAppContext(): AppContext & Finalizable {
   const appRegistry: Registry<AppContext> = {
-    routerModel: (_ctx: Partial<AppContext>) => new RouterModel(),
     flagsService: (_ctx: Partial<AppContext>) =>
       new FlagsServiceImplementation(),
     reportingService: (ctx: Partial<AppContext>) => {
@@ -112,6 +111,8 @@
   resolver: <T>(token: DependencyToken<T>) => T
 ): Map<DependencyToken<unknown>, Creator<unknown>> {
   const dependencies = new Map<DependencyToken<unknown>, Creator<unknown>>();
+  const routerModelCreator = () => new RouterModel();
+  dependencies.set(routerModelToken, routerModelCreator);
   const userModelCreator = () => new UserModel(appContext.restApiService);
   dependencies.set(userModelToken, userModelCreator);
   const browserModelCreator = () => new BrowserModel(resolver(userModelToken));
@@ -150,7 +151,7 @@
   const routerCreator = () =>
     new GrRouter(
       appContext.reportingService,
-      appContext.routerModel,
+      resolver(routerModelToken),
       appContext.restApiService,
       resolver(adminViewModelToken),
       resolver(agreementViewModelToken),
@@ -170,7 +171,7 @@
 
   const changeModelCreator = () =>
     new ChangeModel(
-      appContext.routerModel,
+      resolver(routerModelToken),
       appContext.restApiService,
       resolver(userModelToken)
     );
@@ -178,7 +179,7 @@
 
   const commentsModelCreator = () =>
     new CommentsModel(
-      appContext.routerModel,
+      resolver(routerModelToken),
       resolver(changeModelToken),
       appContext.accountsModel,
       appContext.restApiService,
@@ -200,7 +201,6 @@
 
   const checksModelCreator = () =>
     new ChecksModel(
-      appContext.routerModel,
       resolver(changeViewModelToken),
       resolver(changeModelToken),
       appContext.reportingService,
diff --git a/polygerrit-ui/app/services/app-context.ts b/polygerrit-ui/app/services/app-context.ts
index 62e6331..5394ee4 100644
--- a/polygerrit-ui/app/services/app-context.ts
+++ b/polygerrit-ui/app/services/app-context.ts
@@ -11,13 +11,11 @@
 import {RestApiService} from './gr-rest-api/gr-rest-api';
 import {JsApiService} from '../elements/shared/gr-js-api-interface/gr-js-api-types';
 import {StorageService} from './storage/gr-storage';
-import {RouterModel} from './router/router-model';
 import {PluginsModel} from '../models/plugins/plugins-model';
 import {HighlightService} from './highlight/highlight-service';
 import {AccountsModel} from '../models/accounts-model/accounts-model';
 
 export interface AppContext {
-  routerModel: RouterModel;
   flagsService: FlagsService;
   reportingService: ReportingService;
   eventEmitter: EventEmitterService;
diff --git a/polygerrit-ui/app/services/router/router-model.ts b/polygerrit-ui/app/services/router/router-model.ts
index b90fa6a..edde7a4 100644
--- a/polygerrit-ui/app/services/router/router-model.ts
+++ b/polygerrit-ui/app/services/router/router-model.ts
@@ -11,6 +11,7 @@
 } from '../../types/common';
 import {Model} from '../../models/model';
 import {select} from '../../utils/observable-util';
+import {define} from '../../models/dependency';
 
 export enum GerritView {
   ADMIN = 'admin',
@@ -35,6 +36,7 @@
   basePatchNum?: BasePatchSetNum;
 }
 
+export const routerModelToken = define<RouterModel>('router-model');
 export class RouterModel extends Model<RouterState> {
   readonly routerView$: Observable<GerritView | undefined> = select(
     this.state$,
diff --git a/polygerrit-ui/app/test/test-app-context-init.ts b/polygerrit-ui/app/test/test-app-context-init.ts
index 33ff997..f0c9ba8 100644
--- a/polygerrit-ui/app/test/test-app-context-init.ts
+++ b/polygerrit-ui/app/test/test-app-context-init.ts
@@ -15,7 +15,6 @@
 import {FlagsServiceImplementation} from '../services/flags/flags_impl';
 import {EventEmitter} from '../services/gr-event-interface/gr-event-interface_impl';
 import {GrJsApiInterface} from '../elements/shared/gr-js-api-interface/gr-js-api-interface-element';
-import {RouterModel} from '../services/router/router-model';
 import {PluginsModel} from '../models/plugins/plugins-model';
 import {MockHighlightService} from '../services/highlight/highlight-service-mock';
 import {AccountsModel} from '../models/accounts-model/accounts-model';
@@ -25,7 +24,6 @@
 
 export function createTestAppContext(): AppContext & Finalizable {
   const appRegistry: Registry<AppContext> = {
-    routerModel: (_ctx: Partial<AppContext>) => new RouterModel(),
     flagsService: (_ctx: Partial<AppContext>) =>
       new FlagsServiceImplementation(),
     reportingService: (_ctx: Partial<AppContext>) => grReportingMock,