Migrate Comments Model to Dependency Injection
Change-Id: I1d255999195e33100a893c96bf92150e79a49885
diff --git a/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts b/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts
index 08b42c2..dafa384 100644
--- a/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-summary/gr-change-summary.ts
@@ -59,6 +59,8 @@
import {modifierPressed} from '../../../utils/dom-util';
import {DropdownLink} from '../../shared/gr-dropdown/gr-dropdown';
import {fontStyles} from '../../../styles/gr-font-styles';
+import {commentsModelToken} from '../../../services/comments/comments-model';
+import {resolve} from '../../../services/dependency';
export enum SummaryChipStyles {
INFO = 'info',
@@ -401,14 +403,14 @@
private showAllChips = new Map<RunStatus | Category, boolean>();
- private commentsModel = getAppContext().commentsModel;
+ private getCommentsModel = resolve(this, commentsModelToken);
private userModel = getAppContext().userModel;
private checksModel = getAppContext().checksModel;
- constructor() {
- super();
+ override connectedCallback() {
+ super.connectedCallback();
subscribe(
this,
this.checksModel.allRunsLatestPatchsetLatestAttempt$,
@@ -441,12 +443,12 @@
);
subscribe(
this,
- this.commentsModel.changeComments$,
+ this.getCommentsModel().changeComments$,
x => (this.changeComments = x)
);
subscribe(
this,
- this.commentsModel.threads$,
+ this.getCommentsModel().threads$,
x => (this.commentThreads = x)
);
subscribe(this, this.userModel.account$, x => (this.selfAccount = x));
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 a018edb..5a54599 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
@@ -45,7 +45,6 @@
import '../../checks/gr-checks-tab';
import {ChangeStarToggleStarDetail} from '../../shared/gr-change-star/gr-change-star';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-change-view_html';
import {
KeyboardShortcutMixin,
@@ -198,6 +197,8 @@
} from '../../../utils/attention-set-util';
import {listen} from '../../../services/shortcuts/shortcuts-service';
import {LoadingStatus} from '../../../services/change/change-model';
+import {commentsModelToken} from '../../../services/comments/comments-model';
+import {resolve, DIPolymerElement} from '../../../services/dependency';
const MIN_LINES_FOR_COMMIT_COLLAPSE = 18;
@@ -248,7 +249,7 @@
export type ChangeViewPatchRange = Partial<PatchRange>;
// This avoids JSC_DYNAMIC_EXTENDS_WITHOUT_JSDOC closure compiler error.
-const base = KeyboardShortcutMixin(PolymerElement);
+const base = KeyboardShortcutMixin(DIPolymerElement);
@customElement('gr-change-view')
export class GrChangeView extends base {
@@ -610,7 +611,8 @@
private readonly routerModel = getAppContext().routerModel;
- private readonly commentsModel = getAppContext().commentsModel;
+ // Private but used in tests.
+ readonly getCommentsModel = resolve(this, commentsModelToken);
private readonly shortcuts = getAppContext().shortcutsService;
@@ -634,47 +636,6 @@
// visible for testing
routerPatchNum?: PatchSetNum;
- override ready() {
- super.ready();
- this.subscriptions.push(
- this.checksModel.aPluginHasRegistered$.subscribe(b => {
- this._showChecksTab = b;
- })
- );
- this.subscriptions.push(
- this.routerModel.routerView$.subscribe(view => {
- this.isViewCurrent = view === GerritView.CHANGE;
- })
- );
- this.subscriptions.push(
- this.routerModel.routerPatchNum$.subscribe(patchNum => {
- this.routerPatchNum = patchNum;
- })
- );
- this.subscriptions.push(
- this.commentsModel.drafts$.subscribe(drafts => {
- this._diffDrafts = {...drafts};
- })
- );
- this.subscriptions.push(
- this.userModel.preferenceDiffViewMode$.subscribe(diffViewMode => {
- this.diffViewMode = diffViewMode;
- })
- );
- this.subscriptions.push(
- this.commentsModel.changeComments$.subscribe(changeComments => {
- this._changeComments = changeComments;
- })
- );
- this.subscriptions.push(
- this.changeModel.change$.subscribe(change => {
- // The change view is tied to a specific change number, so don't update
- // _change to undefined.
- if (change) this._change = change;
- })
- );
- }
-
constructor() {
super();
this.addEventListener('topic-changed', () => this._handleTopicChanged());
@@ -695,8 +656,49 @@
this.addEventListener('open-reply-dialog', () => this._openReplyDialog());
}
+ private setupSubscriptions() {
+ this.subscriptions.push(
+ this.checksModel.aPluginHasRegistered$.subscribe(b => {
+ this._showChecksTab = b;
+ })
+ );
+ this.subscriptions.push(
+ this.routerModel.routerView$.subscribe(view => {
+ this.isViewCurrent = view === GerritView.CHANGE;
+ })
+ );
+ this.subscriptions.push(
+ this.routerModel.routerPatchNum$.subscribe(patchNum => {
+ this.routerPatchNum = patchNum;
+ })
+ );
+ this.subscriptions.push(
+ this.getCommentsModel().drafts$.subscribe(drafts => {
+ this._diffDrafts = {...drafts};
+ })
+ );
+ this.subscriptions.push(
+ this.userModel.preferenceDiffViewMode$.subscribe(diffViewMode => {
+ this.diffViewMode = diffViewMode;
+ })
+ );
+ this.subscriptions.push(
+ this.getCommentsModel().changeComments$.subscribe(changeComments => {
+ this._changeComments = changeComments;
+ })
+ );
+ this.subscriptions.push(
+ this.changeModel.change$.subscribe(change => {
+ // The change view is tied to a specific change number, so don't update
+ // _change to undefined.
+ if (change) this._change = change;
+ })
+ );
+ }
+
override connectedCallback() {
super.connectedCallback();
+ this.setupSubscriptions();
this._throttledToggleChangeStar = throttleWrap<KeyboardEvent>(_ =>
this._handleToggleChangeStar()
);
@@ -2205,13 +2207,13 @@
const promises = [this.loadAndSetCommitInfo(), this.$.fileList.reload()];
if (patchNumChanged) {
promises.push(
- this.commentsModel.reloadPortedComments(
+ this.getCommentsModel().reloadPortedComments(
this._changeNum,
this._patchRange?.patchNum
)
);
promises.push(
- this.commentsModel.reloadPortedDrafts(
+ this.getCommentsModel().reloadPortedDrafts(
this._changeNum,
this._patchRange?.patchNum
)
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
index 69cca9f..4ca593a 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
@@ -39,7 +39,6 @@
import {
mockPromise,
queryAndAssert,
- stubComments,
stubRestApi,
stubUsers,
waitQueryAndAssert,
@@ -1362,8 +1361,14 @@
sinon.stub(element, 'loadAndSetCommitInfo');
sinon.stub(element.$.fileList, 'reload');
flush();
- const reloadPortedCommentsStub = stubComments('reloadPortedComments');
- const reloadPortedDraftsStub = stubComments('reloadPortedDrafts');
+ const reloadPortedCommentsStub = sinon.stub(
+ element.getCommentsModel(),
+ 'reloadPortedComments'
+ );
+ const reloadPortedDraftsStub = sinon.stub(
+ element.getCommentsModel(),
+ 'reloadPortedDrafts'
+ );
sinon.stub(element.$.fileList, 'collapseAllDiffs');
const value: AppElementChangeViewParams = {
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts
index e26a0d5..9bcedc8 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.ts
@@ -31,6 +31,8 @@
import {subscribe} from '../../lit/subscription-controller';
import {getAppContext} from '../../../services/app-context';
import {ParsedChangeInfo} from '../../../types/types';
+import {commentsModelToken} from '../../../services/comments/comments-model';
+import {resolve} from '../../../services/dependency';
@customElement('gr-confirm-submit-dialog')
export class GrConfirmSubmitDialog extends LitElement {
@@ -61,7 +63,7 @@
@state()
initialised = false;
- private commentsModel = getAppContext().commentsModel;
+ private getCommentsModel = resolve(this, commentsModelToken);
private changeModel = getAppContext().changeModel;
@@ -91,12 +93,12 @@
];
}
- constructor() {
- super();
+ override connectedCallback() {
+ super.connectedCallback();
subscribe(this, this.changeModel.change$, x => (this.change = x));
subscribe(
this,
- this.commentsModel.threads$,
+ this.getCommentsModel().threads$,
x => (this.unresolvedThreads = x.filter(isUnresolved))
);
}
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
index b8f41d9..b1e6a1b 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
@@ -87,6 +87,7 @@
import {select} from '../../../utils/observable-util';
import {resolve, DIPolymerElement} from '../../../services/dependency';
import {browserModelToken} from '../../../services/browser/browser-model';
+import {commentsModelToken} from '../../../services/comments/comments-model';
export const DEFAULT_NUM_FILES_SHOWN = 200;
@@ -317,7 +318,7 @@
private readonly userModel = getAppContext().userModel;
- private readonly commentsModel = getAppContext().commentsModel;
+ private readonly getCommentsModel = resolve(this, commentsModelToken);
private readonly getBrowserModel = resolve(this, browserModelToken);
@@ -378,7 +379,7 @@
override connectedCallback() {
super.connectedCallback();
this.subscriptions = [
- this.commentsModel.changeComments$.subscribe(changeComments => {
+ this.getCommentsModel().changeComments$.subscribe(changeComments => {
this.changeComments = changeComments;
}),
this.getBrowserModel().diffViewMode$.subscribe(
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.ts b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.ts
index 36d0ce6..8ae0115 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.ts
@@ -21,7 +21,6 @@
import '../gr-message/gr-message';
import '../../../styles/gr-paper-styles';
import '../../../styles/shared-styles';
-import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-messages-list_html';
import {
Shortcut,
@@ -51,6 +50,8 @@
FormattedReviewerUpdateInfo,
ParsedChangeInfo,
} from '../../../types/types';
+import {commentsModelToken} from '../../../services/comments/comments-model';
+import {resolve, DIPolymerElement} from '../../../services/dependency';
/**
* The content of the enum is also used in the UI for the button text.
@@ -194,7 +195,7 @@
}
@customElement('gr-messages-list')
-export class GrMessagesList extends PolymerElement {
+export class GrMessagesList extends DIPolymerElement {
static get template() {
return htmlTemplate;
}
@@ -252,7 +253,7 @@
private readonly userModel = getAppContext().userModel;
// Private but used in tests.
- readonly commentsModel = getAppContext().commentsModel;
+ readonly getCommentsModel = resolve(this, commentsModelToken);
private readonly changeModel = getAppContext().changeModel;
@@ -265,7 +266,7 @@
override connectedCallback() {
super.connectedCallback();
this.subscriptions.push(
- this.commentsModel.threads$.subscribe(x => {
+ this.getCommentsModel().threads$.subscribe(x => {
this.commentThreads = x;
})
);
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js
index 65c3c74..0a69d8a 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js
@@ -139,7 +139,7 @@
// comment API.
commentApiWrapper = basicFixture.instantiate();
element = commentApiWrapper.$.messagesList;
- await element.commentsModel.reloadComments();
+ await element.getCommentsModel().reloadComments();
element.messages = messages;
await flush();
});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
index 9cc0dbb..9aafd36 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
@@ -90,6 +90,7 @@
import {DisplayLine, RenderPreferences} from '../../../api/diff';
import {resolve, DIPolymerElement} from '../../../services/dependency';
import {browserModelToken} from '../../../services/browser/browser-model';
+import {commentsModelToken} from '../../../services/comments/comments-model';
const EMPTY_BLAME = 'No blame information for this diff.';
@@ -269,7 +270,7 @@
private readonly getBrowserModel = resolve(this, browserModelToken);
- private readonly commentsModel = getAppContext().commentsModel;
+ private readonly getCommentsModel = resolve(this, commentsModelToken);
private readonly reporting = getAppContext().reportingService;
@@ -323,7 +324,7 @@
this._loggedIn = loggedIn;
});
this.subscriptions.push(
- this.commentsModel.changeComments$.subscribe(changeComments => {
+ this.getCommentsModel().changeComments$.subscribe(changeComments => {
this.changeComments = changeComments;
})
);
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 e1b7b4f..b1cfe55 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
@@ -119,6 +119,7 @@
import {DisplayLine} from '../../../api/diff';
import {GrDownloadDialog} from '../../change/gr-download-dialog/gr-download-dialog';
import {browserModelToken} from '../../../services/browser/browser-model';
+import {commentsModelToken} from '../../../services/comments/comments-model';
import {resolve, DIPolymerElement} from '../../../services/dependency';
const ERR_REVIEW_STATUS = 'Couldn’t change file review status.';
@@ -369,7 +370,7 @@
readonly getBrowserModel = resolve(this, browserModelToken);
// Private but used in tests.
- readonly commentsModel = getAppContext().commentsModel;
+ readonly getCommentsModel = resolve(this, commentsModelToken);
private readonly shortcuts = getAppContext().shortcutsService;
@@ -394,7 +395,7 @@
});
this.subscriptions.push(
- this.commentsModel.changeComments$.subscribe(changeComments => {
+ this.getCommentsModel().changeComments$.subscribe(changeComments => {
this._changeComments = changeComments;
})
);
@@ -1163,7 +1164,7 @@
)
);
}
- promises.push(until(this.commentsModel.commentsLoading$, isFalse));
+ promises.push(until(this.getCommentsModel().commentsLoading$, isFalse));
this.$.diffHost.cancel();
this.$.diffHost.clearDiffContent();
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
index aa39f87..b590625 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
@@ -91,7 +91,7 @@
]});
await flush();
- element.commentsModel.setState({
+ element.getCommentsModel().setState({
comments: {},
robotComments: {},
drafts: {},
@@ -145,7 +145,7 @@
});
test('comment url resolves to comment.patch_set vs latest', () => {
- element.commentsModel.setState({
+ element.getCommentsModel().setState({
comments: {
'/COMMIT_MSG': [
{
@@ -219,7 +219,7 @@
test('unchanged diff X vs latest from comment links navigates to base vs X'
, () => {
const diffNavStub = sinon.stub(GerritNav, 'navigateToDiff');
- element.commentsModel.setState({
+ element.getCommentsModel().setState({
comments: {
'/COMMIT_MSG': [
{
@@ -272,7 +272,7 @@
test('unchanged diff Base vs latest from comment does not navigate'
, () => {
const diffNavStub = sinon.stub(GerritNav, 'navigateToDiff');
- element.commentsModel.setState({
+ element.getCommentsModel().setState({
comments: {
'/COMMIT_MSG': [
{
@@ -353,7 +353,7 @@
});
test('diff toast to go to latest is shown and not base', async () => {
- element.commentsModel.setState({
+ element.getCommentsModel().setState({
comments: {
'/COMMIT_MSG': [
{
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts
index 71fee62..b6397b0 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts
@@ -51,6 +51,8 @@
import {LitElement, PropertyValues, css, html} from 'lit';
import {customElement, property, query, state} from 'lit/decorators';
import {subscribe} from '../../lit/subscription-controller';
+import {commentsModelToken} from '../../../services/comments/comments-model';
+import {resolve} from '../../../services/dependency';
// Maximum length for patch set descriptions.
const PATCH_DESC_MAX_LENGTH = 500;
@@ -126,13 +128,13 @@
private readonly reporting: ReportingService =
getAppContext().reportingService;
- private readonly commentsModel = getAppContext().commentsModel;
+ private readonly getCommentsModel = resolve(this, commentsModelToken);
- constructor() {
- super();
+ override connectedCallback() {
+ super.connectedCallback();
subscribe(
this,
- this.commentsModel.changeComments$,
+ this.getCommentsModel().changeComments$,
x => (this.changeComments = x)
);
}
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
index 7a4b6f2..0f33ffb 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.ts
@@ -70,6 +70,8 @@
import {ShortcutController} from '../../lit/shortcut-controller';
import {ValueChangedEvent} from '../../../types/events';
import {notDeepEqual} from '../../../utils/deep-util';
+import {resolve} from '../../../services/dependency';
+import {commentsModelToken} from '../../../services/comments/comments-model';
const NEWLINE_PATTERN = /\n/g;
@@ -245,7 +247,8 @@
@state()
saving = false;
- private readonly commentsModel = getAppContext().commentsModel;
+ // Private but used in tests.
+ readonly getCommentsModel = resolve(this, commentsModelToken);
private readonly changeModel = getAppContext().changeModel;
@@ -783,7 +786,7 @@
} else {
try {
this.saving = true;
- await this.commentsModel.saveDraft(unsaved);
+ await this.getCommentsModel().saveDraft(unsaved);
} finally {
this.saving = false;
}
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
index 4615bb7..9e3db21 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.ts
@@ -28,7 +28,6 @@
import {
mockPromise,
queryAndAssert,
- stubComments,
stubRestApi,
waitUntilCalled,
MockPromise,
@@ -234,7 +233,9 @@
setup(async () => {
savePromise = mockPromise<DraftInfo>();
- stub = stubComments('saveDraft').returns(savePromise);
+ stub = sinon
+ .stub(element.getCommentsModel(), 'saveDraft')
+ .returns(savePromise);
element.thread = createThread(c1, {...c2, unresolved: true});
await element.updateComplete;
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
index 19d2ea6..18ef5a9 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
@@ -30,6 +30,7 @@
import {getAppContext} from '../../../services/app-context';
import {css, html, LitElement, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators';
+import {resolve} from '../../../services/dependency';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {GrTextarea} from '../gr-textarea/gr-textarea';
import {GrOverlay} from '../gr-overlay/gr-overlay';
@@ -55,6 +56,7 @@
import {fire, fireEvent} from '../../../utils/event-util';
import {assertIsDefined} from '../../../utils/common-util';
import {Key, Modifier} from '../../../utils/dom-util';
+import {commentsModelToken} from '../../../services/comments/comments-model';
import {sharedStyles} from '../../../styles/shared-styles';
import {subscribe} from '../../lit/subscription-controller';
import {ShortcutController} from '../../lit/shortcut-controller';
@@ -230,7 +232,8 @@
private readonly changeModel = getAppContext().changeModel;
- private readonly commentsModel = getAppContext().commentsModel;
+ // Private but used in tests.
+ readonly getCommentsModel = resolve(this, commentsModelToken);
private readonly userModel = getAppContext().userModel;
@@ -1092,7 +1095,7 @@
if (messageToSave === '') {
// Don't try to discard UnsavedInfo. Nothing to do then.
if (this.comment.id) {
- await this.commentsModel.discardDraft(this.comment.id);
+ await this.getCommentsModel().discardDraft(this.comment.id);
}
} else {
// No need to make a backend call when nothing has changed.
@@ -1115,7 +1118,7 @@
/** For sharing between save() and autoSave(). */
private rawSave(message: string, options: {showToast: boolean}) {
if (!isDraftOrUnsaved(this.comment)) throw new Error('not a draft');
- return this.commentsModel.saveDraft(
+ return this.getCommentsModel().saveDraft(
{
...this.comment,
message,
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts
index a6e0f50..d3a1007 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.ts
@@ -24,7 +24,6 @@
query,
pressKey,
listenOnce,
- stubComments,
mockPromise,
waitUntilCalled,
dispatch,
@@ -453,7 +452,9 @@
test('save', async () => {
const savePromise = mockPromise<DraftInfo>();
- const stub = stubComments('saveDraft').returns(savePromise);
+ const stub = sinon
+ .stub(element.getCommentsModel(), 'saveDraft')
+ .returns(savePromise);
element.comment = createDraft();
element.editing = true;
@@ -480,9 +481,9 @@
});
test('save failed', async () => {
- stubComments('saveDraft').returns(
- Promise.reject(new Error('saving failed'))
- );
+ sinon
+ .stub(element.getCommentsModel(), 'saveDraft')
+ .returns(Promise.reject(new Error('saving failed')));
element.comment = createDraft();
element.editing = true;
@@ -500,7 +501,9 @@
test('discard', async () => {
const discardPromise = mockPromise<void>();
- const stub = stubComments('discardDraft').returns(discardPromise);
+ const stub = sinon
+ .stub(element.getCommentsModel(), 'discardDraft')
+ .returns(discardPromise);
element.comment = createDraft();
element.editing = true;
@@ -522,7 +525,7 @@
});
test('resolved comment state indicated by checkbox', async () => {
- const saveStub = stubComments('saveDraft');
+ const saveStub = sinon.stub(element.getCommentsModel(), 'saveDraft');
element.comment = {
...createComment(),
__draft: true,
@@ -546,8 +549,11 @@
});
test('saving empty text calls discard()', async () => {
- const saveStub = stubComments('saveDraft');
- const discardStub = stubComments('discardDraft');
+ const saveStub = sinon.stub(element.getCommentsModel(), 'saveDraft');
+ const discardStub = sinon.stub(
+ element.getCommentsModel(),
+ 'discardDraft'
+ );
element.comment = createDraft();
element.editing = true;
await element.updateComplete;
@@ -619,7 +625,9 @@
setup(async () => {
clock = sinon.useFakeTimers();
savePromise = mockPromise<DraftInfo>();
- saveStub = stubComments('saveDraft').returns(savePromise);
+ saveStub = sinon
+ .stub(element.getCommentsModel(), 'saveDraft')
+ .returns(savePromise);
element.comment = createUnsaved();
element.editing = true;
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 c4658ec..7d31062 100644
--- a/polygerrit-ui/app/embed/gr-diff-app-context-init.ts
+++ b/polygerrit-ui/app/embed/gr-diff-app-context-init.ts
@@ -78,9 +78,6 @@
changeModel: (_ctx: Partial<AppContext>) => {
throw new Error('changeModel is not implemented');
},
- commentsModel: (_ctx: Partial<AppContext>) => {
- throw new Error('commentsModel is not implemented');
- },
checksModel: (_ctx: Partial<AppContext>) => {
throw new Error('checksModel is not implemented');
},
diff --git a/polygerrit-ui/app/services/app-context-init.ts b/polygerrit-ui/app/services/app-context-init.ts
index fe325c5..14efe4c 100644
--- a/polygerrit-ui/app/services/app-context-init.ts
+++ b/polygerrit-ui/app/services/app-context-init.ts
@@ -27,7 +27,7 @@
import {GrJsApiInterface} from '../elements/shared/gr-js-api-interface/gr-js-api-interface-element';
import {GrStorageService} from './storage/gr-storage_impl';
import {UserModel} from './user/user-model';
-import {CommentsModel} from './comments/comments-model';
+import {CommentsModel, commentsModelToken} from './comments/comments-model';
import {RouterModel} from './router/router-model';
import {ShortcutsService} from './shortcuts/shortcuts-service';
import {assertIsDefined} from '../utils/common-util';
@@ -63,22 +63,6 @@
assertIsDefined(restApiService, 'restApiService');
return new ChangeModel(routerModel, restApiService);
},
- commentsModel: (ctx: Partial<AppContext>) => {
- const routerModel = ctx.routerModel;
- const changeModel = ctx.changeModel;
- const restApiService = ctx.restApiService;
- const reportingService = ctx.reportingService;
- assertIsDefined(routerModel, 'routerModel');
- assertIsDefined(changeModel, 'changeModel');
- assertIsDefined(restApiService, 'restApiService');
- assertIsDefined(reportingService, 'reportingService');
- return new CommentsModel(
- routerModel,
- changeModel,
- restApiService,
- reportingService
- );
- },
checksModel: (ctx: Partial<AppContext>) => {
const routerModel = ctx.routerModel;
const changeModel = ctx.changeModel;
@@ -121,5 +105,13 @@
const browserModel = new BrowserModel(appContext.userModel!);
dependencies.set(browserModelToken, browserModel);
+ const commentsModel = new CommentsModel(
+ appContext.routerModel,
+ appContext.changeModel,
+ appContext.restApiService,
+ appContext.reportingService
+ );
+ dependencies.set(commentsModelToken, commentsModel);
+
return dependencies;
}
diff --git a/polygerrit-ui/app/services/app-context.ts b/polygerrit-ui/app/services/app-context.ts
index b5aadb7..2e02ebf 100644
--- a/polygerrit-ui/app/services/app-context.ts
+++ b/polygerrit-ui/app/services/app-context.ts
@@ -25,7 +25,6 @@
import {JsApiService} from '../elements/shared/gr-js-api-interface/gr-js-api-types';
import {StorageService} from './storage/gr-storage';
import {UserModel} from './user/user-model';
-import {CommentsModel} from './comments/comments-model';
import {RouterModel} from './router/router-model';
import {ShortcutsService} from './shortcuts/shortcuts-service';
import {ConfigModel} from './config/config-model';
@@ -38,7 +37,6 @@
authService: AuthService;
restApiService: RestApiService;
changeModel: ChangeModel;
- commentsModel: CommentsModel;
checksModel: ChecksModel;
jsApiService: JsApiService;
storageService: StorageService;
diff --git a/polygerrit-ui/app/services/comments/comments-model.ts b/polygerrit-ui/app/services/comments/comments-model.ts
index a8d47f1..8e860f7 100644
--- a/polygerrit-ui/app/services/comments/comments-model.ts
+++ b/polygerrit-ui/app/services/comments/comments-model.ts
@@ -39,6 +39,7 @@
import {select} from '../../utils/observable-util';
import {RouterModel} from '../router/router-model';
import {Finalizable} from '../registry';
+import {define} from '../dependency';
import {combineLatest, Subscription} from 'rxjs';
import {fire, fireAlert, fireEvent} from '../../utils/event-util';
import {CURRENT} from '../../utils/patch-set-util';
@@ -220,6 +221,7 @@
return setDiscardedDraft(nextState, discardedDraft);
}
+export const commentsModelToken = define<CommentsModel>('comments-model');
export class CommentsModel implements Finalizable {
private readonly privateState$: BehaviorSubject<CommentState> =
new BehaviorSubject(initialState);
diff --git a/polygerrit-ui/app/services/dependency.ts b/polygerrit-ui/app/services/dependency.ts
index d49f2ef..e7ac242c 100644
--- a/polygerrit-ui/app/services/dependency.ts
+++ b/polygerrit-ui/app/services/dependency.ts
@@ -177,10 +177,10 @@
}
override disconnectedCallback() {
+ super.disconnectedCallback();
for (const c of this.___controllers) {
c.hostDisconnected?.();
}
- super.disconnectedCallback();
}
addController(controller: ReactiveController) {
diff --git a/polygerrit-ui/app/test/common-test-setup.ts b/polygerrit-ui/app/test/common-test-setup.ts
index 8714575..19cb790 100644
--- a/polygerrit-ui/app/test/common-test-setup.ts
+++ b/polygerrit-ui/app/test/common-test-setup.ts
@@ -26,6 +26,7 @@
import {
createTestAppContext,
createTestDependencies,
+ Creator,
} from './test-app-context-init';
import {_testOnly_resetPluginLoader} from '../elements/shared/gr-js-api-interface/gr-plugin-loader';
import {_testOnlyResetGrRestApiSharedObjects} from '../elements/shared/gr-rest-api-interface/gr-rest-api-impl';
@@ -114,16 +115,21 @@
function injectDependency<T>(
dependency: DependencyToken<T>,
- service: T & Finalizable
+ creator: Creator<T>
) {
- injectedDependencies.set(dependency, () => service);
- finalizers.push(service);
+ let service: (T & Finalizable) | undefined = undefined;
+ injectedDependencies.set(dependency, () => {
+ if (service) return service;
+ service = creator();
+ finalizers.push(service);
+ return service;
+ });
}
function resolveDependency(evt: DependencyRequestEvent<unknown>) {
- const service = injectedDependencies.get(evt.dependency);
- if (service) {
- evt.callback(service());
+ const provider = injectedDependencies.get(evt.dependency);
+ if (provider) {
+ evt.callback(provider());
} else {
throw new DependencyError(
evt.dependency,
@@ -143,8 +149,8 @@
injectAppContext(appContext);
finalizers.push(appContext);
const dependencies = createTestDependencies(appContext);
- for (const [token, service] of dependencies) {
- injectDependency(token, service);
+ for (const [token, provider] of dependencies) {
+ injectDependency(token, provider);
}
document.addEventListener('request-dependency', resolveDependency);
// The following calls is nessecary to avoid influence of previously executed
diff --git a/polygerrit-ui/app/test/test-app-context-init.ts b/polygerrit-ui/app/test/test-app-context-init.ts
index 4e22e44..491a891 100644
--- a/polygerrit-ui/app/test/test-app-context-init.ts
+++ b/polygerrit-ui/app/test/test-app-context-init.ts
@@ -30,7 +30,10 @@
import {ChecksModel} from '../services/checks/checks-model';
import {GrJsApiInterface} from '../elements/shared/gr-js-api-interface/gr-js-api-interface-element';
import {UserModel} from '../services/user/user-model';
-import {CommentsModel} from '../services/comments/comments-model';
+import {
+ CommentsModel,
+ commentsModelToken,
+} from '../services/comments/comments-model';
import {RouterModel} from '../services/router/router-model';
import {ShortcutsService} from '../services/shortcuts/shortcuts-service';
import {ConfigModel} from '../services/config/config-model';
@@ -58,22 +61,6 @@
assertIsDefined(restApiService, 'restApiService');
return new ChangeModel(routerModel, restApiService);
},
- commentsModel: (ctx: Partial<AppContext>) => {
- const routerModel = ctx.routerModel;
- const changeModel = ctx.changeModel;
- const restApiService = ctx.restApiService;
- const reportingService = ctx.reportingService;
- assertIsDefined(routerModel, 'routerModel');
- assertIsDefined(changeModel, 'changeModel');
- assertIsDefined(restApiService, 'restApiService');
- assertIsDefined(reportingService, 'reportingService');
- return new CommentsModel(
- routerModel,
- changeModel,
- restApiService,
- reportingService
- );
- },
checksModel: (ctx: Partial<AppContext>) => {
const routerModel = ctx.routerModel;
const changeModel = ctx.changeModel;
@@ -106,12 +93,27 @@
return create<AppContext>(appRegistry);
}
+export type Creator<T> = () => T & Finalizable;
+
+// Test dependencies are provides as creator functions to ensure that they are
+// not created if a test doesn't depend on them. E.g. don't create a
+// change-model in change-model_test.ts because it creates one in the test
+// after setting up stubs.
export function createTestDependencies(
appContext: AppContext
-): Map<DependencyToken<unknown>, Finalizable> {
+): Map<DependencyToken<unknown>, Creator<unknown>> {
const dependencies = new Map();
- const browserModel = new BrowserModel(appContext.userModel!);
+ const browserModel = () => new BrowserModel(appContext.userModel!);
dependencies.set(browserModelToken, browserModel);
+ const commentsModel = () =>
+ new CommentsModel(
+ appContext.routerModel,
+ appContext.changeModel,
+ appContext.restApiService,
+ appContext.reportingService
+ );
+ dependencies.set(commentsModelToken, commentsModel);
+
return dependencies;
}
diff --git a/polygerrit-ui/app/test/test-utils.ts b/polygerrit-ui/app/test/test-utils.ts
index a40f14a..7652039 100644
--- a/polygerrit-ui/app/test/test-utils.ts
+++ b/polygerrit-ui/app/test/test-utils.ts
@@ -23,7 +23,6 @@
import {StorageService} from '../services/storage/gr-storage';
import {AuthService} from '../services/gr-auth/gr-auth';
import {ReportingService} from '../services/gr-reporting/gr-reporting';
-import {CommentsModel} from '../services/comments/comments-model';
import {UserModel} from '../services/user/user-model';
import {ShortcutsService} from '../services/shortcuts/shortcuts-service';
import {queryAndAssert, query} from '../utils/common-util';
@@ -112,10 +111,6 @@
return sinon.spy(getAppContext().restApiService, method);
}
-export function stubComments<K extends keyof CommentsModel>(method: K) {
- return sinon.stub(getAppContext().commentsModel, method);
-}
-
export function stubUsers<K extends keyof UserModel>(method: K) {
return sinon.stub(getAppContext().userModel, method);
}