Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/super_sidebar/utils_spec.js')
-rw-r--r--spec/frontend/super_sidebar/utils_spec.js167
1 files changed, 162 insertions, 5 deletions
diff --git a/spec/frontend/super_sidebar/utils_spec.js b/spec/frontend/super_sidebar/utils_spec.js
index 8c8673ddbc4..536599e6c12 100644
--- a/spec/frontend/super_sidebar/utils_spec.js
+++ b/spec/frontend/super_sidebar/utils_spec.js
@@ -1,14 +1,21 @@
+import * as Sentry from '@sentry/browser';
import {
getTopFrequentItems,
trackContextAccess,
formatContextSwitcherItems,
+ getItemsFromLocalStorage,
+ removeItemFromLocalStorage,
ariaCurrent,
} from '~/super_sidebar/utils';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import AccessorUtilities from '~/lib/utils/accessor';
import { FREQUENT_ITEMS, FIFTEEN_MINUTES_IN_MS } from '~/frequent_items/constants';
import { unsortedFrequentItems, sortedFrequentItems } from '../frequent_items/mock_data';
-import { searchUserProjectsAndGroupsResponseMock } from './mock_data';
+import { cachedFrequentProjects, searchUserProjectsAndGroupsResponseMock } from './mock_data';
+
+jest.mock('@sentry/browser');
+
+useLocalStorageSpy();
describe('Super sidebar utils spec', () => {
describe('getTopFrequentItems', () => {
@@ -35,8 +42,6 @@ describe('Super sidebar utils spec', () => {
});
describe('trackContextAccess', () => {
- useLocalStorageSpy();
-
const username = 'root';
const context = {
namespace: 'groups',
@@ -65,7 +70,7 @@ describe('Super sidebar utils spec', () => {
);
});
- it('updates existing item if it was persisted to the local storage over 15 minutes ago', () => {
+ it('updates existing item frequency/access time if it was persisted to the local storage over 15 minutes ago', () => {
window.localStorage.setItem(
storageKey,
JSON.stringify([
@@ -90,7 +95,7 @@ describe('Super sidebar utils spec', () => {
);
});
- it('leaves item as is if it was persisted to the local storage under 15 minutes ago', () => {
+ it('leaves item frequency/access time as is if it was persisted to the local storage under 15 minutes ago', () => {
const jsonString = JSON.stringify([
{
id: 1,
@@ -109,6 +114,39 @@ describe('Super sidebar utils spec', () => {
expect(window.localStorage.setItem).toHaveBeenLastCalledWith(storageKey, jsonString);
});
+ it('always updates stored item metadata', () => {
+ window.localStorage.setItem(
+ storageKey,
+ JSON.stringify([
+ {
+ id: 1,
+ frequency: 2,
+ lastAccessedOn: Date.now(),
+ },
+ ]),
+ );
+
+ trackContextAccess(username, {
+ ...context,
+ item: {
+ ...context.item,
+ avatarUrl: '/group.png',
+ },
+ });
+
+ expect(window.localStorage.setItem).toHaveBeenCalledWith(
+ storageKey,
+ JSON.stringify([
+ {
+ id: 1,
+ avatarUrl: '/group.png',
+ frequency: 2,
+ lastAccessedOn: Date.now(),
+ },
+ ]),
+ );
+ });
+
it('replaces the least popular item in the local storage once the persisted items limit has been hit', () => {
// Add the maximum amount of items to the local storage, in increasing popularity
const storedItems = Array.from({ length: FREQUENT_ITEMS.MAX_COUNT }).map((_, i) => ({
@@ -159,6 +197,125 @@ describe('Super sidebar utils spec', () => {
});
});
+ describe('getItemsFromLocalStorage', () => {
+ const storageKey = 'mockStorageKey';
+ const maxItems = 5;
+ const storedItems = JSON.parse(cachedFrequentProjects);
+
+ beforeEach(() => {
+ window.localStorage.setItem(storageKey, cachedFrequentProjects);
+ });
+
+ describe('when localStorage cannot be accessed', () => {
+ beforeEach(() => {
+ jest.spyOn(AccessorUtilities, 'canUseLocalStorage').mockReturnValue(false);
+ });
+
+ it('returns an empty array', () => {
+ const items = getItemsFromLocalStorage({ storageKey, maxItems });
+ expect(items).toEqual([]);
+ });
+ });
+
+ describe('when localStorage contains parseable data', () => {
+ it('returns an array of items limited by max items', () => {
+ const items = getItemsFromLocalStorage({ storageKey, maxItems });
+ expect(items.length).toEqual(maxItems);
+
+ items.forEach((item) => {
+ expect(storedItems).toContainEqual(item);
+ });
+ });
+
+ it('returns all items if max items is large', () => {
+ const items = getItemsFromLocalStorage({ storageKey, maxItems: 1 });
+ expect(items.length).toEqual(1);
+
+ expect(storedItems).toContainEqual(items[0]);
+ });
+ });
+
+ describe('when localStorage contains unparseable data', () => {
+ let items;
+
+ beforeEach(() => {
+ window.localStorage.setItem(storageKey, 'unparseable');
+ items = getItemsFromLocalStorage({ storageKey, maxItems });
+ });
+
+ it('logs an error to Sentry', () => {
+ expect(Sentry.captureException).toHaveBeenCalled();
+ });
+
+ it('returns an empty array', () => {
+ expect(items).toEqual([]);
+ });
+ });
+ });
+
+ describe('removeItemFromLocalStorage', () => {
+ const storageKey = 'mockStorageKey';
+ const originalStoredItems = JSON.parse(cachedFrequentProjects);
+
+ beforeEach(() => {
+ window.localStorage.setItem(storageKey, cachedFrequentProjects);
+ });
+
+ describe('when given an item to delete', () => {
+ let items;
+ let modifiedStoredItems;
+
+ beforeEach(() => {
+ items = removeItemFromLocalStorage({ storageKey, item: { id: 3 } });
+ modifiedStoredItems = JSON.parse(window.localStorage.getItem(storageKey));
+ });
+
+ it('removes the item from localStorage', () => {
+ expect(modifiedStoredItems.length).toBe(originalStoredItems.length - 1);
+ expect(modifiedStoredItems).not.toContainEqual(originalStoredItems[2]);
+ });
+
+ it('returns the resulting stored structure', () => {
+ expect(items).toEqual(modifiedStoredItems);
+ });
+ });
+
+ describe('when given an unknown item to delete', () => {
+ let items;
+ let modifiedStoredItems;
+
+ beforeEach(() => {
+ items = removeItemFromLocalStorage({ storageKey, item: { id: 'does-not-exist' } });
+ modifiedStoredItems = JSON.parse(window.localStorage.getItem(storageKey));
+ });
+
+ it('does not change the stored value', () => {
+ expect(modifiedStoredItems).toEqual(originalStoredItems);
+ });
+
+ it('returns the stored structure', () => {
+ expect(items).toEqual(originalStoredItems);
+ });
+ });
+
+ describe('when localStorage has unparseable data', () => {
+ let items;
+
+ beforeEach(() => {
+ window.localStorage.setItem(storageKey, 'unparseable');
+ items = removeItemFromLocalStorage({ storageKey, item: { id: 3 } });
+ });
+
+ it('logs an error to Sentry', () => {
+ expect(Sentry.captureException).toHaveBeenCalled();
+ });
+
+ it('returns an empty array', () => {
+ expect(items).toEqual([]);
+ });
+ });
+ });
+
describe('ariaCurrent', () => {
it.each`
isActive | expected