Convert gr-storage to service
Change-Id: Iaf731da59e52eee9d62badcf57f7a5fc76d8933d
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
index 7fb09df..e0e2e46 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
@@ -21,7 +21,6 @@
import '../../shared/gr-button/gr-button';
import '../../shared/gr-formatted-text/gr-formatted-text';
import '../../shared/gr-overlay/gr-overlay';
-import '../../shared/gr-storage/gr-storage';
import '../../shared/gr-account-list/gr-account-list';
import '../gr-label-scores/gr-label-scores';
import '../gr-thread-list/gr-thread-list';
@@ -98,7 +97,6 @@
import {GrTextarea} from '../../shared/gr-textarea/gr-textarea';
import {GrAccountChip} from '../../shared/gr-account-chip/gr-account-chip';
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
-import {GrStorage, StorageLocation} from '../../shared/gr-storage/gr-storage';
import {isAttentionSetEnabled} from '../../../utils/attention-set-util';
import {
CODE_REVIEW,
@@ -114,6 +112,7 @@
} from '../../../utils/event-util';
import {ErrorCallback} from '../../../api/rest';
import {debounce, DelayedTask} from '../../../utils/async-util';
+import {StorageLocation} from '../../../services/storage/gr-storage';
const STORAGE_DEBOUNCE_INTERVAL_MS = 400;
@@ -374,7 +373,7 @@
private readonly restApiService = appContext.restApiService;
- private readonly storage = new GrStorage();
+ private readonly storage = appContext.storageService;
private readonly jsAPI = appContext.jsApiService;
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
index d0d40ca..c1e2564 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
@@ -18,7 +18,7 @@
import '../../../test/common-test-setup-karma.js';
import {IronOverlayManager} from '@polymer/iron-overlay-behavior/iron-overlay-manager.js';
import './gr-reply-dialog.js';
-import {mockPromise} from '../../../test/test-utils.js';
+import {mockPromise, stubStorage} from '../../../test/test-utils.js';
import {SpecialFilePath} from '../../../constants/constants.js';
import {appContext} from '../../../services/app-context.js';
import {addListenerForTest} from '../../../test/test-utils.js';
@@ -113,9 +113,9 @@
],
};
- getDraftCommentStub = sinon.stub(element.storage, 'getDraftComment');
- setDraftCommentStub = sinon.stub(element.storage, 'setDraftComment');
- eraseDraftCommentStub = sinon.stub(element.storage, 'eraseDraftComment');
+ getDraftCommentStub = stubStorage('getDraftComment');
+ setDraftCommentStub = stubStorage('setDraftComment');
+ eraseDraftCommentStub = stubStorage('eraseDraftComment');
// sinon.stub(patchSetUtilMockProxy, 'fetchChangeUpdates')
// .returns(Promise.resolve({isLatest: true}));
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts
index 7c4e8d6..fb8c2e0 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.ts
@@ -18,7 +18,6 @@
import '../../plugins/gr-endpoint-param/gr-endpoint-param';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-editable-label/gr-editable-label';
-import '../../shared/gr-storage/gr-storage';
import '../gr-default-editor/gr-default-editor';
import '../../../styles/shared-styles';
import {PolymerElement} from '@polymer/polymer/polymer-element';
@@ -38,7 +37,6 @@
NumericChangeId,
EditPatchSetNum,
} from '../../../types/common';
-import {GrStorage} from '../../shared/gr-storage/gr-storage';
import {HttpMethod, NotifyType} from '../../../constants/constants';
import {fireAlert, fireTitleChange} from '../../../utils/event-util';
import {appContext} from '../../../services/app-context';
@@ -117,7 +115,7 @@
private readonly restApiService = appContext.restApiService;
- private readonly storage = new GrStorage();
+ private readonly storage = appContext.storageService;
private storeTask?: DelayedTask;
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 a57bdfa..7e67fb8 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
@@ -15,7 +15,6 @@
* limitations under the License.
*/
import '../../../styles/shared-styles';
-import '../gr-storage/gr-storage';
import '../gr-comment/gr-comment';
import '../../diff/gr-diff/gr-diff';
import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
@@ -51,7 +50,6 @@
} from '../../../types/common';
import {GrComment} from '../gr-comment/gr-comment';
import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces';
-import {GrStorage, StorageLocation} from '../gr-storage/gr-storage';
import {CustomKeyboardEvent} from '../../../types/events';
import {LineNumber, FILE} from '../../diff/gr-diff/gr-diff-line';
import {GrButton} from '../gr-button/gr-button';
@@ -61,6 +59,7 @@
import {check, assertIsDefined} from '../../../utils/common-util';
import {waitForEventOnce} from '../../../utils/event-util';
import {GrSyntaxLayer} from '../../diff/gr-syntax-layer/gr-syntax-layer';
+import {StorageLocation} from '../../../services/storage/gr-storage';
const UNRESOLVED_EXPAND_COUNT = 5;
const NEWLINE_PATTERN = /\n/g;
@@ -208,7 +207,7 @@
flagsService = appContext.flagsService;
- readonly storage = new GrStorage();
+ readonly storage = appContext.storageService;
private readonly syntaxLayer = new GrSyntaxLayer();
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 8b15203..35b0d8c 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
@@ -44,8 +44,8 @@
tap,
pressAndReleaseKeyOn,
} from '@polymer/iron-test-helpers/mock-interactions';
-import {html} from '@polymer/polymer/lib/utils/html-tag';
-import {stubRestApi} from '../../../test/test-utils';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+import {stubRestApi, stubStorage} from '../../../test/test-utils';
const basicFixture = fixtureFromElement('gr-comment-thread');
@@ -652,7 +652,7 @@
__draft: true,
},
];
- const storageStub = sinon.stub(element.storage, 'setDraftComment');
+ const storageStub = stubStorage('setDraftComment');
flush();
const draftEl = element.root?.querySelectorAll('gr-comment')[1];
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 7fb85a4..b7f1bcc 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.ts
@@ -24,7 +24,6 @@
import '../gr-formatted-text/gr-formatted-text';
import '../gr-icons/gr-icons';
import '../gr-overlay/gr-overlay';
-import '../gr-storage/gr-storage';
import '../gr-textarea/gr-textarea';
import '../gr-tooltip-content/gr-tooltip-content';
import '../gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog';
@@ -38,7 +37,6 @@
import {customElement, observe, property} from '@polymer/decorators';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {GrTextarea} from '../gr-textarea/gr-textarea';
-import {GrStorage, StorageLocation} from '../gr-storage/gr-storage';
import {GrOverlay} from '../gr-overlay/gr-overlay';
import {
AccountDetailInfo,
@@ -62,6 +60,7 @@
import {pluralize} from '../../../utils/string-util';
import {assertIsDefined} from '../../../utils/common-util';
import {debounce, DelayedTask} from '../../../utils/async-util';
+import {StorageLocation} from '../../../services/storage/gr-storage';
const STORAGE_DEBOUNCE_INTERVAL = 400;
const TOAST_DEBOUNCE_INTERVAL = 200;
@@ -269,7 +268,7 @@
private readonly restApiService = appContext.restApiService;
- private readonly storage = new GrStorage();
+ private readonly storage = appContext.storageService;
reporting = appContext.reportingService;
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
index b5205a6..be647ab 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
@@ -20,7 +20,7 @@
import {html} from '@polymer/polymer/lib/utils/html-tag.js';
import {__testOnly_UNSAVED_MESSAGE} from './gr-comment.js';
import {SpecialFilePath, Side} from '../../../constants/constants.js';
-import {stubRestApi} from '../../../test/test-utils.js';
+import {stubRestApi, stubStorage} from '../../../test/test-utils.js';
const basicFixture = fixtureFromElement('gr-comment');
@@ -115,7 +115,7 @@
});
test('message is not retrieved from storage when other edits', done => {
- const storageStub = sinon.stub(element.storage, 'getDraftComment');
+ const storageStub = stubStorage('getDraftComment');
const loadSpy = sinon.spy(element, '_loadLocalDraft');
element.changeNum = 1;
@@ -135,7 +135,7 @@
});
test('message is retrieved from storage when no other edits', done => {
- const storageStub = sinon.stub(element.storage, 'getDraftComment');
+ const storageStub = stubStorage('getDraftComment');
const loadSpy = sinon.spy(element, '_loadLocalDraft');
element.changeNum = 1;
@@ -1022,8 +1022,8 @@
test('cancelling an unsaved draft discards, persists in storage', () => {
const discardSpy = sinon.spy(element, '_fireDiscard');
- const storeStub = sinon.stub(element.storage, 'setDraftComment');
- const eraseStub = sinon.stub(element.storage, 'eraseDraftComment');
+ const storeStub = stubStorage('setDraftComment');
+ const eraseStub = stubStorage('eraseDraftComment');
element._messageText = 'test text';
flush();
element.storeTask.flush();
@@ -1038,7 +1038,7 @@
test('cancelling edit on a saved draft does not store', () => {
element.comment.id = 'foo';
const discardSpy = sinon.spy(element, '_fireDiscard');
- const storeStub = sinon.stub(element.storage, 'setDraftComment');
+ const storeStub = stubStorage('setDraftComment');
element._messageText = 'test text';
flush();
if (element.storeTask) element.storeTask.flush();
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
index 12f07ba..096697f 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.ts
@@ -16,9 +16,7 @@
*/
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
import '../../../styles/shared-styles';
-import '../gr-storage/gr-storage';
import '../gr-button/gr-button';
-import {GrStorage} from '../gr-storage/gr-storage';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {customElement, property} from '@polymer/decorators';
import {htmlTemplate} from './gr-editable-content_html';
@@ -111,7 +109,7 @@
@property({type: Boolean})
_isNewChangeSummaryUiEnabled = false;
- private readonly storage = new GrStorage();
+ private readonly storage = appContext.storageService;
private readonly flagsService = appContext.flagsService;
diff --git a/polygerrit-ui/app/services/app-context-init.ts b/polygerrit-ui/app/services/app-context-init.ts
index 0369ccf..479ab88 100644
--- a/polygerrit-ui/app/services/app-context-init.ts
+++ b/polygerrit-ui/app/services/app-context-init.ts
@@ -23,6 +23,7 @@
import {ChangeService} from './change/change-service';
import {ChecksService} from './checks/checks-service';
import {GrJsApiInterface} from '../elements/shared/gr-js-api-interface/gr-js-api-interface-element';
+import {GrStorageService} from './storage/gr-storage_impl';
type ServiceName = keyof AppContext;
type ServiceCreator<T> = () => T;
@@ -73,5 +74,6 @@
changeService: () => new ChangeService(),
checksService: () => new ChecksService(),
jsApiService: () => new GrJsApiInterface(),
+ storageService: () => new GrStorageService(),
});
}
diff --git a/polygerrit-ui/app/services/app-context.ts b/polygerrit-ui/app/services/app-context.ts
index 1f618fd..cf186f0 100644
--- a/polygerrit-ui/app/services/app-context.ts
+++ b/polygerrit-ui/app/services/app-context.ts
@@ -22,6 +22,7 @@
import {ChangeService} from './change/change-service';
import {ChecksService} from './checks/checks-service';
import {JsApiService} from '../elements/shared/gr-js-api-interface/gr-js-api-types';
+import {StorageService} from './storage/gr-storage';
export interface AppContext {
flagsService: FlagsService;
@@ -32,6 +33,7 @@
changeService: ChangeService;
checksService: ChecksService;
jsApiService: JsApiService;
+ storageService: StorageService;
}
/**
diff --git a/polygerrit-ui/app/services/storage/gr-storage.ts b/polygerrit-ui/app/services/storage/gr-storage.ts
new file mode 100644
index 0000000..08a3387
--- /dev/null
+++ b/polygerrit-ui/app/services/storage/gr-storage.ts
@@ -0,0 +1,49 @@
+/**
+ * @license
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {CommentRange, PatchSetNum} from '../../types/common';
+
+export interface StorageLocation {
+ changeNum: number;
+ patchNum: PatchSetNum | '@change';
+ path?: string;
+ line?: number;
+ range?: CommentRange;
+}
+
+export interface StorageObject {
+ message?: string;
+ updated: number;
+}
+
+export interface StorageService {
+ getDraftComment(location: StorageLocation): StorageObject | null;
+
+ setDraftComment(location: StorageLocation, message: string): void;
+
+ eraseDraftComment(location: StorageLocation): void;
+
+ getEditableContentItem(key: string): StorageObject | null;
+
+ setEditableContentItem(key: string, message: string): void;
+
+ getRespectfulTipVisibility(): StorageObject | null;
+
+ setRespectfulTipVisibility(delayDays?: number): void;
+
+ eraseEditableContentItem(key: string): void;
+}
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.ts b/polygerrit-ui/app/services/storage/gr-storage_impl.ts
similarity index 72%
rename from polygerrit-ui/app/elements/shared/gr-storage/gr-storage.ts
rename to polygerrit-ui/app/services/storage/gr-storage_impl.ts
index a86d8f2..0c0d151 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.ts
+++ b/polygerrit-ui/app/services/storage/gr-storage_impl.ts
@@ -14,22 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {CommentRange, PatchSetNum} from '../../../types/common';
-export interface StorageLocation {
- changeNum: number;
- patchNum: PatchSetNum | '@change';
- path?: string;
- line?: number;
- range?: CommentRange;
-}
+import {StorageLocation, StorageObject, StorageService} from './gr-storage';
-export interface StorageObject {
- message?: string;
- updated: number;
-}
-
-const DURATION_DAY = 24 * 60 * 60 * 1000;
+export const DURATION_DAY = 24 * 60 * 60 * 1000;
// Clean up old entries no more frequently than one day.
const CLEANUP_THROTTLE_INTERVAL = DURATION_DAY;
@@ -39,7 +27,7 @@
CLEANUP_PREFIXES_MAX_AGE_MAP.set('draft', DURATION_DAY);
CLEANUP_PREFIXES_MAX_AGE_MAP.set('editablecontent', DURATION_DAY);
-export class GrStorage {
+export class GrStorageService implements StorageService {
private lastCleanup = 0;
private readonly storage = window.localStorage;
@@ -47,49 +35,49 @@
private exceededQuota = false;
getDraftComment(location: StorageLocation): StorageObject | null {
- this._cleanupItems();
- return this._getObject(this._getDraftKey(location));
+ this.cleanupItems();
+ return this.getObject(this.getDraftKey(location));
}
setDraftComment(location: StorageLocation, message: string) {
- const key = this._getDraftKey(location);
- this._setObject(key, {message, updated: Date.now()});
+ const key = this.getDraftKey(location);
+ this.setObject(key, {message, updated: Date.now()});
}
eraseDraftComment(location: StorageLocation) {
- const key = this._getDraftKey(location);
+ const key = this.getDraftKey(location);
this.storage.removeItem(key);
}
getEditableContentItem(key: string): StorageObject | null {
- this._cleanupItems();
- return this._getObject(this._getEditableContentKey(key));
+ this.cleanupItems();
+ return this.getObject(this.getEditableContentKey(key));
}
setEditableContentItem(key: string, message: string) {
- this._setObject(this._getEditableContentKey(key), {
+ this.setObject(this.getEditableContentKey(key), {
message,
updated: Date.now(),
});
}
getRespectfulTipVisibility(): StorageObject | null {
- this._cleanupItems();
- return this._getObject('respectfultip:visibility');
+ this.cleanupItems();
+ return this.getObject('respectfultip:visibility');
}
setRespectfulTipVisibility(delayDays = 0) {
- this._cleanupItems();
- this._setObject('respectfultip:visibility', {
+ this.cleanupItems();
+ this.setObject('respectfultip:visibility', {
updated: Date.now() + delayDays * DURATION_DAY,
});
}
eraseEditableContentItem(key: string) {
- this.storage.removeItem(this._getEditableContentKey(key));
+ this.storage.removeItem(this.getEditableContentKey(key));
}
- _getDraftKey(location: StorageLocation): string {
+ private getDraftKey(location: StorageLocation): string {
const range = location.range
? `${location.range.start_line}-${location.range.start_character}` +
`-${location.range.end_character}-${location.range.end_line}`
@@ -107,11 +95,11 @@
return key;
}
- _getEditableContentKey(key: string): string {
+ private getEditableContentKey(key: string): string {
return `editablecontent:${key}`;
}
- _cleanupItems() {
+ private cleanupItems() {
// Throttle cleanup to the throttle interval.
if (
this.lastCleanup &&
@@ -125,7 +113,7 @@
const entries = CLEANUP_PREFIXES_MAX_AGE_MAP.entries();
for (const [prefix, expiration] of entries) {
if (key.startsWith(prefix)) {
- const item = this._getObject(key);
+ const item = this.getObject(key);
if (!item || Date.now() - item.updated > expiration) {
this.storage.removeItem(key);
}
@@ -134,7 +122,7 @@
});
}
- _getObject(key: string): StorageObject | null {
+ private getObject(key: string): StorageObject | null {
const serial = this.storage.getItem(key);
if (!serial) {
return null;
@@ -142,7 +130,7 @@
return JSON.parse(serial) as StorageObject;
}
- _setObject(key: string, obj: StorageObject) {
+ private setObject(key: string, obj: StorageObject) {
if (this.exceededQuota) {
return;
}
diff --git a/polygerrit-ui/app/services/storage/gr-storage_mock.ts b/polygerrit-ui/app/services/storage/gr-storage_mock.ts
new file mode 100644
index 0000000..02215a8
--- /dev/null
+++ b/polygerrit-ui/app/services/storage/gr-storage_mock.ts
@@ -0,0 +1,91 @@
+/**
+ * @license
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {StorageLocation, StorageObject, StorageService} from './gr-storage';
+import {DURATION_DAY} from './gr-storage_impl';
+
+const storage = new Map();
+
+const getDraftKey = (location: StorageLocation): string => {
+ const range = location.range
+ ? `${location.range.start_line}-${location.range.start_character}` +
+ `-${location.range.end_character}-${location.range.end_line}`
+ : null;
+ let key = [
+ 'draft',
+ location.changeNum,
+ location.patchNum,
+ location.path,
+ location.line || '',
+ ].join(':');
+ if (range) {
+ key = key + ':' + range;
+ }
+ return key;
+};
+
+const getEditableContentKey = (key: string): string => {
+ return `editablecontent:${key}`;
+};
+
+export function cleanUpStorage() {
+ storage.clear();
+}
+
+export const grStorageMock: StorageService = {
+ getDraftComment(location: StorageLocation): StorageObject | null {
+ return storage.get(getDraftKey(location));
+ },
+
+ setDraftComment(location: StorageLocation, message: string) {
+ const key = getDraftKey(location);
+ storage.set(key, {message, updated: Date.now()});
+ },
+
+ eraseDraftComment(location: StorageLocation) {
+ const key = getDraftKey(location);
+ storage.delete(key);
+ },
+
+ getEditableContentItem(key: string): StorageObject | null {
+ return storage.get(getEditableContentKey(key));
+ },
+
+ setEditableContentItem(key: string, message: string): void {
+ storage.set(
+ getEditableContentKey(key),
+ JSON.stringify({
+ message,
+ updated: Date.now(),
+ })
+ );
+ },
+
+ getRespectfulTipVisibility(): StorageObject | null {
+ return storage.get('respectfultip:visibility');
+ },
+
+ setRespectfulTipVisibility(delayDays = 0): void {
+ storage.set('respectfultip:visibility', {
+ updated: Date.now() + delayDays * DURATION_DAY,
+ });
+ },
+
+ eraseEditableContentItem(key: string): void {
+ storage.delete(getEditableContentKey(key));
+ },
+};
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js b/polygerrit-ui/app/services/storage/gr-storage_test.js
similarity index 87%
rename from polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
rename to polygerrit-ui/app/services/storage/gr-storage_test.js
index 64d3750..6cbfacf 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
+++ b/polygerrit-ui/app/services/storage/gr-storage_test.js
@@ -15,8 +15,8 @@
* limitations under the License.
*/
-import '../../../test/common-test-setup-karma.js';
-import {GrStorage} from './gr-storage.js';
+import '../../test/common-test-setup-karma.js';
+import {GrStorageService} from './gr-storage_impl.js';
suite('gr-storage tests', () => {
let grStorage;
@@ -34,7 +34,7 @@
}
setup(() => {
- grStorage = new GrStorage();
+ grStorage = new GrStorageService();
grStorage.storage = mockStorage();
});
@@ -51,7 +51,7 @@
};
// The key is in the expected format.
- const key = grStorage._getDraftKey(location);
+ const key = grStorage.getDraftKey(location);
assert.equal(key, ['draft', changeNum, patchNum, path, line].join(':'));
// There should be no draft initially.
@@ -82,12 +82,12 @@
line,
};
- const key = grStorage._getDraftKey(location);
+ const key = grStorage.getDraftKey(location);
// Make sure that the call to cleanup doesn't get throttled.
grStorage.lastCleanup = 0;
- const cleanupSpy = sinon.spy(grStorage, '_cleanupItems');
+ const cleanupSpy = sinon.spy(grStorage, 'cleanupItems');
// Create a message with a timestamp that is a second behind the max age.
grStorage.storage.setItem(key, JSON.stringify({
@@ -103,7 +103,7 @@
assert.isNotOk(grStorage.storage.getItem(key));
});
- test('_getDraftKey', () => {
+ test('getDraftKey', () => {
const changeNum = 1234;
const patchNum = 5;
const path = 'my_source_file.js';
@@ -115,7 +115,7 @@
line,
};
let expectedResult = 'draft:1234:5:my_source_file.js:123';
- assert.equal(grStorage._getDraftKey(location), expectedResult);
+ assert.equal(grStorage.getDraftKey(location), expectedResult);
location.range = {
start_character: 1,
start_line: 1,
@@ -123,7 +123,7 @@
end_line: 2,
};
expectedResult = 'draft:1234:5:my_source_file.js:123:1-1-1-2';
- assert.equal(grStorage._getDraftKey(location), expectedResult);
+ assert.equal(grStorage.getDraftKey(location), expectedResult);
});
test('exceeded quota disables storage', () => {
@@ -140,16 +140,16 @@
path,
line,
};
- const key = grStorage._getDraftKey(location);
+ const key = grStorage.getDraftKey(location);
grStorage.setDraftComment(location, 'my comment');
assert.isTrue(grStorage.exceededQuota);
assert.isNotOk(grStorage.storage.getItem(key));
});
test('editable content items', () => {
- const cleanupStub = sinon.stub(grStorage, '_cleanupItems');
+ const cleanupStub = sinon.stub(grStorage, 'cleanupItems');
const key = 'testKey';
- const computedKey = grStorage._getEditableContentKey(key);
+ const computedKey = grStorage.getEditableContentKey(key);
// Key correctly computed.
assert.equal(computedKey, 'editablecontent:testKey');
diff --git a/polygerrit-ui/app/test/common-test-setup.ts b/polygerrit-ui/app/test/common-test-setup.ts
index 848eeaf..34a13ba 100644
--- a/polygerrit-ui/app/test/common-test-setup.ts
+++ b/polygerrit-ui/app/test/common-test-setup.ts
@@ -43,6 +43,7 @@
installPolymerResin,
} from '../scripts/polymer-resin-install';
import {_testOnly_allTasks} from '../utils/async-util';
+import {cleanUpStorage} from '../services/storage/gr-storage_mock';
declare global {
interface Window {
@@ -204,6 +205,7 @@
checkGlobalSpace();
removeIronOverlayBackdropStyleEl();
cancelAllTasks();
+ cleanUpStorage();
const testTeardownTimestampMs = new Date().getTime();
const elapsedMs = testTeardownTimestampMs - testSetupTimestampMs;
if (elapsedMs > 1000) {
diff --git a/polygerrit-ui/app/test/test-app-context-init.ts b/polygerrit-ui/app/test/test-app-context-init.ts
index 57afd8a..d74a9c1 100644
--- a/polygerrit-ui/app/test/test-app-context-init.ts
+++ b/polygerrit-ui/app/test/test-app-context-init.ts
@@ -20,6 +20,7 @@
import {grReportingMock} from '../services/gr-reporting/gr-reporting_mock';
import {AppContext, appContext} from '../services/app-context';
import {grRestApiMock} from './mocks/gr-rest-api_mock';
+import {grStorageMock} from '../services/storage/gr-storage_mock';
export function _testOnlyInitAppContext() {
initAppContext();
@@ -36,4 +37,5 @@
}
setMock('reportingService', grReportingMock);
setMock('restApiService', grRestApiMock);
+ setMock('storageService', grStorageMock);
}
diff --git a/polygerrit-ui/app/test/test-utils.ts b/polygerrit-ui/app/test/test-utils.ts
index 50f465f..26b99ac 100644
--- a/polygerrit-ui/app/test/test-utils.ts
+++ b/polygerrit-ui/app/test/test-utils.ts
@@ -24,6 +24,7 @@
import {appContext} from '../services/app-context';
import {RestApiService} from '../services/gr-rest-api/gr-rest-api';
import {SinonSpy} from 'sinon/pkg/sinon-esm';
+import {StorageService} from '../services/storage/gr-storage';
export interface MockPromise extends Promise<unknown> {
resolve: (value?: unknown) => void;
@@ -165,6 +166,10 @@
return sinon.spy(appContext.restApiService, method);
}
+export function stubStorage<K extends keyof StorageService>(method: K) {
+ return sinon.stub(appContext.storageService, method);
+}
+
export type SinonSpyMember<F extends (...args: any) => any> = SinonSpy<
Parameters<F>,
ReturnType<F>