diff options
Diffstat (limited to 'spec/javascripts')
20 files changed, 650 insertions, 135 deletions
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js index 0a6e042b700..ea7753c7a1d 100644 --- a/spec/javascripts/awards_handler_spec.js +++ b/spec/javascripts/awards_handler_spec.js @@ -287,6 +287,20 @@ import AwardsHandler from '~/awards_handler'; done.fail(`Failed to open and build emoji menu: ${err.message}`); }); }); + + it('should disregard invalid frequently used emoji that are being attempted to be added', function() { + awardsHandler.addEmojiToFrequentlyUsedList('8ball'); + awardsHandler.addEmojiToFrequentlyUsedList('invalid_emoji'); + awardsHandler.addEmojiToFrequentlyUsedList('grinning'); + + expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']); + }); + + it('should disregard invalid frequently used emoji already set in cookie', function() { + Cookies.set('frequently_used_emojis', '8ball,invalid_emoji,grinning'); + + expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']); + }); }); }); }).call(window); diff --git a/spec/javascripts/boards/board_blank_state_spec.js b/spec/javascripts/boards/board_blank_state_spec.js new file mode 100644 index 00000000000..47baf83512f --- /dev/null +++ b/spec/javascripts/boards/board_blank_state_spec.js @@ -0,0 +1,93 @@ +/* global BoardService */ +import Vue from 'vue'; +import '~/boards/stores/boards_store'; +import boardBlankState from '~/boards/components/board_blank_state'; +import './mock_data'; + +describe('Boards blank state', () => { + let vm; + let fail = false; + + beforeEach((done) => { + const Comp = Vue.extend(boardBlankState); + + gl.issueBoards.BoardsStore.create(); + gl.boardService = new BoardService('/test/issue-boards/board', '', '1'); + + spyOn(gl.boardService, 'generateDefaultLists').and.callFake(() => new Promise((resolve, reject) => { + if (fail) { + reject(); + } else { + resolve({ + json() { + return [{ + id: 1, + title: 'To Do', + label: { id: 1 }, + }, { + id: 2, + title: 'Doing', + label: { id: 2 }, + }]; + }, + }); + } + })); + + vm = new Comp(); + + setTimeout(() => { + vm.$mount(); + done(); + }); + }); + + it('renders pre-defined labels', () => { + expect( + vm.$el.querySelectorAll('.board-blank-state-list li').length, + ).toBe(2); + + expect( + vm.$el.querySelectorAll('.board-blank-state-list li')[0].textContent.trim(), + ).toEqual('To Do'); + + expect( + vm.$el.querySelectorAll('.board-blank-state-list li')[1].textContent.trim(), + ).toEqual('Doing'); + }); + + it('clears blank state', (done) => { + vm.$el.querySelector('.btn-default').click(); + + setTimeout(() => { + expect(gl.issueBoards.BoardsStore.welcomeIsHidden()).toBeTruthy(); + + done(); + }); + }); + + it('creates pre-defined labels', (done) => { + vm.$el.querySelector('.btn-create').click(); + + setTimeout(() => { + expect(gl.issueBoards.BoardsStore.state.lists.length).toBe(2); + expect(gl.issueBoards.BoardsStore.state.lists[0].title).toEqual('To Do'); + expect(gl.issueBoards.BoardsStore.state.lists[1].title).toEqual('Doing'); + + done(); + }); + }); + + it('resets the store if request fails', (done) => { + fail = true; + + vm.$el.querySelector('.btn-create').click(); + + setTimeout(() => { + expect(gl.issueBoards.BoardsStore.welcomeIsHidden()).toBeFalsy(); + expect(gl.issueBoards.BoardsStore.state.lists.length).toBe(1); + + done(); + }); + }); +}); diff --git a/spec/javascripts/build_spec.js b/spec/javascripts/build_spec.js index fe7f3d2e9c4..549c7af8ea8 100644 --- a/spec/javascripts/build_spec.js +++ b/spec/javascripts/build_spec.js @@ -17,7 +17,7 @@ describe('Build', () => { spyOn($, 'ajax'); }); - describe('constructor', () => { + describe('class constructor', () => { beforeEach(() => { jasmine.clock().install(); }); diff --git a/spec/javascripts/commit/pipelines/mock_data.js b/spec/javascripts/commit/pipelines/mock_data.js index 188908d66bd..82b00b4c1ec 100644 --- a/spec/javascripts/commit/pipelines/mock_data.js +++ b/spec/javascripts/commit/pipelines/mock_data.js @@ -1,5 +1,4 @@ -/* eslint-disable no-unused-vars */ -const pipeline = { +export default { id: 73, user: { name: 'Administrator', @@ -88,5 +87,3 @@ const pipeline = { created_at: '2017-01-16T17:13:59.800Z', updated_at: '2017-01-25T00:00:17.132Z', }; - -module.exports = pipeline; diff --git a/spec/javascripts/commit/pipelines/pipelines_spec.js b/spec/javascripts/commit/pipelines/pipelines_spec.js index f09c57978a1..75efcc06585 100644 --- a/spec/javascripts/commit/pipelines/pipelines_spec.js +++ b/spec/javascripts/commit/pipelines/pipelines_spec.js @@ -1,11 +1,6 @@ -/* global pipeline, Vue */ - -require('~/flash'); -require('~/commit/pipelines/pipelines_store'); -require('~/commit/pipelines/pipelines_service'); -require('~/commit/pipelines/pipelines_table'); -require('~/vue_shared/vue_resource_interceptor'); -const pipeline = require('./mock_data'); +import Vue from 'vue'; +import PipelinesTable from '~/commit/pipelines/pipelines_table'; +import pipeline from './mock_data'; describe('Pipelines table in Commits and Merge requests', () => { preloadFixtures('static/pipelines_table.html.raw'); @@ -33,7 +28,7 @@ describe('Pipelines table in Commits and Merge requests', () => { }); it('should render the empty state', (done) => { - const component = new gl.commits.pipelines.PipelinesTableView({ + const component = new PipelinesTable({ el: document.querySelector('#commit-pipeline-table-view'), }); @@ -62,7 +57,7 @@ describe('Pipelines table in Commits and Merge requests', () => { }); it('should render a table with the received pipelines', (done) => { - const component = new gl.commits.pipelines.PipelinesTableView({ + const component = new PipelinesTable({ el: document.querySelector('#commit-pipeline-table-view'), }); @@ -92,7 +87,7 @@ describe('Pipelines table in Commits and Merge requests', () => { }); it('should render empty state', (done) => { - const component = new gl.commits.pipelines.PipelinesTableView({ + const component = new PipelinesTable({ el: document.querySelector('#commit-pipeline-table-view'), }); diff --git a/spec/javascripts/commit/pipelines/pipelines_store_spec.js b/spec/javascripts/commit/pipelines/pipelines_store_spec.js deleted file mode 100644 index 4182a4b28ff..00000000000 --- a/spec/javascripts/commit/pipelines/pipelines_store_spec.js +++ /dev/null @@ -1,30 +0,0 @@ -const PipelinesStore = require('~/commit/pipelines/pipelines_store'); - -describe('Store', () => { - let store; - - beforeEach(() => { - store = new PipelinesStore(); - }); - - it('should start with a blank state', () => { - expect(store.state.pipelines.length).toBe(0); - }); - - it('should store an array of pipelines', () => { - const pipelines = [ - { - id: '1', - name: 'pipeline', - }, - { - id: '2', - name: 'pipeline_2', - }, - ]; - - store.storePipelines(pipelines); - - expect(store.state.pipelines.length).toBe(pipelines.length); - }); -}); diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js index 5c65903701b..e6538020896 100644 --- a/spec/javascripts/filtered_search/dropdown_utils_spec.js +++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js @@ -126,7 +126,11 @@ require('~/filtered_search/filtered_search_dropdown_manager'); beforeEach(() => { setFixtures(` - <input type="text" id="test" /> + <ul class="tokens-container"> + <li class="input-token"> + <input class="filtered-search" type="text" id="test" /> + </li> + </ul> `); input = document.getElementById('test'); @@ -142,7 +146,7 @@ require('~/filtered_search/filtered_search_dropdown_manager'); input.value = 'o'; updatedItem = gl.DropdownUtils.filterHint(input, { hint: 'label', - }, 'o'); + }); expect(updatedItem.droplab_hidden).toBe(true); }); @@ -150,6 +154,29 @@ require('~/filtered_search/filtered_search_dropdown_manager'); const updatedItem = gl.DropdownUtils.filterHint(input, {}, ''); expect(updatedItem.droplab_hidden).toBe(false); }); + + it('should allow multiple if item.type is array', () => { + input.value = 'label:~first la'; + const updatedItem = gl.DropdownUtils.filterHint(input, { + hint: 'label', + type: 'array', + }); + expect(updatedItem.droplab_hidden).toBe(false); + }); + + it('should prevent multiple if item.type is not array', () => { + input.value = 'milestone:~first mile'; + let updatedItem = gl.DropdownUtils.filterHint(input, { + hint: 'milestone', + }); + expect(updatedItem.droplab_hidden).toBe(true); + + updatedItem = gl.DropdownUtils.filterHint(input, { + hint: 'milestone', + type: 'string', + }); + expect(updatedItem.droplab_hidden).toBe(true); + }); }); describe('setDataValueIfSelected', () => { diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js index ae9c263d1d7..113161c21c6 100644 --- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js @@ -246,5 +246,17 @@ const FilteredSearchSpecHelper = require('../helpers/filtered_search_spec_helper expect(gl.FilteredSearchVisualTokens.unselectTokens).toHaveBeenCalled(); }); }); + + describe('toggleInputContainerFocus', () => { + it('toggles on focus', () => { + input.focus(); + expect(document.querySelector('.filtered-search-input-container').classList.contains('focus')).toEqual(true); + }); + + it('toggles on blur', () => { + input.blur(); + expect(document.querySelector('.filtered-search-input-container').classList.contains('focus')).toEqual(false); + }); + }); }); })(); diff --git a/spec/javascripts/gl_emoji_spec.js b/spec/javascripts/gl_emoji_spec.js index 9b44b25980c..b2b46640e5b 100644 --- a/spec/javascripts/gl_emoji_spec.js +++ b/spec/javascripts/gl_emoji_spec.js @@ -43,6 +43,11 @@ const emojiFixtureMap = { moji: '5️⃣', unicodeVersion: '3.0', }, + grey_question: { + name: 'grey_question', + moji: '❔', + unicodeVersion: '6.0', + }, }; function markupToDomElement(markup) { @@ -153,6 +158,37 @@ describe('gl_emoji', () => { }, ); }); + + it('question mark when invalid emoji name given', () => { + const name = 'invalid_emoji'; + const emojiKey = 'grey_question'; + const markup = glEmojiTag(name); + const glEmojiElement = markupToDomElement(markup); + testGlEmojiElement( + glEmojiElement, + emojiFixtureMap[emojiKey].name, + emojiFixtureMap[emojiKey].unicodeVersion, + emojiFixtureMap[emojiKey].moji, + ); + }); + + it('question mark with image fallback when invalid emoji name given', () => { + const name = 'invalid_emoji'; + const emojiKey = 'grey_question'; + const markup = glEmojiTag(name, { + forceFallback: true, + }); + const glEmojiElement = markupToDomElement(markup); + testGlEmojiElement( + glEmojiElement, + emojiFixtureMap[emojiKey].name, + emojiFixtureMap[emojiKey].unicodeVersion, + emojiFixtureMap[emojiKey].moji, + { + forceFallback: true, + }, + ); + }); }); describe('isFlagEmoji', () => { diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index 8d25500b9fd..aabc8bea12f 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -136,6 +136,21 @@ describe('Issue', function() { expectErrorMessage(); expect($('.issue_counter')).toHaveText(1); }); + + it('updates counter', () => { + spyOn(jQuery, 'ajax').and.callFake(function(req) { + expectPendingRequest(req, $btnClose); + req.success({ + id: 34 + }); + }); + + expect($('.issue_counter')).toHaveText(1); + $('.issue_counter').text('1,001'); + expect($('.issue_counter').text()).toEqual('1,001'); + $btnClose.trigger('click'); + expect($('.issue_counter').text()).toEqual('1,000'); + }); }); describe('reopen issue', function() { diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index fae462561e9..5cdb6473eda 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -32,10 +32,11 @@ testsContext.keys().forEach(function (path) { } }); -// workaround: include all source files to find files with 0% coverage -// see also https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15 -describe('Uncovered files', function () { - // the following files throw errors because of undefined variables +// if we're generating coverage reports, make sure to include all files so +// that we can catch files with 0% coverage +// see: https://github.com/deepsweet/istanbul-instrumenter-loader/issues/15 +if (process.env.BABEL_ENV === 'coverage') { + // exempt these files from the coverage report const troubleMakers = [ './blob_edit/blob_edit_bundle.js', './cycle_analytics/components/stage_plan_component.js', @@ -48,21 +49,23 @@ describe('Uncovered files', function () { './network/branch_graph.js', ]; - const sourceFiles = require.context('~', true, /^\.\/(?!application\.js).*\.(js|es6)$/); - sourceFiles.keys().forEach(function (path) { - // ignore if there is a matching spec file - if (testsContext.keys().indexOf(`${path.replace(/\.js(\.es6)?$/, '')}_spec`) > -1) { - return; - } + describe('Uncovered files', function () { + const sourceFiles = require.context('~', true, /\.js$/); + sourceFiles.keys().forEach(function (path) { + // ignore if there is a matching spec file + if (testsContext.keys().indexOf(`${path.replace(/\.js$/, '')}_spec`) > -1) { + return; + } - it(`includes '${path}'`, function () { - try { - sourceFiles(path); - } catch (err) { - if (troubleMakers.indexOf(path) === -1) { - expect(err).toBeNull(); + it(`includes '${path}'`, function () { + try { + sourceFiles(path); + } catch (err) { + if (troubleMakers.indexOf(path) === -1) { + expect(err).toBeNull(); + } } - } + }); }); }); -}); +} diff --git a/spec/javascripts/vue_pipelines_index/async_button_spec.js b/spec/javascripts/vue_pipelines_index/async_button_spec.js new file mode 100644 index 00000000000..bc8e504c413 --- /dev/null +++ b/spec/javascripts/vue_pipelines_index/async_button_spec.js @@ -0,0 +1,93 @@ +import Vue from 'vue'; +import asyncButtonComp from '~/vue_pipelines_index/components/async_button'; + +describe('Pipelines Async Button', () => { + let component; + let spy; + let AsyncButtonComponent; + + beforeEach(() => { + AsyncButtonComponent = Vue.extend(asyncButtonComp); + + spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); + + component = new AsyncButtonComponent({ + propsData: { + endpoint: '/foo', + title: 'Foo', + icon: 'fa fa-foo', + cssClass: 'bar', + service: { + postAction: spy, + }, + }, + }).$mount(); + }); + + it('should render a button', () => { + expect(component.$el.tagName).toEqual('BUTTON'); + }); + + it('should render the provided icon', () => { + expect(component.$el.querySelector('i').getAttribute('class')).toContain('fa fa-foo'); + }); + + it('should render the provided title', () => { + expect(component.$el.getAttribute('title')).toContain('Foo'); + expect(component.$el.getAttribute('aria-label')).toContain('Foo'); + }); + + it('should render the provided cssClass', () => { + expect(component.$el.getAttribute('class')).toContain('bar'); + }); + + it('should call the service when it is clicked with the provided endpoint', () => { + component.$el.click(); + expect(spy).toHaveBeenCalledWith('/foo'); + }); + + it('should hide loading if request fails', () => { + spy = jasmine.createSpy('spy').and.returnValue(Promise.reject()); + + component = new AsyncButtonComponent({ + propsData: { + endpoint: '/foo', + title: 'Foo', + icon: 'fa fa-foo', + cssClass: 'bar', + dataAttributes: { + 'data-foo': 'foo', + }, + service: { + postAction: spy, + }, + }, + }).$mount(); + + component.$el.click(); + expect(component.$el.querySelector('.fa-spinner')).toBe(null); + }); + + describe('With confirm dialog', () => { + it('should call the service when confimation is positive', () => { + spyOn(window, 'confirm').and.returnValue(true); + spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); + + component = new AsyncButtonComponent({ + propsData: { + endpoint: '/foo', + title: 'Foo', + icon: 'fa fa-foo', + cssClass: 'bar', + service: { + postAction: spy, + }, + confirmActionMessage: 'bar', + }, + }).$mount(); + + component.$el.click(); + expect(spy).toHaveBeenCalledWith('/foo'); + }); + }); +}); diff --git a/spec/javascripts/vue_pipelines_index/pipeline_url_spec.js b/spec/javascripts/vue_pipelines_index/pipeline_url_spec.js new file mode 100644 index 00000000000..96a2a37b5f7 --- /dev/null +++ b/spec/javascripts/vue_pipelines_index/pipeline_url_spec.js @@ -0,0 +1,100 @@ +import Vue from 'vue'; +import pipelineUrlComp from '~/vue_pipelines_index/components/pipeline_url'; + +describe('Pipeline Url Component', () => { + let PipelineUrlComponent; + + beforeEach(() => { + PipelineUrlComponent = Vue.extend(pipelineUrlComp); + }); + + it('should render a table cell', () => { + const component = new PipelineUrlComponent({ + propsData: { + pipeline: { + id: 1, + path: 'foo', + flags: {}, + }, + }, + }).$mount(); + + expect(component.$el.tagName).toEqual('TD'); + }); + + it('should render a link the provided path and id', () => { + const component = new PipelineUrlComponent({ + propsData: { + pipeline: { + id: 1, + path: 'foo', + flags: {}, + }, + }, + }).$mount(); + + expect(component.$el.querySelector('.js-pipeline-url-link').getAttribute('href')).toEqual('foo'); + expect(component.$el.querySelector('.js-pipeline-url-link span').textContent).toEqual('#1'); + }); + + it('should render user information when a user is provided', () => { + const mockData = { + pipeline: { + id: 1, + path: 'foo', + flags: {}, + user: { + web_url: '/', + name: 'foo', + avatar_url: '/', + }, + }, + }; + + const component = new PipelineUrlComponent({ + propsData: mockData, + }).$mount(); + + const image = component.$el.querySelector('.js-pipeline-url-user img'); + + expect( + component.$el.querySelector('.js-pipeline-url-user').getAttribute('href'), + ).toEqual(mockData.pipeline.user.web_url); + expect(image.getAttribute('title')).toEqual(mockData.pipeline.user.name); + expect(image.getAttribute('src')).toEqual(mockData.pipeline.user.avatar_url); + }); + + it('should render "API" when no user is provided', () => { + const component = new PipelineUrlComponent({ + propsData: { + pipeline: { + id: 1, + path: 'foo', + flags: {}, + }, + }, + }).$mount(); + + expect(component.$el.querySelector('.js-pipeline-url-api').textContent).toContain('API'); + }); + + it('should render latest, yaml invalid and stuck flags when provided', () => { + const component = new PipelineUrlComponent({ + propsData: { + pipeline: { + id: 1, + path: 'foo', + flags: { + latest: true, + yaml_errors: true, + stuck: true, + }, + }, + }, + }).$mount(); + + expect(component.$el.querySelector('.js-pipeline-url-lastest').textContent).toContain('latest'); + expect(component.$el.querySelector('.js-pipeline-url-yaml').textContent).toContain('yaml invalid'); + expect(component.$el.querySelector('.js-pipeline-url-stuck').textContent).toContain('stuck'); + }); +}); diff --git a/spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js b/spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js new file mode 100644 index 00000000000..dba998c7688 --- /dev/null +++ b/spec/javascripts/vue_pipelines_index/pipelines_actions_spec.js @@ -0,0 +1,62 @@ +import Vue from 'vue'; +import pipelinesActionsComp from '~/vue_pipelines_index/components/pipelines_actions'; + +describe('Pipelines Actions dropdown', () => { + let component; + let spy; + let actions; + let ActionsComponent; + + beforeEach(() => { + ActionsComponent = Vue.extend(pipelinesActionsComp); + + actions = [ + { + name: 'stop_review', + path: '/root/review-app/builds/1893/play', + }, + ]; + + spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); + + component = new ActionsComponent({ + propsData: { + actions, + service: { + postAction: spy, + }, + }, + }).$mount(); + }); + + it('should render a dropdown with the provided actions', () => { + expect( + component.$el.querySelectorAll('.dropdown-menu li').length, + ).toEqual(actions.length); + }); + + it('should call the service when an action is clicked', () => { + component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click(); + component.$el.querySelector('.js-pipeline-action-link').click(); + + expect(spy).toHaveBeenCalledWith(actions[0].path); + }); + + it('should hide loading if request fails', () => { + spy = jasmine.createSpy('spy').and.returnValue(Promise.reject()); + + component = new ActionsComponent({ + propsData: { + actions, + service: { + postAction: spy, + }, + }, + }).$mount(); + + component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click(); + component.$el.querySelector('.js-pipeline-action-link').click(); + + expect(component.$el.querySelector('.fa-spinner')).toEqual(null); + }); +}); diff --git a/spec/javascripts/vue_pipelines_index/pipelines_artifacts_spec.js b/spec/javascripts/vue_pipelines_index/pipelines_artifacts_spec.js new file mode 100644 index 00000000000..f7f49649c1c --- /dev/null +++ b/spec/javascripts/vue_pipelines_index/pipelines_artifacts_spec.js @@ -0,0 +1,40 @@ +import Vue from 'vue'; +import artifactsComp from '~/vue_pipelines_index/components/pipelines_artifacts'; + +describe('Pipelines Artifacts dropdown', () => { + let component; + let artifacts; + + beforeEach(() => { + const ArtifactsComponent = Vue.extend(artifactsComp); + + artifacts = [ + { + name: 'artifact', + path: '/download/path', + }, + ]; + + component = new ArtifactsComponent({ + propsData: { + artifacts, + }, + }).$mount(); + }); + + it('should render a dropdown with the provided artifacts', () => { + expect( + component.$el.querySelectorAll('.dropdown-menu li').length, + ).toEqual(artifacts.length); + }); + + it('should render a link with the provided path', () => { + expect( + component.$el.querySelector('.dropdown-menu li a').getAttribute('href'), + ).toEqual(artifacts[0].path); + + expect( + component.$el.querySelector('.dropdown-menu li a span').textContent, + ).toContain(artifacts[0].name); + }); +}); diff --git a/spec/javascripts/vue_pipelines_index/pipelines_store_spec.js b/spec/javascripts/vue_pipelines_index/pipelines_store_spec.js new file mode 100644 index 00000000000..5c0934404bb --- /dev/null +++ b/spec/javascripts/vue_pipelines_index/pipelines_store_spec.js @@ -0,0 +1,72 @@ +import PipelineStore from '~/vue_pipelines_index/stores/pipelines_store'; + +describe('Pipelines Store', () => { + let store; + + beforeEach(() => { + store = new PipelineStore(); + }); + + it('should be initialized with an empty state', () => { + expect(store.state.pipelines).toEqual([]); + expect(store.state.count).toEqual({}); + expect(store.state.pageInfo).toEqual({}); + }); + + describe('storePipelines', () => { + it('should use the default parameter if none is provided', () => { + store.storePipelines(); + expect(store.state.pipelines).toEqual([]); + }); + + it('should store the provided array', () => { + const array = [{ id: 1, status: 'running' }, { id: 2, status: 'success' }]; + store.storePipelines(array); + expect(store.state.pipelines).toEqual(array); + }); + }); + + describe('storeCount', () => { + it('should use the default parameter if none is provided', () => { + store.storeCount(); + expect(store.state.count).toEqual({}); + }); + + it('should store the provided count', () => { + const count = { all: 20, finished: 10 }; + store.storeCount(count); + + expect(store.state.count).toEqual(count); + }); + }); + + describe('storePagination', () => { + it('should use the default parameter if none is provided', () => { + store.storePagination(); + expect(store.state.pageInfo).toEqual({}); + }); + + it('should store pagination information normalized and parsed', () => { + const pagination = { + 'X-nExt-pAge': '2', + 'X-page': '1', + 'X-Per-Page': '1', + 'X-Prev-Page': '2', + 'X-TOTAL': '37', + 'X-Total-Pages': '2', + }; + + const expectedResult = { + perPage: 1, + page: 1, + total: 37, + totalPages: 2, + nextPage: 2, + previousPage: 2, + }; + + store.storePagination(pagination); + expect(store.state.pageInfo).toEqual(expectedResult); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js index 15ab10b9b69..df547299d75 100644 --- a/spec/javascripts/vue_shared/components/commit_spec.js +++ b/spec/javascripts/vue_shared/components/commit_spec.js @@ -1,13 +1,17 @@ -require('~/vue_shared/components/commit'); +import Vue from 'vue'; +import commitComp from '~/vue_shared/components/commit'; describe('Commit component', () => { let props; let component; + let CommitComponent; + + beforeEach(() => { + CommitComponent = Vue.extend(commitComp); + }); it('should render a code-fork icon if it does not represent a tag', () => { - setFixtures('<div class="test-commit-container"></div>'); - component = new window.gl.CommitComponent({ - el: document.querySelector('.test-commit-container'), + component = new CommitComponent({ propsData: { tag: false, commitRef: { @@ -23,15 +27,13 @@ describe('Commit component', () => { username: 'jschatz1', }, }, - }); + }).$mount(); expect(component.$el.querySelector('.icon-container i').classList).toContain('fa-code-fork'); }); describe('Given all the props', () => { beforeEach(() => { - setFixtures('<div class="test-commit-container"></div>'); - props = { tag: true, commitRef: { @@ -49,10 +51,9 @@ describe('Commit component', () => { commitIconSvg: '<svg></svg>', }; - component = new window.gl.CommitComponent({ - el: document.querySelector('.test-commit-container'), + component = new CommitComponent({ propsData: props, - }); + }).$mount(); }); it('should render a tag icon if it represents a tag', () => { @@ -105,7 +106,6 @@ describe('Commit component', () => { describe('When commit title is not provided', () => { it('should render default message', () => { - setFixtures('<div class="test-commit-container"></div>'); props = { tag: false, commitRef: { @@ -118,10 +118,9 @@ describe('Commit component', () => { author: {}, }; - component = new window.gl.CommitComponent({ - el: document.querySelector('.test-commit-container'), + component = new CommitComponent({ propsData: props, - }); + }).$mount(); expect( component.$el.querySelector('.commit-title span').textContent, diff --git a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js index 412abfd5e41..699625cdbb7 100644 --- a/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js +++ b/spec/javascripts/vue_shared/components/pipelines_table_row_spec.js @@ -1,20 +1,20 @@ -require('~/vue_shared/components/pipelines_table_row'); -const pipeline = require('../../commit/pipelines/mock_data'); +import Vue from 'vue'; +import tableRowComp from '~/vue_shared/components/pipelines_table_row'; +import pipeline from '../../commit/pipelines/mock_data'; describe('Pipelines Table Row', () => { let component; - preloadFixtures('static/environments/element.html.raw'); beforeEach(() => { - loadFixtures('static/environments/element.html.raw'); + const PipelinesTableRowComponent = Vue.extend(tableRowComp); - component = new gl.pipelines.PipelinesTableRowComponent({ + component = new PipelinesTableRowComponent({ el: document.querySelector('.test-dom-element'), propsData: { pipeline, - svgs: {}, + service: {}, }, - }); + }).$mount(); }); it('should render a table row', () => { diff --git a/spec/javascripts/vue_shared/components/pipelines_table_spec.js b/spec/javascripts/vue_shared/components/pipelines_table_spec.js index 54d81e2ea7d..b0b1df5a753 100644 --- a/spec/javascripts/vue_shared/components/pipelines_table_spec.js +++ b/spec/javascripts/vue_shared/components/pipelines_table_spec.js @@ -1,24 +1,24 @@ -require('~/vue_shared/components/pipelines_table'); -require('~/lib/utils/datetime_utility'); -const pipeline = require('../../commit/pipelines/mock_data'); +import Vue from 'vue'; +import pipelinesTableComp from '~/vue_shared/components/pipelines_table'; +import '~/lib/utils/datetime_utility'; +import pipeline from '../../commit/pipelines/mock_data'; describe('Pipelines Table', () => { - preloadFixtures('static/environments/element.html.raw'); + let PipelinesTableComponent; beforeEach(() => { - loadFixtures('static/environments/element.html.raw'); + PipelinesTableComponent = Vue.extend(pipelinesTableComp); }); describe('table', () => { let component; beforeEach(() => { - component = new gl.pipelines.PipelinesTableComponent({ - el: document.querySelector('.test-dom-element'), + component = new PipelinesTableComponent({ propsData: { pipelines: [], - svgs: {}, + service: {}, }, - }); + }).$mount(); }); it('should render a table', () => { @@ -37,26 +37,25 @@ describe('Pipelines Table', () => { describe('without data', () => { it('should render an empty table', () => { - const component = new gl.pipelines.PipelinesTableComponent({ - el: document.querySelector('.test-dom-element'), + const component = new PipelinesTableComponent({ propsData: { pipelines: [], - svgs: {}, + service: {}, }, - }); + }).$mount(); expect(component.$el.querySelectorAll('tbody tr').length).toEqual(0); }); }); describe('with data', () => { it('should render rows', () => { - const component = new gl.pipelines.PipelinesTableComponent({ + const component = new PipelinesTableComponent({ el: document.querySelector('.test-dom-element'), propsData: { pipelines: [pipeline], - svgs: {}, + service: {}, }, - }); + }).$mount(); expect(component.$el.querySelectorAll('tbody tr').length).toEqual(1); }); diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js b/spec/javascripts/vue_shared/components/table_pagination_spec.js index 9cb067921a7..a5c3870b3ac 100644 --- a/spec/javascripts/vue_shared/components/table_pagination_spec.js +++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js @@ -1,8 +1,10 @@ -require('~/lib/utils/common_utils'); -require('~/vue_shared/components/table_pagination'); +import Vue from 'vue'; +import paginationComp from '~/vue_shared/components/table_pagination'; +import '~/lib/utils/common_utils'; describe('Pagination component', () => { let component; + let PaginationComponent; const changeChanges = { one: '', @@ -12,11 +14,12 @@ describe('Pagination component', () => { changeChanges.one = one; }; - it('should render and start at page 1', () => { - setFixtures('<div class="test-pagination-container"></div>'); + beforeEach(() => { + PaginationComponent = Vue.extend(paginationComp); + }); - component = new window.gl.VueGlPagination({ - el: document.querySelector('.test-pagination-container'), + it('should render and start at page 1', () => { + component = new PaginationComponent({ propsData: { pageInfo: { totalPages: 10, @@ -25,7 +28,7 @@ describe('Pagination component', () => { }, change, }, - }); + }).$mount(); expect(component.$el.classList).toContain('gl-pagination'); @@ -35,10 +38,7 @@ describe('Pagination component', () => { }); it('should go to the previous page', () => { - setFixtures('<div class="test-pagination-container"></div>'); - - component = new window.gl.VueGlPagination({ - el: document.querySelector('.test-pagination-container'), + component = new PaginationComponent({ propsData: { pageInfo: { totalPages: 10, @@ -47,7 +47,7 @@ describe('Pagination component', () => { }, change, }, - }); + }).$mount(); component.changePage({ target: { innerText: 'Prev' } }); @@ -55,10 +55,7 @@ describe('Pagination component', () => { }); it('should go to the next page', () => { - setFixtures('<div class="test-pagination-container"></div>'); - - component = new window.gl.VueGlPagination({ - el: document.querySelector('.test-pagination-container'), + component = new PaginationComponent({ propsData: { pageInfo: { totalPages: 10, @@ -67,7 +64,7 @@ describe('Pagination component', () => { }, change, }, - }); + }).$mount(); component.changePage({ target: { innerText: 'Next' } }); @@ -75,10 +72,7 @@ describe('Pagination component', () => { }); it('should go to the last page', () => { - setFixtures('<div class="test-pagination-container"></div>'); - - component = new window.gl.VueGlPagination({ - el: document.querySelector('.test-pagination-container'), + component = new PaginationComponent({ propsData: { pageInfo: { totalPages: 10, @@ -87,7 +81,7 @@ describe('Pagination component', () => { }, change, }, - }); + }).$mount(); component.changePage({ target: { innerText: 'Last >>' } }); @@ -95,10 +89,7 @@ describe('Pagination component', () => { }); it('should go to the first page', () => { - setFixtures('<div class="test-pagination-container"></div>'); - - component = new window.gl.VueGlPagination({ - el: document.querySelector('.test-pagination-container'), + component = new PaginationComponent({ propsData: { pageInfo: { totalPages: 10, @@ -107,7 +98,7 @@ describe('Pagination component', () => { }, change, }, - }); + }).$mount(); component.changePage({ target: { innerText: '<< First' } }); @@ -115,10 +106,7 @@ describe('Pagination component', () => { }); it('should do nothing', () => { - setFixtures('<div class="test-pagination-container"></div>'); - - component = new window.gl.VueGlPagination({ - el: document.querySelector('.test-pagination-container'), + component = new PaginationComponent({ propsData: { pageInfo: { totalPages: 10, @@ -127,7 +115,7 @@ describe('Pagination component', () => { }, change, }, - }); + }).$mount(); component.changePage({ target: { innerText: '...' } }); |