Commit fd19c626 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'himkp-jest-frequent-item' into 'master'

Migrate spec/javascripts/frequent_items/ to Jest

Closes #32479 and #28698

See merge request gitlab-org/gitlab!32498
parents 8c92785b 527a0a8f
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { mountComponentWithStore } from 'helpers/vue_mount_component_helper';
import axios from '~/lib/utils/axios_utils';
import appComponent from '~/frequent_items/components/app.vue';
import eventHub from '~/frequent_items/event_hub';
......@@ -8,6 +8,10 @@ import store from '~/frequent_items/store';
import { FREQUENT_ITEMS, HOUR_IN_MS } from '~/frequent_items/constants';
import { getTopFrequentItems } from '~/frequent_items/utils';
import { currentSession, mockFrequentProjects, mockSearchedProjects } from '../mock_data';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import waitForPromises from 'helpers/wait_for_promises';
useLocalStorageSpy();
let session;
const createComponentWithStore = (namespace = 'projects') => {
......@@ -42,7 +46,7 @@ describe('Frequent Items App Component', () => {
describe('methods', () => {
describe('dropdownOpenHandler', () => {
it('should fetch frequent items when no search has been previously made on desktop', () => {
spyOn(vm, 'fetchFrequentItems');
jest.spyOn(vm, 'fetchFrequentItems').mockImplementation(() => {});
vm.dropdownOpenHandler();
......@@ -56,11 +60,11 @@ describe('Frequent Items App Component', () => {
beforeEach(() => {
storage = {};
spyOn(window.localStorage, 'setItem').and.callFake((storageKey, value) => {
localStorage.setItem.mockImplementation((storageKey, value) => {
storage[storageKey] = value;
});
spyOn(window.localStorage, 'getItem').and.callFake(storageKey => {
localStorage.getItem.mockImplementation(storageKey => {
if (storage[storageKey]) {
return storage[storageKey];
}
......@@ -156,12 +160,12 @@ describe('Frequent Items App Component', () => {
describe('created', () => {
it('should bind event listeners on eventHub', done => {
spyOn(eventHub, '$on');
jest.spyOn(eventHub, '$on').mockImplementation(() => {});
createComponentWithStore().$mount();
Vue.nextTick(() => {
expect(eventHub.$on).toHaveBeenCalledWith('projects-dropdownOpen', jasmine.any(Function));
expect(eventHub.$on).toHaveBeenCalledWith('projects-dropdownOpen', expect.any(Function));
done();
});
});
......@@ -169,13 +173,13 @@ describe('Frequent Items App Component', () => {
describe('beforeDestroy', () => {
it('should unbind event listeners on eventHub', done => {
spyOn(eventHub, '$off');
jest.spyOn(eventHub, '$off').mockImplementation(() => {});
vm.$mount();
vm.$destroy();
Vue.nextTick(() => {
expect(eventHub.$off).toHaveBeenCalledWith('projects-dropdownOpen', jasmine.any(Function));
expect(eventHub.$off).toHaveBeenCalledWith('projects-dropdownOpen', expect.any(Function));
done();
});
});
......@@ -211,9 +215,7 @@ describe('Frequent Items App Component', () => {
it('should render frequent projects list', done => {
const expectedResult = getTopFrequentItems(mockFrequentProjects);
spyOn(window.localStorage, 'getItem').and.callFake(() =>
JSON.stringify(mockFrequentProjects),
);
localStorage.getItem.mockImplementation(() => JSON.stringify(mockFrequentProjects));
expect(vm.$el.querySelectorAll('.frequent-items-list-container li').length).toBe(1);
......@@ -236,15 +238,7 @@ describe('Frequent Items App Component', () => {
.then(() => {
expect(vm.$el.querySelector('.loading-animation')).toBeDefined();
})
// This test waits for multiple ticks in order to allow the responses to
// propagate through each interceptor installed on the Axios instance.
// This shouldn't be necessary; this test should be refactored to avoid this.
// https://gitlab.com/gitlab-org/gitlab/issues/32479
.then(vm.$nextTick)
.then(vm.$nextTick)
.then(vm.$nextTick)
.then(waitForPromises)
.then(() => {
expect(vm.$el.querySelectorAll('.frequent-items-list-container li').length).toBe(
mockSearchedProjects.data.length,
......
import { TEST_HOST } from 'helpers/test_constants';
export const currentSession = {
groups: {
username: 'root',
storageKey: 'root/frequent-groups',
apiVersion: 'v4',
group: {
id: 1,
name: 'dummy-group',
full_name: 'dummy-parent-group',
webUrl: `${TEST_HOST}/dummy-group`,
avatarUrl: null,
lastAccessedOn: Date.now(),
},
},
projects: {
username: 'root',
storageKey: 'root/frequent-projects',
apiVersion: 'v4',
project: {
id: 1,
name: 'dummy-project',
namespace: 'SampleGroup / Dummy-Project',
webUrl: `${TEST_HOST}/samplegroup/dummy-project`,
avatarUrl: null,
lastAccessedOn: Date.now(),
},
},
};
export const mockNamespace = 'projects';
export const mockStorageKey = 'test-user/frequent-projects';
export const mockGroup = {
id: 1,
name: 'Sub451',
namespace: 'Commit451 / Sub451',
webUrl: `${TEST_HOST}/Commit451/Sub451`,
avatarUrl: null,
};
export const mockRawGroup = {
id: 1,
name: 'Sub451',
full_name: 'Commit451 / Sub451',
web_url: `${TEST_HOST}/Commit451/Sub451`,
avatar_url: null,
};
export const mockFrequentGroups = [
{
id: 3,
name: 'Subgroup451',
full_name: 'Commit451 / Subgroup451',
webUrl: '/Commit451/Subgroup451',
avatarUrl: null,
frequency: 7,
lastAccessedOn: 1497979281815,
},
{
id: 1,
name: 'Commit451',
full_name: 'Commit451',
webUrl: '/Commit451',
avatarUrl: null,
frequency: 3,
lastAccessedOn: 1497979281815,
},
];
export const mockSearchedGroups = [mockRawGroup];
export const mockProcessedSearchedGroups = [mockGroup];
export const mockProject = {
id: 1,
name: 'GitLab Community Edition',
namespace: 'gitlab-org / gitlab-ce',
webUrl: `${TEST_HOST}/gitlab-org/gitlab-foss`,
avatarUrl: null,
};
export const mockRawProject = {
id: 1,
name: 'GitLab Community Edition',
name_with_namespace: 'gitlab-org / gitlab-ce',
web_url: `${TEST_HOST}/gitlab-org/gitlab-foss`,
avatar_url: null,
};
export const mockFrequentProjects = [
{
id: 1,
......@@ -48,10 +137,34 @@ export const mockFrequentProjects = [
},
];
export const mockProject = {
id: 1,
name: 'GitLab Community Edition',
namespace: 'gitlab-org / gitlab-ce',
webUrl: `${TEST_HOST}/gitlab-org/gitlab-foss`,
avatarUrl: null,
};
export const mockSearchedProjects = { data: [mockRawProject] };
export const mockProcessedSearchedProjects = [mockProject];
export const unsortedFrequentItems = [
{ id: 1, frequency: 12, lastAccessedOn: 1491400843391 },
{ id: 2, frequency: 14, lastAccessedOn: 1488240890738 },
{ id: 3, frequency: 44, lastAccessedOn: 1497675908472 },
{ id: 4, frequency: 8, lastAccessedOn: 1497979281815 },
{ id: 5, frequency: 34, lastAccessedOn: 1488089211943 },
{ id: 6, frequency: 14, lastAccessedOn: 1493517292488 },
{ id: 7, frequency: 42, lastAccessedOn: 1486815299875 },
{ id: 8, frequency: 33, lastAccessedOn: 1500762279114 },
{ id: 10, frequency: 46, lastAccessedOn: 1483251641543 },
];
/**
* This const has a specific order which tests authenticity
* of `getTopFrequentItems` method so
* DO NOT change order of items in this const.
*/
export const sortedFrequentItems = [
{ id: 10, frequency: 46, lastAccessedOn: 1483251641543 },
{ id: 3, frequency: 44, lastAccessedOn: 1497675908472 },
{ id: 7, frequency: 42, lastAccessedOn: 1486815299875 },
{ id: 5, frequency: 34, lastAccessedOn: 1488089211943 },
{ id: 8, frequency: 33, lastAccessedOn: 1500762279114 },
{ id: 6, frequency: 14, lastAccessedOn: 1493517292488 },
{ id: 2, frequency: 14, lastAccessedOn: 1488240890738 },
{ id: 1, frequency: 12, lastAccessedOn: 1491400843391 },
{ id: 4, frequency: 8, lastAccessedOn: 1497979281815 },
];
import testAction from 'spec/helpers/vuex_action_helper';
import testAction from 'helpers/vuex_action_helper';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import AccessorUtilities from '~/lib/utils/accessor';
......@@ -109,7 +109,7 @@ describe('Frequent Items Dropdown Store Actions', () => {
});
it('should dispatch `receiveFrequentItemsError`', done => {
spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').and.returnValue(false);
jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(false);
mockedState.namespace = mockNamespace;
mockedState.storageKey = mockStorageKey;
......
......@@ -11,25 +11,25 @@ import { mockProject, unsortedFrequentItems, sortedFrequentItems } from './mock_
describe('Frequent Items utils spec', () => {
describe('isMobile', () => {
it('returns true when the screen is medium ', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('md');
jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('md');
expect(isMobile()).toBe(true);
});
it('returns true when the screen is small ', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('sm');
jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('sm');
expect(isMobile()).toBe(true);
});
it('returns true when the screen is extra-small ', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('xs');
jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('xs');
expect(isMobile()).toBe(true);
});
it('returns false when the screen is larger than medium ', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('lg');
jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('lg');
expect(isMobile()).toBe(false);
});
......@@ -43,21 +43,21 @@ describe('Frequent Items utils spec', () => {
});
it('returns correct amount of items for mobile', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('md');
jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('md');
const result = getTopFrequentItems(unsortedFrequentItems);
expect(result.length).toBe(FREQUENT_ITEMS.LIST_COUNT_MOBILE);
});
it('returns correct amount of items for desktop', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('xl');
jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('xl');
const result = getTopFrequentItems(unsortedFrequentItems);
expect(result.length).toBe(FREQUENT_ITEMS.LIST_COUNT_DESKTOP);
});
it('sorts frequent items in order of frequency and lastAccessedOn', () => {
spyOn(bp, 'getBreakpointSize').and.returnValue('xl');
jest.spyOn(bp, 'getBreakpointSize').mockReturnValue('xl');
const result = getTopFrequentItems(unsortedFrequentItems);
const expectedResult = sortedFrequentItems.slice(0, FREQUENT_ITEMS.LIST_COUNT_DESKTOP);
......
export const currentSession = {
groups: {
username: 'root',
storageKey: 'root/frequent-groups',
apiVersion: 'v4',
group: {
id: 1,
name: 'dummy-group',
full_name: 'dummy-parent-group',
webUrl: `${gl.TEST_HOST}/dummy-group`,
avatarUrl: null,
lastAccessedOn: Date.now(),
},
},
projects: {
username: 'root',
storageKey: 'root/frequent-projects',
apiVersion: 'v4',
project: {
id: 1,
name: 'dummy-project',
namespace: 'SampleGroup / Dummy-Project',
webUrl: `${gl.TEST_HOST}/samplegroup/dummy-project`,
avatarUrl: null,
lastAccessedOn: Date.now(),
},
},
};
export const mockNamespace = 'projects';
export const mockStorageKey = 'test-user/frequent-projects';
export const mockGroup = {
id: 1,
name: 'Sub451',
namespace: 'Commit451 / Sub451',
webUrl: `${gl.TEST_HOST}/Commit451/Sub451`,
avatarUrl: null,
};
export const mockRawGroup = {
id: 1,
name: 'Sub451',
full_name: 'Commit451 / Sub451',
web_url: `${gl.TEST_HOST}/Commit451/Sub451`,
avatar_url: null,
};
export const mockFrequentGroups = [
{
id: 3,
name: 'Subgroup451',
full_name: 'Commit451 / Subgroup451',
webUrl: '/Commit451/Subgroup451',
avatarUrl: null,
frequency: 7,
lastAccessedOn: 1497979281815,
},
{
id: 1,
name: 'Commit451',
full_name: 'Commit451',
webUrl: '/Commit451',
avatarUrl: null,
frequency: 3,
lastAccessedOn: 1497979281815,
},
];
export const mockSearchedGroups = [mockRawGroup];
export const mockProcessedSearchedGroups = [mockGroup];
export const mockProject = {
id: 1,
name: 'GitLab Community Edition',
namespace: 'gitlab-org / gitlab-ce',
webUrl: `${gl.TEST_HOST}/gitlab-org/gitlab-foss`,
avatarUrl: null,
};
export const mockRawProject = {
id: 1,
name: 'GitLab Community Edition',
name_with_namespace: 'gitlab-org / gitlab-ce',
web_url: `${gl.TEST_HOST}/gitlab-org/gitlab-foss`,
avatar_url: null,
};
export const mockFrequentProjects = [
{
id: 1,
name: 'GitLab Community Edition',
namespace: 'gitlab-org / gitlab-ce',
webUrl: `${gl.TEST_HOST}/gitlab-org/gitlab-foss`,
avatarUrl: null,
frequency: 1,
lastAccessedOn: Date.now(),
},
{
id: 2,
name: 'GitLab CI',
namespace: 'gitlab-org / gitlab-ci',
webUrl: `${gl.TEST_HOST}/gitlab-org/gitlab-ci`,
avatarUrl: null,
frequency: 9,
lastAccessedOn: Date.now(),
},
{
id: 3,
name: 'Typeahead.Js',
namespace: 'twitter / typeahead-js',
webUrl: `${gl.TEST_HOST}/twitter/typeahead-js`,
avatarUrl: '/uploads/-/system/project/avatar/7/TWBS.png',
frequency: 2,
lastAccessedOn: Date.now(),
},
{
id: 4,
name: 'Intel',
namespace: 'platform / hardware / bsp / intel',
webUrl: `${gl.TEST_HOST}/platform/hardware/bsp/intel`,
avatarUrl: null,
frequency: 3,
lastAccessedOn: Date.now(),
},
{
id: 5,
name: 'v4.4',
namespace: 'platform / hardware / bsp / kernel / common / v4.4',
webUrl: `${gl.TEST_HOST}/platform/hardware/bsp/kernel/common/v4.4`,
avatarUrl: null,
frequency: 8,
lastAccessedOn: Date.now(),
},
];
export const mockSearchedProjects = { data: [mockRawProject] };
export const mockProcessedSearchedProjects = [mockProject];
export const unsortedFrequentItems = [
{ id: 1, frequency: 12, lastAccessedOn: 1491400843391 },
{ id: 2, frequency: 14, lastAccessedOn: 1488240890738 },
{ id: 3, frequency: 44, lastAccessedOn: 1497675908472 },
{ id: 4, frequency: 8, lastAccessedOn: 1497979281815 },
{ id: 5, frequency: 34, lastAccessedOn: 1488089211943 },
{ id: 6, frequency: 14, lastAccessedOn: 1493517292488 },
{ id: 7, frequency: 42, lastAccessedOn: 1486815299875 },
{ id: 8, frequency: 33, lastAccessedOn: 1500762279114 },
{ id: 10, frequency: 46, lastAccessedOn: 1483251641543 },
];
/**
* This const has a specific order which tests authenticity
* of `getTopFrequentItems` method so
* DO NOT change order of items in this const.
*/
export const sortedFrequentItems = [
{ id: 10, frequency: 46, lastAccessedOn: 1483251641543 },
{ id: 3, frequency: 44, lastAccessedOn: 1497675908472 },
{ id: 7, frequency: 42, lastAccessedOn: 1486815299875 },
{ id: 5, frequency: 34, lastAccessedOn: 1488089211943 },
{ id: 8, frequency: 33, lastAccessedOn: 1500762279114 },
{ id: 6, frequency: 14, lastAccessedOn: 1493517292488 },
{ id: 2, frequency: 14, lastAccessedOn: 1488240890738 },
{ id: 1, frequency: 12, lastAccessedOn: 1491400843391 },
{ id: 4, frequency: 8, lastAccessedOn: 1497979281815 },
];
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment