From 3fcc7460f0e4c833f2075ad943e3bd46033afa3a Mon Sep 17 00:00:00 2001 From: kushalpandya Date: Mon, 4 Sep 2017 21:55:56 +0530 Subject: [PATCH] Projects Dropdown App Service Spec --- .../service/projects_service_spec.js | 178 ++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 spec/javascripts/projects_dropdown/service/projects_service_spec.js diff --git a/spec/javascripts/projects_dropdown/service/projects_service_spec.js b/spec/javascripts/projects_dropdown/service/projects_service_spec.js new file mode 100644 index 00000000000..e9aabfaec1f --- /dev/null +++ b/spec/javascripts/projects_dropdown/service/projects_service_spec.js @@ -0,0 +1,178 @@ +import Vue from 'vue'; +import VueResource from 'vue-resource'; + +import bp from '~/breakpoints'; +import ProjectsService from '~/projects_dropdown/service/projects_service'; +import { FREQUENT_PROJECTS } from '~/projects_dropdown/constants'; +import { currentSession, unsortedFrequents, sortedFrequents } from '../mock_data'; + +Vue.use(VueResource); + +FREQUENT_PROJECTS.MAX_COUNT = 3; + +describe('ProjectsService', () => { + let service; + + beforeEach(() => { + gon.api_version = currentSession.apiVersion; + service = new ProjectsService(currentSession.username); + }); + + describe('contructor', () => { + it('should initialize default properties of class', () => { + expect(service.isLocalStorageAvailable).toBeTruthy(); + expect(service.currentUserName).toBe(currentSession.username); + expect(service.storageKey).toBe(currentSession.storageKey); + expect(service.projectsPath).toBeDefined(); + }); + }); + + describe('getSearchedProjects', () => { + it('should return promise from VueResource HTTP GET', () => { + spyOn(service.projectsPath, 'get').and.stub(); + + const searchQuery = 'lab'; + const queryParams = { + simple: false, + per_page: 20, + membership: false, + order_by: 'last_activity_at', + search: searchQuery, + }; + + service.getSearchedProjects(searchQuery); + expect(service.projectsPath.get).toHaveBeenCalledWith(queryParams); + }); + }); + + describe('logProjectAccess', () => { + let storage; + + beforeEach(() => { + storage = {}; + + spyOn(window.localStorage, 'setItem').and.callFake((storageKey, value) => { + storage[storageKey] = value; + }); + + spyOn(window.localStorage, 'getItem').and.callFake((storageKey) => { + if (storage[storageKey]) { + return storage[storageKey]; + } + + return null; + }); + }); + + it('should create a project store if it does not exist and adds a project', () => { + service.logProjectAccess(currentSession.project); + + const projects = JSON.parse(storage[currentSession.storageKey]); + expect(projects.length).toBe(1); + expect(projects[0].frequency).toBe(1); + expect(projects[0].lastAccessedOn).toBeDefined(); + }); + + it('should prevent inserting same report multiple times into store', () => { + service.logProjectAccess(currentSession.project); + service.logProjectAccess(currentSession.project); + + const projects = JSON.parse(storage[currentSession.storageKey]); + expect(projects.length).toBe(1); + }); + + it('should increase frequency of report if it was logged multiple times over the course of an hour', () => { + let projects; + spyOn(Math, 'abs').and.returnValue(3600001); // this will lead to `diff` > 1; + service.logProjectAccess(currentSession.project); + + projects = JSON.parse(storage[currentSession.storageKey]); + expect(projects[0].frequency).toBe(1); + + service.logProjectAccess(currentSession.project); + projects = JSON.parse(storage[currentSession.storageKey]); + expect(projects[0].frequency).toBe(2); + expect(projects[0].lastAccessedOn).not.toBe(currentSession.project.lastAccessedOn); + }); + + it('should always update project metadata', () => { + let projects; + const oldProject = { + ...currentSession.project, + }; + + const newProject = { + ...currentSession.project, + name: 'New Name', + avatarUrl: 'new/avatar.png', + namespace: 'New / Namespace', + webUrl: 'http://localhost/new/web/url', + }; + + service.logProjectAccess(oldProject); + projects = JSON.parse(storage[currentSession.storageKey]); + expect(projects[0].name).toBe(oldProject.name); + expect(projects[0].avatarUrl).toBe(oldProject.avatarUrl); + expect(projects[0].namespace).toBe(oldProject.namespace); + expect(projects[0].webUrl).toBe(oldProject.webUrl); + + service.logProjectAccess(newProject); + projects = JSON.parse(storage[currentSession.storageKey]); + expect(projects[0].name).toBe(newProject.name); + expect(projects[0].avatarUrl).toBe(newProject.avatarUrl); + expect(projects[0].namespace).toBe(newProject.namespace); + expect(projects[0].webUrl).toBe(newProject.webUrl); + }); + + it('should not add more than 20 projects in store', () => { + for (let i = 1; i <= 5; i += 1) { + const project = Object.assign(currentSession.project, { id: i }); + service.logProjectAccess(project); + } + + const projects = JSON.parse(storage[currentSession.storageKey]); + expect(projects.length).toBe(3); + }); + }); + + describe('getTopFrequentProjects', () => { + let storage = {}; + + beforeEach(() => { + storage[currentSession.storageKey] = JSON.stringify(unsortedFrequents); + + spyOn(window.localStorage, 'getItem').and.callFake((storageKey) => { + if (storage[storageKey]) { + return storage[storageKey]; + } + + return null; + }); + }); + + it('should return top 5 frequently accessed projects for desktop screens', () => { + spyOn(bp, 'getBreakpointSize').and.returnValue('md'); + const frequentProjects = service.getTopFrequentProjects(); + + expect(frequentProjects.length).toBe(5); + frequentProjects.forEach((project, index) => { + expect(project.id).toBe(sortedFrequents[index].id); + }); + }); + + it('should return top 3 frequently accessed projects for mobile screens', () => { + spyOn(bp, 'getBreakpointSize').and.returnValue('sm'); + const frequentProjects = service.getTopFrequentProjects(); + + expect(frequentProjects.length).toBe(3); + frequentProjects.forEach((project, index) => { + expect(project.id).toBe(sortedFrequents[index].id); + }); + }); + + it('should return empty array if there are no projects available in store', () => { + storage = {}; + expect(service.getTopFrequentProjects().length).toBe(0); + }); + }); +});