diff options
author | Simon Knox <psimyn@gmail.com> | 2017-11-07 18:29:14 +1100 |
---|---|---|
committer | Simon Knox <psimyn@gmail.com> | 2017-11-07 18:29:14 +1100 |
commit | 8b78c1e5726f21147ba05377f241f03b3810d41f (patch) | |
tree | 6d38e8e427e7de58f51d55e8c64804050fef1b63 /spec/javascripts | |
parent | e9fb244ad3fdbb42585c1455302eec91af5e11d2 (diff) | |
parent | e99ddb6f374c9f79c1c78e808c5e9bd983bed227 (diff) | |
download | gitlab-ce-8b78c1e5726f21147ba05377f241f03b3810d41f.tar.gz |
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into 38394-smarter-interval
Diffstat (limited to 'spec/javascripts')
-rw-r--r-- | spec/javascripts/behaviors/copy_as_gfm_spec.js | 47 | ||||
-rw-r--r-- | spec/javascripts/copy_as_gfm_spec.js | 49 | ||||
-rw-r--r-- | spec/javascripts/fixtures/clusters.rb | 2 | ||||
-rw-r--r-- | spec/javascripts/fixtures/search_autocomplete.html.haml | 1 | ||||
-rw-r--r-- | spec/javascripts/lib/utils/datefix_spec.js | 6 | ||||
-rw-r--r-- | spec/javascripts/monitoring/graph/legend_spec.js | 2 | ||||
-rw-r--r-- | spec/javascripts/monitoring/graph_path_spec.js | 2 | ||||
-rw-r--r-- | spec/javascripts/monitoring/utils/multiple_time_series_spec.js | 2 | ||||
-rw-r--r-- | spec/javascripts/notes_spec.js | 21 | ||||
-rw-r--r-- | spec/javascripts/search_autocomplete_spec.js | 30 | ||||
-rw-r--r-- | spec/javascripts/shortcuts_issuable_spec.js | 4 | ||||
-rw-r--r-- | spec/javascripts/test_bundle.js | 40 | ||||
-rw-r--r-- | spec/javascripts/vue_shared/components/markdown/field_spec.js | 27 | ||||
-rw-r--r-- | spec/javascripts/vue_shared/components/markdown/header_spec.js | 10 |
14 files changed, 152 insertions, 91 deletions
diff --git a/spec/javascripts/behaviors/copy_as_gfm_spec.js b/spec/javascripts/behaviors/copy_as_gfm_spec.js new file mode 100644 index 00000000000..b8155144e2a --- /dev/null +++ b/spec/javascripts/behaviors/copy_as_gfm_spec.js @@ -0,0 +1,47 @@ +import { CopyAsGFM } from '~/behaviors/copy_as_gfm'; + +describe('CopyAsGFM', () => { + describe('CopyAsGFM.pasteGFM', () => { + function callPasteGFM() { + const e = { + originalEvent: { + clipboardData: { + getData(mimeType) { + // When GFM code is copied, we put the regular plain text + // on the clipboard as `text/plain`, and the GFM as `text/x-gfm`. + // This emulates the behavior of `getData` with that data. + if (mimeType === 'text/plain') { + return 'code'; + } + if (mimeType === 'text/x-gfm') { + return '`code`'; + } + return null; + }, + }, + }, + preventDefault() {}, + }; + + CopyAsGFM.pasteGFM(e); + } + + it('wraps pasted code when not already in code tags', () => { + spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => { + const insertedText = textFunc('This is code: ', ''); + expect(insertedText).toEqual('`code`'); + }); + + callPasteGFM(); + }); + + it('does not wrap pasted code when already in code tags', () => { + spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => { + const insertedText = textFunc('This is code: `', '`'); + expect(insertedText).toEqual('code'); + }); + + callPasteGFM(); + }); + }); +}); diff --git a/spec/javascripts/copy_as_gfm_spec.js b/spec/javascripts/copy_as_gfm_spec.js deleted file mode 100644 index ded450749d3..00000000000 --- a/spec/javascripts/copy_as_gfm_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import '~/copy_as_gfm'; - -(() => { - describe('gl.CopyAsGFM', () => { - describe('gl.CopyAsGFM.pasteGFM', () => { - function callPasteGFM() { - const e = { - originalEvent: { - clipboardData: { - getData(mimeType) { - // When GFM code is copied, we put the regular plain text - // on the clipboard as `text/plain`, and the GFM as `text/x-gfm`. - // This emulates the behavior of `getData` with that data. - if (mimeType === 'text/plain') { - return 'code'; - } - if (mimeType === 'text/x-gfm') { - return '`code`'; - } - return null; - }, - }, - }, - preventDefault() {}, - }; - - window.gl.CopyAsGFM.pasteGFM(e); - } - - it('wraps pasted code when not already in code tags', () => { - spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => { - const insertedText = textFunc('This is code: ', ''); - expect(insertedText).toEqual('`code`'); - }); - - callPasteGFM(); - }); - - it('does not wrap pasted code when already in code tags', () => { - spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => { - const insertedText = textFunc('This is code: `', '`'); - expect(insertedText).toEqual('code'); - }); - - callPasteGFM(); - }); - }); - }); -})(); diff --git a/spec/javascripts/fixtures/clusters.rb b/spec/javascripts/fixtures/clusters.rb index 5774f36f026..8e74c4f859c 100644 --- a/spec/javascripts/fixtures/clusters.rb +++ b/spec/javascripts/fixtures/clusters.rb @@ -6,7 +6,7 @@ describe Projects::ClustersController, '(JavaScript fixtures)', type: :controlle let(:admin) { create(:admin) } let(:namespace) { create(:namespace, name: 'frontend-fixtures' )} let(:project) { create(:project, :repository, namespace: namespace) } - let(:cluster) { project.create_cluster!(gcp_cluster_name: "gke-test-creation-1", gcp_project_id: 'gitlab-internal-153318', gcp_cluster_zone: 'us-central1-a', gcp_cluster_size: '1', project_namespace: 'aaa', gcp_machine_type: 'n1-standard-1')} + let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } render_views diff --git a/spec/javascripts/fixtures/search_autocomplete.html.haml b/spec/javascripts/fixtures/search_autocomplete.html.haml index 7785120da5b..0421ed2182f 100644 --- a/spec/javascripts/fixtures/search_autocomplete.html.haml +++ b/spec/javascripts/fixtures/search_autocomplete.html.haml @@ -8,3 +8,4 @@ %input#search.search-input.dropdown-menu-toggle .dropdown-menu.dropdown-select .dropdown-content + %input{ type: "hidden", class: "js-search-project-options" } diff --git a/spec/javascripts/lib/utils/datefix_spec.js b/spec/javascripts/lib/utils/datefix_spec.js index 0b9fde2be67..e58ac4300ba 100644 --- a/spec/javascripts/lib/utils/datefix_spec.js +++ b/spec/javascripts/lib/utils/datefix_spec.js @@ -1,4 +1,4 @@ -import { pad, parsePikadayDate, pikadayToString } from '~/lib/utils/datefix'; +import { pad, pikadayToString } from '~/lib/utils/datefix'; describe('datefix', () => { describe('pad', () => { @@ -16,9 +16,7 @@ describe('datefix', () => { }); describe('parsePikadayDate', () => { - it('should return a UTC date', () => { - expect(parsePikadayDate('2020-01-29')).toEqual(new Date('2020-01-29')); - }); + // removed because of https://gitlab.com/gitlab-org/gitlab-ce/issues/39834 }); describe('pikadayToString', () => { diff --git a/spec/javascripts/monitoring/graph/legend_spec.js b/spec/javascripts/monitoring/graph/legend_spec.js index 2571b7ef869..145c8db28d5 100644 --- a/spec/javascripts/monitoring/graph/legend_spec.js +++ b/spec/javascripts/monitoring/graph/legend_spec.js @@ -28,7 +28,7 @@ const defaultValuesComponent = { currentDataIndex: 0, }; -const timeSeries = createTimeSeries(convertedMetrics[0].queries[0], +const timeSeries = createTimeSeries(convertedMetrics[0].queries, defaultValuesComponent.graphWidth, defaultValuesComponent.graphHeight, defaultValuesComponent.graphHeightOffset); diff --git a/spec/javascripts/monitoring/graph_path_spec.js b/spec/javascripts/monitoring/graph_path_spec.js index 81825a3ae87..8ece913ada8 100644 --- a/spec/javascripts/monitoring/graph_path_spec.js +++ b/spec/javascripts/monitoring/graph_path_spec.js @@ -13,7 +13,7 @@ const createComponent = (propsData) => { const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries); -const timeSeries = createTimeSeries(convertedMetrics[0].queries[0], 428, 272, 120); +const timeSeries = createTimeSeries(convertedMetrics[0].queries, 428, 272, 120); const firstTimeSeries = timeSeries[0]; describe('Monitoring Paths', () => { diff --git a/spec/javascripts/monitoring/utils/multiple_time_series_spec.js b/spec/javascripts/monitoring/utils/multiple_time_series_spec.js index 7e44a9ade9e..99584c75287 100644 --- a/spec/javascripts/monitoring/utils/multiple_time_series_spec.js +++ b/spec/javascripts/monitoring/utils/multiple_time_series_spec.js @@ -2,7 +2,7 @@ import createTimeSeries from '~/monitoring/utils/multiple_time_series'; import { convertDatesMultipleSeries, singleRowMetricsMultipleSeries } from '../mock_data'; const convertedMetrics = convertDatesMultipleSeries(singleRowMetricsMultipleSeries); -const timeSeries = createTimeSeries(convertedMetrics[0].queries[0], 428, 272, 120); +const timeSeries = createTimeSeries(convertedMetrics[0].queries, 428, 272, 120); const firstTimeSeries = timeSeries[0]; describe('Multiple time series', () => { diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 53d8faae911..928a4b461cc 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -343,6 +343,7 @@ import '~/notes'; diff_discussion_html: false, }; $form = jasmine.createSpyObj('$form', ['closest', 'find']); + $form.length = 1; row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']); notes = jasmine.createSpyObj('notes', [ @@ -371,13 +372,29 @@ import '~/notes'; $form.closest.and.returnValues(row, $form); $form.find.and.returnValues(discussionContainer); body.attr.and.returnValue(''); - - Notes.prototype.renderDiscussionNote.call(notes, note, $form); }); it('should call Notes.animateAppendNote', () => { + Notes.prototype.renderDiscussionNote.call(notes, note, $form); + expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.discussion_html, $('.main-notes-list')); }); + + it('should append to row selected with line_code', () => { + $form.length = 0; + note.discussion_line_code = 'line_code'; + note.diff_discussion_html = '<tr></tr>'; + + const line = document.createElement('div'); + line.id = note.discussion_line_code; + document.body.appendChild(line); + + $form.closest.and.returnValues($form); + + Notes.prototype.renderDiscussionNote.call(notes, note, $form); + + expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html); + }); }); describe('Discussion sub note', () => { diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js index 5e55a5d2686..a2394857b82 100644 --- a/spec/javascripts/search_autocomplete_spec.js +++ b/spec/javascripts/search_autocomplete_spec.js @@ -57,6 +57,10 @@ import '~/lib/utils/common_utils'; } }; + const disableProjectIssues = function() { + document.querySelector('.js-search-project-options').setAttribute('data-issues-disabled', true); + }; + // Mock `gl` object in window for dashboard specific page. App code will need it. mockDashboardOptions = function() { window.gl || (window.gl = {}); @@ -91,18 +95,20 @@ import '~/lib/utils/common_utils'; assertLinks = function(list, issuesPath, mrsPath) { var a1, a2, a3, a4, issuesAssignedToMeLink, issuesIHaveCreatedLink, mrsAssignedToMeLink, mrsIHaveCreatedLink; - issuesAssignedToMeLink = issuesPath + "/?assignee_username=" + userName; - issuesIHaveCreatedLink = issuesPath + "/?author_username=" + userName; + if (issuesPath) { + issuesAssignedToMeLink = issuesPath + "/?assignee_username=" + userName; + issuesIHaveCreatedLink = issuesPath + "/?author_username=" + userName; + a1 = "a[href='" + issuesAssignedToMeLink + "']"; + a2 = "a[href='" + issuesIHaveCreatedLink + "']"; + expect(list.find(a1).length).toBe(1); + expect(list.find(a1).text()).toBe('Issues assigned to me'); + expect(list.find(a2).length).toBe(1); + expect(list.find(a2).text()).toBe("Issues I've created"); + } mrsAssignedToMeLink = mrsPath + "/?assignee_username=" + userName; mrsIHaveCreatedLink = mrsPath + "/?author_username=" + userName; - a1 = "a[href='" + issuesAssignedToMeLink + "']"; - a2 = "a[href='" + issuesIHaveCreatedLink + "']"; a3 = "a[href='" + mrsAssignedToMeLink + "']"; a4 = "a[href='" + mrsIHaveCreatedLink + "']"; - expect(list.find(a1).length).toBe(1); - expect(list.find(a1).text()).toBe('Issues assigned to me'); - expect(list.find(a2).length).toBe(1); - expect(list.find(a2).text()).toBe("Issues I've created"); expect(list.find(a3).length).toBe(1); expect(list.find(a3).text()).toBe('Merge requests assigned to me'); expect(list.find(a4).length).toBe(1); @@ -153,6 +159,14 @@ import '~/lib/utils/common_utils'; list = widget.wrap.find('.dropdown-menu').find('ul'); return assertLinks(list, projectIssuesPath, projectMRsPath); }); + it('should show only Project mergeRequest dropdown menu items when project issues are disabled', function() { + addBodyAttributes('project'); + disableProjectIssues(); + mockProjectOptions(); + widget.searchInput.triggerHandler('focus'); + const list = widget.wrap.find('.dropdown-menu').find('ul'); + assertLinks(list, null, projectMRsPath); + }); it('should not show category related menu if there is text in the input', function() { var link, list; addBodyAttributes('project'); diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/shortcuts_issuable_spec.js index f6320db8dc4..5d6a885d4cc 100644 --- a/spec/javascripts/shortcuts_issuable_spec.js +++ b/spec/javascripts/shortcuts_issuable_spec.js @@ -1,6 +1,8 @@ -import '~/copy_as_gfm'; +import initCopyAsGFM from '~/behaviors/copy_as_gfm'; import ShortcutsIssuable from '~/shortcuts_issuable'; +initCopyAsGFM(); + describe('ShortcutsIssuable', () => { const fixtureName = 'merge_requests/diff_comment.html.raw'; preloadFixtures(fixtureName); diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index d4e134583c7..fd7aa332d17 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -11,6 +11,12 @@ const isHeadlessChrome = /\bHeadlessChrome\//.test(navigator.userAgent); Vue.config.devtools = !isHeadlessChrome; Vue.config.productionTip = false; +let hasVueWarnings = false; +Vue.config.warnHandler = (msg, vm, trace) => { + hasVueWarnings = true; + fail(`${msg}${trace}`); +}; + Vue.use(VueResource); // enable test fixtures @@ -34,11 +40,6 @@ window.addEventListener('unhandledrejection', (event) => { console.error(event.reason.stack || event.reason); }); -const checkUnhandledPromiseRejections = (done) => { - expect(hasUnhandledPromiseRejections).toBe(false); - done(); -}; - // HACK: Chrome 59 disconnects if there are too many synchronous tests in a row // because it appears to lock up the thread that communicates to Karma's socket // This async beforeEach gets called on every spec and releases the JS thread long @@ -47,17 +48,6 @@ const checkUnhandledPromiseRejections = (done) => { // to run our unit tests. beforeEach(done => done()); -beforeAll(() => { - const origError = console.error; - spyOn(console, 'error').and.callFake((message) => { - if (/^\[Vue warn\]/.test(message)) { - fail(message); - } else { - origError(message); - } - }); -}); - const builtinVueHttpInterceptors = Vue.http.interceptors.slice(); beforeEach(() => { @@ -80,8 +70,22 @@ testsContext.keys().forEach(function (path) { } }); -it('has no unhandled Promise rejections', (done) => { - setTimeout(checkUnhandledPromiseRejections(done), 1000); +describe('test errors', () => { + beforeAll((done) => { + if (hasUnhandledPromiseRejections || hasVueWarnings) { + setTimeout(done, 1000); + } else { + done(); + } + }); + + it('has no unhandled Promise rejections', () => { + expect(hasUnhandledPromiseRejections).toBe(false); + }); + + it('has no Vue warnings', () => { + expect(hasVueWarnings).toBe(false); + }); }); // if we're generating coverage reports, make sure to include all files so diff --git a/spec/javascripts/vue_shared/components/markdown/field_spec.js b/spec/javascripts/vue_shared/components/markdown/field_spec.js index 65c49b9f30b..24209be83fe 100644 --- a/spec/javascripts/vue_shared/components/markdown/field_spec.js +++ b/spec/javascripts/vue_shared/components/markdown/field_spec.js @@ -1,6 +1,12 @@ import Vue from 'vue'; import fieldComponent from '~/vue_shared/components/markdown/field.vue'; +function assertMarkdownTabs(isWrite, writeLink, previewLink, vm) { + expect(writeLink.parentNode.classList.contains('active')).toEqual(isWrite); + expect(previewLink.parentNode.classList.contains('active')).toEqual(!isWrite); + expect(vm.$el.querySelector('.md-preview').style.display).toEqual(isWrite ? 'none' : ''); +} + describe('Markdown field component', () => { let vm; @@ -39,6 +45,7 @@ describe('Markdown field component', () => { describe('markdown preview', () => { let previewLink; + let writeLink; beforeEach(() => { spyOn(Vue.http, 'post').and.callFake(() => new Promise((resolve) => { @@ -53,7 +60,8 @@ describe('Markdown field component', () => { }); })); - previewLink = vm.$el.querySelector('.nav-links li:nth-child(2) a'); + previewLink = vm.$el.querySelector('.nav-links .js-preview-link'); + writeLink = vm.$el.querySelector('.nav-links .js-write-link'); }); it('sets preview link as active', (done) => { @@ -105,6 +113,23 @@ describe('Markdown field component', () => { done(); }, 0); }); + + it('clicking already active write or preview link does nothing', (done) => { + writeLink.click(); + Vue.nextTick() + .then(() => assertMarkdownTabs(true, writeLink, previewLink, vm)) + .then(() => writeLink.click()) + .then(() => Vue.nextTick()) + .then(() => assertMarkdownTabs(true, writeLink, previewLink, vm)) + .then(() => previewLink.click()) + .then(() => Vue.nextTick()) + .then(() => assertMarkdownTabs(false, writeLink, previewLink, vm)) + .then(() => previewLink.click()) + .then(() => Vue.nextTick()) + .then(() => assertMarkdownTabs(false, writeLink, previewLink, vm)) + .then(done) + .catch(done.fail); + }); }); describe('markdown buttons', () => { diff --git a/spec/javascripts/vue_shared/components/markdown/header_spec.js b/spec/javascripts/vue_shared/components/markdown/header_spec.js index 7110ff36937..edebd822295 100644 --- a/spec/javascripts/vue_shared/components/markdown/header_spec.js +++ b/spec/javascripts/vue_shared/components/markdown/header_spec.js @@ -43,11 +43,13 @@ describe('Markdown field header component', () => { it('emits toggle markdown event when clicking preview', () => { spyOn(vm, '$emit'); - vm.$el.querySelector('li:nth-child(2) a').click(); + vm.$el.querySelector('.js-preview-link').click(); - expect( - vm.$emit, - ).toHaveBeenCalledWith('toggle-markdown'); + expect(vm.$emit).toHaveBeenCalledWith('preview-markdown'); + + vm.$el.querySelector('.js-write-link').click(); + + expect(vm.$emit).toHaveBeenCalledWith('write-markdown'); }); it('blurs preview link after click', (done) => { |