diff options
author | Johann Hubert Sonntagbauer <johann.sonntagbauer@gmail.com> | 2018-10-09 20:03:09 +0200 |
---|---|---|
committer | Johann Hubert Sonntagbauer <johann.sonntagbauer@gmail.com> | 2018-10-17 06:57:29 +0200 |
commit | 6f5723a169b5d400c136dbd844fc54c68e5f8563 (patch) | |
tree | e7bad2648366ed5943293655a0abe23367e869a6 /spec/javascripts | |
parent | 28d412e5b2b8499fba22e8fabb1d44f44449228e (diff) | |
download | gitlab-ce-6f5723a169b5d400c136dbd844fc54c68e5f8563.tar.gz |
enable jasmine/new-line-before-expect
Diffstat (limited to 'spec/javascripts')
220 files changed, 1149 insertions, 108 deletions
diff --git a/spec/javascripts/.eslintrc.yml b/spec/javascripts/.eslintrc.yml index 1328b7c362b..b863156b57c 100644 --- a/spec/javascripts/.eslintrc.yml +++ b/spec/javascripts/.eslintrc.yml @@ -36,5 +36,4 @@ rules: - ignore: - 'fixtures/blob' # Temporarily disabled to facilitate an upgrade to eslint-plugin-jasmine - jasmine/new-line-before-expect: off jasmine/prefer-toHaveBeenCalledWith: off diff --git a/spec/javascripts/ajax_loading_spinner_spec.js b/spec/javascripts/ajax_loading_spinner_spec.js index 261375d3a0e..d6d4f7035c2 100644 --- a/spec/javascripts/ajax_loading_spinner_spec.js +++ b/spec/javascripts/ajax_loading_spinner_spec.js @@ -42,6 +42,7 @@ describe('Ajax Loading Spinner', () => { req.complete({}); const icon = ajaxLoadingSpinner.querySelector('i'); + expect(icon).toHaveClass('fa-trash-o'); expect(icon).not.toHaveClass('fa-spinner'); expect(icon).not.toHaveClass('fa-spin'); diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js index 3f84a46e8d9..0bc4021f05f 100644 --- a/spec/javascripts/awards_handler_spec.js +++ b/spec/javascripts/awards_handler_spec.js @@ -74,6 +74,7 @@ import '~/lib/utils/common_utils'; return lazyAssert(done, function() { var $emojiMenu; $emojiMenu = $('.emoji-menu'); + expect($emojiMenu.length).toBe(1); expect($emojiMenu.hasClass('is-visible')).toBe(true); expect($emojiMenu.find('.js-emoji-menu-search').length).toBe(1); @@ -85,7 +86,8 @@ import '~/lib/utils/common_utils'; $('.js-add-award.note-action-button').click(); return lazyAssert(done, function() { var $emojiMenu = $('.emoji-menu'); - return expect($emojiMenu.length).toBe(1); + + expect($emojiMenu.length).toBe(1); }); }); @@ -97,6 +99,7 @@ import '~/lib/utils/common_utils'; var $emojiMenu; $emojiMenu = $('.emoji-menu'); $('body').click(); + expect($emojiMenu.length).toBe(1); expect($emojiMenu.hasClass('is-visible')).toBe(false); return expect($('.js-awards-block.current').length).toBe(0); @@ -111,6 +114,7 @@ import '~/lib/utils/common_utils'; var $emojiMenu; $emojiMenu = $('.emoji-menu'); $('.emoji-search').click(); + expect($emojiMenu.length).toBe(1); expect($emojiMenu.hasClass('is-visible')).toBe(true); return expect($('.js-awards-block.current').length).toBe(1); @@ -124,6 +128,7 @@ import '~/lib/utils/common_utils'; $votesBlock = $('.js-awards-block').eq(0); awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false); $emojiButton = $votesBlock.find('[data-name=heart]'); + expect($emojiButton.length).toBe(1); expect($emojiButton.next('.js-counter').text()).toBe('1'); return expect($votesBlock.hasClass('hidden')).toBe(false); @@ -135,7 +140,8 @@ import '~/lib/utils/common_utils'; awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false); awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false); $emojiButton = $votesBlock.find('[data-name=heart]'); - return expect($emojiButton.length).toBe(0); + + expect($emojiButton.length).toBe(0); }); return it('should decrement the emoji counter', function() { var $emojiButton, $votesBlock; @@ -144,6 +150,7 @@ import '~/lib/utils/common_utils'; $emojiButton = $votesBlock.find('[data-name=heart]'); $emojiButton.next('.js-counter').text(5); awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false); + expect($emojiButton.length).toBe(1); return expect($emojiButton.next('.js-counter').text()).toBe('4'); }); @@ -156,7 +163,8 @@ import '~/lib/utils/common_utils'; $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent(); $thumbsUpEmoji.attr('data-title', 'sam'); awardsHandler.userAuthored($thumbsUpEmoji); - return expect($thumbsUpEmoji.data('originalTitle')).toBe( + + expect($thumbsUpEmoji.data('originalTitle')).toBe( 'You cannot vote on your own issue, MR and note', ); }); @@ -170,13 +178,15 @@ import '~/lib/utils/common_utils'; awardsHandler.userAuthored($thumbsUpEmoji); jasmine.clock().tick(2801); jasmine.clock().uninstall(); - return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam'); + + expect($thumbsUpEmoji.data('originalTitle')).toBe('sam'); }); }); describe('::getAwardUrl', function() { return it('returns the url for request', function() { - return expect(awardsHandler.getAwardUrl()).toBe( + + expect(awardsHandler.getAwardUrl()).toBe( 'http://test.host/snippets/1/toggle_award_emoji', ); }); @@ -190,11 +200,13 @@ import '~/lib/utils/common_utils'; $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent(); $thumbsDownEmoji = $votesBlock.find('[data-name=thumbsdown]').parent(); awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false); + expect($thumbsUpEmoji.hasClass('active')).toBe(true); expect($thumbsDownEmoji.hasClass('active')).toBe(false); $thumbsUpEmoji.tooltip(); $thumbsDownEmoji.tooltip(); awardsHandler.addAward($votesBlock, awardUrl, 'thumbsdown', true); + expect($thumbsUpEmoji.hasClass('active')).toBe(false); return expect($thumbsDownEmoji.hasClass('active')).toBe(true); }); @@ -206,9 +218,11 @@ import '~/lib/utils/common_utils'; awardUrl = awardsHandler.getAwardUrl(); $votesBlock = $('.js-awards-block').eq(0); awardsHandler.addAward($votesBlock, awardUrl, 'fire', false); + expect($votesBlock.find('[data-name=fire]').length).toBe(1); awardsHandler.removeEmoji($votesBlock.find('[data-name=fire]').closest('button')); - return expect($votesBlock.find('[data-name=fire]').length).toBe(0); + + expect($votesBlock.find('[data-name=fire]').length).toBe(0); }); }); @@ -221,7 +235,8 @@ import '~/lib/utils/common_utils'; $thumbsUpEmoji.attr('data-title', 'sam, jerry, max, and andy'); awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false); $thumbsUpEmoji.tooltip(); - return expect($thumbsUpEmoji.data('originalTitle')).toBe('You, sam, jerry, max, and andy'); + + expect($thumbsUpEmoji.data('originalTitle')).toBe('You, sam, jerry, max, and andy'); }); return it('handles the special case where "You" is not cleanly comma seperated', function() { var $thumbsUpEmoji, $votesBlock, awardUrl; @@ -231,7 +246,8 @@ import '~/lib/utils/common_utils'; $thumbsUpEmoji.attr('data-title', 'sam'); awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false); $thumbsUpEmoji.tooltip(); - return expect($thumbsUpEmoji.data('originalTitle')).toBe('You and sam'); + + expect($thumbsUpEmoji.data('originalTitle')).toBe('You and sam'); }); }); @@ -245,7 +261,8 @@ import '~/lib/utils/common_utils'; $thumbsUpEmoji.addClass('active'); awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false); $thumbsUpEmoji.tooltip(); - return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam, jerry, max, and andy'); + + expect($thumbsUpEmoji.data('originalTitle')).toBe('sam, jerry, max, and andy'); }); return it('handles the special case where "You" is not cleanly comma seperated', function() { var $thumbsUpEmoji, $votesBlock, awardUrl; @@ -256,7 +273,8 @@ import '~/lib/utils/common_utils'; $thumbsUpEmoji.addClass('active'); awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false); $thumbsUpEmoji.tooltip(); - return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam'); + + expect($thumbsUpEmoji.data('originalTitle')).toBe('sam'); }); }); @@ -267,6 +285,7 @@ import '~/lib/utils/common_utils'; expect($('[data-name=angel]').is(':visible')).toBe(true); expect($('[data-name=anger]').is(':visible')).toBe(true); awardsHandler.searchEmojis('ali'); + expect($('[data-name=angel]').is(':visible')).toBe(false); expect($('[data-name=anger]').is(':visible')).toBe(false); expect($('[data-name=alien]').is(':visible')).toBe(true); @@ -282,10 +301,12 @@ import '~/lib/utils/common_utils'; return openAndWaitForEmojiMenu() .then(() => { awardsHandler.searchEmojis('ali'); + expect($('[data-name=angel]').is(':visible')).toBe(false); expect($('[data-name=anger]').is(':visible')).toBe(false); expect($('[data-name=alien]').is(':visible')).toBe(true); awardsHandler.searchEmojis(''); + expect($('[data-name=angel]').is(':visible')).toBe(true); expect($('[data-name=anger]').is(':visible')).toBe(true); expect($('[data-name=alien]').is(':visible')).toBe(true); @@ -309,6 +330,7 @@ import '~/lib/utils/common_utils'; expect($emoji.length).toBe(1); expect($block.find(emojiSelector).length).toBe(0); $emoji.click(); + expect($menu.hasClass('.is-visible')).toBe(false); expect($block.find(emojiSelector).length).toBe(1); }); @@ -332,6 +354,7 @@ import '~/lib/utils/common_utils'; `.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`, ); $emoji.click(); + expect($block.find(emojiSelector).length).toBe(0); }) .then(done) diff --git a/spec/javascripts/badges/components/badge_form_spec.js b/spec/javascripts/badges/components/badge_form_spec.js index 31195bd762b..651ac3ba3f9 100644 --- a/spec/javascripts/badges/components/badge_form_spec.js +++ b/spec/javascripts/badges/components/badge_form_spec.js @@ -66,8 +66,10 @@ describe('BadgeForm component', () => { }; const expectInvalidInput = inputElementSelector => { const inputElement = vm.$el.querySelector(inputElementSelector); + expect(inputElement).toBeMatchedBy(':invalid'); const feedbackElement = vm.$el.querySelector(`${inputElementSelector} + .invalid-feedback`); + expect(feedbackElement).toBeVisible(); }; @@ -90,6 +92,7 @@ describe('BadgeForm component', () => { submitForm(); expectInvalidInput(imageUrlSelector); + expect(vm[submitAction]).not.toHaveBeenCalled(); }); @@ -99,6 +102,7 @@ describe('BadgeForm component', () => { submitForm(); expectInvalidInput(imageUrlSelector); + expect(vm[submitAction]).not.toHaveBeenCalled(); }); @@ -108,6 +112,7 @@ describe('BadgeForm component', () => { submitForm(); expectInvalidInput(linkUrlSelector); + expect(vm[submitAction]).not.toHaveBeenCalled(); }); @@ -117,6 +122,7 @@ describe('BadgeForm component', () => { submitForm(); expectInvalidInput(linkUrlSelector); + expect(vm[submitAction]).not.toHaveBeenCalled(); }); @@ -143,8 +149,10 @@ describe('BadgeForm component', () => { it('renders one button', () => { expect(vm.$el.querySelector('.row-content-block')).toBeNull(); const buttons = vm.$el.querySelectorAll('.form-group:last-of-type button'); + expect(buttons.length).toBe(1); const buttonAddElement = buttons[0]; + expect(buttonAddElement).toBeVisible(); expect(buttonAddElement).toHaveText('Add badge'); }); @@ -165,11 +173,14 @@ describe('BadgeForm component', () => { it('renders two buttons', () => { const buttons = vm.$el.querySelectorAll('.row-content-block button'); + expect(buttons.length).toBe(2); const buttonSaveElement = buttons[0]; + expect(buttonSaveElement).toBeVisible(); expect(buttonSaveElement).toHaveText('Save changes'); const buttonCancelElement = buttons[1]; + expect(buttonCancelElement).toBeVisible(); expect(buttonCancelElement).toHaveText('Cancel'); }); diff --git a/spec/javascripts/badges/components/badge_list_row_spec.js b/spec/javascripts/badges/components/badge_list_row_spec.js index 21bd00d82f0..a5b47cc5f32 100644 --- a/spec/javascripts/badges/components/badge_list_row_spec.js +++ b/spec/javascripts/badges/components/badge_list_row_spec.js @@ -34,6 +34,7 @@ describe('BadgeListRow component', () => { it('renders the badge', () => { const badgeElement = vm.$el.querySelector('.project-badge'); + expect(badgeElement).not.toBeNull(); expect(badgeElement.getAttribute('src')).toBe(badge.renderedImageUrl); }); @@ -48,11 +49,14 @@ describe('BadgeListRow component', () => { it('shows edit and delete buttons', () => { const buttons = vm.$el.querySelectorAll('.table-button-footer button'); + expect(buttons).toHaveLength(2); const buttonEditElement = buttons[0]; + expect(buttonEditElement).toBeVisible(); expect(buttonEditElement).toHaveSpriteIcon('pencil'); const buttonDeleteElement = buttons[1]; + expect(buttonDeleteElement).toBeVisible(); expect(buttonDeleteElement).toHaveSpriteIcon('remove'); }); @@ -91,6 +95,7 @@ describe('BadgeListRow component', () => { it('hides edit and delete buttons', () => { const buttons = vm.$el.querySelectorAll('.table-button-footer button'); + expect(buttons).toHaveLength(0); }); }); diff --git a/spec/javascripts/badges/components/badge_list_spec.js b/spec/javascripts/badges/components/badge_list_spec.js index 02e59ae0843..536671db377 100644 --- a/spec/javascripts/badges/components/badge_list_spec.js +++ b/spec/javascripts/badges/components/badge_list_spec.js @@ -34,11 +34,13 @@ describe('BadgeList component', () => { it('renders a header with the badge count', () => { const header = vm.$el.querySelector('.card-header'); + expect(header).toHaveText(new RegExp(`Your badges\\s+${numberOfDummyBadges}`)); }); it('renders a row for each badge', () => { const rows = vm.$el.querySelectorAll('.gl-responsive-table-row'); + expect(rows).toHaveLength(numberOfDummyBadges); }); @@ -59,6 +61,7 @@ describe('BadgeList component', () => { Vue.nextTick() .then(() => { const loadingIcon = vm.$el.querySelector('.fa-spinner'); + expect(loadingIcon).toBeVisible(); }) .then(done) diff --git a/spec/javascripts/badges/components/badge_settings_spec.js b/spec/javascripts/badges/components/badge_settings_spec.js index 59367c85125..aca26b736ca 100644 --- a/spec/javascripts/badges/components/badge_settings_spec.js +++ b/spec/javascripts/badges/components/badge_settings_spec.js @@ -38,6 +38,7 @@ describe('BadgeSettings component', () => { $(modal).on('shown.bs.modal', () => { expect(modal).toContainText('Delete badge?'); const badgeElement = modal.querySelector('img.project-badge'); + expect(badgeElement).not.toBe(null); expect(badgeElement.getAttribute('src')).toBe(badge.renderedImageUrl); @@ -53,14 +54,17 @@ describe('BadgeSettings component', () => { it('displays a form to add a badge', () => { const form = vm.$el.querySelector('form:nth-of-type(2)'); + expect(form).not.toBe(null); const button = form.querySelector('.btn-success'); + expect(button).not.toBe(null); expect(button).toHaveText(/Add badge/); }); it('displays badge list', () => { const badgeListElement = vm.$el.querySelector('.card'); + expect(badgeListElement).not.toBe(null); expect(badgeListElement).toBeVisible(); expect(badgeListElement).toContainText('Your badges'); @@ -77,17 +81,21 @@ describe('BadgeSettings component', () => { it('displays a form to edit a badge', () => { const form = vm.$el.querySelector('form:nth-of-type(1)'); + expect(form).not.toBe(null); const submitButton = form.querySelector('.btn-success'); + expect(submitButton).not.toBe(null); expect(submitButton).toHaveText(/Save changes/); const cancelButton = form.querySelector('.btn-cancel'); + expect(cancelButton).not.toBe(null); expect(cancelButton).toHaveText(/Cancel/); }); it('displays no badge list', () => { const badgeListElement = vm.$el.querySelector('.card'); + expect(badgeListElement).toBeHidden(); }); }); @@ -102,6 +110,7 @@ describe('BadgeSettings component', () => { deleteButton.click(); const badge = store.state.badgeInModal; + expect(vm.deleteBadge).toHaveBeenCalledWith(badge); }); }); diff --git a/spec/javascripts/badges/components/badge_spec.js b/spec/javascripts/badges/components/badge_spec.js index fd1ecc9cdd8..29805408bcf 100644 --- a/spec/javascripts/badges/components/badge_spec.js +++ b/spec/javascripts/badges/components/badge_spec.js @@ -107,6 +107,7 @@ describe('Badge component', () => { expect(vm.isLoading).toBe(false); expect(vm.hasError).toBe(false); const { badgeImage, loadingIcon, reloadButton } = findElements(); + expect(badgeImage).toBeVisible(); expect(loadingIcon).toBeHidden(); expect(reloadButton).toBeHidden(); @@ -119,6 +120,7 @@ describe('Badge component', () => { Vue.nextTick() .then(() => { const { badgeImage, loadingIcon, reloadButton } = findElements(); + expect(badgeImage).toBeHidden(); expect(loadingIcon).toBeVisible(); expect(reloadButton).toBeHidden(); @@ -134,6 +136,7 @@ describe('Badge component', () => { Vue.nextTick() .then(() => { const { badgeImage, loadingIcon, reloadButton } = findElements(); + expect(badgeImage).toBeHidden(); expect(loadingIcon).toBeHidden(); expect(reloadButton).toBeVisible(); diff --git a/spec/javascripts/badges/store/actions_spec.js b/spec/javascripts/badges/store/actions_spec.js index bb6263c6de4..2623465ebd6 100644 --- a/spec/javascripts/badges/store/actions_spec.js +++ b/spec/javascripts/badges/store/actions_spec.js @@ -94,6 +94,7 @@ describe('Badges store actions', () => { link_url: badgeInAddForm.linkUrl, }), ); + expect(dispatch.calls.allArgs()).toEqual([['requestNewBadge']]); dispatch.calls.reset(); return [200, dummyResponse]; @@ -117,6 +118,7 @@ describe('Badges store actions', () => { link_url: badgeInAddForm.linkUrl, }), ); + expect(dispatch.calls.allArgs()).toEqual([['requestNewBadge']]); dispatch.calls.reset(); return [500, '']; @@ -296,6 +298,7 @@ describe('Badges store actions', () => { .loadBadges({ state, dispatch }, dummyData) .then(() => { const badges = dummyReponse.map(transformBackendBadge); + expect(dispatch.calls.allArgs()).toEqual([['receiveLoadBadges', badges]]); }) .then(done) @@ -416,6 +419,7 @@ describe('Badges store actions', () => { .then(() => { expect(axios.get.calls.count()).toBe(1); const url = axios.get.calls.argsFor(0)[0]; + expect(url).toMatch(`^${dummyEndpointUrl}/render?`); expect(url).toMatch('\\?link_url=%3Cscript%3EI%20am%20dangerous!%3C%2Fscript%3E&'); expect(url).toMatch('&image_url=%26make-sandwhich%3Dtrue$'); @@ -436,6 +440,7 @@ describe('Badges store actions', () => { .renderBadge({ state, dispatch }) .then(() => { const renderedBadge = transformBackendBadge(dummyReponse); + expect(dispatch.calls.allArgs()).toEqual([['receiveRenderedBadge', renderedBadge]]); }) .then(done) @@ -525,6 +530,7 @@ describe('Badges store actions', () => { link_url: badgeInEditForm.linkUrl, }), ); + expect(dispatch.calls.allArgs()).toEqual([['requestUpdatedBadge']]); dispatch.calls.reset(); return [200, dummyResponse]; @@ -548,6 +554,7 @@ describe('Badges store actions', () => { link_url: badgeInEditForm.linkUrl, }), ); + expect(dispatch.calls.allArgs()).toEqual([['requestUpdatedBadge']]); dispatch.calls.reset(); return [500, '']; diff --git a/spec/javascripts/behaviors/autosize_spec.js b/spec/javascripts/behaviors/autosize_spec.js index c411c5174fb..59abae479d4 100644 --- a/spec/javascripts/behaviors/autosize_spec.js +++ b/spec/javascripts/behaviors/autosize_spec.js @@ -12,6 +12,7 @@ describe('Autosize behavior', () => { it('does not overwrite the resize property', () => { load(); + expect($('textarea')).toHaveCss({ resize: 'vertical', }); diff --git a/spec/javascripts/behaviors/copy_as_gfm_spec.js b/spec/javascripts/behaviors/copy_as_gfm_spec.js index c2db81c6ce4..f0b4fa63f71 100644 --- a/spec/javascripts/behaviors/copy_as_gfm_spec.js +++ b/spec/javascripts/behaviors/copy_as_gfm_spec.js @@ -29,6 +29,7 @@ describe('CopyAsGFM', () => { 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`'); }); @@ -38,6 +39,7 @@ describe('CopyAsGFM', () => { 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'); }); @@ -86,6 +88,7 @@ describe('CopyAsGFM', () => { simulateCopy(); const expectedGFM = '- List Item1\n- List Item2'; + expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM); }); @@ -95,6 +98,7 @@ describe('CopyAsGFM', () => { simulateCopy(); const expectedGFM = '1. List Item1\n1. List Item2'; + expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM); }); }); diff --git a/spec/javascripts/behaviors/quick_submit_spec.js b/spec/javascripts/behaviors/quick_submit_spec.js index b3a5eac8982..1fbc1f7a8e8 100644 --- a/spec/javascripts/behaviors/quick_submit_spec.js +++ b/spec/javascripts/behaviors/quick_submit_spec.js @@ -30,6 +30,7 @@ describe('Quick Submit behavior', function () { keyCode: 32, }), ); + expect(this.spies.submit).not.toHaveBeenTriggered(); }); @@ -40,6 +41,7 @@ describe('Quick Submit behavior', function () { metaKey: false, }), ); + expect(this.spies.submit).not.toHaveBeenTriggered(); }); @@ -49,6 +51,7 @@ describe('Quick Submit behavior', function () { repeat: true, }), ); + expect(this.spies.submit).not.toHaveBeenTriggered(); }); @@ -86,7 +89,8 @@ describe('Quick Submit behavior', function () { describe('In Macintosh', () => { it('responds to Meta+Enter', () => { this.textarea.trigger(keydownEvent()); - return expect(this.spies.submit).toHaveBeenTriggered(); + + expect(this.spies.submit).toHaveBeenTriggered(); }); it('excludes other modifier keys', () => { @@ -105,13 +109,15 @@ describe('Quick Submit behavior', function () { shiftKey: true, }), ); - return expect(this.spies.submit).not.toHaveBeenTriggered(); + + expect(this.spies.submit).not.toHaveBeenTriggered(); }); }); } else { it('responds to Ctrl+Enter', () => { this.textarea.trigger(keydownEvent()); - return expect(this.spies.submit).toHaveBeenTriggered(); + + expect(this.spies.submit).toHaveBeenTriggered(); }); it('excludes other modifier keys', () => { @@ -130,7 +136,8 @@ describe('Quick Submit behavior', function () { shiftKey: true, }), ); - return expect(this.spies.submit).not.toHaveBeenTriggered(); + + expect(this.spies.submit).not.toHaveBeenTriggered(); }); } }); diff --git a/spec/javascripts/behaviors/requires_input_spec.js b/spec/javascripts/behaviors/requires_input_spec.js index a434949b9da..5d1cc374573 100644 --- a/spec/javascripts/behaviors/requires_input_spec.js +++ b/spec/javascripts/behaviors/requires_input_spec.js @@ -12,33 +12,39 @@ describe('requiresInput', () => { it('disables submit when any field is required', () => { $('.js-requires-input').requiresInput(); + expect(submitButton).toBeDisabled(); }); it('enables submit when no field is required', () => { $('*[required=required]').prop('required', false); $('.js-requires-input').requiresInput(); + expect(submitButton).not.toBeDisabled(); }); it('enables submit when all required fields are pre-filled', () => { $('*[required=required]').remove(); $('.js-requires-input').requiresInput(); + expect($('.submit')).not.toBeDisabled(); }); it('enables submit when all required fields receive input', () => { $('.js-requires-input').requiresInput(); $('#required1').val('input1').change(); + expect(submitButton).toBeDisabled(); $('#optional1').val('input1').change(); + expect(submitButton).toBeDisabled(); $('#required2').val('input2').change(); $('#required3').val('input3').change(); $('#required4').val('input4').change(); $('#required5').val('1').change(); + expect($('.submit')).not.toBeDisabled(); }); }); diff --git a/spec/javascripts/behaviors/secret_values_spec.js b/spec/javascripts/behaviors/secret_values_spec.js index 95122fcf30f..ed42fc099c1 100644 --- a/spec/javascripts/behaviors/secret_values_spec.js +++ b/spec/javascripts/behaviors/secret_values_spec.js @@ -130,6 +130,7 @@ describe('setupSecretValues', () => { values.forEach((value) => { expect(value.classList.contains('hide')).toEqual(true); }); + expect(placeholders.length).toEqual(3); placeholders.forEach((placeholder) => { expect(placeholder.classList.contains('hide')).toEqual(false); @@ -148,6 +149,7 @@ describe('setupSecretValues', () => { values.forEach((value) => { expect(value.classList.contains('hide')).toEqual(false); }); + expect(placeholders.length).toEqual(3); placeholders.forEach((placeholder) => { expect(placeholder.classList.contains('hide')).toEqual(true); @@ -159,6 +161,7 @@ describe('setupSecretValues', () => { values.forEach((value) => { expect(value.classList.contains('hide')).toEqual(true); }); + expect(placeholders.length).toEqual(3); placeholders.forEach((placeholder) => { expect(placeholder.classList.contains('hide')).toEqual(false); @@ -184,6 +187,7 @@ describe('setupSecretValues', () => { values.forEach((value) => { expect(value.classList.contains('hide')).toEqual(false); }); + expect(placeholders.length).toEqual(4); placeholders.forEach((placeholder) => { expect(placeholder.classList.contains('hide')).toEqual(true); @@ -195,6 +199,7 @@ describe('setupSecretValues', () => { values.forEach((value) => { expect(value.classList.contains('hide')).toEqual(true); }); + expect(placeholders.length).toEqual(4); placeholders.forEach((placeholder) => { expect(placeholder.classList.contains('hide')).toEqual(false); diff --git a/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js b/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js index 01b5bc112b2..bc25549cbed 100644 --- a/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js +++ b/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js @@ -57,9 +57,11 @@ describe('ShortcutsIssuable', function() { it('leaves existing input intact', () => { $(FORM_SELECTOR).val('This text was already here.'); + expect($(FORM_SELECTOR).val()).toBe('This text was already here.'); ShortcutsIssuable.replyWithSelectedText(true); + expect($(FORM_SELECTOR).val()).toBe('This text was already here.\n\n> Selected text.\n\n'); }); @@ -70,6 +72,7 @@ describe('ShortcutsIssuable', function() { }); ShortcutsIssuable.replyWithSelectedText(true); + expect(triggered).toBe(true); }); diff --git a/spec/javascripts/blob/blob_fork_suggestion_spec.js b/spec/javascripts/blob/blob_fork_suggestion_spec.js index d1ab0a32f85..fa40a04a8c7 100644 --- a/spec/javascripts/blob/blob_fork_suggestion_spec.js +++ b/spec/javascripts/blob/blob_fork_suggestion_spec.js @@ -26,6 +26,7 @@ describe('BlobForkSuggestion', () => { it('showSuggestionSection', () => { blobForkSuggestion.showSuggestionSection('/foo', 'foo'); + expect(suggestionSection.classList.contains('hidden')).toEqual(false); expect(forkButton.getAttribute('href')).toEqual('/foo'); expect(actionTextPiece.textContent).toEqual('foo'); @@ -33,6 +34,7 @@ describe('BlobForkSuggestion', () => { it('hideSuggestionSection', () => { blobForkSuggestion.hideSuggestionSection(); + expect(suggestionSection.classList.contains('hidden')).toEqual(true); }); }); diff --git a/spec/javascripts/blob/viewer/index_spec.js b/spec/javascripts/blob/viewer/index_spec.js index 8b79624d9f4..b5a9db2da3a 100644 --- a/spec/javascripts/blob/viewer/index_spec.js +++ b/spec/javascripts/blob/viewer/index_spec.js @@ -165,6 +165,7 @@ describe('Blob viewer', () => { expect( simpleBtn.classList.contains('active'), ).toBeTruthy(); + expect(simpleBtn.blur).toHaveBeenCalled(); }); diff --git a/spec/javascripts/boards/boards_store_spec.js b/spec/javascripts/boards/boards_store_spec.js index dfd3ea0db66..3b10550ba63 100644 --- a/spec/javascripts/boards/boards_store_spec.js +++ b/spec/javascripts/boards/boards_store_spec.js @@ -86,10 +86,12 @@ describe('Store', () => { description: 'testing;' } }); + expect(boardsStore.state.lists.length).toBe(1); setTimeout(() => { const list = boardsStore.findList('id', listObj.id); + expect(list).toBeDefined(); expect(list.id).toBe(listObj.id); expect(list.position).toBe(0); @@ -103,6 +105,7 @@ describe('Store', () => { it('check for blank state not adding', () => { boardsStore.addList(listObj); + expect(boardsStore.shouldAddBlankState()).toBe(false); }); @@ -118,6 +121,7 @@ describe('Store', () => { boardsStore.addBlankState(); const list = boardsStore.findList('type', 'blank', 'blank'); + expect(list).toBeDefined(); }); diff --git a/spec/javascripts/boards/issue_spec.js b/spec/javascripts/boards/issue_spec.js index e8387068831..b3d215b7b25 100644 --- a/spec/javascripts/boards/issue_spec.js +++ b/spec/javascripts/boards/issue_spec.js @@ -47,6 +47,7 @@ describe('Issue model', () => { color: 'blue', description: 'bugs!' }); + expect(issue.labels.length).toBe(2); }); @@ -63,12 +64,14 @@ describe('Issue model', () => { it('finds label', () => { const label = issue.findLabel(issue.labels[0]); + expect(label).toBeDefined(); }); it('removes label', () => { const label = issue.findLabel(issue.labels[0]); issue.removeLabel(label); + expect(issue.labels.length).toBe(0); }); @@ -79,9 +82,11 @@ describe('Issue model', () => { color: 'blue', description: 'bugs!' }); + expect(issue.labels.length).toBe(2); issue.removeLabels([issue.labels[0], issue.labels[1]]); + expect(issue.labels.length).toBe(0); }); @@ -98,17 +103,20 @@ describe('Issue model', () => { it('finds assignee', () => { const assignee = issue.findAssignee(issue.assignees[0]); + expect(assignee).toBeDefined(); }); it('removes assignee', () => { const assignee = issue.findAssignee(issue.assignees[0]); issue.removeAssignee(assignee); + expect(issue.assignees.length).toBe(0); }); it('removes all assignees', () => { issue.removeAllAssignees(); + expect(issue.assignees.length).toBe(0); }); @@ -131,6 +139,7 @@ describe('Issue model', () => { it('updates data', () => { issue.updateData({ subscribed: true }); + expect(issue.subscribed).toBe(true); }); diff --git a/spec/javascripts/boards/list_spec.js b/spec/javascripts/boards/list_spec.js index ba6e81a29a9..667fb710062 100644 --- a/spec/javascripts/boards/list_spec.js +++ b/spec/javascripts/boards/list_spec.js @@ -60,6 +60,7 @@ describe('List model', () => { it('destroys the list', (done) => { boardsStore.addList(listObj); list = boardsStore.findList('id', listObj.id); + expect(boardsStore.state.lists.length).toBe(1); list.destroy(); @@ -72,6 +73,7 @@ describe('List model', () => { it('gets issue from list', (done) => { setTimeout(() => { const issue = list.findIssue(1); + expect(issue).toBeDefined(); done(); }, 0); @@ -80,8 +82,10 @@ describe('List model', () => { it('removes issue', (done) => { setTimeout(() => { const issue = list.findIssue(1); + expect(list.issues.length).toBe(1); list.removeIssue(issue); + expect(list.issues.length).toBe(0); done(); }, 0); diff --git a/spec/javascripts/bootstrap_jquery_spec.js b/spec/javascripts/bootstrap_jquery_spec.js index cd61d920fa0..3e2d814a06a 100644 --- a/spec/javascripts/bootstrap_jquery_spec.js +++ b/spec/javascripts/bootstrap_jquery_spec.js @@ -14,13 +14,15 @@ import '~/commons/bootstrap'; var $input; $input = $('input').first(); $input.disable(); - return expect($input).toHaveAttr('disabled', 'disabled'); + + expect($input).toHaveAttr('disabled', 'disabled'); }); return it('adds the disabled class', function() { var $input; $input = $('input').first(); $input.disable(); - return expect($input).toHaveClass('disabled'); + + expect($input).toHaveClass('disabled'); }); }); return describe('enable', function() { @@ -32,13 +34,15 @@ import '~/commons/bootstrap'; var $input; $input = $('input').first(); $input.enable(); - return expect($input).not.toHaveAttr('disabled'); + + expect($input).not.toHaveAttr('disabled'); }); return it('removes the disabled class', function() { var $input; $input = $('input').first(); $input.enable(); - return expect($input).not.toHaveClass('disabled'); + + expect($input).not.toHaveClass('disabled'); }); }); }); diff --git a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js index 2fa50975f0f..dce3696ac7e 100644 --- a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js +++ b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js @@ -41,6 +41,7 @@ describe('VariableList', () => { // Check for the correct default in the new row const $keyInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-key'); + expect($keyInput.val()).toBe(''); }); @@ -54,6 +55,7 @@ describe('VariableList', () => { // Check for the correct default in the new row const $valueInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-key'); + expect($valueInput.val()).toBe(''); }); @@ -129,6 +131,7 @@ describe('VariableList', () => { // Check for the correct default in the new row const $protectedInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-protected'); + expect($protectedInput.val()).toBe('false'); }) .then(done) @@ -166,6 +169,7 @@ describe('VariableList', () => { it('should enable all remove buttons', () => { variableList.toggleEnableRow(false); + expect($wrapper.find('.js-row-remove-button[disabled]').length).toBe(3); variableList.toggleEnableRow(true); @@ -175,6 +179,7 @@ describe('VariableList', () => { it('should enable all key inputs', () => { variableList.toggleEnableRow(false); + expect($wrapper.find('.js-ci-variable-input-key[disabled]').length).toBe(3); variableList.toggleEnableRow(true); diff --git a/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js b/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js index 94a0c999d66..a36c2ba74fd 100644 --- a/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js +++ b/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js @@ -19,6 +19,7 @@ describe('NativeFormVariableList', () => { describe('onFormSubmit', () => { it('should clear out the `name` attribute on the inputs for the last empty row on form submission (avoid BE validation)', () => { const $row = $wrapper.find('.js-row'); + expect($row.find('.js-ci-variable-input-key').attr('name')).toBe('schedule[variables_attributes][][key]'); expect($row.find('.js-ci-variable-input-value').attr('name')).toBe('schedule[variables_attributes][][secret_value]'); diff --git a/spec/javascripts/clusters/clusters_bundle_spec.js b/spec/javascripts/clusters/clusters_bundle_spec.js index d0e0b214509..337afc08a21 100644 --- a/spec/javascripts/clusters/clusters_bundle_spec.js +++ b/spec/javascripts/clusters/clusters_bundle_spec.js @@ -86,6 +86,7 @@ describe('Clusters', () => { }); const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text'); + expect(flashMessage).toBeNull(); }); @@ -99,6 +100,7 @@ describe('Clusters', () => { }); const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text'); + expect(flashMessage).not.toBeNull(); expect(flashMessage.textContent.trim()).toEqual('Helm Tiller was successfully installed on your Kubernetes cluster'); }); @@ -115,6 +117,7 @@ describe('Clusters', () => { }); const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text'); + expect(flashMessage).not.toBeNull(); expect(flashMessage.textContent.trim()).toEqual('Helm Tiller, Ingress was successfully installed on your Kubernetes cluster'); }); @@ -128,9 +131,11 @@ describe('Clusters', () => { expect( cluster.creatingContainer.classList.contains('hidden'), ).toBeFalsy(); + expect( cluster.successContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.errorContainer.classList.contains('hidden'), ).toBeTruthy(); @@ -142,9 +147,11 @@ describe('Clusters', () => { expect( cluster.creatingContainer.classList.contains('hidden'), ).toBeFalsy(); + expect( cluster.successContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.errorContainer.classList.contains('hidden'), ).toBeTruthy(); @@ -158,9 +165,11 @@ describe('Clusters', () => { expect( cluster.creatingContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.successContainer.classList.contains('hidden'), ).toBeFalsy(); + expect( cluster.errorContainer.classList.contains('hidden'), ).toBeTruthy(); @@ -172,9 +181,11 @@ describe('Clusters', () => { expect( cluster.creatingContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.successContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.errorContainer.classList.contains('hidden'), ).toBeTruthy(); @@ -188,9 +199,11 @@ describe('Clusters', () => { expect( cluster.creatingContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.successContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.errorContainer.classList.contains('hidden'), ).toBeFalsy(); @@ -206,9 +219,11 @@ describe('Clusters', () => { expect( cluster.creatingContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.successContainer.classList.contains('hidden'), ).toBeTruthy(); + expect( cluster.errorContainer.classList.contains('hidden'), ).toBeFalsy(); @@ -219,6 +234,7 @@ describe('Clusters', () => { describe('installApplication', () => { it('tries to install helm', (done) => { spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); + expect(cluster.store.state.applications.helm.requestStatus).toEqual(null); cluster.installApplication({ id: 'helm' }); @@ -238,6 +254,7 @@ describe('Clusters', () => { it('tries to install ingress', (done) => { spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); + expect(cluster.store.state.applications.ingress.requestStatus).toEqual(null); cluster.installApplication({ id: 'ingress' }); @@ -257,6 +274,7 @@ describe('Clusters', () => { it('tries to install runner', (done) => { spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); + expect(cluster.store.state.applications.runner.requestStatus).toEqual(null); cluster.installApplication({ id: 'runner' }); @@ -276,6 +294,7 @@ describe('Clusters', () => { it('tries to install jupyter', (done) => { spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve()); + expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(null); cluster.installApplication({ id: 'jupyter', params: { hostname: cluster.store.state.applications.jupyter.hostname } }); @@ -294,6 +313,7 @@ describe('Clusters', () => { it('sets error request status when the request fails', (done) => { spyOn(cluster.service, 'installApplication').and.returnValue(Promise.reject(new Error('STUBBED ERROR'))); + expect(cluster.store.state.applications.helm.requestStatus).toEqual(null); cluster.installApplication({ id: 'helm' }); diff --git a/spec/javascripts/commit_merge_requests_spec.js b/spec/javascripts/commit_merge_requests_spec.js index 3466ef51ea8..f2c777bcfb4 100644 --- a/spec/javascripts/commit_merge_requests_spec.js +++ b/spec/javascripts/commit_merge_requests_spec.js @@ -4,10 +4,12 @@ describe('CommitMergeRequests', () => { describe('createContent', () => { it('should return created content', () => { const content1 = CommitMergeRequests.createContent([{ iid: 1, path: '/path1', title: 'foo' }, { iid: 2, path: '/path2', title: 'baz' }])[0]; + expect(content1.tagName).toEqual('SPAN'); expect(content1.childElementCount).toEqual(4); const content2 = CommitMergeRequests.createContent([])[0]; + expect(content2.tagName).toEqual('SPAN'); expect(content2.childElementCount).toEqual(0); expect(content2.innerText).toEqual('No related merge requests found'); @@ -26,6 +28,7 @@ describe('CommitMergeRequests', () => { describe('createHeader', () => { it('should return created header', () => { const header = CommitMergeRequests.createHeader(0, 1)[0]; + expect(header.tagName).toEqual('SPAN'); expect(header.innerText).toEqual('1 merge request'); }); @@ -34,6 +37,7 @@ describe('CommitMergeRequests', () => { describe('createItem', () => { it('should return created item', () => { const item = CommitMergeRequests.createItem({ iid: 1, path: '/path', title: 'foo' })[0]; + expect(item.tagName).toEqual('SPAN'); expect(item.childElementCount).toEqual(2); expect(item.children[0].tagName).toEqual('A'); @@ -44,6 +48,7 @@ describe('CommitMergeRequests', () => { describe('createLink', () => { it('should return created link', () => { const link = CommitMergeRequests.createLink({ iid: 1, path: '/path', title: 'foo' })[0]; + expect(link.tagName).toEqual('A'); expect(link.href).toMatch(/\/path$/); expect(link.innerText).toEqual('!1'); @@ -53,6 +58,7 @@ describe('CommitMergeRequests', () => { describe('createTitle', () => { it('should return created title', () => { const title = CommitMergeRequests.createTitle({ iid: 1, path: '/path', title: 'foo' })[0]; + expect(title.tagName).toEqual('SPAN'); expect(title.innerText).toEqual('foo'); }); diff --git a/spec/javascripts/create_item_dropdown_spec.js b/spec/javascripts/create_item_dropdown_spec.js index ee26122be12..aee35441112 100644 --- a/spec/javascripts/create_item_dropdown_spec.js +++ b/spec/javascripts/create_item_dropdown_spec.js @@ -63,6 +63,7 @@ describe('CreateItemDropdown', () => { $('.js-dropdown-menu-toggle').click(); const $itemEls = $wrapperEl.find('.js-dropdown-content a'); + expect($itemEls.length).toEqual(DROPDOWN_ITEM_DATA.length); }); }); @@ -106,6 +107,7 @@ describe('CreateItemDropdown', () => { createItemAndClearInput(NEW_ITEM_TEXT); const $itemEls = $wrapperEl.find('.js-dropdown-content a'); + expect($itemEls.length).toEqual(1 + DROPDOWN_ITEM_DATA.length); expect($($itemEls.get(DROPDOWN_ITEM_DATA.length)).text()).toEqual(NEW_ITEM_TEXT); }); @@ -114,6 +116,7 @@ describe('CreateItemDropdown', () => { createItemAndClearInput(DROPDOWN_ITEM_DATA[0].text); const $itemEls = $wrapperEl.find('.js-dropdown-content a'); + expect($itemEls.length).toEqual(DROPDOWN_ITEM_DATA.length); }); }); @@ -142,11 +145,13 @@ describe('CreateItemDropdown', () => { .trigger('input'); const $itemElsAfterFilter = $wrapperEl.find('.js-dropdown-content a'); + expect($itemElsAfterFilter.length).toEqual(1); createItemDropdown.clearDropdown(); const $itemElsAfterClear = $wrapperEl.find('.js-dropdown-content a'); + expect($itemElsAfterClear.length).toEqual(0); expect(filterInput.val()).toEqual(''); }); @@ -176,6 +181,7 @@ describe('CreateItemDropdown', () => { createItemAndClearInput('new-item'); const $itemEls = $wrapperEl.find('.js-dropdown-content a'); + expect($itemEls.length).toEqual(1 + DROPDOWN_ITEM_DATA.length); expect($($itemEls[3]).text()).toEqual('new-item-text'); expect($wrapperEl.find('.dropdown-toggle-text').text()).toEqual('new-item-title'); diff --git a/spec/javascripts/create_merge_request_dropdown_spec.js b/spec/javascripts/create_merge_request_dropdown_spec.js index b229765a8c5..00fe3f451f5 100644 --- a/spec/javascripts/create_merge_request_dropdown_spec.js +++ b/spec/javascripts/create_merge_request_dropdown_spec.js @@ -59,6 +59,7 @@ describe('CreateMergeRequestDropdown', () => { expect(dropdown.createBranchPath).toBe( `${TEST_HOST}/branches?branch_name=contains%23hash&issue=42`, ); + expect(dropdown.createMrPath).toBe( `${TEST_HOST}/create_merge_request?branch_name=contains%23hash&ref=master`, ); diff --git a/spec/javascripts/cycle_analytics/banner_spec.js b/spec/javascripts/cycle_analytics/banner_spec.js index 2815bdba0c2..5eda247b2fd 100644 --- a/spec/javascripts/cycle_analytics/banner_spec.js +++ b/spec/javascripts/cycle_analytics/banner_spec.js @@ -24,9 +24,11 @@ describe('Cycle analytics banner', () => { expect( vm.$el.querySelector('p').textContent.trim().replace(/[\r\n]+/g, ' '), ).toContain('Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.'); + expect( vm.$el.querySelector('a').textContent.trim(), ).toEqual('Read more'); + expect( vm.$el.querySelector('a').getAttribute('href'), ).toEqual('path'); diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js index 24e4871ce44..9fedbcc4c25 100644 --- a/spec/javascripts/datetime_utility_spec.js +++ b/spec/javascripts/datetime_utility_spec.js @@ -24,36 +24,43 @@ describe('Date time utils', () => { describe('get day name', () => { it('should return Sunday', () => { const day = datetimeUtility.getDayName(new Date('07/17/2016')); + expect(day).toBe('Sunday'); }); it('should return Monday', () => { const day = datetimeUtility.getDayName(new Date('07/18/2016')); + expect(day).toBe('Monday'); }); it('should return Tuesday', () => { const day = datetimeUtility.getDayName(new Date('07/19/2016')); + expect(day).toBe('Tuesday'); }); it('should return Wednesday', () => { const day = datetimeUtility.getDayName(new Date('07/20/2016')); + expect(day).toBe('Wednesday'); }); it('should return Thursday', () => { const day = datetimeUtility.getDayName(new Date('07/21/2016')); + expect(day).toBe('Thursday'); }); it('should return Friday', () => { const day = datetimeUtility.getDayName(new Date('07/22/2016')); + expect(day).toBe('Friday'); }); it('should return Saturday', () => { const day = datetimeUtility.getDayName(new Date('07/23/2016')); + expect(day).toBe('Saturday'); }); }); @@ -63,6 +70,7 @@ describe('Date time utils', () => { const firstDay = new Date('07/01/2016'); const secondDay = new Date('07/08/2016'); const difference = datetimeUtility.getDayDifference(firstDay, secondDay); + expect(difference).toBe(7); }); @@ -70,6 +78,7 @@ describe('Date time utils', () => { const firstDay = new Date('07/01/2016'); const secondDay = new Date('08/01/2016'); const difference = datetimeUtility.getDayDifference(firstDay, secondDay); + expect(difference).toBe(31); }); @@ -77,6 +86,7 @@ describe('Date time utils', () => { const firstDay = new Date('07/02/2015'); const secondDay = new Date('07/01/2016'); const difference = datetimeUtility.getDayDifference(firstDay, secondDay); + expect(difference).toBe(365); }); }); @@ -156,6 +166,7 @@ describe('getTimeframeWindowFrom', () => { new Date(2018, 4, 31), ]; const timeframe = datetimeUtility.getTimeframeWindowFrom(startDate, 5); + expect(timeframe.length).toBe(5); timeframe.forEach((timeframeItem, index) => { expect(timeframeItem.getFullYear()).toBe(mockTimeframe[index].getFullYear()); diff --git a/spec/javascripts/deploy_keys/components/app_spec.js b/spec/javascripts/deploy_keys/components/app_spec.js index cd147bb2935..df36d1989d2 100644 --- a/spec/javascripts/deploy_keys/components/app_spec.js +++ b/spec/javascripts/deploy_keys/components/app_spec.js @@ -60,6 +60,7 @@ describe('Deploy keys app component', () => { expect(textContent('.js-deployKeys-tab-available_project_keys')).toContain( 'Privately accessible deploy keys', ); + expect(textContent('.js-deployKeys-tab-public_keys')).toContain( 'Publicly accessible deploy keys', ); @@ -67,9 +68,11 @@ describe('Deploy keys app component', () => { expect(textContent('.js-deployKeys-tab-enabled_keys .badge')).toBe( `${vm.store.keys.enabled_keys.length}`, ); + expect(textContent('.js-deployKeys-tab-available_project_keys .badge')).toBe( `${vm.store.keys.available_project_keys.length}`, ); + expect(textContent('.js-deployKeys-tab-public_keys .badge')).toBe( `${vm.store.keys.public_keys.length}`, ); diff --git a/spec/javascripts/deploy_keys/components/key_spec.js b/spec/javascripts/deploy_keys/components/key_spec.js index d1de9d132b8..7117dc4a9ee 100644 --- a/spec/javascripts/deploy_keys/components/key_spec.js +++ b/spec/javascripts/deploy_keys/components/key_spec.js @@ -82,6 +82,7 @@ describe('Deploy keys key', () => { it('shows expandable button if more than two projects', () => { const labels = vm.$el.querySelectorAll('.deploy-project-label'); + expect(labels.length).toBe(2); expect(labels[1].textContent).toContain('others'); expect(labels[1].getAttribute('data-original-title')).toContain('Expand'); @@ -93,6 +94,7 @@ describe('Deploy keys key', () => { Vue.nextTick(() => { const labels = vm.$el.querySelectorAll('.deploy-project-label'); + expect(labels.length).toBe(length); expect(labels[1].textContent).not.toContain(`+${length} others`); expect(labels[1].getAttribute('data-original-title')).not.toContain('Expand'); @@ -105,6 +107,7 @@ describe('Deploy keys key', () => { Vue.nextTick(() => { const labels = vm.$el.querySelectorAll('.deploy-project-label'); + expect(labels.length).toBe(2); expect(labels[1].textContent).toContain( vm.deployKey.deploy_keys_projects[1].project.full_name, diff --git a/spec/javascripts/diff_comments_store_spec.js b/spec/javascripts/diff_comments_store_spec.js index c6f2e66cebd..a6d363ce88e 100644 --- a/spec/javascripts/diff_comments_store_spec.js +++ b/spec/javascripts/diff_comments_store_spec.js @@ -26,6 +26,7 @@ describe('New discussion', () => { it('creates new discussion', () => { expect(Object.keys(CommentsStore.state).length).toBe(0); createDiscussion(); + expect(Object.keys(CommentsStore.state).length).toBe(1); }); @@ -34,6 +35,7 @@ describe('New discussion', () => { createDiscussion(2); const discussion = CommentsStore.state['a']; + expect(Object.keys(discussion.notes).length).toBe(2); }); }); @@ -46,6 +48,7 @@ describe('Get note', () => { it('gets note by ID', () => { const note = CommentsStore.get('a', 1); + expect(note).toBeDefined(); expect(note.id).toBe(1); }); @@ -59,17 +62,20 @@ describe('Delete discussion', () => { it('deletes discussion by ID', () => { CommentsStore.delete('a', 1); + expect(Object.keys(CommentsStore.state).length).toBe(0); }); it('deletes discussion when no more notes', () => { createDiscussion(); createDiscussion(2); + expect(Object.keys(CommentsStore.state).length).toBe(1); expect(Object.keys(CommentsStore.state['a'].notes).length).toBe(2); CommentsStore.delete('a', 1); CommentsStore.delete('a', 2); + expect(Object.keys(CommentsStore.state).length).toBe(0); }); }); @@ -84,6 +90,7 @@ describe('Update note', () => { CommentsStore.update('a', 1, false, 'test'); const note = CommentsStore.get('a', 1); + expect(note.resolved).toBe(false); }); }); @@ -96,6 +103,7 @@ describe('Discussion resolved', () => { it('is resolved with single note', () => { const discussion = CommentsStore.state['a']; + expect(discussion.isResolved()).toBe(true); }); @@ -118,6 +126,7 @@ describe('Discussion resolved', () => { createDiscussion(2, false); discussion.resolveAllNotes(); + expect(discussion.isResolved()).toBe(true); }); @@ -126,6 +135,7 @@ describe('Discussion resolved', () => { createDiscussion(2); discussion.unResolveAllNotes(); + expect(discussion.isResolved()).toBe(false); }); }); diff --git a/spec/javascripts/diffs/components/diff_file_header_spec.js b/spec/javascripts/diffs/components/diff_file_header_spec.js index 1f7d5f42322..2fd92c6f5b6 100644 --- a/spec/javascripts/diffs/components/diff_file_header_spec.js +++ b/spec/javascripts/diffs/components/diff_file_header_spec.js @@ -98,6 +98,7 @@ describe('diff_file_header', () => { props.discussionPath = 'link://to/discussion'; vm = mountComponentWithStore(Component, { props, store }); const href = vm.$el.querySelector('.js-title-wrapper').getAttribute('href'); + expect(href).toBe(vm.discussionPath); }); }); @@ -270,6 +271,7 @@ describe('diff_file_header', () => { it('displays an file icon in the title', () => { vm = mountComponentWithStore(Component, { props, store }); + expect(vm.$el.querySelector('svg.js-file-icon use').getAttribute('xlink:href')).toContain( 'ruby', ); @@ -312,6 +314,7 @@ describe('diff_file_header', () => { vm = mountComponentWithStore(Component, { props, store }); const button = vm.$el.querySelector('.btn-clipboard'); + expect(button).not.toBe(null); expect(button.dataset.clipboardText).toBe('{"text":"files/ruby/popen.rb","gfm":"`files/ruby/popen.rb`"}'); }); @@ -323,6 +326,7 @@ describe('diff_file_header', () => { vm = mountComponentWithStore(Component, { props, store }); const { fileMode } = vm.$refs; + expect(fileMode).not.toBe(undefined); expect(fileMode).toContainText(props.diffFile.aMode); expect(fileMode).toContainText(props.diffFile.bMode); @@ -334,6 +338,7 @@ describe('diff_file_header', () => { vm = mountComponentWithStore(Component, { props, store }); const { fileMode } = vm.$refs; + expect(fileMode).toBe(undefined); }); }); diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/javascripts/diffs/components/diff_file_spec.js index b8d4b31ee04..f009ef89d88 100644 --- a/spec/javascripts/diffs/components/diff_file_spec.js +++ b/spec/javascripts/diffs/components/diff_file_spec.js @@ -97,6 +97,7 @@ describe('DiffFile', () => { expect(vm.$el.innerText).toContain( 'This source diff could not be displayed because it is too large', ); + expect(vm.$el.querySelector('.js-too-large-diff')).toBeDefined(); expect(vm.$el.querySelector('.js-too-large-diff a').href.indexOf(BLOB_LINK)).toBeGreaterThan(-1); diff --git a/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js b/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js index 0085a16815a..ad2605a5c5c 100644 --- a/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js +++ b/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js @@ -23,6 +23,7 @@ describe('DiffGutterAvatars', () => { it('should return false when all discussions are not expanded', () => { component.discussions[0].expanded = false; + expect(component.discussionsExpanded).toEqual(false); }); }); @@ -56,6 +57,7 @@ describe('DiffGutterAvatars', () => { it('should return empty string if there is no discussion', () => { component.discussions = []; + expect(component.moreText).toEqual(''); }); }); diff --git a/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js b/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js index f36454cc23e..6972e0ee913 100644 --- a/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js +++ b/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js @@ -31,12 +31,14 @@ describe('DiffLineGutterContent', () => { it('should prepend # to lineCode', () => { const lineCode = 'LC_42'; const component = createComponent(); + expect(component.lineHref).toEqual(`#${lineCode}`); }); it('should return # if there is no lineCode', () => { const component = createComponent(); component.line.lineCode = ''; + expect(component.lineHref).toEqual('#'); }); }); @@ -44,6 +46,7 @@ describe('DiffLineGutterContent', () => { describe('discussions, hasDiscussions, shouldShowAvatarsOnGutter', () => { it('should return empty array when there is no discussion', () => { const component = createComponent(); + expect(component.hasDiscussions).toEqual(false); expect(component.shouldShowAvatarsOnGutter).toEqual(false); }); diff --git a/spec/javascripts/diffs/components/diff_line_note_form_spec.js b/spec/javascripts/diffs/components/diff_line_note_form_spec.js index f31fc1f0e2b..c39b54d9cc9 100644 --- a/spec/javascripts/diffs/components/diff_line_note_form_spec.js +++ b/spec/javascripts/diffs/components/diff_line_note_form_spec.js @@ -36,6 +36,7 @@ describe('DiffLineNoteForm', () => { spyOn(window, 'confirm').and.returnValue(false); component.handleCancelCommentForm(true, true); + expect(window.confirm).toHaveBeenCalled(); }); @@ -43,9 +44,11 @@ describe('DiffLineNoteForm', () => { spyOn(window, 'confirm').and.returnValue(false); component.handleCancelCommentForm(true, false); + expect(window.confirm).not.toHaveBeenCalled(); component.handleCancelCommentForm(false, true); + expect(window.confirm).not.toHaveBeenCalled(); }); @@ -60,6 +63,7 @@ describe('DiffLineNoteForm', () => { expect(component.cancelCommentForm).toHaveBeenCalledWith({ lineCode: diffLines[0].lineCode, }); + expect(component.resetAutoSave).toHaveBeenCalled(); done(); diff --git a/spec/javascripts/diffs/store/getters_spec.js b/spec/javascripts/diffs/store/getters_spec.js index cfeaaec6980..807a9e3baf0 100644 --- a/spec/javascripts/diffs/store/getters_spec.js +++ b/spec/javascripts/diffs/store/getters_spec.js @@ -52,11 +52,13 @@ describe('Diffs Module Getters', () => { describe('areAllFilesCollapsed', () => { it('returns true when all files are collapsed', () => { localState.diffFiles = [{ collapsed: true }, { collapsed: true }]; + expect(getters.areAllFilesCollapsed(localState)).toEqual(true); }); it('returns false when at least one file is not collapsed', () => { localState.diffFiles = [{ collapsed: false }, { collapsed: true }]; + expect(getters.areAllFilesCollapsed(localState)).toEqual(false); }); }); @@ -244,6 +246,7 @@ describe('Diffs Module Getters', () => { it('returns false when no line discussions were found', () => { line.discussions = []; + expect(getters.shouldRenderInlineCommentRow(localState)(line)).toEqual(false); }); @@ -288,6 +291,7 @@ describe('Diffs Module Getters', () => { it('returns null if no matching file is found', () => { localState.diffFiles = []; + expect(getters.getDiffFileByHash(localState)('123')).toBeUndefined(); }); }); diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js index 0b712055956..b7e28391419 100644 --- a/spec/javascripts/diffs/store/mutations_spec.js +++ b/spec/javascripts/diffs/store/mutations_spec.js @@ -12,6 +12,7 @@ describe('DiffsStoreMutations', () => { const projectPath = '/root/project'; mutations[types.SET_BASE_CONFIG](state, { endpoint, projectPath }); + expect(state.endpoint).toEqual(endpoint); expect(state.projectPath).toEqual(projectPath); }); @@ -22,6 +23,7 @@ describe('DiffsStoreMutations', () => { const state = {}; mutations[types.SET_LOADING](state, false); + expect(state.isLoading).toEqual(false); }); }); @@ -48,6 +50,7 @@ describe('DiffsStoreMutations', () => { const state = {}; mutations[types.SET_DIFF_VIEW_TYPE](state, INLINE_DIFF_VIEW_TYPE); + expect(state.diffViewType).toEqual(INLINE_DIFF_VIEW_TYPE); }); }); @@ -58,6 +61,7 @@ describe('DiffsStoreMutations', () => { const lineCode = 'FDE'; mutations[types.ADD_COMMENT_FORM_LINE](state, { lineCode }); + expect(state.diffLineCommentForms[lineCode]).toBeTruthy(); }); }); @@ -68,9 +72,11 @@ describe('DiffsStoreMutations', () => { const lineCode = 'FDE'; mutations[types.ADD_COMMENT_FORM_LINE](state, { lineCode }); + expect(state.diffLineCommentForms[lineCode]).toBeTruthy(); mutations[types.REMOVE_COMMENT_FORM_LINE](state, { lineCode }); + expect(state.diffLineCommentForms[lineCode]).toBeUndefined(); }); }); @@ -83,6 +89,7 @@ describe('DiffsStoreMutations', () => { const state = { expandAllFiles: true, diffFiles: [diffFile] }; mutations[types.EXPAND_ALL_FILES](state); + expect(state.diffFiles[0].collapsed).toEqual(false); }); }); @@ -118,11 +125,13 @@ describe('DiffsStoreMutations', () => { options.lineNumbers, options.params.bottom, ); + expect(lineRefSpy).toHaveBeenCalledWith( options.contextLines, options.lineNumbers, options.params.bottom, ); + expect(addContextLinesSpy).toHaveBeenCalledWith({ inlineLines: diffFile.highlightedDiffLines, parallelLines: diffFile.parallelDiffLines, @@ -142,6 +151,7 @@ describe('DiffsStoreMutations', () => { const data = { diff_files: [{ file_hash: fileHash, extra_field: 1, existingField: 1 }] }; mutations[types.ADD_COLLAPSED_DIFFS](state, { file: state.diffFiles[1], data }); + expect(spy).toHaveBeenCalledWith(data, { deep: true }); expect(state.diffFiles[1].fileHash).toEqual(fileHash); @@ -345,6 +355,7 @@ describe('DiffsStoreMutations', () => { fileHash: 'ABC', lineCode: 'ABC_1', }); + expect(state.diffFiles[0].parallelDiffLines[0].left.discussions.length).toEqual(0); expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(0); }); diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js index 257270a91ec..ef367fc09fa 100644 --- a/spec/javascripts/diffs/store/utils_spec.js +++ b/spec/javascripts/diffs/store/utils_spec.js @@ -62,10 +62,12 @@ describe('DiffsStoreUtils', () => { const atParallelIndex = diffFile.parallelDiffLines[parallelIndex]; utils.removeMatchLine(diffFile, lineNumbers, false); + expect(diffFile.highlightedDiffLines[inlineIndex]).not.toEqual(atInlineIndex); expect(diffFile.parallelDiffLines[parallelIndex]).not.toEqual(atParallelIndex); utils.removeMatchLine(diffFile, lineNumbers, true); + expect(diffFile.highlightedDiffLines[inlineIndex + 1]).not.toEqual(atInlineIndex); expect(diffFile.parallelDiffLines[parallelIndex + 1]).not.toEqual(atParallelIndex); }); @@ -87,11 +89,13 @@ describe('DiffsStoreUtils', () => { }; utils.addContextLines(options); + expect(inlineLines[inlineLines.length - 1]).toEqual(contextLines[0]); expect(parallelLines[parallelLines.length - 1]).toEqual(normalizedParallelLine); delete options.bottom; utils.addContextLines(options); + expect(inlineLines[inlineIndex]).toEqual(contextLines[0]); expect(parallelLines[parallelIndex]).toEqual(normalizedParallelLine); }); @@ -274,6 +278,7 @@ describe('DiffsStoreUtils', () => { }; utils.trimFirstCharOfLineContent(lineObj); + expect(lineObj).toEqual({ discussions: [], richText: ' diff' }); }); @@ -288,19 +293,23 @@ describe('DiffsStoreUtils', () => { utils.prepareDiffData(preparedDiff); const firstParallelDiffLine = preparedDiff.diffFiles[0].parallelDiffLines[2]; + expect(firstParallelDiffLine.left.discussions.length).toBe(0); expect(firstParallelDiffLine.left).not.toHaveAttr('text'); expect(firstParallelDiffLine.right.discussions.length).toBe(0); expect(firstParallelDiffLine.right).not.toHaveAttr('text'); const firstParallelChar = firstParallelDiffLine.right.richText.charAt(0); + expect(firstParallelChar).not.toBe(' '); expect(firstParallelChar).not.toBe('+'); expect(firstParallelChar).not.toBe('-'); const checkLine = preparedDiff.diffFiles[0].highlightedDiffLines[0]; + expect(checkLine.discussions.length).toBe(0); expect(checkLine).not.toHaveAttr('text'); const firstChar = checkLine.richText.charAt(0); + expect(firstChar).not.toBe(' '); expect(firstChar).not.toBe('+'); expect(firstChar).not.toBe('-'); diff --git a/spec/javascripts/dirty_submit/dirty_submit_collection_spec.js b/spec/javascripts/dirty_submit/dirty_submit_collection_spec.js index 87a26183b63..08ffc44605f 100644 --- a/spec/javascripts/dirty_submit/dirty_submit_collection_spec.js +++ b/spec/javascripts/dirty_submit/dirty_submit_collection_spec.js @@ -15,9 +15,13 @@ describe('DirtySubmitCollection', () => { expect(submit.disabled).toBe(true); return setInput(input, `${originalValue} changes`) - .then(() => expect(submit.disabled).toBe(false)) + .then(() => { + expect(submit.disabled).toBe(false); + }) .then(() => setInput(input, originalValue)) - .then(() => expect(submit.disabled).toBe(true)) + .then(() => { + expect(submit.disabled).toBe(true); + }) .then(done) .catch(done.fail); }); diff --git a/spec/javascripts/dirty_submit/dirty_submit_form_spec.js b/spec/javascripts/dirty_submit/dirty_submit_form_spec.js index 86d53fa984a..a2ec332e956 100644 --- a/spec/javascripts/dirty_submit/dirty_submit_form_spec.js +++ b/spec/javascripts/dirty_submit/dirty_submit_form_spec.js @@ -12,9 +12,13 @@ describe('DirtySubmitForm', () => { expect(submit.disabled).toBe(true); return setInput(input, `${originalValue} changes`) - .then(() => expect(submit.disabled).toBe(false)) + .then(() => { + expect(submit.disabled).toBe(false); + }) .then(() => setInput(input, originalValue)) - .then(() => expect(submit.disabled).toBe(true)) + .then(() => { + expect(submit.disabled).toBe(true); + }) .then(done) .catch(done.fail); }); diff --git a/spec/javascripts/droplab/plugins/ajax_spec.js b/spec/javascripts/droplab/plugins/ajax_spec.js index 085f25764fe..69fe431e1b9 100644 --- a/spec/javascripts/droplab/plugins/ajax_spec.js +++ b/spec/javascripts/droplab/plugins/ajax_spec.js @@ -8,6 +8,7 @@ describe('Ajax', () => { describe('is not configured', () => { it('passes the data through', () => { const data = ['data']; + expect(Ajax.preprocessing(config, data)).toEqual(data); }); }); @@ -22,13 +23,17 @@ describe('Ajax', () => { it('calls preprocessing', () => { Ajax.preprocessing(config, []); + expect(config.preprocessing.calls.count()).toBe(1); }); it('overrides AjaxCache', () => { - spyOn(AjaxCache, 'override').and.callFake((endpoint, results) => expect(results).toEqual(processedArray)); + spyOn(AjaxCache, 'override').and.callFake((endpoint, results) => { + expect(results).toEqual(processedArray); + }); Ajax.preprocessing(config, []); + expect(AjaxCache.override.calls.count()).toBe(1); }); }); diff --git a/spec/javascripts/emoji_spec.js b/spec/javascripts/emoji_spec.js index 629422780e8..3bcefe19624 100644 --- a/spec/javascripts/emoji_spec.js +++ b/spec/javascripts/emoji_spec.js @@ -375,6 +375,7 @@ describe('gl_emoji', () => { '', '1.0', ); + expect(isSupported).toBeTruthy(); }); @@ -384,6 +385,7 @@ describe('gl_emoji', () => { '', '1.0', ); + expect(isSupported).toBeFalsy(); }); @@ -397,6 +399,7 @@ describe('gl_emoji', () => { emojiFixtureMap[emojiKey].moji, emojiFixtureMap[emojiKey].unicodeVersion, ); + expect(isSupported).toBeTruthy(); }); @@ -408,6 +411,7 @@ describe('gl_emoji', () => { emojiFixtureMap[emojiKey].moji, emojiFixtureMap[emojiKey].unicodeVersion, ); + expect(isSupported).toBeFalsy(); }); @@ -421,6 +425,7 @@ describe('gl_emoji', () => { emojiFixtureMap[emojiKey].moji, emojiFixtureMap[emojiKey].unicodeVersion, ); + expect(isSupported).toBeFalsy(); }); @@ -446,6 +451,7 @@ describe('gl_emoji', () => { emojiFixtureMap[emojiKey].moji, emojiFixtureMap[emojiKey].unicodeVersion, ); + expect(isSupported).toBeFalsy(); }); @@ -463,6 +469,7 @@ describe('gl_emoji', () => { emojiFixtureMap[emojiKey].moji, emojiFixtureMap[emojiKey].unicodeVersion, ); + expect(isSupported).toBeTruthy(); }); @@ -480,6 +487,7 @@ describe('gl_emoji', () => { emojiFixtureMap[emojiKey].moji, emojiFixtureMap[emojiKey].unicodeVersion, ); + expect(isSupported).toBeFalsy(); }); }); diff --git a/spec/javascripts/environments/environments_app_spec.js b/spec/javascripts/environments/environments_app_spec.js index 60787b4c88d..1be983f3592 100644 --- a/spec/javascripts/environments/environments_app_spec.js +++ b/spec/javascripts/environments/environments_app_spec.js @@ -94,6 +94,7 @@ describe('Environment', () => { spyOn(component, 'updateContent'); setTimeout(() => { component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(component.updateContent).toHaveBeenCalledWith({ scope: 'available', page: '2' }); done(); }, 0); diff --git a/spec/javascripts/environments/environments_store_spec.js b/spec/javascripts/environments/environments_store_spec.js index f2c6ec24dd7..c3d16f10d72 100644 --- a/spec/javascripts/environments/environments_store_spec.js +++ b/spec/javascripts/environments/environments_store_spec.js @@ -17,23 +17,27 @@ describe('Store', () => { it('should store environments', () => { store.storeEnvironments(serverData); + expect(store.state.environments.length).toEqual(serverData.length); expect(store.state.environments[0]).toEqual(environmentsList[0]); }); it('should store available count', () => { store.storeAvailableCount(2); + expect(store.state.availableCounter).toEqual(2); }); it('should store stopped count', () => { store.storeStoppedCount(2); + expect(store.state.stoppedCounter).toEqual(2); }); describe('store environments', () => { it('should store environments', () => { store.storeEnvironments(serverData); + expect(store.state.environments.length).toEqual(serverData.length); }); @@ -45,6 +49,7 @@ describe('Store', () => { }; store.storeEnvironments([environment]); + expect(store.state.environments[0].isFolder).toEqual(true); expect(store.state.environments[0].folderName).toEqual('bar'); }); @@ -61,17 +66,20 @@ describe('Store', () => { }; store.storeEnvironments([environment]); + expect(store.state.environments[0].last_deployment).toEqual({}); expect(store.state.environments[0].isStoppable).toEqual(true); }); it('should store latest.name when the environment is not a folder', () => { store.storeEnvironments(serverData); + expect(store.state.environments[0].name).toEqual(serverData[0].latest.name); }); it('should store root level name when environment is a folder', () => { store.storeEnvironments(serverData); + expect(store.state.environments[1].folderName).toEqual(serverData[1].name); }); }); @@ -81,9 +89,11 @@ describe('Store', () => { store.storeEnvironments(serverData); store.toggleFolder(store.state.environments[1]); + expect(store.state.environments[1].isOpen).toEqual(true); store.toggleFolder(store.state.environments[1]); + expect(store.state.environments[1].isOpen).toEqual(false); }); @@ -91,9 +101,11 @@ describe('Store', () => { store.storeEnvironments(serverData); store.toggleFolder(store.state.environments[1]); + expect(store.state.environments[1].isOpen).toEqual(true); store.storeEnvironments(serverData); + expect(store.state.environments[1].isOpen).toEqual(true); }); }); @@ -116,6 +128,7 @@ describe('Store', () => { expect(store.state.environments[1].children.length).toEqual(serverData.length); // poll store.storeEnvironments(serverData); + expect(store.state.environments[1].children.length).toEqual(serverData.length); }); }); @@ -141,6 +154,7 @@ describe('Store', () => { }; store.setPagination(pagination); + expect(store.state.paginationInformation).toEqual(expectedResult); }); }); @@ -150,6 +164,7 @@ describe('Store', () => { store.storeEnvironments(serverData); store.toggleFolder(store.state.environments[1]); + expect(store.getOpenFolders()[0]).toEqual(store.state.environments[1]); }); }); diff --git a/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js b/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js index 2ab6a0077b5..22f46caa8ea 100644 --- a/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js +++ b/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js @@ -14,6 +14,7 @@ describe('feature highlight helper', () => { describe('getSelector', () => { it('returns js-feature-highlight selector', () => { const highlightId = 'highlightId'; + expect(getSelector(highlightId)).toEqual(`.js-feature-highlight[data-highlight=${highlightId}]`); }); }); diff --git a/spec/javascripts/feature_highlight/feature_highlight_spec.js b/spec/javascripts/feature_highlight/feature_highlight_spec.js index ec46d4f905a..5d3bbe9692e 100644 --- a/spec/javascripts/feature_highlight/feature_highlight_spec.js +++ b/spec/javascripts/feature_highlight/feature_highlight_spec.js @@ -63,6 +63,7 @@ describe('feature highlight', () => { it('setup show.bs.popover', () => { $(selector).trigger('show.bs.popover'); + expect(window.addEventListener).toHaveBeenCalledWith('scroll', jasmine.any(Function), { once: true }); }); @@ -73,6 +74,7 @@ describe('feature highlight', () => { it('displays popover', () => { expect(document.querySelector(selector).getAttribute('aria-describedby')).toBeFalsy(); $(selector).trigger('mouseenter'); + expect(document.querySelector(selector).getAttribute('aria-describedby')).toBeTruthy(); }); diff --git a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js index 9d670afe206..23a03558b38 100644 --- a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js +++ b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js @@ -47,6 +47,7 @@ describe('RecentSearchesDropdownContent', () => { expect(el.querySelector('.dropdown-info-note')).toBeDefined(); const items = el.querySelectorAll('.filtered-search-history-dropdown-item'); + expect(items.length).toEqual(propsDataWithoutItems.items.length); }); }); @@ -65,11 +66,13 @@ describe('RecentSearchesDropdownContent', () => { it('should render recent search items', () => { const items = el.querySelectorAll('.filtered-search-history-dropdown-item'); + expect(items.length).toEqual(propsDataWithItems.items.length); expect(trimMarkupWhitespace(items[0].querySelector('.filtered-search-history-dropdown-search-token').textContent)).toEqual('foo'); const item1Tokens = items[1].querySelectorAll('.filtered-search-history-dropdown-token'); + expect(item1Tokens.length).toEqual(2); expect(item1Tokens[0].querySelector('.name').textContent).toEqual('author:'); expect(item1Tokens[0].querySelector('.value').textContent).toEqual('@root'); @@ -132,12 +135,14 @@ describe('RecentSearchesDropdownContent', () => { it('with items', () => { vm = createComponent(propsDataWithItems); const { hasItems } = vm; + expect(hasItems).toEqual(true); }); it('with no items', () => { vm = createComponent(propsDataWithoutItems); const { hasItems } = vm; + expect(hasItems).toEqual(false); }); }); @@ -161,6 +166,7 @@ describe('RecentSearchesDropdownContent', () => { it('emits event', () => { expect(onRecentSearchesItemSelectedSpy).not.toHaveBeenCalled(); vm.onItemActivated('something'); + expect(onRecentSearchesItemSelectedSpy).toHaveBeenCalledWith('something'); }); }); @@ -182,6 +188,7 @@ describe('RecentSearchesDropdownContent', () => { it('emits event', () => { expect(onRequestClearRecentSearchesSpy).not.toHaveBeenCalled(); vm.onRequestClearRecentSearches({ stopPropagation: () => {} }); + expect(onRequestClearRecentSearchesSpy).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js b/spec/javascripts/filtered_search/dropdown_user_spec.js index b48b1456eff..9f4e8ab6234 100644 --- a/spec/javascripts/filtered_search/dropdown_user_spec.js +++ b/spec/javascripts/filtered_search/dropdown_user_spec.js @@ -92,6 +92,7 @@ describe('Dropdown User', () => { it('hides the current user from dropdown', () => { const currentUserElement = findCurrentUserElement(); + expect(currentUserElement).not.toBe(null); dropdown.hideCurrentUser(); @@ -102,6 +103,7 @@ describe('Dropdown User', () => { it('does nothing if no user is logged in', () => { const currentUserElement = findCurrentUserElement(); currentUserElement.parentNode.removeChild(currentUserElement); + expect(findCurrentUserElement()).toBe(null); dropdown.hideCurrentUser(); diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js index 3dc8089cd83..52b54973047 100644 --- a/spec/javascripts/filtered_search/dropdown_utils_spec.js +++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js @@ -10,24 +10,29 @@ describe('Dropdown Utils', () => { describe('getEscapedText', () => { it('should return same word when it has no space', () => { const escaped = DropdownUtils.getEscapedText('textWithoutSpace'); + expect(escaped).toBe('textWithoutSpace'); }); it('should escape with double quotes', () => { let escaped = DropdownUtils.getEscapedText('text with space'); + expect(escaped).toBe('"text with space"'); escaped = DropdownUtils.getEscapedText('won\'t fix'); + expect(escaped).toBe('"won\'t fix"'); }); it('should escape with single quotes', () => { const escaped = DropdownUtils.getEscapedText('won"t fix'); + expect(escaped).toBe('\'won"t fix\''); }); it('should escape with single quotes by default', () => { const escaped = DropdownUtils.getEscapedText('won"t\' fix'); + expect(escaped).toBe('\'won"t\' fix\''); }); }); @@ -50,6 +55,7 @@ describe('Dropdown Utils', () => { input.value = 'roo'; const updatedItem = DropdownUtils.filterWithSymbol('@', input, item); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -57,6 +63,7 @@ describe('Dropdown Utils', () => { input.value = '@roo'; const updatedItem = DropdownUtils.filterWithSymbol('@', input, item); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -69,6 +76,7 @@ describe('Dropdown Utils', () => { input.value = '"'; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -76,6 +84,7 @@ describe('Dropdown Utils', () => { input.value = '~"'; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -83,6 +92,7 @@ describe('Dropdown Utils', () => { input.value = '"community con'; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -90,6 +100,7 @@ describe('Dropdown Utils', () => { input.value = '~"community con'; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -97,6 +108,7 @@ describe('Dropdown Utils', () => { input.value = '\''; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -104,6 +116,7 @@ describe('Dropdown Utils', () => { input.value = '~\''; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -111,6 +124,7 @@ describe('Dropdown Utils', () => { input.value = '\'community con'; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -118,6 +132,7 @@ describe('Dropdown Utils', () => { input.value = '~\'community con'; const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem); + expect(updatedItem.droplab_hidden).toBe(false); }); }); @@ -152,17 +167,20 @@ describe('Dropdown Utils', () => { let updatedItem = DropdownUtils.filterHint(config(), { hint: 'label', }); + expect(updatedItem.droplab_hidden).toBe(false); input.value = 'o'; updatedItem = DropdownUtils.filterHint(config(), { hint: 'label', }); + expect(updatedItem.droplab_hidden).toBe(true); }); it('should return droplab_hidden false when item has no hint', () => { const updatedItem = DropdownUtils.filterHint(config(), {}, ''); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -172,6 +190,7 @@ describe('Dropdown Utils', () => { hint: 'label', type: 'array', }); + expect(updatedItem.droplab_hidden).toBe(false); }); @@ -180,12 +199,14 @@ describe('Dropdown Utils', () => { let updatedItem = DropdownUtils.filterHint(config(), { hint: 'milestone', }); + expect(updatedItem.droplab_hidden).toBe(true); updatedItem = DropdownUtils.filterHint(config(), { hint: 'milestone', type: 'string', }); + expect(updatedItem.droplab_hidden).toBe(true); }); }); @@ -205,6 +226,7 @@ describe('Dropdown Utils', () => { }; const updated = DropdownUtils.mergeDuplicateLabels(dataMap, newLabel); + expect(updated[newLabel.title]).toEqual(newLabel); }); @@ -215,6 +237,7 @@ describe('Dropdown Utils', () => { }; const updated = DropdownUtils.mergeDuplicateLabels(dataMap, duplicate); + expect(updated.label.multipleColors).toEqual([dataMap.label.color, duplicate.color]); }); }); @@ -222,21 +245,25 @@ describe('Dropdown Utils', () => { describe('duplicateLabelColor', () => { it('should linear-gradient 2 colors', () => { const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000']); + expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 50%, #000000 50%, #000000 100%)'); }); it('should linear-gradient 3 colors', () => { const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333']); + expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 33%, #000000 33%, #000000 66%, #333333 66%, #333333 100%)'); }); it('should linear-gradient 4 colors', () => { const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333', '#DDDDDD']); + expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 25%, #000000 25%, #000000 50%, #333333 50%, #333333 75%, #DDDDDD 75%, #DDDDDD 100%)'); }); it('should not linear-gradient more than 4 colors', () => { const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333', '#DDDDDD', '#EEEEEE']); + expect(gradient.indexOf('#EEEEEE')).toBe(-1); }); }); @@ -244,6 +271,7 @@ describe('Dropdown Utils', () => { describe('duplicateLabelPreprocessing', () => { it('should set preprocessed to true', () => { const results = DropdownUtils.duplicateLabelPreprocessing([]); + expect(results.preprocessed).toEqual(true); }); @@ -298,6 +326,7 @@ describe('Dropdown Utils', () => { }; DropdownUtils.setDataValueIfSelected(null, selected); + expect(FilteredSearchDropdownManager.addWordToInput.calls.count()).toEqual(1); }); @@ -308,6 +337,7 @@ describe('Dropdown Utils', () => { }; const result = DropdownUtils.setDataValueIfSelected(null, selected); + expect(result).toBe(true); }); @@ -317,6 +347,7 @@ describe('Dropdown Utils', () => { }; const result = DropdownUtils.setDataValueIfSelected(null, selected); + expect(result).toBe(false); }); }); diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js index a03d5a31b41..5a985e97a34 100644 --- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js @@ -134,6 +134,7 @@ describe('Filtered Search Manager', function () { }; manager.searchState(e); + expect(FilteredSearchManager.prototype.search).not.toHaveBeenCalled(); }); @@ -149,6 +150,7 @@ describe('Filtered Search Manager', function () { }; manager.searchState(e); + expect(FilteredSearchManager.prototype.search).toHaveBeenCalledWith('opened'); }); }); @@ -304,6 +306,7 @@ describe('Filtered Search Manager', function () { ); tokensContainer.querySelector('.js-visual-token .remove-token').click(); + expect(tokensContainer.querySelector('.js-visual-token')).toEqual(null); }); @@ -437,11 +440,13 @@ describe('Filtered Search Manager', function () { it('toggles on focus', () => { input.focus(); + expect(document.querySelector('.filtered-search-box').classList.contains('focus')).toEqual(true); }); it('toggles on blur', () => { input.blur(); + expect(document.querySelector('.filtered-search-box').classList.contains('focus')).toEqual(false); }); }); diff --git a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js index cf7789a1d57..20264caa5c4 100644 --- a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js @@ -51,11 +51,13 @@ describe('Filtered Search Token Keys', () => { describe('searchByKey', () => { it('should return null when key not found', () => { const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchByKey('notakey'); + expect(tokenKey).toBeNull(); }); it('should return tokenKey when found by key', () => { const result = new FilteredSearchTokenKeys(tokenKeys).searchByKey(tokenKeys[0].key); + expect(result).toEqual(tokenKeys[0]); }); }); @@ -63,11 +65,13 @@ describe('Filtered Search Token Keys', () => { describe('searchBySymbol', () => { it('should return null when symbol not found', () => { const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchBySymbol('notasymbol'); + expect(tokenKey).toBeNull(); }); it('should return tokenKey when found by symbol', () => { const result = new FilteredSearchTokenKeys(tokenKeys).searchBySymbol(tokenKeys[0].symbol); + expect(result).toEqual(tokenKeys[0]); }); }); @@ -75,16 +79,19 @@ describe('Filtered Search Token Keys', () => { describe('searchByKeyParam', () => { it('should return null when key param not found', () => { const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam('notakeyparam'); + expect(tokenKey).toBeNull(); }); it('should return tokenKey when found by key param', () => { const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`); + expect(result).toEqual(tokenKeys[0]); }); it('should return alternative tokenKey when found by key param', () => { const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`); + expect(result).toEqual(tokenKeys[0]); }); }); @@ -92,12 +99,14 @@ describe('Filtered Search Token Keys', () => { describe('searchByConditionUrl', () => { it('should return null when condition url not found', () => { const condition = new FilteredSearchTokenKeys([], [], conditions).searchByConditionUrl(null); + expect(condition).toBeNull(); }); it('should return condition when found by url', () => { const result = new FilteredSearchTokenKeys([], [], conditions) .searchByConditionUrl(conditions[0].url); + expect(result).toBe(conditions[0]); }); }); @@ -106,12 +115,14 @@ describe('Filtered Search Token Keys', () => { it('should return null when condition tokenKey and value not found', () => { const condition = new FilteredSearchTokenKeys([], [], conditions) .searchByConditionKeyValue(null, null); + expect(condition).toBeNull(); }); it('should return condition when found by tokenKey and value', () => { const result = new FilteredSearchTokenKeys([], [], conditions) .searchByConditionKeyValue(conditions[0].tokenKey, conditions[0].value); + expect(result).toEqual(conditions[0]); }); }); diff --git a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js index 4f9f546cbb5..d8eb75ec000 100644 --- a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js @@ -7,6 +7,7 @@ describe('Filtered Search Tokenizer', () => { describe('processTokens', () => { it('returns for input containing only search value', () => { const results = FilteredSearchTokenizer.processTokens('searchTerm', allowedKeys); + expect(results.searchToken).toBe('searchTerm'); expect(results.tokens.length).toBe(0); expect(results.lastToken).toBe(results.searchToken); @@ -15,6 +16,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input containing only tokens', () => { const results = FilteredSearchTokenizer .processTokens('author:@root label:~"Very Important" milestone:%v1.0 assignee:none', allowedKeys); + expect(results.searchToken).toBe(''); expect(results.tokens.length).toBe(4); expect(results.tokens[3]).toBe(results.lastToken); @@ -39,6 +41,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input starting with search value and ending with tokens', () => { const results = FilteredSearchTokenizer .processTokens('searchTerm anotherSearchTerm milestone:none', allowedKeys); + expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.tokens.length).toBe(1); expect(results.tokens[0]).toBe(results.lastToken); @@ -83,6 +86,7 @@ describe('Filtered Search Tokenizer', () => { it('returns for input containing search value in between tokens', () => { const results = FilteredSearchTokenizer .processTokens('author:@root searchTerm assignee:none anotherSearchTerm label:~Doing', allowedKeys); + expect(results.searchToken).toBe('searchTerm anotherSearchTerm'); expect(results.tokens.length).toBe(3); expect(results.tokens[2]).toBe(results.lastToken); @@ -102,6 +106,7 @@ describe('Filtered Search Tokenizer', () => { it('returns search value for invalid tokens', () => { const results = FilteredSearchTokenizer.processTokens('fake:token', allowedKeys); + expect(results.lastToken).toBe('fake:token'); expect(results.searchToken).toBe('fake:token'); expect(results.tokens.length).toEqual(0); @@ -109,6 +114,7 @@ describe('Filtered Search Tokenizer', () => { it('returns search value and token for mix of valid and invalid tokens', () => { const results = FilteredSearchTokenizer.processTokens('label:real fake:token', allowedKeys); + expect(results.tokens.length).toEqual(1); expect(results.tokens[0].key).toBe('label'); expect(results.tokens[0].value).toBe('real'); @@ -119,12 +125,14 @@ describe('Filtered Search Tokenizer', () => { it('returns search value for invalid symbols', () => { const results = FilteredSearchTokenizer.processTokens('std::includes', allowedKeys); + expect(results.lastToken).toBe('std::includes'); expect(results.searchToken).toBe('std::includes'); }); it('removes duplicated values', () => { const results = FilteredSearchTokenizer.processTokens('label:~foo label:~foo', allowedKeys); + expect(results.tokens.length).toBe(1); expect(results.tokens[0].key).toBe('label'); expect(results.tokens[0].value).toBe('foo'); diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js index 53a6d1d62b0..b1fb474e755 100644 --- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js @@ -131,6 +131,7 @@ describe('Filtered Search Visual Tokens', () => { describe('getEndpointWithQueryParams', () => { it('returns `endpoint` string as is when second param `endpointQueryParams` is undefined, null or empty string', () => { const endpoint = 'foo/bar/labels.json'; + expect(subject.getEndpointWithQueryParams(endpoint)).toBe(endpoint); expect(subject.getEndpointWithQueryParams(endpoint, null)).toBe(endpoint); expect(subject.getEndpointWithQueryParams(endpoint, '')).toBe(endpoint); @@ -161,6 +162,7 @@ describe('Filtered Search Visual Tokens', () => { `); const selected = tokensContainer.querySelector('.js-visual-token .selected'); + expect(selected.classList.contains('selected')).toEqual(true); subject.unselectTokens(); @@ -675,6 +677,7 @@ describe('Filtered Search Visual Tokens', () => { subject.moveInputToTheRight(); const token = tokensContainer.children[1]; + expect(token.querySelector('.value').innerText).toEqual('~bug'); }); }); @@ -712,6 +715,7 @@ describe('Filtered Search Visual Tokens', () => { expect(tokenValueElement.innerText).toBe(tokenValue); expect(updateUserTokenAppearanceSpy.calls.count()).toBe(1); const expectedArgs = [tokenValueContainer, tokenValueElement, tokenValue]; + expect(updateUserTokenAppearanceSpy.calls.argsFor(0)).toEqual(expectedArgs); expect(updateLabelTokenColorSpy.calls.count()).toBe(0); }); @@ -727,6 +731,7 @@ describe('Filtered Search Visual Tokens', () => { expect(tokenValueElement.innerText).toBe(tokenValue); expect(updateLabelTokenColorSpy.calls.count()).toBe(1); const expectedArgs = [tokenValueContainer, tokenValue]; + expect(updateLabelTokenColorSpy.calls.argsFor(0)).toEqual(expectedArgs); expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); }); @@ -814,6 +819,7 @@ describe('Filtered Search Visual Tokens', () => { expect(tokenValueContainer.dataset.originalValue).toBe(tokenValue); expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); const avatar = tokenValueElement.querySelector('img.avatar'); + expect(avatar.src).toBe(dummyUser.avatar_url); expect(avatar.alt).toBe(''); }) @@ -837,6 +843,7 @@ describe('Filtered Search Visual Tokens', () => { .then(() => { expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); tokenValueElement.querySelector('.avatar').remove(); + expect(tokenValueElement.innerHTML.trim()).toBe(_.escape(dummyUser.name)); }) .then(done) @@ -854,23 +861,27 @@ describe('Filtered Search Visual Tokens', () => { it('should set backgroundColor', () => { const originalBackgroundColor = bugLabelToken.style.backgroundColor; const token = subject.setTokenStyle(bugLabelToken, 'blue', 'white'); + expect(token.style.backgroundColor).toEqual('blue'); expect(token.style.backgroundColor).not.toEqual(originalBackgroundColor); }); it('should not set backgroundColor when it is a linear-gradient', () => { const token = subject.setTokenStyle(bugLabelToken, 'linear-gradient(135deg, red, blue)', 'white'); + expect(token.style.backgroundColor).toEqual(bugLabelToken.style.backgroundColor); }); it('should set textColor', () => { const token = subject.setTokenStyle(bugLabelToken, 'white', 'black'); + expect(token.style.color).toEqual('black'); expect(token.style.color).not.toEqual(originalTextColor); }); it('should add inverted class when textColor is #FFFFFF', () => { const token = subject.setTokenStyle(bugLabelToken, 'black', '#FFFFFF'); + expect(token.style.color).toEqual('rgb(255, 255, 255)'); expect(token.style.color).not.toEqual(originalTextColor); expect(token.querySelector('.remove-token').classList.contains('inverted')).toEqual(true); @@ -894,14 +905,17 @@ describe('Filtered Search Visual Tokens', () => { describe('not preprocessed before', () => { it('returns preprocessed labels', () => { let labels = []; + expect(labels.preprocessed).not.toEqual(true); labels = FilteredSearchVisualTokens.preprocessLabel(endpoint, labels); + expect(labels.preprocessed).toEqual(true); }); it('overrides AjaxCache with preprocessed results', () => { spyOn(AjaxCache, 'override').and.callFake(() => {}); FilteredSearchVisualTokens.preprocessLabel(endpoint, []); + expect(AjaxCache.override.calls.count()).toEqual(1); }); }); @@ -982,6 +996,7 @@ describe('Filtered Search Visual Tokens', () => { const { tokenValueContainer, tokenValueElement } = findElements(missingLabelToken); const tokenValue = tokenValueElement.innerText; const matchingLabel = findLabel(tokenValue); + expect(matchingLabel).toBe(undefined); subject.updateLabelTokenColor(tokenValueContainer, tokenValue) diff --git a/spec/javascripts/filtered_search/services/recent_searches_service_spec.js b/spec/javascripts/filtered_search/services/recent_searches_service_spec.js index c293c0afa97..e8cb69aba7f 100644 --- a/spec/javascripts/filtered_search/services/recent_searches_service_spec.js +++ b/spec/javascripts/filtered_search/services/recent_searches_service_spec.js @@ -92,6 +92,7 @@ describe('RecentSearchesService', () => { const items = ['foo', 'bar']; service.save(items); const newLocalStorageValue = window.localStorage.getItem(service.localStorageKey); + expect(JSON.parse(newLocalStorageValue)).toEqual(items); }); }); diff --git a/spec/javascripts/flash_spec.js b/spec/javascripts/flash_spec.js index 0a8e5a628c0..bdb26c4eb0d 100644 --- a/spec/javascripts/flash_spec.js +++ b/spec/javascripts/flash_spec.js @@ -39,6 +39,7 @@ describe('Flash', () => { expect( el.querySelector('.flash-text').classList.contains('container-fluid'), ).toBeTruthy(); + expect( el.querySelector('.flash-text').classList.contains('container-limited'), ).toBeTruthy(); @@ -59,6 +60,7 @@ describe('Flash', () => { expect( el.style['transition-property'], ).toBe('opacity'); + expect( el.style['transition-duration'], ).toBe('0.3s'); @@ -78,6 +80,7 @@ describe('Flash', () => { expect( el.style.opacity, ).toBe(''); + expect( el.style.transition, ).toBe(''); @@ -166,6 +169,7 @@ describe('Flash', () => { expect( flashEl, ).toBeNull(); + expect( document.querySelector('.flash-alert'), ).toBeNull(); diff --git a/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js b/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js index 201aca77b10..7deed985219 100644 --- a/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js +++ b/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js @@ -30,9 +30,11 @@ describe('FrequentItemsListItemComponent', () => { describe('hasAvatar', () => { it('should return `true` or `false` if whether avatar is present or not', () => { vm.avatarUrl = 'path/to/avatar.png'; + expect(vm.hasAvatar).toBe(true); vm.avatarUrl = null; + expect(vm.hasAvatar).toBe(false); }); }); @@ -40,11 +42,13 @@ describe('FrequentItemsListItemComponent', () => { describe('highlightedItemName', () => { it('should enclose part of project name in <b> & </b> which matches with `matcher` prop', () => { vm.matcher = 'lab'; + expect(vm.highlightedItemName).toContain('<b>Lab</b>'); }); it('should return project name as it is if `matcher` is not available', () => { vm.matcher = null; + expect(vm.highlightedItemName).toBe(mockProject.name); }); }); @@ -52,11 +56,13 @@ describe('FrequentItemsListItemComponent', () => { describe('truncatedNamespace', () => { it('should truncate project name from namespace string', () => { vm.namespace = 'platform / nokia-3310'; + expect(vm.truncatedNamespace).toBe('platform'); }); it('should truncate namespace string from the middle if it includes more than two groups in path', () => { vm.namespace = 'platform / hardware / broadcom / Wifi Group / Mobile Chipset / nokia-3310'; + expect(vm.truncatedNamespace).toBe('platform / ... / Mobile Chipset'); }); }); diff --git a/spec/javascripts/frequent_items/components/frequent_items_list_spec.js b/spec/javascripts/frequent_items/components/frequent_items_list_spec.js index 3003b7ee000..8518a681a26 100644 --- a/spec/javascripts/frequent_items/components/frequent_items_list_spec.js +++ b/spec/javascripts/frequent_items/components/frequent_items_list_spec.js @@ -30,9 +30,11 @@ describe('FrequentItemsListComponent', () => { describe('isListEmpty', () => { it('should return `true` or `false` representing whether if `items` is empty or not with projects', () => { vm.items = []; + expect(vm.isListEmpty).toBe(true); vm.items = mockFrequentProjects; + expect(vm.isListEmpty).toBe(false); }); }); @@ -40,9 +42,11 @@ describe('FrequentItemsListComponent', () => { describe('fetched item messages', () => { it('should return appropriate empty list message based on value of `localStorageFailed` prop with projects', () => { vm.isFetchFailed = true; + expect(vm.listEmptyMessage).toBe('This feature requires browser localStorage support'); vm.isFetchFailed = false; + expect(vm.listEmptyMessage).toBe('Projects you visit often will appear here'); }); }); @@ -51,9 +55,11 @@ describe('FrequentItemsListComponent', () => { it('should return appropriate empty list message based on value of `searchFailed` prop with projects', () => { vm.hasSearchQuery = true; vm.isFetchFailed = true; + expect(vm.listEmptyMessage).toBe('Something went wrong on our end.'); vm.isFetchFailed = false; + expect(vm.listEmptyMessage).toBe('Sorry, no projects matched your search'); }); }); diff --git a/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js b/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js index 6a11038e70a..d564292f1ba 100644 --- a/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js +++ b/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js @@ -26,6 +26,7 @@ describe('FrequentItemsSearchInputComponent', () => { spyOn(vm.$refs.search, 'focus'); vm.setFocus(); + expect(vm.$refs.search.focus).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/gl_dropdown_spec.js b/spec/javascripts/gl_dropdown_spec.js index 62c87642184..64d1b8a6523 100644 --- a/spec/javascripts/gl_dropdown_spec.js +++ b/spec/javascripts/gl_dropdown_spec.js @@ -70,8 +70,10 @@ describe('glDropdown', function describeDropdown() { it('should open on click', () => { initDropDown.call(this, false); + expect(this.dropdownContainerElement).not.toHaveClass('show'); this.dropdownButtonElement.click(); + expect(this.dropdownContainerElement).toHaveClass('show'); }); @@ -141,9 +143,12 @@ describe('glDropdown', function describeDropdown() { navigateWithKeys('enter', null, () => { expect(this.dropdownContainerElement).not.toHaveClass('show'); const link = $(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement); + expect(link).toHaveClass('is-active'); const linkedLocation = link.attr('href'); - if (linkedLocation && linkedLocation !== '#') expect(visitUrl).toHaveBeenCalledWith(linkedLocation); + if (linkedLocation && linkedLocation !== '#') { + expect(visitUrl).toHaveBeenCalledWith(linkedLocation); + } }); }); }); @@ -155,6 +160,7 @@ describe('glDropdown', function describeDropdown() { which: ARROW_KEYS.ESC, keyCode: ARROW_KEYS.ESC }); + expect(this.dropdownContainerElement).not.toHaveClass('show'); }); }); @@ -170,17 +176,20 @@ describe('glDropdown', function describeDropdown() { expect(dropdownMenu.className.indexOf('is-loading')).not.toBe(-1); remoteCallback(); + expect(dropdownMenu.className.indexOf('is-loading')).toBe(-1); }); it('should not focus search input while remote task is not complete', () => { expect($(document.activeElement)).not.toEqual($(SEARCH_INPUT_SELECTOR)); remoteCallback(); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); }); it('should focus search input after remote task is complete', () => { remoteCallback(); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); }); @@ -193,6 +202,7 @@ describe('glDropdown', function describeDropdown() { }); this.dropdownButtonElement.click(); this.dropdownContainerElement.trigger('transitionend'); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); }); }); @@ -202,6 +212,7 @@ describe('glDropdown', function describeDropdown() { initDropDown.call(this, false, true); this.dropdownButtonElement.click(); this.dropdownContainerElement.trigger('transitionend'); + expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR)); }); }); @@ -213,11 +224,13 @@ describe('glDropdown', function describeDropdown() { .trigger('focus') .val('g') .trigger('input'); + expect($searchInput.val()).toEqual('g'); this.dropdownButtonElement.trigger('hidden.bs.dropdown'); $searchInput .trigger('blur') .trigger('focus'); + expect($searchInput.val()).toEqual('g'); }); @@ -240,6 +253,7 @@ describe('glDropdown', function describeDropdown() { const html = dropdown.renderItem(dummyData, null, null); const link = html.querySelector('a'); + expect(link).toHaveClass('is-active'); }); @@ -251,6 +265,7 @@ describe('glDropdown', function describeDropdown() { const html = dropdown.renderItem(dummyData, null, null); const link = html.querySelector('a'); + expect(link).not.toHaveClass('is-active'); }); }); @@ -271,10 +286,12 @@ describe('glDropdown', function describeDropdown() { // select item the first time this.dropdownButtonElement.click(); $item.click(); + expect($item).toHaveClass('is-active'); // select item the second time this.dropdownButtonElement.click(); $item.click(); + expect($item).toHaveClass('is-active'); expect($('.dropdown-toggle-text')).toHaveText(this.projectsData[0].id.toString()); diff --git a/spec/javascripts/gl_field_errors_spec.js b/spec/javascripts/gl_field_errors_spec.js index 21c462cd040..4a95d4f4a24 100644 --- a/spec/javascripts/gl_field_errors_spec.js +++ b/spec/javascripts/gl_field_errors_spec.js @@ -19,6 +19,7 @@ describe('GL Style Field Errors', function() { expect(this.$form.length).toBe(1); expect(this.fieldErrors).toBeDefined(); const { inputs } = this.fieldErrors.state; + expect(inputs.length).toBe(4); }); @@ -31,6 +32,7 @@ describe('GL Style Field Errors', function() { const customErrors = this.fieldErrors.state.inputs.filter((input) => { return input.inputElement.hasClass(customErrorFlag); }); + expect(customErrors.length).toBe(0); }); @@ -40,6 +42,7 @@ describe('GL Style Field Errors', function() { this.$form.find('.alphanumberic').val('?---*').keyup(); const errorsShown = this.$form.find('.gl-field-error-outline'); + expect(errorsShown.length).toBe(0); }); @@ -51,6 +54,7 @@ describe('GL Style Field Errors', function() { this.$form.submit(); const errorsShown = this.$form.find('.gl-field-error-outline'); + expect(errorsShown.length).toBe(4); }); @@ -68,30 +72,35 @@ describe('GL Style Field Errors', function() { // Then invalid input emailInputElement.val('not-a-valid-email').keyup(); + expect(emailInputElement).toHaveClass('gl-field-error-outline'); expect(fieldState.empty).toBe(false); expect(fieldState.valid).toBe(false); // Then valid input emailInputElement.val('email@gitlab.com').keyup(); + expect(emailInputElement).not.toHaveClass('gl-field-error-outline'); expect(fieldState.empty).toBe(false); expect(fieldState.valid).toBe(true); // Then invalid input emailInputElement.val('not-a-valid-email').keyup(); + expect(emailInputElement).toHaveClass('gl-field-error-outline'); expect(fieldState.empty).toBe(false); expect(fieldState.valid).toBe(false); // Then empty input emailInputElement.val('').keyup(); + expect(emailInputElement).toHaveClass('gl-field-error-outline'); expect(fieldState.empty).toBe(true); expect(fieldState.valid).toBe(false); // Then valid input emailInputElement.val('email@gitlab.com').keyup(); + expect(emailInputElement).not.toHaveClass('gl-field-error-outline'); expect(fieldState.empty).toBe(false); expect(fieldState.valid).toBe(true); diff --git a/spec/javascripts/gl_form_spec.js b/spec/javascripts/gl_form_spec.js index 74383f901b2..70ba3d07a89 100644 --- a/spec/javascripts/gl_form_spec.js +++ b/spec/javascripts/gl_form_spec.js @@ -101,6 +101,7 @@ describe('GLForm', () => { spyOn($.prototype, 'outerHeight').and.returnValue(200); spyOn($.prototype, 'data').and.returnValue(200); spyOn(autosize, 'destroy'); + expect(this.glForm.destroyAutosize()).toBeUndefined(); expect(autosize.destroy).not.toHaveBeenCalled(); }); diff --git a/spec/javascripts/gpg_badges_spec.js b/spec/javascripts/gpg_badges_spec.js index 78330dd9633..e73f6d3909e 100644 --- a/spec/javascripts/gpg_badges_spec.js +++ b/spec/javascripts/gpg_badges_spec.js @@ -69,6 +69,7 @@ describe('GpgBadges', () => { .then(() => { expect(document.querySelector('.js-loading-gpg-badge:empty')).toBe(null); const spinners = document.querySelectorAll('.js-loading-gpg-badge i.fa.fa-spinner.fa-spin'); + expect(spinners.length).toBe(1); done(); }) @@ -82,6 +83,7 @@ describe('GpgBadges', () => { .then(() => { expect(document.querySelector('.js-loading-gpg-badge')).toBe(null); const parentContainer = document.querySelector('.parent-container'); + expect(parentContainer.innerHTML.trim()).toEqual(dummyBadgeHtml); done(); }) diff --git a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js index 4a4d6969e86..7fd619b66a7 100644 --- a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js +++ b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js @@ -10,6 +10,7 @@ describe("ContributorsGraph", function () { describe("#set_x_domain", function () { it("set the x_domain", function () { ContributorsGraph.set_x_domain(20); + expect(ContributorsGraph.prototype.x_domain).toEqual(20); }); }); @@ -17,6 +18,7 @@ describe("ContributorsGraph", function () { describe("#set_y_domain", function () { it("sets the y_domain", function () { ContributorsGraph.set_y_domain([{ commits: 30 }]); + expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]); }); }); @@ -24,6 +26,7 @@ describe("ContributorsGraph", function () { describe("#init_x_domain", function () { it("sets the initial x_domain", function () { ContributorsGraph.init_x_domain([{ date: "2013-01-31" }, { date: "2012-01-31" }]); + expect(ContributorsGraph.prototype.x_domain).toEqual(["2012-01-31", "2013-01-31"]); }); }); @@ -31,6 +34,7 @@ describe("ContributorsGraph", function () { describe("#init_y_domain", function () { it("sets the initial y_domain", function () { ContributorsGraph.init_y_domain([{ commits: 30 }]); + expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]); }); }); @@ -40,6 +44,7 @@ describe("ContributorsGraph", function () { spyOn(ContributorsGraph, "init_x_domain"); spyOn(ContributorsGraph, "init_y_domain"); ContributorsGraph.init_domain(); + expect(ContributorsGraph.init_x_domain).toHaveBeenCalled(); expect(ContributorsGraph.init_y_domain).toHaveBeenCalled(); }); @@ -48,6 +53,7 @@ describe("ContributorsGraph", function () { describe("#set_dates", function () { it("sets the dates", function () { ContributorsGraph.set_dates("2013-12-01"); + expect(ContributorsGraph.prototype.dates).toEqual("2013-12-01"); }); }); @@ -59,6 +65,7 @@ describe("ContributorsGraph", function () { instance.x = d3.scaleTime().range([0, 100]).clamp(true); spyOn(instance.x, 'domain'); instance.set_x_domain(); + expect(instance.x.domain).toHaveBeenCalledWith(20); }); }); @@ -70,6 +77,7 @@ describe("ContributorsGraph", function () { instance.y = d3.scaleLinear().range([100, 0]).nice(); spyOn(instance.y, 'domain'); instance.set_y_domain(); + expect(instance.y.domain).toHaveBeenCalledWith(30); }); }); @@ -80,6 +88,7 @@ describe("ContributorsGraph", function () { spyOn(instance, 'set_x_domain'); spyOn(instance, 'set_y_domain'); instance.set_domain(); + expect(instance.set_x_domain).toHaveBeenCalled(); expect(instance.set_y_domain).toHaveBeenCalled(); }); @@ -89,6 +98,7 @@ describe("ContributorsGraph", function () { it("sets the data", function () { var instance = new ContributorsGraph(); instance.set_data("20"); + expect(instance.data).toEqual("20"); }); }); @@ -114,6 +124,7 @@ describe("ContributorsMasterGraph", function () { it("plucks the date field from data collection", function () { var graph = new ContributorsMasterGraph(); var data = [{ date: "2013-01-01" }, { date: "2012-12-15" }]; + expect(graph.get_dates(data)).toEqual(["2013-01-01", "2012-12-15"]); }); }); @@ -125,6 +136,7 @@ describe("ContributorsMasterGraph", function () { var data = [{ date: "2013-01-01" }, { date: "2012-12-15" }]; var correct = [{ date: parseDate(data[0].date) }, { date: parseDate(data[1].date) }]; graph.parse_dates(data); + expect(data).toEqual(correct); }); }); diff --git a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js index 8854d3d554a..a4f3e94db6b 100644 --- a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js +++ b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js @@ -28,6 +28,7 @@ describe("ContributorsStatGraphUtil", function () { } ] }; + expect(ContributorsStatGraphUtil.parse_log(fake_log)).toEqual(correct_parsed_log); }); }); @@ -40,18 +41,21 @@ describe("ContributorsStatGraphUtil", function () { it("calls #store_commits", function () { spyOn(ContributorsStatGraphUtil, 'store_commits'); ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author); + expect(ContributorsStatGraphUtil.store_commits).toHaveBeenCalled(); }); it("calls #store_additions", function () { spyOn(ContributorsStatGraphUtil, 'store_additions'); ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author); + expect(ContributorsStatGraphUtil.store_additions).toHaveBeenCalled(); }); it("calls #store_deletions", function () { spyOn(ContributorsStatGraphUtil, 'store_deletions'); ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author); + expect(ContributorsStatGraphUtil.store_deletions).toHaveBeenCalled(); }); }); @@ -72,12 +76,14 @@ describe("ContributorsStatGraphUtil", function () { it("adds 1 to current test_field in collection", function () { var fake_collection = { test_field: 10 }; ContributorsStatGraphUtil.add(fake_collection, "test_field", 1); + expect(fake_collection.test_field).toEqual(11); }); it("inits and adds 1 if test_field in collection is not defined", function () { var fake_collection = {}; ContributorsStatGraphUtil.add(fake_collection, "test_field", 1); + expect(fake_collection.test_field).toEqual(1); }); }); @@ -111,6 +117,7 @@ describe("ContributorsStatGraphUtil", function () { var fake_date = "2013-10-02"; var fake_collection = {}; ContributorsStatGraphUtil.add_date(fake_date, fake_collection); + expect(fake_collection[fake_date].date).toEqual("2013-10-02"); }); }); @@ -121,6 +128,7 @@ describe("ContributorsStatGraphUtil", function () { var fake_author_collection = {}; var fake_email_collection = {}; ContributorsStatGraphUtil.add_author(fake_author, fake_author_collection, fake_email_collection); + expect(fake_author_collection[fake_author.author_name].author_name).toEqual("Author"); expect(fake_email_collection[fake_author.author_email].author_name).toEqual("Author"); }); @@ -148,6 +156,7 @@ describe("ContributorsStatGraphUtil", function () { { date: "2013-05-08", commits: 3 }, { date: "2013-05-09", commits: 1 } ]; + expect(ContributorsStatGraphUtil.get_total_data(fake_parsed_log, "commits")).toEqual(correct_total_data); }); }); @@ -160,6 +169,7 @@ describe("ContributorsStatGraphUtil", function () { ]; ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, "commits"); var correct_pick_field_data = [{ date: "2013-05-09", commits: 1 }, { date: "2013-05-08", commits: 3 }]; + expect(ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, "commits")).toEqual(correct_pick_field_data); }); }); @@ -186,6 +196,7 @@ describe("ContributorsStatGraphUtil", function () { { author_name: "Dmitriy Zaporozhets", author_email: "dzaporozhets@email.com", dates: { "2013-05-08": 3 }, deletions: 7, additions: 54, "commits": 3 }, { author_name: "Karlo Soriano", author_email: "karlo@email.com", dates: { "2013-05-09": 1 }, deletions: 0, additions: 471, commits: 1 } ]; + expect(ContributorsStatGraphUtil.get_author_data(fake_parsed_log, "commits")).toEqual(correct_author_data); }); }); @@ -196,6 +207,7 @@ describe("ContributorsStatGraphUtil", function () { "2013-05-09": { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 } }; var correct_parsed_log = { author_name: "Karlo Soriano", author_email: "karlo@email.com", dates: { "2013-05-09": 1 }, deletions: 0, additions: 471, commits: 1 }; + expect(ContributorsStatGraphUtil.parse_log_entry(fake_log_entry, 'commits', null)).toEqual(correct_parsed_log); }); }); @@ -208,11 +220,13 @@ describe("ContributorsStatGraphUtil", function () { it("returns true if date is in range", function () { var date_range = [new Date("2013-01-01"), new Date("2013-12-12")]; + expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(true); }); it("returns false if date is not in range", function () { var date_range = [new Date("1999-12-01"), new Date("2000-12-01")]; + expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(false); }); }); diff --git a/spec/javascripts/groups/components/app_spec.js b/spec/javascripts/groups/components/app_spec.js index 89c07d1f06d..d832441dc93 100644 --- a/spec/javascripts/groups/components/app_spec.js +++ b/spec/javascripts/groups/components/app_spec.js @@ -76,6 +76,7 @@ describe('AppComponent', () => { spyOn(vm.store, 'getGroups'); const { groups } = vm; + expect(vm.store.getGroups).toHaveBeenCalled(); expect(groups).not.toBeDefined(); }); @@ -86,6 +87,7 @@ describe('AppComponent', () => { spyOn(vm.store, 'getPaginationInfo'); const { pageInfo } = vm; + expect(vm.store.getPaginationInfo).toHaveBeenCalled(); expect(pageInfo).not.toBeDefined(); }); @@ -154,6 +156,7 @@ describe('AppComponent', () => { spyOn(vm, 'updateGroups').and.callThrough(); vm.fetchAllGroups(); + expect(vm.isLoading).toBe(true); expect(vm.fetchGroups).toHaveBeenCalled(); setTimeout(() => { @@ -168,6 +171,7 @@ describe('AppComponent', () => { spyOn(vm, 'updateGroups').and.callThrough(); vm.fetchAllGroups(); + expect(vm.fetchGroups).toHaveBeenCalledWith({ page: null, filterGroupsBy: null, @@ -191,6 +195,7 @@ describe('AppComponent', () => { spyOn($, 'scrollTo'); vm.fetchPage(2, null, null, true); + expect(vm.isLoading).toBe(true); expect(vm.fetchGroups).toHaveBeenCalledWith({ page: 2, @@ -210,6 +215,7 @@ describe('AppComponent', () => { jasmine.any(String), jasmine.any(String), ); + expect(vm.updateGroups).toHaveBeenCalled(); done(); }, 0); @@ -230,6 +236,7 @@ describe('AppComponent', () => { spyOn(vm.store, 'setGroupChildren'); vm.toggleChildren(groupItem); + expect(groupItem.isChildrenLoading).toBe(true); expect(vm.fetchGroups).toHaveBeenCalledWith({ parentId: groupItem.id, @@ -245,6 +252,7 @@ describe('AppComponent', () => { groupItem.children = mockRawChildren; vm.toggleChildren(groupItem); + expect(vm.fetchGroups).not.toHaveBeenCalled(); expect(groupItem.isOpen).toBe(true); }); @@ -254,6 +262,7 @@ describe('AppComponent', () => { groupItem.isOpen = true; vm.toggleChildren(groupItem); + expect(vm.fetchGroups).not.toHaveBeenCalled(); expect(groupItem.isOpen).toBe(false); }); @@ -262,6 +271,7 @@ describe('AppComponent', () => { spyOn(vm, 'fetchGroups').and.returnValue(returnServicePromise({}, true)); vm.toggleChildren(groupItem); + expect(groupItem.isChildrenLoading).toBe(true); setTimeout(() => { expect(groupItem.isChildrenLoading).toBe(false); @@ -273,18 +283,22 @@ describe('AppComponent', () => { describe('showLeaveGroupModal', () => { it('caches candidate group (as props) which is to be left', () => { const group = Object.assign({}, mockParentGroupItem); + expect(vm.targetGroup).toBe(null); expect(vm.targetParentGroup).toBe(null); vm.showLeaveGroupModal(group, mockParentGroupItem); + expect(vm.targetGroup).not.toBe(null); expect(vm.targetParentGroup).not.toBe(null); }); it('updates props which show modal confirmation dialog', () => { const group = Object.assign({}, mockParentGroupItem); + expect(vm.showModal).toBe(false); expect(vm.groupLeaveConfirmationMessage).toBe(''); vm.showLeaveGroupModal(group, mockParentGroupItem); + expect(vm.showModal).toBe(true); expect(vm.groupLeaveConfirmationMessage).toBe( `Are you sure you want to leave the "${group.fullName}" group?`, @@ -296,8 +310,10 @@ describe('AppComponent', () => { it('hides modal confirmation which is shown before leaving the group', () => { const group = Object.assign({}, mockParentGroupItem); vm.showLeaveGroupModal(group, mockParentGroupItem); + expect(vm.showModal).toBe(true); vm.hideLeaveGroupModal(); + expect(vm.showModal).toBe(false); }); }); @@ -323,6 +339,7 @@ describe('AppComponent', () => { spyOn($, 'scrollTo'); vm.leaveGroup(); + expect(vm.showModal).toBe(false); expect(vm.targetGroup.isBeingRemoved).toBe(true); expect(vm.service.leaveGroup).toHaveBeenCalledWith(vm.targetGroup.leavePath); @@ -343,6 +360,7 @@ describe('AppComponent', () => { spyOn(window, 'Flash'); vm.leaveGroup(); + expect(vm.targetGroup.isBeingRemoved).toBe(true); expect(vm.service.leaveGroup).toHaveBeenCalledWith(childGroupItem.leavePath); setTimeout(() => { @@ -362,6 +380,7 @@ describe('AppComponent', () => { spyOn(window, 'Flash'); vm.leaveGroup(childGroupItem, groupItem); + expect(vm.targetGroup.isBeingRemoved).toBe(true); expect(vm.service.leaveGroup).toHaveBeenCalledWith(childGroupItem.leavePath); setTimeout(() => { @@ -378,6 +397,7 @@ describe('AppComponent', () => { spyOn(vm.store, 'setPaginationInfo'); vm.updatePagination(mockRawPageInfo); + expect(vm.store.setPaginationInfo).toHaveBeenCalledWith(mockRawPageInfo); }); }); @@ -387,6 +407,7 @@ describe('AppComponent', () => { spyOn(vm.store, 'setGroups'); vm.updateGroups(mockGroups); + expect(vm.store.setGroups).toHaveBeenCalledWith(mockGroups); }); @@ -394,14 +415,17 @@ describe('AppComponent', () => { spyOn(vm.store, 'setSearchedGroups'); vm.updateGroups(mockGroups, true); + expect(vm.store.setSearchedGroups).toHaveBeenCalledWith(mockGroups); }); it('should set `isSearchEmpty` prop based on groups count', () => { vm.updateGroups(mockGroups); + expect(vm.isSearchEmpty).toBe(false); vm.updateGroups([]); + expect(vm.isSearchEmpty).toBe(true); }); }); @@ -497,6 +521,7 @@ describe('AppComponent', () => { vm.showModal = true; Vue.nextTick(() => { const modalDialogEl = vm.$el.querySelector('.modal'); + expect(modalDialogEl).not.toBe(null); expect(modalDialogEl.querySelector('.modal-title').innerText.trim()).toBe('Are you sure?'); expect(modalDialogEl.querySelector('.btn.btn-warning').innerText.trim()).toBe('Leave'); diff --git a/spec/javascripts/groups/components/group_folder_spec.js b/spec/javascripts/groups/components/group_folder_spec.js index 4eb198595fb..9342c04e4d5 100644 --- a/spec/javascripts/groups/components/group_folder_spec.js +++ b/spec/javascripts/groups/components/group_folder_spec.js @@ -59,6 +59,7 @@ describe('GroupFolderComponent', () => { const newVm = createComponent(mockGroups, parentGroup); newVm.$mount(); + expect(newVm.$el.querySelector('li.group-row a.has-more-items')).toBeDefined(); newVm.$destroy(); }); diff --git a/spec/javascripts/groups/components/group_item_spec.js b/spec/javascripts/groups/components/group_item_spec.js index 49d4f7efd72..48e79fd85e4 100644 --- a/spec/javascripts/groups/components/group_item_spec.js +++ b/spec/javascripts/groups/components/group_item_spec.js @@ -57,11 +57,13 @@ describe('GroupItemComponent', () => { group.childrenCount = 5; newVm = createComponent(group); + expect(newVm.hasChildren).toBeTruthy(); newVm.$destroy(); group.childrenCount = 0; newVm = createComponent(group); + expect(newVm.hasChildren).toBeFalsy(); newVm.$destroy(); }); @@ -74,11 +76,13 @@ describe('GroupItemComponent', () => { group.avatarUrl = null; newVm = createComponent(group); + expect(newVm.hasAvatar).toBeFalsy(); newVm.$destroy(); group.avatarUrl = '/uploads/group_avatar.png'; newVm = createComponent(group); + expect(newVm.hasAvatar).toBeTruthy(); newVm.$destroy(); }); @@ -91,11 +95,13 @@ describe('GroupItemComponent', () => { group.type = 'group'; newVm = createComponent(group); + expect(newVm.isGroup).toBeTruthy(); newVm.$destroy(); group.type = 'project'; newVm = createComponent(group); + expect(newVm.isGroup).toBeFalsy(); newVm.$destroy(); }); @@ -127,6 +133,7 @@ describe('GroupItemComponent', () => { spyOn(eventHub, '$emit'); vm.onClickRowGroup(event); + expect(eventHub.$emit).toHaveBeenCalledWith('toggleChildren', vm.group); }); diff --git a/spec/javascripts/groups/components/groups_spec.js b/spec/javascripts/groups/components/groups_spec.js index 5af86b55532..0f3907f1ca2 100644 --- a/spec/javascripts/groups/components/groups_spec.js +++ b/spec/javascripts/groups/components/groups_spec.js @@ -42,6 +42,7 @@ describe('GroupsComponent', () => { spyOn(eventHub, '$emit').and.stub(); vm.change(2); + expect(eventHub.$emit).toHaveBeenCalledWith('fetchPage', 2, jasmine.any(Object), jasmine.any(Object), jasmine.any(Object)); }); }); diff --git a/spec/javascripts/groups/components/item_actions_spec.js b/spec/javascripts/groups/components/item_actions_spec.js index 15fd37ebcd2..bffeb4acd45 100644 --- a/spec/javascripts/groups/components/item_actions_spec.js +++ b/spec/javascripts/groups/components/item_actions_spec.js @@ -30,6 +30,7 @@ describe('ItemActionsComponent', () => { it('emits `showLeaveGroupModal` event with `group` and `parentGroup` props', () => { spyOn(eventHub, '$emit'); vm.onLeaveGroup(); + expect(eventHub.$emit).toHaveBeenCalledWith('showLeaveGroupModal', vm.group, vm.parentGroup); }); }); @@ -46,6 +47,7 @@ describe('ItemActionsComponent', () => { const newVm = createComponent(group); const editBtn = newVm.$el.querySelector('a.edit-group'); + expect(editBtn).toBeDefined(); expect(editBtn.classList.contains('no-expand')).toBeTruthy(); expect(editBtn.getAttribute('href')).toBe(group.editPath); @@ -63,6 +65,7 @@ describe('ItemActionsComponent', () => { const newVm = createComponent(group); const leaveBtn = newVm.$el.querySelector('a.leave-group'); + expect(leaveBtn).toBeDefined(); expect(leaveBtn.classList.contains('no-expand')).toBeTruthy(); expect(leaveBtn.getAttribute('href')).toBe(group.leavePath); diff --git a/spec/javascripts/groups/components/item_caret_spec.js b/spec/javascripts/groups/components/item_caret_spec.js index 36f838a104f..6e430dbcdb2 100644 --- a/spec/javascripts/groups/components/item_caret_spec.js +++ b/spec/javascripts/groups/components/item_caret_spec.js @@ -16,6 +16,7 @@ describe('ItemCaretComponent', () => { describe('template', () => { it('should render component template correctly', () => { const vm = createComponent(); + expect(vm.$el.classList.contains('folder-caret')).toBeTruthy(); expect(vm.$el.querySelectorAll('svg').length).toBe(1); vm.$destroy(); @@ -23,12 +24,14 @@ describe('ItemCaretComponent', () => { it('should render caret down icon if `isGroupOpen` prop is `true`', () => { const vm = createComponent(true); + expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('angle-down'); vm.$destroy(); }); it('should render caret right icon if `isGroupOpen` prop is `false`', () => { const vm = createComponent(); + expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('angle-right'); vm.$destroy(); }); diff --git a/spec/javascripts/groups/components/item_stats_spec.js b/spec/javascripts/groups/components/item_stats_spec.js index e6a57495eb1..55a28dfea11 100644 --- a/spec/javascripts/groups/components/item_stats_spec.js +++ b/spec/javascripts/groups/components/item_stats_spec.js @@ -25,6 +25,7 @@ describe('ItemStatsComponent', () => { Object.keys(VISIBILITY_TYPE_ICON).forEach((visibility) => { const item = Object.assign({}, mockParentGroupItem, { visibility }); const vm = createComponent(item); + expect(vm.visibilityIcon).toBe(VISIBILITY_TYPE_ICON[visibility]); vm.$destroy(); }); @@ -39,6 +40,7 @@ describe('ItemStatsComponent', () => { type: ITEM_TYPE.GROUP, }); const vm = createComponent(item); + expect(vm.visibilityTooltip).toBe(GROUP_VISIBILITY_TYPE[visibility]); vm.$destroy(); }); @@ -51,6 +53,7 @@ describe('ItemStatsComponent', () => { type: ITEM_TYPE.PROJECT, }); const vm = createComponent(item); + expect(vm.visibilityTooltip).toBe(PROJECT_VISIBILITY_TYPE[visibility]); vm.$destroy(); }); @@ -64,11 +67,13 @@ describe('ItemStatsComponent', () => { item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.PROJECT }); vm = createComponent(item); + expect(vm.isProject).toBeTruthy(); vm.$destroy(); item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.GROUP }); vm = createComponent(item); + expect(vm.isProject).toBeFalsy(); vm.$destroy(); }); @@ -81,11 +86,13 @@ describe('ItemStatsComponent', () => { item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.GROUP }); vm = createComponent(item); + expect(vm.isGroup).toBeTruthy(); vm.$destroy(); item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.PROJECT }); vm = createComponent(item); + expect(vm.isGroup).toBeFalsy(); vm.$destroy(); }); @@ -105,6 +112,7 @@ describe('ItemStatsComponent', () => { const vm = createComponent(); const visibilityIconEl = vm.$el.querySelector('.item-visibility'); + expect(visibilityIconEl).not.toBe(null); expect(visibilityIconEl.dataset.originalTitle).toBe(vm.visibilityTooltip); expect(visibilityIconEl.querySelectorAll('svg').length).toBeGreaterThan(0); @@ -120,6 +128,7 @@ describe('ItemStatsComponent', () => { const vm = createComponent(item); const projectStarIconEl = vm.$el.querySelector('.project-stars'); + expect(projectStarIconEl).not.toBeNull(); expect(projectStarIconEl.querySelectorAll('svg').length).toBeGreaterThan(0); expect(projectStarIconEl.querySelectorAll('.stat-value').length).toBeGreaterThan(0); diff --git a/spec/javascripts/groups/components/item_stats_value_spec.js b/spec/javascripts/groups/components/item_stats_value_spec.js index 2a995e8efe6..ea8edcf49cd 100644 --- a/spec/javascripts/groups/components/item_stats_value_spec.js +++ b/spec/javascripts/groups/components/item_stats_value_spec.js @@ -29,11 +29,13 @@ describe('ItemStatsValueComponent', () => { describe('isValuePresent', () => { it('returns true if non-empty `value` is present', () => { vm = createComponent(Object.assign({}, itemConfig, { value: 10 })); + expect(vm.isValuePresent).toBeTruthy(); }); it('returns false if empty `value` is present', () => { vm = createComponent(itemConfig); + expect(vm.isValuePresent).toBeFalsy(); }); diff --git a/spec/javascripts/groups/components/item_type_icon_spec.js b/spec/javascripts/groups/components/item_type_icon_spec.js index 24380689b29..73108512222 100644 --- a/spec/javascripts/groups/components/item_type_icon_spec.js +++ b/spec/javascripts/groups/components/item_type_icon_spec.js @@ -18,6 +18,7 @@ describe('ItemTypeIconComponent', () => { it('should render component template correctly', () => { const vm = createComponent(); vm.$mount(); + expect(vm.$el.classList.contains('item-type-icon')).toBeTruthy(); vm.$destroy(); }); @@ -27,11 +28,13 @@ describe('ItemTypeIconComponent', () => { vm = createComponent(ITEM_TYPE.GROUP, true); vm.$mount(); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('folder-open'); vm.$destroy(); vm = createComponent(ITEM_TYPE.GROUP); vm.$mount(); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('folder'); vm.$destroy(); }); @@ -41,11 +44,13 @@ describe('ItemTypeIconComponent', () => { vm = createComponent(ITEM_TYPE.PROJECT); vm.$mount(); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('bookmark'); vm.$destroy(); vm = createComponent(ITEM_TYPE.GROUP); vm.$mount(); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).not.toContain('bookmark'); vm.$destroy(); }); diff --git a/spec/javascripts/groups/service/groups_service_spec.js b/spec/javascripts/groups/service/groups_service_spec.js index 20bb63687f7..339e5131615 100644 --- a/spec/javascripts/groups/service/groups_service_spec.js +++ b/spec/javascripts/groups/service/groups_service_spec.js @@ -24,9 +24,11 @@ describe('GroupsService', () => { }; service.getGroups(55, 2, 'git', 'created_asc', true); + expect(service.groups.get).toHaveBeenCalledWith({ parent_id: 55 }); service.getGroups(null, 2, 'git', 'created_asc', true); + expect(service.groups.get).toHaveBeenCalledWith(queryParams); }); }); @@ -36,6 +38,7 @@ describe('GroupsService', () => { spyOn(Vue.http, 'delete').and.stub(); service.leaveGroup(mockParentGroupItem.leavePath); + expect(Vue.http.delete).toHaveBeenCalledWith(mockParentGroupItem.leavePath); }); }); diff --git a/spec/javascripts/groups/store/groups_store_spec.js b/spec/javascripts/groups/store/groups_store_spec.js index 78caf8f80bf..23324d26cf0 100644 --- a/spec/javascripts/groups/store/groups_store_spec.js +++ b/spec/javascripts/groups/store/groups_store_spec.js @@ -11,12 +11,14 @@ describe('ProjectsStore', () => { let store; store = new GroupsStore(); + expect(Object.keys(store.state).length).toBe(2); expect(Array.isArray(store.state.groups)).toBeTruthy(); expect(Object.keys(store.state.pageInfo).length).toBe(0); expect(store.hideProjects).not.toBeDefined(); store = new GroupsStore(true); + expect(store.hideProjects).toBeTruthy(); }); }); @@ -27,6 +29,7 @@ describe('ProjectsStore', () => { spyOn(store, 'formatGroupItem').and.callThrough(); store.setGroups(mockGroups); + expect(store.state.groups.length).toBe(mockGroups.length); expect(store.formatGroupItem).toHaveBeenCalledWith(jasmine.any(Object)); expect(Object.keys(store.state.groups[0]).indexOf('fullName')).toBeGreaterThan(-1); @@ -39,6 +42,7 @@ describe('ProjectsStore', () => { spyOn(store, 'formatGroupItem').and.callThrough(); store.setSearchedGroups(mockSearchedGroups); + expect(store.state.groups.length).toBe(mockSearchedGroups.length); expect(store.formatGroupItem).toHaveBeenCalledWith(jasmine.any(Object)); expect(Object.keys(store.state.groups[0]).indexOf('fullName')).toBeGreaterThan(-1); @@ -52,6 +56,7 @@ describe('ProjectsStore', () => { spyOn(store, 'formatGroupItem').and.callThrough(); store.setGroupChildren(mockParentGroupItem, mockRawChildren); + expect(store.formatGroupItem).toHaveBeenCalledWith(jasmine.any(Object)); expect(mockParentGroupItem.children.length).toBe(1); expect(Object.keys(mockParentGroupItem.children[0]).indexOf('fullName')).toBeGreaterThan(-1); @@ -65,6 +70,7 @@ describe('ProjectsStore', () => { const store = new GroupsStore(); store.setPaginationInfo(mockRawPageInfo); + expect(store.state.pageInfo.perPage).toBe(10); expect(store.state.pageInfo.page).toBe(10); expect(store.state.pageInfo.total).toBe(10); @@ -81,6 +87,7 @@ describe('ProjectsStore', () => { store = new GroupsStore(); updatedGroupItem = store.formatGroupItem(mockRawChildren[0]); + expect(Object.keys(updatedGroupItem).indexOf('fullName')).toBeGreaterThan(-1); expect(updatedGroupItem.childrenCount).toBe(mockRawChildren[0].children_count); expect(updatedGroupItem.isChildrenLoading).toBe(false); @@ -88,6 +95,7 @@ describe('ProjectsStore', () => { store = new GroupsStore(true); updatedGroupItem = store.formatGroupItem(mockRawChildren[0]); + expect(Object.keys(updatedGroupItem).indexOf('fullName')).toBeGreaterThan(-1); expect(updatedGroupItem.childrenCount).toBe(mockRawChildren[0].subgroup_count); }); @@ -104,6 +112,7 @@ describe('ProjectsStore', () => { const childItem = store.state.groups[0].children[0]; store.removeGroup(childItem, store.state.groups[0]); + expect(store.state.groups[0].children.length).toBe(0); }); }); diff --git a/spec/javascripts/header_spec.js b/spec/javascripts/header_spec.js index 16ac438f7ac..3d1adc081cd 100644 --- a/spec/javascripts/header_spec.js +++ b/spec/javascripts/header_spec.js @@ -21,16 +21,19 @@ describe('Header', function () { it('should update todos-count after receiving the todo:toggle event', () => { triggerToggle('5'); + expect($(todosPendingCount).text()).toEqual('5'); }); it('should hide todos-count when it is 0', () => { triggerToggle('0'); + expect(isTodosCountHidden()).toEqual(true); }); it('should show todos-count when it is more than 0', () => { triggerToggle('10'); + expect(isTodosCountHidden()).toEqual(false); }); diff --git a/spec/javascripts/ide/components/branches/item_spec.js b/spec/javascripts/ide/components/branches/item_spec.js index 8b756c8f168..249b80bbba6 100644 --- a/spec/javascripts/ide/components/branches/item_spec.js +++ b/spec/javascripts/ide/components/branches/item_spec.js @@ -29,6 +29,7 @@ describe('IDE branch item', () => { it('renders branch name and timeago', () => { const timeText = getTimeago().format(TEST_BRANCH.committedDate); + expect(vm.$el).toContainText(TEST_BRANCH.name); expect(vm.$el.querySelector('time')).toHaveText(timeText); expect(vm.$el.querySelector('.ic-mobile-issue-close')).toBe(null); @@ -36,6 +37,7 @@ describe('IDE branch item', () => { it('renders link to branch', () => { const expectedHref = router.resolve(`/project/${TEST_PROJECT_ID}/edit/${TEST_BRANCH.name}`).href; + expect(vm.$el).toMatch('a'); expect(vm.$el).toHaveAttr('href', expectedHref); }); diff --git a/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js b/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js index 942cc19f46d..c06dfa46303 100644 --- a/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js +++ b/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js @@ -76,6 +76,7 @@ describe('IDE commit message field', () => { expect(vm.$el.querySelector('.highlights span').textContent).toContain( 'text less than 50 chars', ); + expect(vm.$el.querySelector('mark').style.display).toBe('none'); }) .then(done) @@ -92,6 +93,7 @@ describe('IDE commit message field', () => { expect(vm.$el.querySelector('.highlights span').textContent).toContain( 'text less than 50 chars that should not highlighte', ); + expect(vm.$el.querySelector('mark').style.display).not.toBe('none'); expect(vm.$el.querySelector('mark').textContent).toBe( 'd. text more than 50 should be highlighted', diff --git a/spec/javascripts/ide/components/ide_status_bar_spec.js b/spec/javascripts/ide/components/ide_status_bar_spec.js index 47d6492a7a6..9874e7b597e 100644 --- a/spec/javascripts/ide/components/ide_status_bar_spec.js +++ b/spec/javascripts/ide/components/ide_status_bar_spec.js @@ -50,9 +50,11 @@ describe('ideStatusBar', () => { expect(vm.commitAgeUpdate).not.toHaveBeenCalled(); jasmine.clock().tick(1100); + expect(vm.commitAgeUpdate.calls.count()).toEqual(1); jasmine.clock().tick(1000); + expect(vm.commitAgeUpdate.calls.count()).toEqual(2); }); }); diff --git a/spec/javascripts/ide/components/merge_requests/item_spec.js b/spec/javascripts/ide/components/merge_requests/item_spec.js index 750948cae3c..c92e6b89c78 100644 --- a/spec/javascripts/ide/components/merge_requests/item_spec.js +++ b/spec/javascripts/ide/components/merge_requests/item_spec.js @@ -30,6 +30,7 @@ describe('IDE merge request item', () => { it('renders link with href', () => { const expectedHref = router.resolve(`/project/${vm.item.projectPathWithNamespace}/merge_requests/${vm.item.iid}`).href; + expect(vm.$el).toMatch('a'); expect(vm.$el).toHaveAttr('href', expectedHref); }); diff --git a/spec/javascripts/ide/components/new_dropdown/index_spec.js b/spec/javascripts/ide/components/new_dropdown/index_spec.js index 8a8cbd2cee4..83e530f0a6a 100644 --- a/spec/javascripts/ide/components/new_dropdown/index_spec.js +++ b/spec/javascripts/ide/components/new_dropdown/index_spec.js @@ -36,6 +36,7 @@ describe('new dropdown component', () => { it('renders new file, upload and new directory links', () => { const buttons = vm.$el.querySelectorAll('.dropdown-menu button'); + expect(buttons[0].textContent.trim()).toBe('New file'); expect(buttons[1].textContent.trim()).toBe('Upload file'); expect(buttons[2].textContent.trim()).toBe('New directory'); diff --git a/spec/javascripts/ide/components/repo_editor_spec.js b/spec/javascripts/ide/components/repo_editor_spec.js index 991fb750876..d9136d636d0 100644 --- a/spec/javascripts/ide/components/repo_editor_spec.js +++ b/spec/javascripts/ide/components/repo_editor_spec.js @@ -52,6 +52,7 @@ describe('RepoEditor', () => { it('renders only an edit tab', done => { Vue.nextTick(() => { const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li'); + expect(tabs.length).toBe(1); expect(tabs[0].textContent.trim()).toBe('Edit'); @@ -72,6 +73,7 @@ describe('RepoEditor', () => { it('renders an Edit and a Preview Tab', done => { Vue.nextTick(() => { const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li'); + expect(tabs.length).toBe(2); expect(tabs[0].textContent.trim()).toBe('Edit'); expect(tabs[1].textContent.trim()).toBe('Preview Markdown'); @@ -109,6 +111,7 @@ describe('RepoEditor', () => { it('renders an Edit and a Preview Tab', done => { Vue.nextTick(() => { const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li'); + expect(tabs.length).toBe(2); expect(tabs[0].textContent.trim()).toBe('Review'); expect(tabs[1].textContent.trim()).toBe('Preview Markdown'); diff --git a/spec/javascripts/ide/components/shared/tokened_input_spec.js b/spec/javascripts/ide/components/shared/tokened_input_spec.js index 09940fe8c6a..935ee0beea8 100644 --- a/spec/javascripts/ide/components/shared/tokened_input_spec.js +++ b/spec/javascripts/ide/components/shared/tokened_input_spec.js @@ -85,10 +85,12 @@ describe('IDE shared/TokenedInput', () => { vm.value = ''; vm.onBackspace(); + expect(vm.$emit).not.toHaveBeenCalled(); expect(vm.backspaceCount).toEqual(1); vm.onBackspace(); + expect(vm.$emit).toHaveBeenCalledWith('removeToken', TEST_TOKENS[TEST_TOKENS.length - 1]); expect(vm.backspaceCount).toEqual(0); }); diff --git a/spec/javascripts/ide/stores/actions/merge_request_spec.js b/spec/javascripts/ide/stores/actions/merge_request_spec.js index 8564f04ce8a..c4fd2c56315 100644 --- a/spec/javascripts/ide/stores/actions/merge_request_spec.js +++ b/spec/javascripts/ide/stores/actions/merge_request_spec.js @@ -311,6 +311,7 @@ describe('IDE store merge request actions', () => { file: store.state.entries[change.new_path], mrChange: change, }); + expect(store.dispatch).toHaveBeenCalledWith('getFileData', { path: change.new_path, makeFileActive: i === 0, diff --git a/spec/javascripts/ide/stores/actions/tree_spec.js b/spec/javascripts/ide/stores/actions/tree_spec.js index 9f098eded08..d47c60dc581 100644 --- a/spec/javascripts/ide/stores/actions/tree_spec.js +++ b/spec/javascripts/ide/stores/actions/tree_spec.js @@ -71,6 +71,7 @@ describe('Multi-file store tree actions', () => { .dispatch('getFiles', basicCallParameters) .then(() => { projectTree = store.state.trees['abcproject/master']; + expect(projectTree.tree.length).toBe(2); expect(projectTree.tree[0].type).toBe('tree'); expect(projectTree.tree[0].tree[1].name).toBe('fileinfolder.js'); diff --git a/spec/javascripts/ide/stores/mutations/merge_request_spec.js b/spec/javascripts/ide/stores/mutations/merge_request_spec.js index f724bf464f5..e30ca22022f 100644 --- a/spec/javascripts/ide/stores/mutations/merge_request_spec.js +++ b/spec/javascripts/ide/stores/mutations/merge_request_spec.js @@ -45,6 +45,7 @@ describe('IDE store merge request mutations', () => { }); const newMr = localState.projects.abcproject.mergeRequests[1]; + expect(newMr.changes.diff).toBe('abc'); }); }); @@ -58,6 +59,7 @@ describe('IDE store merge request mutations', () => { }); const newMr = localState.projects.abcproject.mergeRequests[1]; + expect(newMr.versions.length).toBe(1); expect(newMr.versions[0].id).toBe(123); }); diff --git a/spec/javascripts/image_diff/helpers/badge_helper_spec.js b/spec/javascripts/image_diff/helpers/badge_helper_spec.js index ce3add1fd90..8ea05203d00 100644 --- a/spec/javascripts/image_diff/helpers/badge_helper_spec.js +++ b/spec/javascripts/image_diff/helpers/badge_helper_spec.js @@ -90,6 +90,7 @@ describe('badge helper', () => { it('should create icon comment button', () => { const iconEl = buttonEl.querySelector('svg'); + expect(iconEl).toBeDefined(); }); }); diff --git a/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js b/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js index 9d05c6859df..8e3e7f1222e 100644 --- a/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js +++ b/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js @@ -29,9 +29,11 @@ describe('commentIndicatorHelper', () => { it('should contain image-comment-dark svg', () => { const svgEl = buttonEl.querySelector('svg'); + expect(svgEl).toBeDefined(); const svgLink = svgEl.querySelector('use').getAttribute('xlink:href'); + expect(svgLink.indexOf('image-comment-dark')).not.toBe(-1); }); }); @@ -40,6 +42,7 @@ describe('commentIndicatorHelper', () => { describe('removeCommentIndicator', () => { it('should return removed false if there is no comment-indicator', () => { const result = commentIndicatorHelper.removeCommentIndicator(containerEl); + expect(result.removed).toEqual(false); }); @@ -84,6 +87,7 @@ describe('commentIndicatorHelper', () => { it('should set commentIndicator coordinates', () => { const commentIndicatorEl = containerEl.querySelector('.comment-indicator'); + expect(commentIndicatorEl.style.left).toEqual(`${coordinate.x}px`); expect(commentIndicatorEl.style.top).toEqual(`${coordinate.y}px`); }); @@ -96,6 +100,7 @@ describe('commentIndicatorHelper', () => { it('should addCommentIndicator', () => { const buttonEl = containerEl.querySelector('.comment-indicator'); + expect(buttonEl).toBeDefined(); expect(buttonEl.style.left).toEqual(`${coordinate.x}px`); expect(buttonEl.style.top).toEqual(`${coordinate.y}px`); diff --git a/spec/javascripts/image_diff/helpers/dom_helper_spec.js b/spec/javascripts/image_diff/helpers/dom_helper_spec.js index 8dde924e8ae..ffe712af2dd 100644 --- a/spec/javascripts/image_diff/helpers/dom_helper_spec.js +++ b/spec/javascripts/image_diff/helpers/dom_helper_spec.js @@ -92,6 +92,7 @@ describe('domHelper', () => { it('should force formEl to display none', () => { const formEl = element.querySelector('.discussion-form'); + expect(formEl.style.display).toEqual('none'); }); }); @@ -111,6 +112,7 @@ describe('domHelper', () => { it('should force formEl to display block', () => { const formEl = element.querySelector('.discussion-form'); + expect(formEl.style.display).toEqual('block'); }); }); diff --git a/spec/javascripts/image_diff/helpers/utils_helper_spec.js b/spec/javascripts/image_diff/helpers/utils_helper_spec.js index 31949c39d9c..70bdf0d3609 100644 --- a/spec/javascripts/image_diff/helpers/utils_helper_spec.js +++ b/spec/javascripts/image_diff/helpers/utils_helper_spec.js @@ -57,6 +57,7 @@ describe('utilsHelper', () => { it('should return actual image properties', () => { const { actual } = result; + expect(actual.x).toEqual(imageMeta.x); expect(actual.y).toEqual(imageMeta.y); expect(actual.width).toEqual(imageMeta.width); @@ -65,6 +66,7 @@ describe('utilsHelper', () => { it('should return browser image properties', () => { const { browser } = result; + expect(browser.x).toBeDefined(); expect(browser.y).toBeDefined(); expect(browser.width).toBeDefined(); @@ -106,6 +108,7 @@ describe('utilsHelper', () => { const result = utilsHelper.getTargetSelection(event); const { browser } = result; + expect(browser.x).toEqual(event.offsetX); expect(browser.y).toEqual(event.offsetY); expect(browser.width).toEqual(imageProperties.width); @@ -117,6 +120,7 @@ describe('utilsHelper', () => { const result = utilsHelper.getTargetSelection(event); const { actual } = result; + expect(actual.x).toEqual(100); expect(actual.y).toEqual(100); expect(actual.width).toEqual(imageProperties.naturalWidth); @@ -127,24 +131,28 @@ describe('utilsHelper', () => { it('should return x = 0 if x < 0', () => { const event = generateEvent(-5, 50); const result = utilsHelper.getTargetSelection(event); + expect(result.browser.x).toEqual(0); }); it('should return x = width if x > width', () => { const event = generateEvent(1000, 50); const result = utilsHelper.getTargetSelection(event); + expect(result.browser.x).toEqual(imageProperties.width); }); it('should return y = 0 if y < 0', () => { const event = generateEvent(50, -10); const result = utilsHelper.getTargetSelection(event); + expect(result.browser.y).toEqual(0); }); it('should return y = height if y > height', () => { const event = generateEvent(50, 1000); const result = utilsHelper.getTargetSelection(event); + expect(result.browser.y).toEqual(imageProperties.height); }); }); @@ -178,6 +186,7 @@ describe('utilsHelper', () => { `; const imageDiff = utilsHelper.initImageDiff(fileEl, true, false); + expect(ImageDiff.prototype.init).toHaveBeenCalled(); expect(imageDiff.canCreateNote).toEqual(true); expect(imageDiff.renderCommentBadge).toEqual(false); @@ -191,6 +200,7 @@ describe('utilsHelper', () => { `; const replacedImageDiff = utilsHelper.initImageDiff(fileEl, false, true); + expect(ReplacedImageDiff.prototype.init).toHaveBeenCalled(); expect(replacedImageDiff.canCreateNote).toEqual(false); expect(replacedImageDiff.renderCommentBadge).toEqual(true); diff --git a/spec/javascripts/image_diff/image_badge_spec.js b/spec/javascripts/image_diff/image_badge_spec.js index 87f98fc0926..ce723e5d23c 100644 --- a/spec/javascripts/image_diff/image_badge_spec.js +++ b/spec/javascripts/image_diff/image_badge_spec.js @@ -15,6 +15,7 @@ describe('ImageBadge', () => { })); const { actual } = imageBadge; + expect(actual.x).toEqual(imageMeta.x); expect(actual.y).toEqual(imageMeta.y); expect(actual.width).toEqual(imageMeta.width); @@ -27,6 +28,7 @@ describe('ImageBadge', () => { })); const { browser } = imageBadge; + expect(browser.x).toEqual(imageMeta.x); expect(browser.y).toEqual(imageMeta.y); expect(browser.width).toEqual(imageMeta.width); @@ -35,11 +37,13 @@ describe('ImageBadge', () => { it('should save noteId', () => { const imageBadge = new ImageBadge(options); + expect(imageBadge.noteId).toEqual(noteId); }); it('should save discussionId', () => { const imageBadge = new ImageBadge(options); + expect(imageBadge.discussionId).toEqual(discussionId); }); @@ -52,6 +56,7 @@ describe('ImageBadge', () => { it('should return defaultimageMeta if actual property is not provided', () => { const { actual } = imageBadge; + expect(actual.x).toEqual(0); expect(actual.y).toEqual(0); expect(actual.width).toEqual(0); @@ -60,6 +65,7 @@ describe('ImageBadge', () => { it('should return defaultimageMeta if browser property is not provided', () => { const { browser } = imageBadge; + expect(browser.x).toEqual(0); expect(browser.y).toEqual(0); expect(browser.width).toEqual(0); diff --git a/spec/javascripts/image_diff/image_diff_spec.js b/spec/javascripts/image_diff/image_diff_spec.js index 346282328c7..9a7f288cd6b 100644 --- a/spec/javascripts/image_diff/image_diff_spec.js +++ b/spec/javascripts/image_diff/image_diff_spec.js @@ -117,11 +117,13 @@ describe('ImageDiff', () => { it('should register click event delegation to js-diff-notes-toggle', () => { element.querySelector('.js-diff-notes-toggle').click(); + expect(imageDiffHelper.toggleCollapsed).toHaveBeenCalled(); }); it('should register click event delegation to comment-indicator', () => { element.querySelector('.comment-indicator').click(); + expect(imageDiffHelper.commentIndicatorOnClick).toHaveBeenCalled(); }); }); @@ -147,6 +149,7 @@ describe('ImageDiff', () => { it('should registers load eventListener', () => { const loadEvent = new Event('load'); imageEl.dispatchEvent(loadEvent); + expect(imageDiff.renderBadges).toHaveBeenCalled(); }); }); @@ -164,24 +167,28 @@ describe('ImageDiff', () => { it('should register click.imageDiff event', () => { const event = new CustomEvent('click.imageDiff'); element.dispatchEvent(event); + expect(imageDiff.imageClicked).toHaveBeenCalled(); }); it('should register blur.imageDiff event', () => { const event = new CustomEvent('blur.imageDiff'); element.dispatchEvent(event); + expect(imageDiffHelper.removeCommentIndicator).toHaveBeenCalled(); }); it('should register addBadge.imageDiff event', () => { const event = new CustomEvent('addBadge.imageDiff'); element.dispatchEvent(event); + expect(imageDiff.addBadge).toHaveBeenCalled(); }); it('should register removeBadge.imageDiff event', () => { const event = new CustomEvent('removeBadge.imageDiff'); element.dispatchEvent(event); + expect(imageDiff.removeBadge).toHaveBeenCalled(); }); }); @@ -197,6 +204,7 @@ describe('ImageDiff', () => { it('should not register click.imageDiff event', () => { const event = new CustomEvent('click.imageDiff'); element.dispatchEvent(event); + expect(imageDiff.imageClicked).not.toHaveBeenCalled(); }); }); @@ -240,6 +248,7 @@ describe('ImageDiff', () => { it('should call renderBadge for each discussionEl', () => { const discussionEls = element.querySelectorAll('.note-container .discussion-notes .notes'); + expect(imageDiff.renderBadge.calls.count()).toEqual(discussionEls.length); }); }); @@ -336,6 +345,7 @@ describe('ImageDiff', () => { describe('cascade badge count', () => { it('should update next imageBadgeEl value', () => { const imageBadgeEls = imageDiff.imageFrameEl.querySelectorAll('.badge'); + expect(imageBadgeEls[0].innerText).toEqual('1'); expect(imageBadgeEls[1].innerText).toEqual('2'); expect(imageBadgeEls.length).toEqual(2); diff --git a/spec/javascripts/image_diff/init_discussion_tab_spec.js b/spec/javascripts/image_diff/init_discussion_tab_spec.js index 7c447d6f70d..fbc68679c41 100644 --- a/spec/javascripts/image_diff/init_discussion_tab_spec.js +++ b/spec/javascripts/image_diff/init_discussion_tab_spec.js @@ -32,6 +32,7 @@ describe('initDiscussionTab', () => { it('should call initImageDiff for each diffFileEls', () => { spyOn(imageDiffHelper, 'initImageDiff').and.callFake(() => {}); initDiscussionTab(); + expect(imageDiffHelper.initImageDiff.calls.count()).toEqual(2); }); }); diff --git a/spec/javascripts/image_diff/replaced_image_diff_spec.js b/spec/javascripts/image_diff/replaced_image_diff_spec.js index 5f8cd7c531a..49fed323871 100644 --- a/spec/javascripts/image_diff/replaced_image_diff_spec.js +++ b/spec/javascripts/image_diff/replaced_image_diff_spec.js @@ -58,6 +58,7 @@ describe('ReplacedImageDiff', () => { it('should extend ImageDiff', () => { replacedImageDiff = new ReplacedImageDiff(element); + expect(replacedImageDiff instanceof ImageDiff).toEqual(true); }); @@ -72,6 +73,7 @@ describe('ReplacedImageDiff', () => { it('should set imageFrameEls', () => { const { imageFrameEls } = replacedImageDiff; + expect(imageFrameEls).toBeDefined(); expect(imageFrameEls[viewTypes.TWO_UP]).toEqual(element.querySelector('.two-up .js-image-frame')); expect(imageFrameEls[viewTypes.SWIPE]).toEqual(element.querySelector('.swipe .js-image-frame')); @@ -80,6 +82,7 @@ describe('ReplacedImageDiff', () => { it('should set viewModesEls', () => { const { viewModesEls } = replacedImageDiff; + expect(viewModesEls).toBeDefined(); expect(viewModesEls[viewTypes.TWO_UP]).toEqual(element.querySelector('.view-modes-menu .two-up')); expect(viewModesEls[viewTypes.SWIPE]).toEqual(element.querySelector('.view-modes-menu .swipe')); @@ -97,6 +100,7 @@ describe('ReplacedImageDiff', () => { describe('currentView', () => { it('should set currentView', () => { replacedImageDiff.init(viewTypes.ONION_SKIN); + expect(replacedImageDiff.currentView).toEqual(viewTypes.ONION_SKIN); }); @@ -121,6 +125,7 @@ describe('ReplacedImageDiff', () => { it('should set imageEls', () => { replacedImageDiff.generateImageEls(); const { imageEls } = replacedImageDiff; + expect(imageEls).toBeDefined(); expect(imageEls[viewTypes.TWO_UP]).toEqual(element.querySelector('.two-up img')); expect(imageEls[viewTypes.SWIPE]).toEqual(element.querySelector('.swipe img')); @@ -138,6 +143,7 @@ describe('ReplacedImageDiff', () => { it('should call super.bindEvents', () => { replacedImageDiff.bindEvents(); + expect(ImageDiff.prototype.bindEvents).toHaveBeenCalled(); }); @@ -184,6 +190,7 @@ describe('ReplacedImageDiff', () => { expect(replacedImageDiff.imageEl).toEqual(element.querySelector('.two-up img')); replacedImageDiff.currentView = viewTypes.SWIPE; + expect(replacedImageDiff.imageEl).toEqual(element.querySelector('.swipe img')); }); }); @@ -199,6 +206,7 @@ describe('ReplacedImageDiff', () => { expect(replacedImageDiff.imageFrameEl).toEqual(element.querySelector('.two-up .js-image-frame')); replacedImageDiff.currentView = viewTypes.ONION_SKIN; + expect(replacedImageDiff.imageFrameEl).toEqual(element.querySelector('.onion-skin .js-image-frame')); }); }); @@ -248,6 +256,7 @@ describe('ReplacedImageDiff', () => { it('should call renderNewView', () => { jasmine.clock().tick(251); + expect(replacedImageDiff.renderNewView).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/importer_status_spec.js b/spec/javascripts/importer_status_spec.js index 63cdb3d5114..c4a6b1d28e0 100644 --- a/spec/javascripts/importer_status_spec.js +++ b/spec/javascripts/importer_status_spec.js @@ -63,6 +63,7 @@ describe('Importer Status', () => { }) .then(() => { const flashMessage = document.querySelector('.flash-text'); + expect(flashMessage.textContent.trim()).toEqual('An error occurred while importing project: You forgot your lunch'); done(); }) diff --git a/spec/javascripts/integrations/integration_settings_form_spec.js b/spec/javascripts/integrations/integration_settings_form_spec.js index e07343810d2..3eaaee5cda6 100644 --- a/spec/javascripts/integrations/integration_settings_form_spec.js +++ b/spec/javascripts/integrations/integration_settings_form_spec.js @@ -68,6 +68,7 @@ describe('IntegrationSettingsForm', () => { integrationSettingsForm.canTestService = true; integrationSettingsForm.toggleSubmitBtnLabel(true); + expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Test settings and save changes'); }); @@ -75,14 +76,17 @@ describe('IntegrationSettingsForm', () => { integrationSettingsForm.canTestService = false; integrationSettingsForm.toggleSubmitBtnLabel(false); + expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Save changes'); integrationSettingsForm.toggleSubmitBtnLabel(true); + expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Save changes'); integrationSettingsForm.canTestService = true; integrationSettingsForm.toggleSubmitBtnLabel(false); + expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Save changes'); }); }); @@ -149,6 +153,7 @@ describe('IntegrationSettingsForm', () => { integrationSettingsForm.testSettings(formData) .then(() => { const $flashContainer = $('.flash-container'); + expect($flashContainer.find('.flash-text').text().trim()).toEqual('Test failed. some error'); expect($flashContainer.find('.flash-action')).toBeDefined(); expect($flashContainer.find('.flash-action').text().trim()).toEqual('Save anyway'); @@ -170,6 +175,7 @@ describe('IntegrationSettingsForm', () => { integrationSettingsForm.testSettings(formData) .then(() => { const $flashContainer = $('.flash-container'); + expect($flashContainer.find('.flash-text').text().trim()).toEqual('Validations failed. some error'); expect($flashContainer.find('.flash-action')).toBeDefined(); expect($flashContainer.find('.flash-action').text().trim()).toEqual(''); @@ -208,6 +214,7 @@ describe('IntegrationSettingsForm', () => { integrationSettingsForm.testSettings(formData) .then(() => { const $flashAction = $('.flash-container .flash-action'); + expect($flashAction).toBeDefined(); $flashAction.get(0).click(); diff --git a/spec/javascripts/issuable_spec.js b/spec/javascripts/issuable_spec.js index 57bf746f080..f91510a43d8 100644 --- a/spec/javascripts/issuable_spec.js +++ b/spec/javascripts/issuable_spec.js @@ -8,6 +8,7 @@ describe('Issuable', () => { describe('initBulkUpdate', () => { it('should not set bulkUpdateSidebar', () => { Issuable = new IssuableIndex('issue_'); + expect(Issuable.bulkUpdateSidebar).not.toBeDefined(); }); @@ -17,6 +18,7 @@ describe('Issuable', () => { document.body.appendChild(element); Issuable = new IssuableIndex('issue_'); + expect(Issuable.bulkUpdateSidebar).toBeDefined(); }); }); diff --git a/spec/javascripts/issue_show/components/app_spec.js b/spec/javascripts/issue_show/components/app_spec.js index 36328382448..67d59d5cc5f 100644 --- a/spec/javascripts/issue_show/components/app_spec.js +++ b/spec/javascripts/issue_show/components/app_spec.js @@ -258,6 +258,7 @@ describe('Issuable output', () => { expect( eventHub.$emit, ).toHaveBeenCalledWith('close.form'); + expect( window.Flash, ).toHaveBeenCalledWith('Error updating issue'); @@ -276,6 +277,7 @@ describe('Issuable output', () => { expect( eventHub.$emit, ).toHaveBeenCalledWith('close.form'); + expect( window.Flash, ).toHaveBeenCalledWith('Error updating merge request'); @@ -383,6 +385,7 @@ describe('Issuable output', () => { expect( eventHub.$emit, ).toHaveBeenCalledWith('close.form'); + expect( window.Flash, ).toHaveBeenCalledWith('Error deleting issue'); @@ -422,6 +425,7 @@ describe('Issuable output', () => { it('should render if showInlineEditButton', () => { vm.showInlineEditButton = true; + expect(vm.$el.querySelector('.title-container .note-action-button')).toBeDefined(); }); }); diff --git a/spec/javascripts/issue_show/components/edit_actions_spec.js b/spec/javascripts/issue_show/components/edit_actions_spec.js index 004621f488a..4f4dae87efe 100644 --- a/spec/javascripts/issue_show/components/edit_actions_spec.js +++ b/spec/javascripts/issue_show/components/edit_actions_spec.js @@ -146,6 +146,7 @@ describe('Edit Actions components', () => { expect( eventHub.$emit, ).not.toHaveBeenCalledWith('delete.issuable'); + expect( vm.$el.querySelector('.btn-danger .fa'), ).toBeNull(); diff --git a/spec/javascripts/issue_show/components/title_spec.js b/spec/javascripts/issue_show/components/title_spec.js index 5370f4e1fea..9e6f236b687 100644 --- a/spec/javascripts/issue_show/components/title_spec.js +++ b/spec/javascripts/issue_show/components/title_spec.js @@ -86,12 +86,14 @@ describe('Title component', () => { it('should not show if canUpdate is false', () => { vm.showInlineEditButton = true; vm.canUpdate = false; + expect(vm.$el.querySelector('.btn-edit')).toBeNull(); }); it('should show if showInlineEditButton and canUpdate', () => { vm.showInlineEditButton = true; vm.canUpdate = true; + expect(vm.$el.querySelector('.btn-edit')).toBeDefined(); }); @@ -101,6 +103,7 @@ describe('Title component', () => { Vue.nextTick(() => { vm.$el.querySelector('.btn-edit').click(); + expect(eventHub.$emit).toHaveBeenCalledWith('open.form'); }); }); diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js index 62c71e00334..28c9931f904 100644 --- a/spec/javascripts/issue_spec.js +++ b/spec/javascripts/issue_spec.js @@ -15,6 +15,7 @@ describe('Issue', function() { function expectErrorMessage() { const $flashMessage = $('div.flash-alert'); + expect($flashMessage).toExist(); expect($flashMessage).toBeVisible(); expect($flashMessage).toHaveText('Unable to update this issue at this time.'); @@ -23,6 +24,7 @@ describe('Issue', function() { function expectIssueState(isIssueOpen) { expectVisibility($boxClosed, !isIssueOpen); expectVisibility($boxOpen, isIssueOpen); + expect($btn).toHaveText(isIssueOpen ? 'Close issue' : 'Reopen issue'); } @@ -32,6 +34,7 @@ describe('Issue', function() { } const $available = Issue.$btnNewBranch.find('.available'); + expect($available).toHaveText('New branch'); if (!isPending && canCreate) { @@ -41,6 +44,7 @@ describe('Issue', function() { } const $unavailable = Issue.$btnNewBranch.find('.unavailable'); + expect($unavailable).toHaveText('New branch unavailable'); if (!isPending && !canCreate) { @@ -60,14 +64,17 @@ describe('Issue', function() { function findElements(isIssueInitiallyOpen) { $boxClosed = $('div.status-box-issue-closed'); + expect($boxClosed).toExist(); expect($boxClosed).toHaveText('Closed'); $boxOpen = $('div.status-box-open'); + expect($boxOpen).toExist(); expect($boxOpen).toHaveText('Open'); $btn = $('.js-issuable-close-button'); + expect($btn).toExist(); expect($btn).toHaveText(isIssueInitiallyOpen ? 'Close issue' : 'Reopen issue'); } @@ -135,6 +142,7 @@ describe('Issue', function() { setTimeout(() => { expectIssueState(!isIssueInitiallyOpen); + expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull(); expect(this.$projectIssuesCounter.text()).toBe(isIssueInitiallyOpen ? '1,000' : '1,002'); expectNewBranchButtonState(false, !isIssueInitiallyOpen); @@ -153,8 +161,10 @@ describe('Issue', function() { setTimeout(() => { expectIssueState(isIssueInitiallyOpen); + expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull(); expectErrorMessage(); + expect(this.$projectIssuesCounter.text()).toBe('1,001'); expectNewBranchButtonState(false, isIssueInitiallyOpen); @@ -170,8 +180,10 @@ describe('Issue', function() { setTimeout(() => { expectIssueState(isIssueInitiallyOpen); + expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull(); expectErrorMessage(); + expect(this.$projectIssuesCounter.text()).toBe('1,001'); expectNewBranchButtonState(false, isIssueInitiallyOpen); diff --git a/spec/javascripts/jobs/components/commit_block_spec.js b/spec/javascripts/jobs/components/commit_block_spec.js index 0bcc4ff940f..98eba3ac976 100644 --- a/spec/javascripts/jobs/components/commit_block_spec.js +++ b/spec/javascripts/jobs/components/commit_block_spec.js @@ -34,6 +34,7 @@ describe('Commit block', () => { expect(vm.$el.querySelector('.js-commit-sha').getAttribute('href')).toEqual( props.commit.commit_path, ); + expect(vm.$el.querySelector('.js-commit-sha').textContent.trim()).toEqual( props.commit.short_id, ); @@ -55,6 +56,7 @@ describe('Commit block', () => { expect(vm.$el.querySelector('.js-link-commit').getAttribute('href')).toEqual( props.mergeRequest.path, ); + expect(vm.$el.querySelector('.js-link-commit').textContent.trim()).toEqual( `!${props.mergeRequest.iid}`, ); diff --git a/spec/javascripts/jobs/components/empty_state_spec.js b/spec/javascripts/jobs/components/empty_state_spec.js index 73488eaab9b..0a39709221c 100644 --- a/spec/javascripts/jobs/components/empty_state_spec.js +++ b/spec/javascripts/jobs/components/empty_state_spec.js @@ -56,6 +56,7 @@ describe('Empty State', () => { vm = mountComponent(Component, { ...props, }); + expect(vm.$el.querySelector('.js-job-empty-state-content')).toBeNull(); }); }); @@ -84,6 +85,7 @@ describe('Empty State', () => { ...props, content, }); + expect(vm.$el.querySelector('.js-job-empty-state-action')).toBeNull(); }); }); diff --git a/spec/javascripts/jobs/components/environments_block_spec.js b/spec/javascripts/jobs/components/environments_block_spec.js index 7d836129b13..0866ddd21d8 100644 --- a/spec/javascripts/jobs/components/environments_block_spec.js +++ b/spec/javascripts/jobs/components/environments_block_spec.js @@ -54,6 +54,7 @@ describe('Environments block', () => { expect(vm.$el.textContent.trim()).toEqual( 'This job is an out-of-date deployment to environment. View the most recent deployment #deployment.', ); + expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('bar'); }); }); @@ -110,6 +111,7 @@ describe('Environments block', () => { expect(vm.$el.textContent.trim()).toEqual( 'This job is creating a deployment to environment and will overwrite the latest deployment.', ); + expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('foo'); }); }); @@ -139,6 +141,7 @@ describe('Environments block', () => { }, iconStatus: status, }); + expect(vm.$el.querySelector('.js-environment-link')).toBeNull(); }); }); diff --git a/spec/javascripts/jobs/components/job_log_controllers_spec.js b/spec/javascripts/jobs/components/job_log_controllers_spec.js index 3dcb57d23ce..d527c6708fc 100644 --- a/spec/javascripts/jobs/components/job_log_controllers_spec.js +++ b/spec/javascripts/jobs/components/job_log_controllers_spec.js @@ -199,6 +199,7 @@ describe('Job log controllers', () => { isScrollingDown: false, isTraceSizeVisible: true, }); + expect(vm.$el.querySelector('.js-scroll-bottom').className).not.toContain('animate'); }); }); diff --git a/spec/javascripts/jobs/components/sidebar_spec.js b/spec/javascripts/jobs/components/sidebar_spec.js index a113377b19f..ca4f62bd6ef 100644 --- a/spec/javascripts/jobs/components/sidebar_spec.js +++ b/spec/javascripts/jobs/components/sidebar_spec.js @@ -74,6 +74,7 @@ describe('Sidebar details block', () => { expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual( job.new_issue_path, ); + expect(vm.$el.querySelector('.js-new-issue').textContent.trim()).toEqual('New issue'); }); diff --git a/spec/javascripts/jobs/store/getters_spec.js b/spec/javascripts/jobs/store/getters_spec.js index e262a47b837..46a20122ec8 100644 --- a/spec/javascripts/jobs/store/getters_spec.js +++ b/spec/javascripts/jobs/store/getters_spec.js @@ -46,6 +46,7 @@ describe('Job Store Getters', () => { it('returns created_at key', () => { const created = '2018-08-31T16:20:49.023Z'; localState.job.created_at = created; + expect(getters.headerTime(localState)).toEqual(created); }); }); @@ -64,6 +65,7 @@ describe('Job Store Getters', () => { describe('without status & with callout message', () => { it('returns false', () => { localState.job.callout_message = 'Callout message'; + expect(getters.shouldRenderCalloutMessage(localState)).toEqual(false); }); }); @@ -81,6 +83,7 @@ describe('Job Store Getters', () => { describe('when started equals null', () => { it('returns false', () => { localState.job.started = null; + expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(false); }); }); @@ -88,6 +91,7 @@ describe('Job Store Getters', () => { describe('when started equals string', () => { it('returns true', () => { localState.job.started = '2018-08-31T16:20:49.023Z'; + expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(true); }); }); @@ -103,6 +107,7 @@ describe('Job Store Getters', () => { describe('with an empty object for `deployment_status`', () => { it('returns false', () => { localState.job.deployment_status = {}; + expect(getters.hasEnvironment(localState)).toEqual(false); }); }); diff --git a/spec/javascripts/jobs/store/mutations_spec.js b/spec/javascripts/jobs/store/mutations_spec.js index 701fcc7f4c8..c058a3b3d51 100644 --- a/spec/javascripts/jobs/store/mutations_spec.js +++ b/spec/javascripts/jobs/store/mutations_spec.js @@ -15,6 +15,7 @@ describe('Jobs Store Mutations', () => { describe('SET_JOB_ENDPOINT', () => { it('should set jobEndpoint', () => { mutations[types.SET_JOB_ENDPOINT](stateCopy, 'job/21312321.json'); + expect(stateCopy.jobEndpoint).toEqual('job/21312321.json'); }); }); @@ -22,6 +23,7 @@ describe('Jobs Store Mutations', () => { describe('REQUEST_STATUS_FAVICON', () => { it('should set fetchingStatusFavicon to true', () => { mutations[types.REQUEST_STATUS_FAVICON](stateCopy); + expect(stateCopy.fetchingStatusFavicon).toEqual(true); }); }); @@ -29,6 +31,7 @@ describe('Jobs Store Mutations', () => { describe('RECEIVE_STATUS_FAVICON_SUCCESS', () => { it('should set fetchingStatusFavicon to false', () => { mutations[types.RECEIVE_STATUS_FAVICON_SUCCESS](stateCopy); + expect(stateCopy.fetchingStatusFavicon).toEqual(false); }); }); @@ -36,6 +39,7 @@ describe('Jobs Store Mutations', () => { describe('RECEIVE_STATUS_FAVICON_ERROR', () => { it('should set fetchingStatusFavicon to false', () => { mutations[types.RECEIVE_STATUS_FAVICON_ERROR](stateCopy); + expect(stateCopy.fetchingStatusFavicon).toEqual(false); }); }); @@ -48,6 +52,7 @@ describe('Jobs Store Mutations', () => { mutations[types.RECEIVE_TRACE_SUCCESS](stateCopy, { state: stateLog, }); + expect(stateCopy.traceState).toEqual(stateLog); }); }); @@ -77,6 +82,7 @@ describe('Jobs Store Mutations', () => { size: 511846, complete: true, }); + expect(stateCopy.trace).toEqual(html); expect(stateCopy.traceSize).toEqual(511846); expect(stateCopy.isTraceComplete).toEqual(true); @@ -86,6 +92,7 @@ describe('Jobs Store Mutations', () => { describe('STOP_POLLING_TRACE', () => { it('sets isTraceComplete to true', () => { mutations[types.STOP_POLLING_TRACE](stateCopy); + expect(stateCopy.isTraceComplete).toEqual(true); }); }); @@ -93,6 +100,7 @@ describe('Jobs Store Mutations', () => { describe('RECEIVE_TRACE_ERROR', () => { it('resets trace state and sets error to true', () => { mutations[types.RECEIVE_TRACE_ERROR](stateCopy); + expect(stateCopy.isLoadingTrace).toEqual(false); expect(stateCopy.isTraceComplete).toEqual(true); expect(stateCopy.hasTraceError).toEqual(true); @@ -110,29 +118,35 @@ describe('Jobs Store Mutations', () => { describe('RECEIVE_JOB_SUCCESS', () => { it('sets is loading to false', () => { mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321 }); + expect(stateCopy.isLoading).toEqual(false); }); it('sets hasError to false', () => { mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321 }); + expect(stateCopy.hasError).toEqual(false); }); it('sets job data', () => { mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321 }); + expect(stateCopy.job).toEqual({ id: 1312321 }); }); it('sets selectedStage when the selectedStage is More', () => { expect(stateCopy.selectedStage).toEqual('More'); mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321, stage: 'deploy' }); + expect(stateCopy.selectedStage).toEqual('deploy'); }); it('does not set selectedStage when the selectedStage is not More', () => { stateCopy.selectedStage = 'notify' + expect(stateCopy.selectedStage).toEqual('notify'); mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321, stage: 'deploy' }); + expect(stateCopy.selectedStage).toEqual('notify'); }); }); @@ -178,6 +192,7 @@ describe('Jobs Store Mutations', () => { describe('REQUEST_STAGES', () => { it('sets isLoadingStages to true', () => { mutations[types.REQUEST_STAGES](stateCopy); + expect(stateCopy.isLoadingStages).toEqual(true); }); }); @@ -213,11 +228,13 @@ describe('Jobs Store Mutations', () => { describe('REQUEST_JOBS_FOR_STAGE', () => { it('sets isLoadingStages to true', () => { mutations[types.REQUEST_JOBS_FOR_STAGE](stateCopy, { name: 'deploy' }); + expect(stateCopy.isLoadingJobs).toEqual(true); }); it('sets selectedStage', () => { mutations[types.REQUEST_JOBS_FOR_STAGE](stateCopy, { name: 'deploy' }); + expect(stateCopy.selectedStage).toEqual('deploy'); }) }); diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js index b2b8f64d705..514d6ddeae5 100644 --- a/spec/javascripts/lib/utils/common_utils_spec.js +++ b/spec/javascripts/lib/utils/common_utils_spec.js @@ -42,6 +42,7 @@ describe('common_utils', () => { it('should remove the question mark from the search params', () => { const paramsArray = commonUtils.urlParamsToArray('?test=thing'); + expect(paramsArray[0][0]).not.toBe('?'); }); }); @@ -121,6 +122,7 @@ describe('common_utils', () => { commonUtils.handleLocationHash(); expectGetElementIdToHaveBeenCalledWith('test'); + expect(window.scrollY).toBe(document.getElementById('test').offsetTop); document.getElementById('parent').remove(); @@ -139,6 +141,7 @@ describe('common_utils', () => { expectGetElementIdToHaveBeenCalledWith('test'); expectGetElementIdToHaveBeenCalledWith('user-content-test'); + expect(window.scrollY).toBe(document.getElementById('user-content-test').offsetTop); document.getElementById('parent').remove(); @@ -159,6 +162,7 @@ describe('common_utils', () => { expectGetElementIdToHaveBeenCalledWith('test'); expectGetElementIdToHaveBeenCalledWith('user-content-test'); + expect(window.scrollY).toBe(document.getElementById('user-content-test').offsetTop - 50); expect(window.scrollBy).toHaveBeenCalledWith(0, -50); @@ -222,20 +226,24 @@ describe('common_utils', () => { it('should return valid parameter', () => { const value = commonUtils.getParameterByName('scope'); + expect(commonUtils.getParameterByName('p')).toEqual('2'); expect(value).toBe('all'); }); it('should return invalid parameter', () => { const value = commonUtils.getParameterByName('fakeParameter'); + expect(value).toBe(null); }); it('should return valid paramentes if URL is provided', () => { let value = commonUtils.getParameterByName('foo', 'http://cocteau.twins/?foo=bar'); + expect(value).toBe('bar'); value = commonUtils.getParameterByName('manan', 'http://cocteau.twins/?foo=bar&manan=canchu'); + expect(value).toBe('canchu'); }); }); @@ -395,6 +403,7 @@ describe('common_utils', () => { }) ).catch(done.fail)).then((respBackoff) => { const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout); + expect(timeouts).toEqual([2000, 4000]); expect(respBackoff).toBe(expectedResponseValue); done(); @@ -405,6 +414,7 @@ describe('common_utils', () => { commonUtils.backOff(next => next(), 64000) .catch((errBackoffResp) => { const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout); + expect(timeouts).toEqual([2000, 4000, 8000, 16000, 32000, 32000]); expect(errBackoffResp instanceof Error).toBe(true); expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT'); @@ -450,6 +460,7 @@ describe('common_utils', () => { const favicon = document.getElementById('favicon'); favicon.setAttribute('href', 'new/favicon'); commonUtils.resetFavicon(); + expect(document.getElementById('favicon').getAttribute('href')).toEqual('default/favicon'); }); }); @@ -507,6 +518,7 @@ describe('common_utils', () => { commonUtils.setCiStatusFavicon(BUILD_URL) .catch(() => { const favicon = document.getElementById('favicon'); + expect(favicon.getAttribute('href')).toEqual(faviconDataUrl); done(); }); @@ -520,6 +532,7 @@ describe('common_utils', () => { commonUtils.setCiStatusFavicon(BUILD_URL) .then(() => { const favicon = document.getElementById('favicon'); + expect(favicon.getAttribute('href')).toEqual(faviconWithOverlayDataUrl); done(); }) diff --git a/spec/javascripts/lib/utils/dom_utils_spec.js b/spec/javascripts/lib/utils/dom_utils_spec.js index 867bf5912d1..1fb2e4584a0 100644 --- a/spec/javascripts/lib/utils/dom_utils_spec.js +++ b/spec/javascripts/lib/utils/dom_utils_spec.js @@ -18,6 +18,7 @@ describe('DOM Utils', () => { it('adds class if element exists', () => { const childElement = parentElement.querySelector('.child'); + expect(childElement).not.toBe(null); addClassIfElementExists(childElement, className); @@ -27,6 +28,7 @@ describe('DOM Utils', () => { it('does not throw if element does not exist', () => { const childElement = parentElement.querySelector('.other-child'); + expect(childElement).toBe(null); addClassIfElementExists(childElement, className); diff --git a/spec/javascripts/lib/utils/number_utility_spec.js b/spec/javascripts/lib/utils/number_utility_spec.js index fcf27f6805f..a5099a2a3b8 100644 --- a/spec/javascripts/lib/utils/number_utility_spec.js +++ b/spec/javascripts/lib/utils/number_utility_spec.js @@ -10,6 +10,7 @@ describe('Number Utils', () => { const formattedNumber = formatRelevantDigits('1000.1234567'); const rightFromDecimal = formattedNumber.split('.')[1]; const leftFromDecimal = formattedNumber.split('.')[0]; + expect(rightFromDecimal.length).toBe(4); expect(leftFromDecimal.length).toBe(4); }); @@ -18,6 +19,7 @@ describe('Number Utils', () => { const formattedNumber = formatRelevantDigits('0.1234567'); const rightFromDecimal = formattedNumber.split('.')[1]; const leftFromDecimal = formattedNumber.split('.')[0]; + expect(rightFromDecimal.length).toBe(3); expect(leftFromDecimal.length).toBe(1); }); @@ -26,6 +28,7 @@ describe('Number Utils', () => { const formattedNumber = formatRelevantDigits('10.1234567'); const rightFromDecimal = formattedNumber.split('.')[1]; const leftFromDecimal = formattedNumber.split('.')[0]; + expect(rightFromDecimal.length).toBe(2); expect(leftFromDecimal.length).toBe(2); }); @@ -34,6 +37,7 @@ describe('Number Utils', () => { const formattedNumber = formatRelevantDigits('100.1234567'); const rightFromDecimal = formattedNumber.split('.')[1]; const leftFromDecimal = formattedNumber.split('.')[0]; + expect(rightFromDecimal.length).toBe(1); expect(leftFromDecimal.length).toBe(3); }); diff --git a/spec/javascripts/lib/utils/sticky_spec.js b/spec/javascripts/lib/utils/sticky_spec.js index b87c836654d..694bd136aa3 100644 --- a/spec/javascripts/lib/utils/sticky_spec.js +++ b/spec/javascripts/lib/utils/sticky_spec.js @@ -54,6 +54,7 @@ describe('sticky', () => { expect( el.classList.remove, ).toHaveBeenCalledWith('is-stuck'); + expect( el.classList.contains('is-stuck'), ).toBeFalsy(); diff --git a/spec/javascripts/lib/utils/text_markdown_spec.js b/spec/javascripts/lib/utils/text_markdown_spec.js index 043dd018e0c..73807350679 100644 --- a/spec/javascripts/lib/utils/text_markdown_spec.js +++ b/spec/javascripts/lib/utils/text_markdown_spec.js @@ -95,6 +95,7 @@ describe('init markdown', () => { select }); const expectedText = text.replace(selected, `[${selected}](url)`); + expect(textArea.value).toEqual(expectedText); expect(textArea.selectionStart).toEqual(expectedText.indexOf(select)); expect(textArea.selectionEnd).toEqual(expectedText.indexOf(select) + select.length); @@ -114,6 +115,7 @@ describe('init markdown', () => { select }); const expectedText = initialValue.replace(selected, `[${selected}](url)`); + expect(textArea.value).toEqual(expectedText); expect(textArea.selectionStart).toEqual(expectedText.lastIndexOf(select)); expect(textArea.selectionEnd).toEqual(expectedText.lastIndexOf(select) + select.length); diff --git a/spec/javascripts/line_highlighter_spec.js b/spec/javascripts/line_highlighter_spec.js index 15bb78032b2..84cbb47a69e 100644 --- a/spec/javascripts/line_highlighter_spec.js +++ b/spec/javascripts/line_highlighter_spec.js @@ -1,4 +1,4 @@ -/* eslint-disable no-var, prefer-template, no-else-return, dot-notation, no-return-assign, no-new, one-var, no-underscore-dangle */ +/* eslint-disable no-var, prefer-template, no-else-return, dot-notation, no-return-assign, no-new, no-underscore-dangle */ import $ from 'jquery'; import LineHighlighter from '~/line_highlighter'; @@ -27,39 +27,42 @@ import LineHighlighter from '~/line_highlighter'; describe('behavior', function() { it('highlights one line given in the URL hash', function() { new LineHighlighter({ hash: '#L13' }); - return expect($('#LC13')).toHaveClass(this.css); + + expect($('#LC13')).toHaveClass(this.css); }); it('highlights one line given in the URL hash with given CSS class name', function() { const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' }); + expect(hiliter.highlightLineClass).toBe('hilite'); expect($('#LC13')).toHaveClass('hilite'); expect($('#LC13')).not.toHaveClass('hll'); }); it('highlights a range of lines given in the URL hash', function() { - var line, results; + var line; new LineHighlighter({ hash: '#L5-25' }); + expect($("." + this.css).length).toBe(21); - results = []; for (line = 5; line <= 25; line += 1) { - results.push(expect($("#LC" + line)).toHaveClass(this.css)); + expect($("#LC" + line)).toHaveClass(this.css); } - return results; }); it('scrolls to the first highlighted line on initial load', function() { var spy; spy = spyOn($, 'scrollTo'); new LineHighlighter({ hash: '#L5-25' }); - return expect(spy).toHaveBeenCalledWith('#L5', jasmine.anything()); + + expect(spy).toHaveBeenCalledWith('#L5', jasmine.anything()); }); it('discards click events', function() { var spy; spy = spyOnEvent('a[data-line-number]', 'click'); clickLine(13); - return expect(spy).toHaveBeenPrevented(); + + expect(spy).toHaveBeenPrevented(); }); it('handles garbage input from the hash', function() { @@ -67,7 +70,8 @@ import LineHighlighter from '~/line_highlighter'; func = function() { return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' }); }; - return expect(func).not.toThrow(); + + expect(func).not.toThrow(); }); }); @@ -76,30 +80,36 @@ import LineHighlighter from '~/line_highlighter'; var spy; spy = spyOn(this["class"], 'setHash').and.callThrough(); $('#L13 i').mousedown().click(); + expect(spy).toHaveBeenCalledWith(13); - return expect($('#LC13')).toHaveClass(this.css); + expect($('#LC13')).toHaveClass(this.css); }); describe('without shiftKey', function() { it('highlights one line when clicked', function() { clickLine(13); - return expect($('#LC13')).toHaveClass(this.css); + + expect($('#LC13')).toHaveClass(this.css); }); it('unhighlights previously highlighted lines', function() { clickLine(13); clickLine(20); + expect($('#LC13')).not.toHaveClass(this.css); - return expect($('#LC20')).toHaveClass(this.css); + expect($('#LC20')).toHaveClass(this.css); }); - return it('sets the hash', function() { + + it('sets the hash', function() { var spy; spy = spyOn(this["class"], 'setHash').and.callThrough(); clickLine(13); - return expect(spy).toHaveBeenCalledWith(13); + + expect(spy).toHaveBeenCalledWith(13); }); }); - return describe('with shiftKey', function() { + + describe('with shiftKey', function() { it('sets the hash', function() { var spy; spy = spyOn(this["class"], 'setHash').and.callThrough(); @@ -107,8 +117,9 @@ import LineHighlighter from '~/line_highlighter'; clickLine(20, { shiftKey: true }); + expect(spy).toHaveBeenCalledWith(13); - return expect(spy).toHaveBeenCalledWith(13, 20); + expect(spy).toHaveBeenCalledWith(13, 20); }); describe('without existing highlight', function() { @@ -116,80 +127,82 @@ import LineHighlighter from '~/line_highlighter'; clickLine(13, { shiftKey: true }); + expect($('#LC13')).toHaveClass(this.css); - return expect($("." + this.css).length).toBe(1); + expect($("." + this.css).length).toBe(1); }); - return it('sets the hash', function() { + + it('sets the hash', function() { var spy; spy = spyOn(this["class"], 'setHash'); clickLine(13, { shiftKey: true }); - return expect(spy).toHaveBeenCalledWith(13); + + expect(spy).toHaveBeenCalledWith(13); }); }); describe('with existing single-line highlight', function() { it('uses existing line as last line when target is lesser', function() { - var line, results; + var line; clickLine(20); clickLine(15, { shiftKey: true }); + expect($("." + this.css).length).toBe(6); - results = []; for (line = 15; line <= 20; line += 1) { - results.push(expect($("#LC" + line)).toHaveClass(this.css)); + expect($("#LC" + line)).toHaveClass(this.css); } - return results; }); - return it('uses existing line as first line when target is greater', function() { - var line, results; + + it('uses existing line as first line when target is greater', function() { + var line; clickLine(5); clickLine(10, { shiftKey: true }); + expect($("." + this.css).length).toBe(6); - results = []; for (line = 5; line <= 10; line += 1) { - results.push(expect($("#LC" + line)).toHaveClass(this.css)); + expect($("#LC" + line)).toHaveClass(this.css); } - return results; }); }); - return describe('with existing multi-line highlight', function() { + + describe('with existing multi-line highlight', function() { beforeEach(function() { clickLine(10, { shiftKey: true }); - return clickLine(13, { + clickLine(13, { shiftKey: true }); }); it('uses target as first line when it is less than existing first line', function() { - var line, results; + var line; clickLine(5, { shiftKey: true }); + expect($("." + this.css).length).toBe(6); - results = []; for (line = 5; line <= 10; line += 1) { - results.push(expect($("#LC" + line)).toHaveClass(this.css)); + expect($("#LC" + line)).toHaveClass(this.css); } - return results; }); - return it('uses target as last line when it is greater than existing first line', function() { - var line, results; + + it('uses target as last line when it is greater than existing first line', function() { + var line; clickLine(15, { shiftKey: true }); + expect($("." + this.css).length).toBe(6); - results = []; for (line = 10; line <= 15; line += 1) { - results.push(expect($("#LC" + line)).toHaveClass(this.css)); + expect($("#LC" + line)).toHaveClass(this.css); } - return results; }); }); }); @@ -197,47 +210,58 @@ import LineHighlighter from '~/line_highlighter'; describe('hashToRange', function() { beforeEach(function() { - return this.subject = this["class"].hashToRange; + this.subject = this["class"].hashToRange; }); it('extracts a single line number from the hash', function() { - return expect(this.subject('#L5')).toEqual([5, null]); + + expect(this.subject('#L5')).toEqual([5, null]); }); it('extracts a range of line numbers from the hash', function() { - return expect(this.subject('#L5-15')).toEqual([5, 15]); + + expect(this.subject('#L5-15')).toEqual([5, 15]); }); - return it('returns [null, null] when the hash is not a line number', function() { - return expect(this.subject('#foo')).toEqual([null, null]); + + it('returns [null, null] when the hash is not a line number', function() { + + expect(this.subject('#foo')).toEqual([null, null]); }); }); describe('highlightLine', function() { beforeEach(function() { - return this.subject = this["class"].highlightLine; + this.subject = this["class"].highlightLine; }); it('highlights the specified line', function() { this.subject(13); - return expect($('#LC13')).toHaveClass(this.css); + + expect($('#LC13')).toHaveClass(this.css); }); - return it('accepts a String-based number', function() { + + it('accepts a String-based number', function() { this.subject('13'); - return expect($('#LC13')).toHaveClass(this.css); + + expect($('#LC13')).toHaveClass(this.css); }); }); - return describe('setHash', function() { + + describe('setHash', function() { beforeEach(function() { - return this.subject = this["class"].setHash; + this.subject = this["class"].setHash; }); it('sets the location hash for a single line', function() { this.subject(5); - return expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5'); + + expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5'); }); - return it('sets the location hash for a range', function() { + + it('sets the location hash for a range', function() { this.subject(5, 15); - return expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15'); + + expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15'); }); }); }); diff --git a/spec/javascripts/locale/ensure_single_line_spec.js b/spec/javascripts/locale/ensure_single_line_spec.js index bbefa8f40f3..20b04cab9c8 100644 --- a/spec/javascripts/locale/ensure_single_line_spec.js +++ b/spec/javascripts/locale/ensure_single_line_spec.js @@ -4,6 +4,7 @@ describe('locale', () => { describe('ensureSingleLine', () => { it('should remove newlines at the start of the string', () => { const result = 'Test'; + expect(ensureSingleLine(`\n${result}`)).toBe(result); expect(ensureSingleLine(`\t\n\t${result}`)).toBe(result); expect(ensureSingleLine(`\r\n${result}`)).toBe(result); @@ -14,6 +15,7 @@ describe('locale', () => { it('should remove newlines at the end of the string', () => { const result = 'Test'; + expect(ensureSingleLine(`${result}\n`)).toBe(result); expect(ensureSingleLine(`${result}\t\n\t`)).toBe(result); expect(ensureSingleLine(`${result}\r\n`)).toBe(result); @@ -24,6 +26,7 @@ describe('locale', () => { it('should replace newlines in the middle of the string with a single space', () => { const result = 'Test'; + expect(ensureSingleLine(`${result}\n${result}`)).toBe(`${result} ${result}`); expect(ensureSingleLine(`${result}\t\n\t${result}`)).toBe(`${result} ${result}`); expect(ensureSingleLine(`${result}\r\n${result}`)).toBe(`${result} ${result}`); diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js index 7502f1fa2e1..76590fa5a12 100644 --- a/spec/javascripts/merge_request_spec.js +++ b/spec/javascripts/merge_request_spec.js @@ -37,7 +37,8 @@ import IssuablesHelper from '~/helpers/issuables_helper'; $('input[type=checkbox]') .attr('checked', true)[0] .dispatchEvent(changeEvent); - return expect($('.js-task-list-field').val()).toBe('- [x] Task List Item'); + + expect($('.js-task-list-field').val()).toBe('- [x] Task List Item'); }); it('submits an ajax request on tasklist:changed', done => { diff --git a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js b/spec/javascripts/mini_pipeline_graph_dropdown_spec.js index 1879424c629..952efe140c1 100644 --- a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js +++ b/spec/javascripts/mini_pipeline_graph_dropdown_spec.js @@ -61,6 +61,7 @@ describe('Mini Pipeline Graph Dropdown', () => { new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents(); document.querySelector('.js-builds-dropdown-button').click(); + expect(ajaxSpy.calls.allArgs()[0][0]).toEqual('foobar'); }); diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js index 732c37a24bf..a3477c5f8c6 100644 --- a/spec/javascripts/monitoring/dashboard_spec.js +++ b/spec/javascripts/monitoring/dashboard_spec.js @@ -107,6 +107,7 @@ describe('Dashboard', () => { setTimeout(() => { const dropdownMenuEnvironments = component.$el.querySelectorAll('.dropdown-menu ul li a'); + expect(dropdownMenuEnvironments.length).toEqual(component.store.environmentsData.length); done(); }); @@ -124,6 +125,7 @@ describe('Dashboard', () => { const dropdownIsActiveElement = component.$el.querySelectorAll( '.dropdown-menu ul li a.is-active', ); + expect(dropdownIsActiveElement.length).toEqual(1); expect(dropdownIsActiveElement[0].textContent.trim()).toEqual( component.currentEnvironmentName, diff --git a/spec/javascripts/monitoring/graph_path_spec.js b/spec/javascripts/monitoring/graph_path_spec.js index 5f270c5cfe9..37303c11173 100644 --- a/spec/javascripts/monitoring/graph_path_spec.js +++ b/spec/javascripts/monitoring/graph_path_spec.js @@ -45,9 +45,11 @@ describe('Monitoring Paths', () => { }); component.lineStyle = 'dashed'; + expect(component.strokeDashArray).toBe('3, 1'); component.lineStyle = 'dotted'; + expect(component.strokeDashArray).toBe('1, 1'); }); }); diff --git a/spec/javascripts/monitoring/graph_spec.js b/spec/javascripts/monitoring/graph_spec.js index 99180e4d303..4cc18afdf24 100644 --- a/spec/javascripts/monitoring/graph_spec.js +++ b/spec/javascripts/monitoring/graph_spec.js @@ -49,6 +49,7 @@ describe('Graph', () => { }); const transformedHeight = `${component.graphHeight - 100}`; + expect(component.axisTransform.indexOf(transformedHeight)).not.toEqual(-1); }); @@ -62,6 +63,7 @@ describe('Graph', () => { }); const viewBoxArray = component.outerViewBox.split(' '); + expect(typeof component.outerViewBox).toEqual('string'); expect(viewBoxArray[2]).toEqual(component.graphWidth.toString()); expect(viewBoxArray[3]).toEqual((component.graphHeight - 50).toString()); @@ -99,6 +101,7 @@ describe('Graph', () => { component.seriesUnderMouse = component.timeSeries; component.positionFlag(); + expect(component.currentData).toBe(component.timeSeries[0].values[10]); }); }); diff --git a/spec/javascripts/monitoring/monitoring_store_spec.js b/spec/javascripts/monitoring/monitoring_store_spec.js index ccdf4eda563..c0c20ca4a7f 100644 --- a/spec/javascripts/monitoring/monitoring_store_spec.js +++ b/spec/javascripts/monitoring/monitoring_store_spec.js @@ -17,6 +17,7 @@ describe('MonitoringStore', function () { it('contains deployment data', () => { this.store.storeDeploymentData(deploymentData); + expect(this.store.deploymentData).toBeDefined(); expect(this.store.deploymentData.length).toEqual(3); expect(typeof this.store.deploymentData[0]).toEqual('object'); @@ -24,6 +25,7 @@ describe('MonitoringStore', function () { it('only stores environment data that contains deployments', () => { this.store.storeEnvironmentsData(environmentData); + expect(this.store.environmentsData.length).toEqual(2); }); }); diff --git a/spec/javascripts/new_branch_spec.js b/spec/javascripts/new_branch_spec.js index 85419e640d8..e17f340831a 100644 --- a/spec/javascripts/new_branch_spec.js +++ b/spec/javascripts/new_branch_spec.js @@ -5,14 +5,14 @@ import NewBranchForm from '~/new_branch_form'; (function() { describe('Branch', function() { - return describe('create a new branch', function() { + describe('create a new branch', function() { var expectToHaveError, fillNameWith; preloadFixtures('branches/new_branch.html.raw'); fillNameWith = function(value) { return $('.js-branch-name').val(value).trigger('blur'); }; expectToHaveError = function(error) { - return expect($('.js-branch-name-error span').text()).toEqual(error); + expect($('.js-branch-name-error span').text()).toEqual(error); }; beforeEach(function() { loadFixtures('branches/new_branch.html.raw'); @@ -164,28 +164,35 @@ import NewBranchForm from '~/new_branch_form'; it("removes the error message when is a valid name", function() { fillNameWith('foo?bar'); + expect($('.js-branch-name-error span').length).toEqual(1); fillNameWith('foobar'); - return expect($('.js-branch-name-error span').length).toEqual(0); + + expect($('.js-branch-name-error span').length).toEqual(0); }); it("can have dashes anywhere", function() { fillNameWith('-foo-bar-zoo-'); - return expect($('.js-branch-name-error span').length).toEqual(0); + + expect($('.js-branch-name-error span').length).toEqual(0); }); it("can have underscores anywhere", function() { fillNameWith('_foo_bar_zoo_'); - return expect($('.js-branch-name-error span').length).toEqual(0); + + expect($('.js-branch-name-error span').length).toEqual(0); }); it("can have numbers anywhere", function() { fillNameWith('1foo2bar3zoo4'); - return expect($('.js-branch-name-error span').length).toEqual(0); + + expect($('.js-branch-name-error span').length).toEqual(0); }); - return it("can be only letters", function() { + + it("can be only letters", function() { fillNameWith('foo'); - return expect($('.js-branch-name-error span').length).toEqual(0); + + expect($('.js-branch-name-error span').length).toEqual(0); }); }); }); diff --git a/spec/javascripts/notes/components/comment_form_spec.js b/spec/javascripts/notes/components/comment_form_spec.js index 155c91dcc46..2b7f550d266 100644 --- a/spec/javascripts/notes/components/comment_form_spec.js +++ b/spec/javascripts/notes/components/comment_form_spec.js @@ -51,6 +51,7 @@ describe('issue_comment_form component', () => { spyOn(vm, 'stopPolling'); vm.handleSave(); + expect(vm.isSubmitting).toEqual(true); expect(vm.note).toEqual(''); expect(vm.saveNote).toHaveBeenCalled(); @@ -77,10 +78,14 @@ describe('issue_comment_form component', () => { vm.handleSave(); Vue.nextTick() - .then(() => expect(actionButton.disabled).toBeTruthy()) + .then(() => { + expect(actionButton.disabled).toBeTruthy(); + }) .then(saveNotePromise) .then(Vue.nextTick) - .then(() => expect(actionButton.disabled).toBeFalsy()) + .then(() => { + expect(actionButton.disabled).toBeFalsy(); + }) .then(done) .catch(done.fail); }); @@ -121,6 +126,7 @@ describe('issue_comment_form component', () => { it('should link to markdown docs', () => { const { markdownDocsPath } = notesDataMock; + expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual( 'Markdown', ); @@ -128,6 +134,7 @@ describe('issue_comment_form component', () => { it('should link to quick actions docs', () => { const { quickActionsDocsPath } = notesDataMock; + expect( vm.$el.querySelector(`a[href="${quickActionsDocsPath}"]`).textContent.trim(), ).toEqual('quick actions'); @@ -215,6 +222,7 @@ describe('issue_comment_form component', () => { expect(vm.$el.querySelector('.btn-comment-and-close').textContent.trim()).toEqual( 'Comment & close issue', ); + expect(vm.$el.querySelector('.js-note-discard')).toBeDefined(); done(); }); diff --git a/spec/javascripts/notes/components/note_app_spec.js b/spec/javascripts/notes/components/note_app_spec.js index 7eb4d3aed29..3e289a6b8e6 100644 --- a/spec/javascripts/notes/components/note_app_spec.js +++ b/spec/javascripts/notes/components/note_app_spec.js @@ -223,6 +223,7 @@ describe('note_app', () => { it('should render markdown docs url', () => { const { markdownDocsPath } = mockData.notesDataMock; + expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual( 'Markdown', ); @@ -230,6 +231,7 @@ describe('note_app', () => { it('should render quick action docs url', () => { const { quickActionsDocsPath } = mockData.notesDataMock; + expect(vm.$el.querySelector(`a[href="${quickActionsDocsPath}"]`).textContent.trim()).toEqual( 'quick actions', ); diff --git a/spec/javascripts/notes/components/note_form_spec.js b/spec/javascripts/notes/components/note_form_spec.js index eefd9ddd63c..5db20fd285f 100644 --- a/spec/javascripts/notes/components/note_form_spec.js +++ b/spec/javascripts/notes/components/note_form_spec.js @@ -76,6 +76,7 @@ describe('issue_note_form component', () => { it('should link to markdown docs', () => { const { markdownDocsPath } = notesDataMock; + expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual( 'Markdown', ); diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js index 40b5f009ceb..7c8ee69a984 100644 --- a/spec/javascripts/notes/components/noteable_discussion_spec.js +++ b/spec/javascripts/notes/components/noteable_discussion_spec.js @@ -144,6 +144,7 @@ describe('noteable_discussion component', () => { }; const note = vm.componentData(data); + expect(note).toEqual(data.notes[0]); }); @@ -155,6 +156,7 @@ describe('noteable_discussion component', () => { }; const note = vm.componentData(data); + expect(note).toEqual(data); }); }); diff --git a/spec/javascripts/notes/components/noteable_note_spec.js b/spec/javascripts/notes/components/noteable_note_spec.js index a31d17cacbb..8ade6fc2ced 100644 --- a/spec/javascripts/notes/components/noteable_note_spec.js +++ b/spec/javascripts/notes/components/noteable_note_spec.js @@ -36,6 +36,7 @@ describe('issue_note', () => { it('should render note header content', () => { const el = vm.$el.querySelector('.note-header .note-header-author-name'); + expect(el.textContent.trim()).toEqual(note.author.name); }); diff --git a/spec/javascripts/notes/stores/getters_spec.js b/spec/javascripts/notes/stores/getters_spec.js index 7f8ede51508..f853f9ff088 100644 --- a/spec/javascripts/notes/stores/getters_spec.js +++ b/spec/javascripts/notes/stores/getters_spec.js @@ -205,6 +205,7 @@ describe('Getters Notes Store', () => { '123', '456', ]); + expect(getters.unresolvedDiscussionsIdsOrdered(state, localGetters)(undefined)).toEqual([ '123', '456', diff --git a/spec/javascripts/notes/stores/mutation_spec.js b/spec/javascripts/notes/stores/mutation_spec.js index 1ecfe914859..9d652ba9f1e 100644 --- a/spec/javascripts/notes/stores/mutation_spec.js +++ b/spec/javascripts/notes/stores/mutation_spec.js @@ -30,11 +30,13 @@ describe('Notes Store mutations', () => { expect(state).toEqual({ discussions: [noteData], }); + expect(state.discussions.length).toBe(1); }); it('should not add the same note to the notes array', () => { mutations.ADD_NEW_NOTE(state, note); + expect(state.discussions.length).toBe(1); }); }); @@ -106,6 +108,7 @@ describe('Notes Store mutations', () => { }; mutations.SET_NOTES_DATA(state, notesDataMock); + expect(state.notesData).toEqual(notesDataMock); }); }); @@ -117,6 +120,7 @@ describe('Notes Store mutations', () => { }; mutations.SET_NOTEABLE_DATA(state, noteableDataMock); + expect(state.noteableData).toEqual(noteableDataMock); }); }); @@ -128,6 +132,7 @@ describe('Notes Store mutations', () => { }; mutations.SET_USER_DATA(state, userDataMock); + expect(state.userData).toEqual(userDataMock); }); }); @@ -151,6 +156,7 @@ describe('Notes Store mutations', () => { }; mutations.SET_INITIAL_DISCUSSIONS(state, [note, legacyNote]); + expect(state.discussions[0].id).toEqual(note.id); expect(state.discussions[1].notes[0].note).toBe(legacyNote.notes[0].note); expect(state.discussions[2].notes[0].note).toBe(legacyNote.notes[1].note); @@ -200,6 +206,7 @@ describe('Notes Store mutations', () => { }; mutations.SET_LAST_FETCHED_AT(state, 'timestamp'); + expect(state.lastFetchedAt).toEqual('timestamp'); }); }); @@ -211,6 +218,7 @@ describe('Notes Store mutations', () => { }; mutations.SET_TARGET_NOTE_HASH(state, 'hash'); + expect(state.targetNoteHash).toEqual('hash'); }); }); @@ -221,6 +229,7 @@ describe('Notes Store mutations', () => { discussions: [], }; mutations.SHOW_PLACEHOLDER_NOTE(state, note); + expect(state.discussions[0].isPlaceholderNote).toEqual(true); }); }); @@ -261,6 +270,7 @@ describe('Notes Store mutations', () => { awardName: 'bath_tone3', }; mutations.TOGGLE_AWARD(state, data); + expect(state.discussions[0].award_emoji.length).toEqual(2); }); }); @@ -316,6 +326,7 @@ describe('Notes Store mutations', () => { }; mutations.CLOSE_ISSUE(state); + expect(state.noteableData.state).toEqual('closed'); }); }); @@ -333,6 +344,7 @@ describe('Notes Store mutations', () => { }; mutations.REOPEN_ISSUE(state); + expect(state.noteableData.state).toEqual('reopened'); }); }); @@ -350,6 +362,7 @@ describe('Notes Store mutations', () => { }; mutations.TOGGLE_STATE_BUTTON_LOADING(state, true); + expect(state.isToggleStateButtonLoading).toEqual(true); }); @@ -365,6 +378,7 @@ describe('Notes Store mutations', () => { }; mutations.TOGGLE_STATE_BUTTON_LOADING(state, false); + expect(state.isToggleStateButtonLoading).toEqual(false); }); }); @@ -376,6 +390,7 @@ describe('Notes Store mutations', () => { }; mutations.SET_NOTES_FETCHED_STATE(state, true); + expect(state.isNotesFetched).toEqual(true); }); }); diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index 7bfbca83c77..259b9746fe3 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -123,9 +123,11 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; it('autosizes after comment submission', function() { $(textarea).text('This is an example comment note'); + expect(this.autoSizeSpy).not.toHaveBeenTriggered(); $('.js-comment-button').click(); + expect(this.autoSizeSpy).toHaveBeenTriggered(); }); @@ -136,6 +138,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; deferred.reject(); $('.js-comment-button').click(); + expect($(textarea).val()).toEqual('A comment with `markup`.'); }); }); @@ -538,6 +541,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; mockNotesPost(); $('.js-comment-button').click(); + expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0); }); @@ -556,6 +560,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; describe('postComment', () => { it('disables the submit button', done => { const $submitButton = $form.find('.js-comment-submit-button'); + expect($submitButton).not.toBeDisabled(); const dummyEvent = { preventDefault() {}, @@ -637,6 +642,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; .then(timeoutPromise) .then(() => { const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`); + expect($updatedNoteEl.hasClass('.being-posted')).toEqual(false); // Remove being-posted visuals expect( $updatedNoteEl @@ -644,6 +650,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; .text() .trim(), ).toEqual(sampleComment); // See if comment reverted back to original + expect($('.flash-container').is(':visible')).toEqual(true); // Flash error message shown done(); @@ -749,6 +756,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; const $updatedNoteEl = $notesContainer .find(`#note_${note.id}`) .find('.js-task-list-container'); + expect( $updatedNoteEl .find('.note-text') @@ -860,6 +868,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; it('should return executing quick action description when note has single quick action', () => { const sampleComment = '/close'; + expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe( 'Applying command to close this issue', ); @@ -867,6 +876,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; it('should return generic multiple quick action description when note has multiple quick actions', () => { const sampleComment = '/close\n/title [Duplicate] Issue foobar'; + expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe( 'Applying multiple commands', ); @@ -874,6 +884,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; it('should return generic quick action description when available quick actions list is not populated', () => { const sampleComment = '/close\n/title [Duplicate] Issue foobar'; + expect(this.notes.getQuickActionDescription(sampleComment)).toBe('Applying command'); }); }); @@ -907,6 +918,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; $tempNote.find('.timeline-icon > a, .note-header-info > a').each(function() { expect($(this).attr('href')).toEqual(`/${currentUsername}`); }); + expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar); expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy(); expect( @@ -915,12 +927,14 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; .text() .trim(), ).toEqual(currentUserFullname); + expect( $tempNoteHeader .find('.note-headline-light') .text() .trim(), ).toEqual(`@${currentUsername}`); + expect( $tempNote .find('.note-body .note-text p') @@ -953,6 +967,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; currentUserAvatar, }); const $tempNoteHeader = $tempNote.find('.note-header'); + expect( $tempNoteHeader .find('.d-none.d-sm-inline-block') diff --git a/spec/javascripts/pager_spec.js b/spec/javascripts/pager_spec.js index 04f2e7ef4f9..93efc139254 100644 --- a/spec/javascripts/pager_spec.js +++ b/spec/javascripts/pager_spec.js @@ -30,6 +30,7 @@ describe('pager', () => { const href = `${gl.TEST_HOST}/some_list.json`; setFixtures(`<div class="content_list" data-href="${href}"></div>`); Pager.init(); + expect(Pager.url).toBe(href); }); @@ -37,12 +38,14 @@ describe('pager', () => { const href = `${gl.TEST_HOST}/some_list`; spyOnDependency(Pager, 'removeParams').and.returnValue(href); Pager.init(); + expect(Pager.url).toBe(href); }); it('should get initial offset from query parameter', () => { window.history.replaceState({}, null, '?offset=100'); Pager.init(); + expect(Pager.offset).toBe(100); }); @@ -51,6 +54,7 @@ describe('pager', () => { const href = `${gl.TEST_HOST}/some_list?filter=test`; const removeParams = spyOnDependency(Pager, 'removeParams').and.returnValue(href); Pager.init(); + expect(removeParams).toHaveBeenCalledWith(['limit', 'offset']); expect(Pager.url).toEqual(href); }); @@ -132,6 +136,7 @@ describe('pager', () => { offset: 100, }, }); + expect(url).toBe('/some_list'); done(); diff --git a/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js b/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js index b0dc6ccc3d4..0195ffcb52e 100644 --- a/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js +++ b/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js @@ -8,7 +8,9 @@ describe('Abuse Reports', () => { let $messages; - const assertMaxLength = $message => expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH); + const assertMaxLength = $message => { + expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH); + }; const findMessage = searchText => $messages.filter( (index, element) => element.innerText.indexOf(searchText) > -1, ).first(); @@ -23,18 +25,21 @@ describe('Abuse Reports', () => { it('should truncate long messages', () => { const $longMessage = findMessage('LONG MESSAGE'); + expect($longMessage.data('originalMessage')).toEqual(jasmine.anything()); assertMaxLength($longMessage); }); it('should not truncate short messages', () => { const $shortMessage = findMessage('SHORT MESSAGE'); + expect($shortMessage.data('originalMessage')).not.toEqual(jasmine.anything()); }); it('should allow clicking a truncated message to expand and collapse the full message', () => { const $longMessage = findMessage('LONG MESSAGE'); $longMessage.click(); + expect($longMessage.data('originalMessage').length).toEqual($longMessage.text().length); $longMessage.click(); assertMaxLength($longMessage); diff --git a/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js b/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js index 4dbfd8f0eaa..e3dcd55759a 100644 --- a/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js +++ b/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js @@ -24,6 +24,7 @@ describe('AccountAndLimits', () => { it('is checked', (done) => { if (!$userDefaultExternal.prop('checked')) $userDefaultExternal.click(); + expect($userDefaultExternal.prop('checked')).toBeTruthy(); expect($userInternalRegex.placeholder).toEqual(PLACEHOLDER_USER_EXTERNAL_DEFAULT_TRUE); expect($userInternalRegex.readOnly).toBeFalsy(); diff --git a/spec/javascripts/pages/profiles/show/emoji_menu_spec.js b/spec/javascripts/pages/profiles/show/emoji_menu_spec.js index b70368fc92f..864bda65736 100644 --- a/spec/javascripts/pages/profiles/show/emoji_menu_spec.js +++ b/spec/javascripts/pages/profiles/show/emoji_menu_spec.js @@ -81,6 +81,7 @@ describe('EmojiMenu', () => { 'mouseenter focus', jasmine.anything(), ); + expect(emojiMenu.registerEventListener).toHaveBeenCalledWith( 'on', jasmine.anything(), @@ -107,6 +108,7 @@ describe('EmojiMenu', () => { it('renders the menu with custom menu class', () => { const menuElement = () => document.body.querySelector(`.emoji-menu.${dummyMenuClass} .emoji-menu-content`); + expect(menuElement()).toBe(null); emojiMenu.createEmojiMenu(); diff --git a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js index 4655e29eed0..cbd5afaede9 100644 --- a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js +++ b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js @@ -85,6 +85,7 @@ describe('Interval Pattern Input Component', function () { it('prop initialCronInterval is set', function () { const defaultInitialCronInterval = ''; + expect(this.intervalPatternComponent.initialCronInterval).toBe(defaultInitialCronInterval); }); @@ -148,6 +149,7 @@ describe('Interval Pattern Input Component', function () { Vue.nextTick(() => { const intervalWithSpaceAppended = `${cronIntervalPresets.everyMonth} `; + expect(this.intervalPatternComponent.cronInterval).toBe(intervalWithSpaceAppended); expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(intervalWithSpaceAppended); done(); diff --git a/spec/javascripts/pdf/page_spec.js b/spec/javascripts/pdf/page_spec.js index a207f2afce6..ef967210b65 100644 --- a/spec/javascripts/pdf/page_spec.js +++ b/spec/javascripts/pdf/page_spec.js @@ -34,6 +34,7 @@ describe('Page component', () => { page: testPage, number: 1, }); + expect(vm.rendering).toBe(true); promise diff --git a/spec/javascripts/pipelines/pipeline_store_spec.js b/spec/javascripts/pipelines/pipeline_store_spec.js index ab2287cc344..1d5754d1f05 100644 --- a/spec/javascripts/pipelines/pipeline_store_spec.js +++ b/spec/javascripts/pipelines/pipeline_store_spec.js @@ -20,6 +20,7 @@ describe('Pipeline Store', () => { it('should store received object', () => { store.storePipeline({ foo: 'bar' }); + expect(store.state.pipeline).toEqual({ foo: 'bar' }); }); }); diff --git a/spec/javascripts/pipelines/pipeline_url_spec.js b/spec/javascripts/pipelines/pipeline_url_spec.js index ddd580ae8b7..c9011b403b7 100644 --- a/spec/javascripts/pipelines/pipeline_url_spec.js +++ b/spec/javascripts/pipelines/pipeline_url_spec.js @@ -38,6 +38,7 @@ describe('Pipeline Url Component', () => { expect(component.$el.querySelector('.js-pipeline-url-link').getAttribute('href')).toEqual( 'foo', ); + expect(component.$el.querySelector('.js-pipeline-url-link span').textContent).toEqual('#1'); }); @@ -66,6 +67,7 @@ describe('Pipeline Url Component', () => { expect(component.$el.querySelector('.js-pipeline-url-user').getAttribute('href')).toEqual( mockData.pipeline.user.web_url, ); + expect(image.getAttribute('data-original-title')).toEqual(mockData.pipeline.user.name); expect(image.getAttribute('src')).toEqual(`${mockData.pipeline.user.avatar_url}?width=20`); }); @@ -105,6 +107,7 @@ describe('Pipeline Url Component', () => { 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/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js index 0566bc55693..b5c62178642 100644 --- a/spec/javascripts/pipelines/pipelines_actions_spec.js +++ b/spec/javascripts/pipelines/pipelines_actions_spec.js @@ -31,11 +31,13 @@ describe('Pipelines Actions dropdown', () => { it('renders a dropdown with the provided actions', () => { const dropdownItems = vm.$el.querySelectorAll('.dropdown-menu li'); + expect(dropdownItems.length).toEqual(actions.length); }); it("renders a disabled action when it's not playable", () => { const dropdownItem = vm.$el.querySelector('.dropdown-menu li:last-child button'); + expect(dropdownItem).toBeDisabled(); }); }); diff --git a/spec/javascripts/pipelines/pipelines_spec.js b/spec/javascripts/pipelines/pipelines_spec.js index ab4c00a79ef..b788049311f 100644 --- a/spec/javascripts/pipelines/pipelines_spec.js +++ b/spec/javascripts/pipelines/pipelines_spec.js @@ -371,18 +371,23 @@ describe('Pipelines', () => { expect( vm.$el.querySelector('.js-pipelines-tab-pending').textContent.trim(), ).toContain('Pending'); + expect( vm.$el.querySelector('.js-pipelines-tab-all').textContent.trim(), ).toContain('All'); + expect( vm.$el.querySelector('.js-pipelines-tab-running').textContent.trim(), ).toContain('Running'); + expect( vm.$el.querySelector('.js-pipelines-tab-finished').textContent.trim(), ).toContain('Finished'); + expect( vm.$el.querySelector('.js-pipelines-tab-branches').textContent.trim(), ).toContain('Branches'); + expect( vm.$el.querySelector('.js-pipelines-tab-tags').textContent.trim(), ).toContain('Tags'); @@ -415,6 +420,7 @@ describe('Pipelines', () => { vm.$nextTick(() => { vm.$el.querySelector('.js-next-button a').click(); + expect(vm.updateContent).toHaveBeenCalledWith({ scope: 'all', page: '2' }); done(); diff --git a/spec/javascripts/pipelines/pipelines_store_spec.js b/spec/javascripts/pipelines/pipelines_store_spec.js index 10ff0c6bb84..ce21f788ed5 100644 --- a/spec/javascripts/pipelines/pipelines_store_spec.js +++ b/spec/javascripts/pipelines/pipelines_store_spec.js @@ -16,12 +16,14 @@ describe('Pipelines Store', () => { 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); }); }); @@ -29,6 +31,7 @@ describe('Pipelines Store', () => { describe('storeCount', () => { it('should use the default parameter if none is provided', () => { store.storeCount(); + expect(store.state.count).toEqual({}); }); @@ -43,6 +46,7 @@ describe('Pipelines Store', () => { describe('storePagination', () => { it('should use the default parameter if none is provided', () => { store.storePagination(); + expect(store.state.pageInfo).toEqual({}); }); @@ -66,6 +70,7 @@ describe('Pipelines Store', () => { }; store.storePagination(pagination); + expect(store.state.pageInfo).toEqual(expectedResult); }); }); diff --git a/spec/javascripts/pipelines/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js index 42795f5c134..fbd87506326 100644 --- a/spec/javascripts/pipelines/pipelines_table_row_spec.js +++ b/spec/javascripts/pipelines/pipelines_table_row_spec.js @@ -37,6 +37,7 @@ describe('Pipelines Table Row', () => { it('should render a table row', () => { component = buildComponent(pipeline); + expect(component.$el.getAttribute('class')).toContain('gl-responsive-table-row'); }); @@ -97,6 +98,7 @@ describe('Pipelines Table Row', () => { component = buildComponent(pipeline); const commitLink = component.$el.querySelector('.branch-commit .commit-sha'); + expect(commitLink.getAttribute('href')).toEqual(pipeline.commit.commit_path); }); @@ -177,6 +179,7 @@ describe('Pipelines Table Row', () => { expect(component.$el.querySelector('.js-pipelines-retry-button')).not.toBeNull(); expect(component.$el.querySelector('.js-pipelines-cancel-button')).not.toBeNull(); const dropdownMenu = component.$el.querySelectorAll('.dropdown-menu'); + expect(dropdownMenu).toContainText(scheduledJobAction.name); }); @@ -186,6 +189,7 @@ describe('Pipelines Table Row', () => { }); component.$el.querySelector('.js-pipelines-retry-button').click(); + expect(component.isRetrying).toEqual(true); }); diff --git a/spec/javascripts/pipelines/pipelines_table_spec.js b/spec/javascripts/pipelines/pipelines_table_spec.js index d21ba35e96d..e0582acb954 100644 --- a/spec/javascripts/pipelines/pipelines_table_spec.js +++ b/spec/javascripts/pipelines/pipelines_table_spec.js @@ -54,6 +54,7 @@ describe('Pipelines Table', () => { viewType: 'root', }, }).$mount(); + expect(component.$el.querySelectorAll('.commit.gl-responsive-table-row').length).toEqual(0); }); }); diff --git a/spec/javascripts/pipelines/stage_spec.js b/spec/javascripts/pipelines/stage_spec.js index 3f6789759ae..7f28f310b43 100644 --- a/spec/javascripts/pipelines/stage_spec.js +++ b/spec/javascripts/pipelines/stage_spec.js @@ -53,6 +53,7 @@ describe('Pipelines stage component', () => { expect( component.$el.querySelector('.js-builds-dropdown-container ul').textContent.trim(), ).toContain(stageReply.latest_statuses[0].name); + expect(eventHub.$emit).toHaveBeenCalledWith('clickedDropdown'); done(); }, 0); diff --git a/spec/javascripts/pretty_time_spec.js b/spec/javascripts/pretty_time_spec.js index 084ffe08917..158cd76dd13 100644 --- a/spec/javascripts/pretty_time_spec.js +++ b/spec/javascripts/pretty_time_spec.js @@ -122,11 +122,13 @@ describe('prettyTime methods', () => { describe('abbreviateTime', () => { it('should abbreviate stringified times for weeks', () => { const fullTimeString = '1w 3d 4h 5m'; + expect(abbreviateTime(fullTimeString)).toBe('1w'); }); it('should abbreviate stringified times for non-weeks', () => { const fullTimeString = '0w 3d 4h 5m'; + expect(abbreviateTime(fullTimeString)).toBe('3d'); }); }); diff --git a/spec/javascripts/profile/account/components/delete_account_modal_spec.js b/spec/javascripts/profile/account/components/delete_account_modal_spec.js index a0939ff5c20..afd9ad9b2ba 100644 --- a/spec/javascripts/profile/account/components/delete_account_modal_spec.js +++ b/spec/javascripts/profile/account/components/delete_account_modal_spec.js @@ -53,6 +53,7 @@ describe('DeleteAccountModal component', () => { expect(vm.enteredPassword).toBe(input.value); expect(submitButton).toHaveAttr('disabled', 'disabled'); submitButton.click(); + expect(form.submit).not.toHaveBeenCalled(); }) .then(done) @@ -70,6 +71,7 @@ describe('DeleteAccountModal component', () => { expect(vm.enteredPassword).toBe(input.value); expect(submitButton).not.toHaveAttr('disabled', 'disabled'); submitButton.click(); + expect(form.submit).toHaveBeenCalled(); }) .then(done) @@ -103,6 +105,7 @@ describe('DeleteAccountModal component', () => { expect(vm.enteredUsername).toBe(input.value); expect(submitButton).toHaveAttr('disabled', 'disabled'); submitButton.click(); + expect(form.submit).not.toHaveBeenCalled(); }) .then(done) @@ -120,6 +123,7 @@ describe('DeleteAccountModal component', () => { expect(vm.enteredUsername).toBe(input.value); expect(submitButton).not.toHaveAttr('disabled', 'disabled'); submitButton.click(); + expect(form.submit).toHaveBeenCalled(); }) .then(done) diff --git a/spec/javascripts/profile/account/components/update_username_spec.js b/spec/javascripts/profile/account/components/update_username_spec.js index 5311499fb73..9cdd01fc85a 100644 --- a/spec/javascripts/profile/account/components/update_username_spec.js +++ b/spec/javascripts/profile/account/components/update_username_spec.js @@ -113,6 +113,7 @@ describe('UpdateUsername component', () => { Vue.nextTick() .then(() => { confirmModalBtn.click(); + expect(axios.put).toHaveBeenCalledWith(actionUrl, { user: { username: newUsername } }); }) .then(done) diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js index 3d1a0b87bb8..0cae29c2613 100644 --- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js +++ b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js @@ -48,6 +48,7 @@ describe('GkeProjectIdDropdown', () => { it('returns project billing validation text', () => { vm.setIsValidatingProjectBilling(true); + expect(vm.toggleText).toBe(LABELS.VALIDATING_PROJECT_BILLING); }); diff --git a/spec/javascripts/registry/components/table_registry_spec.js b/spec/javascripts/registry/components/table_registry_spec.js index 6aa61afc445..d9f9d71307e 100644 --- a/spec/javascripts/registry/components/table_registry_spec.js +++ b/spec/javascripts/registry/components/table_registry_spec.js @@ -29,6 +29,7 @@ describe('table registry', () => { it('should render registry tag', () => { const textRendered = vm.$el.querySelector('.table tbody tr').textContent.trim().replace(/\s\s+/g, ' '); + expect(textRendered).toContain(repoPropsData.list[0].tag); expect(textRendered).toContain(repoPropsData.list[0].shortRevision); expect(textRendered).toContain(repoPropsData.list[0].layers); diff --git a/spec/javascripts/registry/stores/mutations_spec.js b/spec/javascripts/registry/stores/mutations_spec.js index 2e4c0659daa..e19fe7a27cf 100644 --- a/spec/javascripts/registry/stores/mutations_spec.js +++ b/spec/javascripts/registry/stores/mutations_spec.js @@ -18,6 +18,7 @@ describe('Mutations Registry Store', () => { it('should set the main endpoint', () => { const expectedState = Object.assign({}, mockState, { endpoint: 'foo' }); mutations[types.SET_MAIN_ENDPOINT](mockState, 'foo'); + expect(mockState).toEqual(expectedState); }); }); @@ -25,6 +26,7 @@ describe('Mutations Registry Store', () => { describe('SET_REPOS_LIST', () => { it('should set a parsed repository list', () => { mutations[types.SET_REPOS_LIST](mockState, reposServerResponse); + expect(mockState.repos).toEqual(parsedReposServerResponse); }); }); @@ -32,6 +34,7 @@ describe('Mutations Registry Store', () => { describe('TOGGLE_MAIN_LOADING', () => { it('should set a parsed repository list', () => { mutations[types.TOGGLE_MAIN_LOADING](mockState); + expect(mockState.isLoading).toEqual(true); }); }); @@ -75,6 +78,7 @@ describe('Mutations Registry Store', () => { }); mutations[types.TOGGLE_REGISTRY_LIST_LOADING](mockState, mockState.repos[0]); + expect(mockState.repos[0].isLoading).toEqual(true); }); }); diff --git a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js index 333cefe5f8a..f58515daa4f 100644 --- a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js +++ b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js @@ -42,6 +42,7 @@ describe('Grouped Test Reports App', () => { expect(vm.$el.textContent).toContain( 'rspec:pg found no changed test results out of 8 total tests', ); + expect(vm.$el.textContent).toContain( 'java ant found no changed test results out of 3 total tests', ); @@ -88,6 +89,7 @@ describe('Grouped Test Reports App', () => { expect(vm.$el.textContent).toContain( 'rspec:pg found 2 failed test results out of 8 total tests', ); + expect(vm.$el.textContent).toContain('New'); expect(vm.$el.textContent).toContain( 'java ant found no changed test results out of 3 total tests', @@ -115,6 +117,7 @@ describe('Grouped Test Reports App', () => { expect(vm.$el.textContent).toContain( 'rspec:pg found 1 failed test result and 2 fixed test results out of 8 total tests', ); + expect(vm.$el.textContent).toContain('New'); expect(vm.$el.textContent).toContain( ' java ant found 1 failed test result out of 3 total tests', @@ -151,6 +154,7 @@ describe('Grouped Test Reports App', () => { expect(vm.$el.querySelector('.js-mr-code-resolved-issues').textContent).toContain( resolvedFailures.suites[0].resolved_failures[0].name, ); + expect(vm.$el.querySelector('.js-mr-code-resolved-issues').textContent).toContain( resolvedFailures.suites[0].resolved_failures[1].name, ); diff --git a/spec/javascripts/reports/components/report_section_spec.js b/spec/javascripts/reports/components/report_section_spec.js index bf11dbea386..eb7307605d7 100644 --- a/spec/javascripts/reports/components/report_section_spec.js +++ b/spec/javascripts/reports/components/report_section_spec.js @@ -97,6 +97,7 @@ describe('Report section', () => { successText: 'Code quality improved on 1 point and degraded on 1 point', hasIssues: false, }); + expect(vm.$el.textContent.trim()).toEqual('Loading codeclimate report'); }); }); @@ -169,6 +170,7 @@ describe('Report section', () => { successText: 'Code quality improved on 1 point and degraded on 1 point', hasIssues: false, }); + expect(vm.$el.textContent.trim()).toEqual('Failed to load codeclimate report'); }); }); diff --git a/spec/javascripts/reports/components/test_issue_body_spec.js b/spec/javascripts/reports/components/test_issue_body_spec.js index 0ea81f714e7..32baf904ad7 100644 --- a/spec/javascripts/reports/components/test_issue_body_spec.js +++ b/spec/javascripts/reports/components/test_issue_body_spec.js @@ -29,6 +29,7 @@ describe('Test Issue body', () => { spyOn(vm, 'openModal'); vm.$el.querySelector('button').click(); + expect(vm.openModal).toHaveBeenCalledWith({ issue: commonProps.issue, }); diff --git a/spec/javascripts/reports/store/mutations_spec.js b/spec/javascripts/reports/store/mutations_spec.js index 7d19b16efb9..9446cd454ab 100644 --- a/spec/javascripts/reports/store/mutations_spec.js +++ b/spec/javascripts/reports/store/mutations_spec.js @@ -13,6 +13,7 @@ describe('Reports Store Mutations', () => { describe('SET_ENDPOINT', () => { it('should set endpoint', () => { mutations[types.SET_ENDPOINT](stateCopy, 'endpoint.json'); + expect(stateCopy.endpoint).toEqual('endpoint.json'); }); }); @@ -20,6 +21,7 @@ describe('Reports Store Mutations', () => { describe('REQUEST_REPORTS', () => { it('should set isLoading to true', () => { mutations[types.REQUEST_REPORTS](stateCopy); + expect(stateCopy.isLoading).toEqual(true); }); }); diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js index bc1bb50dc5c..7530fd2a43b 100644 --- a/spec/javascripts/search_autocomplete_spec.js +++ b/spec/javascripts/search_autocomplete_spec.js @@ -111,6 +111,7 @@ describe('Search autocomplete dropdown', () => { if (issuesPath) { const issuesAssignedToMeLink = `a[href="${issuesPath}/?assignee_id=${userId}"]`; const issuesIHaveCreatedLink = `a[href="${issuesPath}/?author_id=${userId}"]`; + expect(list.find(issuesAssignedToMeLink).length).toBe(1); expect(list.find(issuesAssignedToMeLink).text()).toBe('Issues assigned to me'); expect(list.find(issuesIHaveCreatedLink).length).toBe(1); @@ -118,6 +119,7 @@ describe('Search autocomplete dropdown', () => { } const mrsAssignedToMeLink = `a[href="${mrsPath}/?assignee_id=${userId}"]`; const mrsIHaveCreatedLink = `a[href="${mrsPath}/?author_id=${userId}"]`; + expect(list.find(mrsAssignedToMeLink).length).toBe(1); expect(list.find(mrsAssignedToMeLink).text()).toBe('Merge requests assigned to me'); expect(list.find(mrsIHaveCreatedLink).length).toBe(1); @@ -185,7 +187,8 @@ describe('Search autocomplete dropdown', () => { widget.searchInput.triggerHandler('focus'); list = widget.wrap.find('.dropdown-menu').find('ul'); link = "a[href='" + projectIssuesPath + '/?assignee_id=' + userId + "']"; - return expect(list.find(link).length).toBe(0); + + expect(list.find(link).length).toBe(0); }); it('should not submit the search form when selecting an autocomplete row with the keyboard', function() { diff --git a/spec/javascripts/shared/popover_spec.js b/spec/javascripts/shared/popover_spec.js index 1d574c9424b..60140e23fab 100644 --- a/spec/javascripts/shared/popover_spec.js +++ b/spec/javascripts/shared/popover_spec.js @@ -119,6 +119,7 @@ describe('popover', () => { spyOn($.fn, 'init').and.callFake(selector => (selector === '.popover:hover' ? fakeJquery : $.fn)); spyOn(togglePopover, 'call'); mouseleave(); + expect(togglePopover.call).toHaveBeenCalledWith(jasmine.any(Object), false); }); @@ -130,6 +131,7 @@ describe('popover', () => { spyOn($.fn, 'init').and.callFake(selector => (selector === '.popover:hover' ? fakeJquery : $.fn)); spyOn(togglePopover, 'call'); mouseleave(); + expect(togglePopover.call).not.toHaveBeenCalledWith(false); }); }); @@ -140,6 +142,7 @@ describe('popover', () => { it('shows popover', () => { spyOn(togglePopover, 'call').and.returnValue(false); mouseenter.call(context); + expect(togglePopover.call).toHaveBeenCalledWith(jasmine.any(Object), true); }); @@ -156,6 +159,7 @@ describe('popover', () => { spyOn(togglePopover, 'call').and.returnValue(false); const spy = spyOn($.fn, 'on').and.callFake(() => {}); mouseenter.call(context); + expect(spy).not.toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/sidebar/assignees_spec.js b/spec/javascripts/sidebar/assignees_spec.js index 843e7002180..e7f8f4f9936 100644 --- a/spec/javascripts/sidebar/assignees_spec.js +++ b/spec/javascripts/sidebar/assignees_spec.js @@ -22,6 +22,7 @@ describe('Assignee component', () => { }).$mount(); const collapsed = component.$el.querySelector('.sidebar-collapsed-icon'); + expect(collapsed.childElementCount).toEqual(1); expect(collapsed.children[0].getAttribute('aria-label')).toEqual('No Assignee'); expect(collapsed.children[0].classList.contains('fa')).toEqual(true); @@ -67,6 +68,7 @@ describe('Assignee component', () => { spyOn(component, '$emit'); component.$el.querySelector('.assign-yourself .btn-link').click(); + expect(component.$emit).toHaveBeenCalledWith('assign-self'); }); }); @@ -85,6 +87,7 @@ describe('Assignee component', () => { const collapsed = component.$el.querySelector('.sidebar-collapsed-icon'); const assignee = collapsed.children[0]; + expect(collapsed.childElementCount).toEqual(1); expect(assignee.querySelector('.avatar').getAttribute('src')).toEqual(UsersMock.user.avatar); expect(assignee.querySelector('.avatar').getAttribute('alt')).toEqual(`${UsersMock.user.name}'s avatar`); @@ -138,14 +141,17 @@ describe('Assignee component', () => { }).$mount(); const collapsed = component.$el.querySelector('.sidebar-collapsed-icon'); + expect(collapsed.childElementCount).toEqual(2); const first = collapsed.children[0]; + expect(first.querySelector('.avatar').getAttribute('src')).toEqual(users[0].avatar); expect(first.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[0].name}'s avatar`); expect(first.querySelector('.author').innerText.trim()).toEqual(users[0].name); const second = collapsed.children[1]; + expect(second.querySelector('.avatar').getAttribute('src')).toEqual(users[1].avatar); expect(second.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[1].name}'s avatar`); expect(second.querySelector('.author').innerText.trim()).toEqual(users[1].name); @@ -162,14 +168,17 @@ describe('Assignee component', () => { }).$mount(); const collapsed = component.$el.querySelector('.sidebar-collapsed-icon'); + expect(collapsed.childElementCount).toEqual(2); const first = collapsed.children[0]; + expect(first.querySelector('.avatar').getAttribute('src')).toEqual(users[0].avatar); expect(first.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[0].name}'s avatar`); expect(first.querySelector('.author').innerText.trim()).toEqual(users[0].name); const second = collapsed.children[1]; + expect(second.querySelector('.avatar-counter').innerText.trim()).toEqual('+2'); }); @@ -200,6 +209,7 @@ describe('Assignee component', () => { expect(component.$el.querySelectorAll('.user-item').length).toEqual(component.defaultRenderCount); expect(component.$el.querySelector('.user-list-more')).not.toBe(null); const usersLabelExpectation = users.length - component.defaultRenderCount; + expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim()) .not.toBe(`+${usersLabelExpectation} more`); component.toggleShowLess(); diff --git a/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js b/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js index 0e30759c41d..b4aeef182a6 100644 --- a/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js +++ b/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js @@ -88,6 +88,7 @@ describe('Issuable Time Tracker', () => { Vue.nextTick(() => { expect(vm.showComparisonState).toBe(true); const $comparisonPane = vm.$el.querySelector('.time-tracking-comparison-pane'); + expect($comparisonPane).toBeVisible(); done(); }); diff --git a/spec/javascripts/sidebar/participants_spec.js b/spec/javascripts/sidebar/participants_spec.js index e796ddee62f..54b9f30ad93 100644 --- a/spec/javascripts/sidebar/participants_spec.js +++ b/spec/javascripts/sidebar/participants_spec.js @@ -182,6 +182,7 @@ describe('Participants', function () { const participantsIconEl = vm.$el.querySelector('.sidebar-collapsed-icon'); participantsIconEl.click(); + expect(vm.$emit).toHaveBeenCalledWith('toggleSidebar'); }); }); diff --git a/spec/javascripts/sidebar/sidebar_assignees_spec.js b/spec/javascripts/sidebar/sidebar_assignees_spec.js index ebaaa6e806b..50e86781393 100644 --- a/spec/javascripts/sidebar/sidebar_assignees_spec.js +++ b/spec/javascripts/sidebar/sidebar_assignees_spec.js @@ -39,6 +39,7 @@ describe('sidebar assignees', () => { it('calls the mediator when saves the assignees', () => { vm.saveAssignees(); + expect(mediator.saveAssignees).toHaveBeenCalled(); }); @@ -51,6 +52,7 @@ describe('sidebar assignees', () => { it('hides assignees until fetched', (done) => { const currentAssignee = sidebarAssigneesEl.querySelector('.value'); + expect(currentAssignee).toBe(null); vm.store.isFetching.assignees = false; diff --git a/spec/javascripts/sidebar/sidebar_store_spec.js b/spec/javascripts/sidebar/sidebar_store_spec.js index 08b112a54ba..7ba62a59d58 100644 --- a/spec/javascripts/sidebar/sidebar_store_spec.js +++ b/spec/javascripts/sidebar/sidebar_store_spec.js @@ -56,11 +56,13 @@ describe('Sidebar store', function () { it('adds a new assignee', () => { this.store.addAssignee(ASSIGNEE); + expect(this.store.assignees.length).toEqual(1); }); it('removes an assignee', () => { this.store.removeAssignee(ASSIGNEE); + expect(this.store.assignees.length).toEqual(0); }); @@ -69,14 +71,17 @@ describe('Sidebar store', function () { this.store.addAssignee(ASSIGNEE); foundAssignee = this.store.findAssignee(ASSIGNEE); + expect(foundAssignee).toBeDefined(); expect(foundAssignee).toEqual(ASSIGNEE); foundAssignee = this.store.findAssignee(ANOTHER_ASSINEE); + expect(foundAssignee).toBeUndefined(); }); it('removes all assignees', () => { this.store.removeAllAssignees(); + expect(this.store.assignees.length).toEqual(0); }); @@ -108,6 +113,7 @@ describe('Sidebar store', function () { }; this.store.setAssigneeData(users); + expect(this.store.isFetching.assignees).toBe(false); expect(this.store.assignees.length).toEqual(3); }); @@ -128,6 +134,7 @@ describe('Sidebar store', function () { it('set time tracking data', () => { this.store.setTimeTrackingData(Mock.time); + expect(this.store.timeEstimate).toEqual(Mock.time.time_estimate); expect(this.store.totalTimeSpent).toEqual(Mock.time.total_time_spent); expect(this.store.humanTimeEstimate).toEqual(Mock.time.human_time_estimate); diff --git a/spec/javascripts/sidebar/subscriptions_spec.js b/spec/javascripts/sidebar/subscriptions_spec.js index f0a53e573c3..16ff3c043fe 100644 --- a/spec/javascripts/sidebar/subscriptions_spec.js +++ b/spec/javascripts/sidebar/subscriptions_spec.js @@ -47,6 +47,7 @@ describe('Subscriptions', function () { spyOn(vm, '$emit'); vm.toggleSubscription(); + expect(eventHub.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object)); expect(vm.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object)); }); @@ -56,6 +57,7 @@ describe('Subscriptions', function () { spyOn(vm, '$emit'); vm.onClickCollapsedIcon(); + expect(vm.$emit).toHaveBeenCalledWith('toggleSidebar'); }); }); diff --git a/spec/javascripts/sidebar/todo_spec.js b/spec/javascripts/sidebar/todo_spec.js index a929b804a29..d1d90109405 100644 --- a/spec/javascripts/sidebar/todo_spec.js +++ b/spec/javascripts/sidebar/todo_spec.js @@ -103,6 +103,7 @@ describe('SidebarTodo', () => { it('emits `toggleTodo` event on component', () => { spyOn(vm, '$emit'); vm.handleButtonClick(); + expect(vm.$emit).toHaveBeenCalledWith('toggleTodo'); }); }); @@ -118,6 +119,7 @@ describe('SidebarTodo', () => { container: 'body', boundary: 'viewport', }; + expect(vm.$el.nodeName).toBe('BUTTON'); const elDataAttrs = vm.$el.dataset; @@ -128,6 +130,7 @@ describe('SidebarTodo', () => { it('renders button label element when `collapsed` prop is `false`', () => { const buttonLabelEl = vm.$el.querySelector('span.issuable-todo-inner'); + expect(buttonLabelEl).not.toBeNull(); expect(buttonLabelEl.innerText.trim()).toBe('Mark todo as done'); }); @@ -137,6 +140,7 @@ describe('SidebarTodo', () => { Vue.nextTick() .then(() => { const buttonIconEl = vm.$el.querySelector('svg'); + expect(buttonIconEl).not.toBeNull(); expect(buttonIconEl.querySelector('use').getAttribute('xlink:href')).toContain('todo-done'); }) @@ -149,6 +153,7 @@ describe('SidebarTodo', () => { Vue.nextTick() .then(() => { const loadingEl = vm.$el.querySelector('span.loading-container'); + expect(loadingEl).not.toBeNull(); }) .then(done) diff --git a/spec/javascripts/smart_interval_spec.js b/spec/javascripts/smart_interval_spec.js index d9b6dd1d487..b2ba0e4200d 100644 --- a/spec/javascripts/smart_interval_spec.js +++ b/spec/javascripts/smart_interval_spec.js @@ -66,6 +66,7 @@ describe('SmartInterval', function () { waitForPromises() .then(() => { const currentInterval = smartInterval.getCurrentInterval(); + expect(currentInterval).toBe(smartInterval.cfg.maxInterval); }) .then(done) @@ -82,6 +83,7 @@ describe('SmartInterval', function () { waitForPromises() .then(() => { const oneInterval = smartInterval.cfg.startingInterval * DEFAULT_INCREMENT_FACTOR; + expect(smartInterval.getCurrentInterval()).toEqual(oneInterval); }) .then(done) @@ -126,6 +128,7 @@ describe('SmartInterval', function () { waitForPromises() .then(() => { const { intervalId } = interval.state; + expect(intervalId).toBeTruthy(); }) .then(done) @@ -212,6 +215,7 @@ describe('SmartInterval', function () { waitForPromises() .then(() => { $(document).triggerHandler('beforeunload'); + expect(interval.state.intervalId).toBeUndefined(); expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval); }) @@ -221,6 +225,7 @@ describe('SmartInterval', function () { it('should execute callback before first interval', function () { const interval = createDefaultSmartInterval({ immediateExecution: true }); + expect(interval.cfg.immediateExecution).toBeFalsy(); }); }); diff --git a/spec/javascripts/syntax_highlight_spec.js b/spec/javascripts/syntax_highlight_spec.js index 512be88c24c..d33c5ad6a73 100644 --- a/spec/javascripts/syntax_highlight_spec.js +++ b/spec/javascripts/syntax_highlight_spec.js @@ -15,13 +15,16 @@ describe('Syntax Highlighter', function() { beforeEach(function() { return setFixtures('<div class="js-syntax-highlight"></div>'); }); - return it('applies syntax highlighting', function() { + + it('applies syntax highlighting', function() { stubUserColorScheme('monokai'); syntaxHighlight($('.js-syntax-highlight')); - return expect($('.js-syntax-highlight')).toHaveClass('monokai'); + + expect($('.js-syntax-highlight')).toHaveClass('monokai'); }); }); - return describe('on a parent element', function() { + + describe('on a parent element', function() { beforeEach(function() { return setFixtures("<div class=\"parent\">\n <div class=\"js-syntax-highlight\"></div>\n <div class=\"foo\"></div>\n <div class=\"js-syntax-highlight\"></div>\n</div>"); }); @@ -29,16 +32,19 @@ describe('Syntax Highlighter', function() { it('applies highlighting to all applicable children', function() { stubUserColorScheme('monokai'); syntaxHighlight($('.parent')); + expect($('.parent, .foo')).not.toHaveClass('monokai'); - return expect($('.monokai').length).toBe(2); + expect($('.monokai').length).toBe(2); }); - return it('prevents an infinite loop when no matches exist', function() { + + it('prevents an infinite loop when no matches exist', function() { var highlight; setFixtures('<div></div>'); highlight = function() { return syntaxHighlight($('div')); }; - return expect(highlight).not.toThrow(); + + expect(highlight).not.toThrow(); }); }); }); diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js index 57e0caa692c..abe28f28dca 100644 --- a/spec/javascripts/u2f/authenticate_spec.js +++ b/spec/javascripts/u2f/authenticate_spec.js @@ -51,10 +51,12 @@ describe('U2FAuthenticate', function () { it('allows authenticating via a U2F device', () => { const inProgressMessage = this.container.find('p'); + expect(inProgressMessage.text()).toContain('Trying to communicate with your device'); this.u2fDevice.respondToAuthenticateRequest({ deviceData: 'this is data from the device', }); + expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}'); }); @@ -66,7 +68,8 @@ describe('U2FAuthenticate', function () { errorCode: 'error!', }); const errorMessage = this.container.find('p'); - return expect(errorMessage.text()).toContain('There was a problem communicating with your device'); + + expect(errorMessage.text()).toContain('There was a problem communicating with your device'); }); return it('allows retrying authentication after an error', () => { let setupButton = this.container.find('#js-login-u2f-device'); @@ -81,6 +84,7 @@ describe('U2FAuthenticate', function () { this.u2fDevice.respondToAuthenticateRequest({ deviceData: 'this is data from the device', }); + expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}'); }); }); diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js index b774627651f..4d90a3ccce6 100644 --- a/spec/javascripts/u2f/register_spec.js +++ b/spec/javascripts/u2f/register_spec.js @@ -16,20 +16,23 @@ describe('U2FRegister', function () { it('allows registering a U2F device', () => { const setupButton = this.container.find('#js-setup-u2f-device'); + expect(setupButton.text()).toBe('Set up new U2F device'); setupButton.trigger('click'); const inProgressMessage = this.container.children('p'); + expect(inProgressMessage.text()).toContain('Trying to communicate with your device'); this.u2fDevice.respondToRegisterRequest({ deviceData: 'this is data from the device', }); const registeredMessage = this.container.find('p'); const deviceResponse = this.container.find('#js-device-response'); + expect(registeredMessage.text()).toContain('Your device was successfully set up!'); - return expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}'); + expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}'); }); - return describe('errors', () => { + describe('errors', () => { it('doesn\'t allow the same device to be registered twice (for the same user', () => { const setupButton = this.container.find('#js-setup-u2f-device'); setupButton.trigger('click'); @@ -37,7 +40,8 @@ describe('U2FRegister', function () { errorCode: 4, }); const errorMessage = this.container.find('p'); - return expect(errorMessage.text()).toContain('already been registered with us'); + + expect(errorMessage.text()).toContain('already been registered with us'); }); it('displays an error message for other errors', () => { @@ -47,10 +51,11 @@ describe('U2FRegister', function () { errorCode: 'error!', }); const errorMessage = this.container.find('p'); - return expect(errorMessage.text()).toContain('There was a problem communicating with your device'); + + expect(errorMessage.text()).toContain('There was a problem communicating with your device'); }); - return it('allows retrying registration after an error', () => { + it('allows retrying registration after an error', () => { let setupButton = this.container.find('#js-setup-u2f-device'); setupButton.trigger('click'); this.u2fDevice.respondToRegisterRequest({ @@ -64,7 +69,8 @@ describe('U2FRegister', function () { deviceData: 'this is data from the device', }); const registeredMessage = this.container.find('p'); - return expect(registeredMessage.text()).toContain('Your device was successfully set up!'); + + expect(registeredMessage.text()).toContain('Your device was successfully set up!'); }); }); }); diff --git a/spec/javascripts/u2f/util_spec.js b/spec/javascripts/u2f/util_spec.js index 4187183236f..d1a64348da6 100644 --- a/spec/javascripts/u2f/util_spec.js +++ b/spec/javascripts/u2f/util_spec.js @@ -4,41 +4,49 @@ describe('U2F Utils', () => { describe('canInjectU2fApi', () => { it('returns false for Chrome < 41', () => { const userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.28 Safari/537.36'; + expect(canInjectU2fApi(userAgent)).toBe(false); }); it('returns true for Chrome >= 41', () => { const userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'; + expect(canInjectU2fApi(userAgent)).toBe(true); }); it('returns false for Opera < 40', () => { const userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.25'; + expect(canInjectU2fApi(userAgent)).toBe(false); }); it('returns true for Opera >= 40', () => { const userAgent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.991'; + expect(canInjectU2fApi(userAgent)).toBe(true); }); it('returns false for Safari', () => { const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4'; + expect(canInjectU2fApi(userAgent)).toBe(false); }); it('returns false for Chrome on Android', () => { const userAgent = 'Mozilla/5.0 (Linux; Android 7.0; VS988 Build/NRD90U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3145.0 Mobile Safari/537.36'; + expect(canInjectU2fApi(userAgent)).toBe(false); }); it('returns false for Chrome on iOS', () => { const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1'; + expect(canInjectU2fApi(userAgent)).toBe(false); }); it('returns false for Safari on iOS', () => { const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A356 Safari/604.1'; + expect(canInjectU2fApi(userAgent)).toBe(false); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/deployment_spec.js b/spec/javascripts/vue_mr_widget/components/deployment_spec.js index 50c2b0e2bd0..97e6ce44348 100644 --- a/spec/javascripts/vue_mr_widget/components/deployment_spec.js +++ b/spec/javascripts/vue_mr_widget/components/deployment_spec.js @@ -39,6 +39,7 @@ describe('Deployment component', () => { describe('deployTimeago', () => { it('return formatted date', () => { const readable = getTimeago().format(deploymentMockData.deployed_at); + expect(vm.deployTimeago).toEqual(readable); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js index 237e2fa79f2..a97458ffc92 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js @@ -41,6 +41,7 @@ describe('MRWidgetHeader', () => { statusPath: 'abc', }, }); + expect(vm.shouldShowCommitsBehindText).toEqual(false); }); }); @@ -165,6 +166,7 @@ describe('MRWidgetHeader', () => { vm = mountComponent(Component, { mr }); const link = vm.$el.querySelector('.js-web-ide'); + expect(link.classList.contains('disabled')).toBe(true); expect(link.getAttribute('href')).toBeNull(); }); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js index 305cee94f57..bb7be2fe1c2 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js @@ -186,9 +186,11 @@ describe('MemoryUsage', () => { expect( el.querySelector('.js-usage-info.usage-info-loading'), ).toBeDefined(); + expect( el.querySelector('.js-usage-info .usage-info-load-spinner'), ).toBeDefined(); + expect(el.querySelector('.js-usage-info').innerText).toContain( messages.loadingMetrics, ); @@ -219,6 +221,7 @@ describe('MemoryUsage', () => { expect( el.querySelector('.js-usage-info.usage-info-failed'), ).toBeDefined(); + expect(el.querySelector('.js-usage-info').innerText).toContain( messages.loadFailed, ); @@ -235,6 +238,7 @@ describe('MemoryUsage', () => { expect( el.querySelector('.js-usage-info.usage-info-unavailable'), ).toBeDefined(); + expect(el.querySelector('.js-usage-info').innerText).toContain( messages.metricsUnavailable, ); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js index b453d180a40..25763634671 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js @@ -40,6 +40,7 @@ describe('Merge request widget rebase component', () => { it('it should render rebase button and warning message', () => { const text = vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim(); + expect(text).toContain('Fast-forward merge is not possible.'); expect(text).toContain('Rebase the source branch onto the target branch or merge target'); expect(text).toContain('branch into source branch to allow this merge request to be merged.'); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js index 5de6ac4079d..38031e42230 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js @@ -19,16 +19,19 @@ describe('MRWidgetRelatedLinks', () => { describe('closesText', () => { it('returns Closes text for open merge request', () => { vm = createComponent({ state: 'open', relatedLinks: {} }); + expect(vm.closesText).toEqual('Closes'); }); it('returns correct text for closed merge request', () => { vm = createComponent({ state: 'closed', relatedLinks: {} }); + expect(vm.closesText).toEqual('Did not close'); }); it('returns correct tense for merged request', () => { vm = createComponent({ state: 'merged', relatedLinks: {} }); + expect(vm.closesText).toEqual('Closed'); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js index 0b25500caf4..a0a336ae604 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js @@ -17,6 +17,7 @@ describe('MR widget status icon component', () => { describe('while loading', () => { it('renders loading icon', () => { vm = mountComponent(Component, { status: 'loading' }); + expect(vm.$el.querySelector('.mr-widget-icon i').classList).toContain('fa-spinner'); }); }); @@ -24,6 +25,7 @@ describe('MR widget status icon component', () => { describe('with status icon', () => { it('renders ci status icon', () => { vm = mountComponent(Component, { status: 'failed' }); + expect(vm.$el.querySelector('.js-ci-status-icon-failed')).not.toBeNull(); }); }); @@ -31,6 +33,7 @@ describe('MR widget status icon component', () => { describe('with disabled button', () => { it('renders a disabled button', () => { vm = mountComponent(Component, { status: 'failed', showDisabledButton: true }); + expect(vm.$el.querySelector('.js-disabled-merge-button').textContent.trim()).toEqual('Merge'); }); }); @@ -38,6 +41,7 @@ describe('MR widget status icon component', () => { describe('without disabled button', () => { it('does not render a disabled button', () => { vm = mountComponent(Component, { status: 'failed' }); + expect(vm.$el.querySelector('.js-disabled-merge-button')).toBeNull(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js index 8de99fd3c96..3229ddd5e27 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js @@ -43,6 +43,7 @@ describe('MRWidgetFailedToMerge', () => { expect(vm.timerText).toEqual('Refreshing in 10 seconds to show the updated status...'); vm.timer = 1; + expect(vm.timerText).toEqual('Refreshing in a second to show the updated status...'); }); }); @@ -73,6 +74,7 @@ describe('MRWidgetFailedToMerge', () => { expect(vm.isRefreshing).toEqual(false); vm.refresh(); + expect(vm.isRefreshing).toEqual(true); expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested'); expect(eventHub.$emit).toHaveBeenCalledWith('EnablePolling'); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js index d47815a5b5a..04380b23e52 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js @@ -42,22 +42,27 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => { it('should return false when user id is not the same with who set the MWPS', () => { vm.mr.mergeUserId = 2; + expect(vm.canRemoveSourceBranch).toBeFalsy(); vm.mr.currentUserId = 2; + expect(vm.canRemoveSourceBranch).toBeTruthy(); vm.mr.currentUserId = 3; + expect(vm.canRemoveSourceBranch).toBeFalsy(); }); it('should return false when shouldRemoveSourceBranch set to false', () => { vm.mr.shouldRemoveSourceBranch = true; + expect(vm.canRemoveSourceBranch).toBeFalsy(); }); it('should return false if user is not able to remove the source branch', () => { vm.mr.canRemoveSourceBranch = false; + expect(vm.canRemoveSourceBranch).toBeFalsy(); }); }); @@ -133,6 +138,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => { Vue.nextTick(() => { const normalizedText = vm.$el.innerText.replace(/\s+/g, ' '); + expect(normalizedText).toContain('The source branch will be removed'); expect(normalizedText).not.toContain('The source branch will not be removed'); done(); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js index 033cb694249..6a21e29e8c9 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js @@ -63,23 +63,27 @@ describe('MRWidgetMerged', () => { describe('shouldShowRemoveSourceBranch', () => { it('returns true when sourceBranchRemoved is false', () => { vm.mr.sourceBranchRemoved = false; + expect(vm.shouldShowRemoveSourceBranch).toEqual(true); }); it('returns false wehn sourceBranchRemoved is true', () => { vm.mr.sourceBranchRemoved = true; + expect(vm.shouldShowRemoveSourceBranch).toEqual(false); }); it('returns false when canRemoveSourceBranch is false', () => { vm.mr.sourceBranchRemoved = false; vm.mr.canRemoveSourceBranch = false; + expect(vm.shouldShowRemoveSourceBranch).toEqual(false); }); it('returns false when is making request', () => { vm.mr.canRemoveSourceBranch = true; vm.isMakingRequest = true; + expect(vm.shouldShowRemoveSourceBranch).toEqual(false); }); @@ -87,6 +91,7 @@ describe('MRWidgetMerged', () => { vm.mr.isRemovingSourceBranch = true; vm.mr.canRemoveSourceBranch = true; vm.isMakingRequest = true; + expect(vm.shouldShowRemoveSourceBranch).toEqual(false); }); }); @@ -94,17 +99,21 @@ describe('MRWidgetMerged', () => { describe('shouldShowSourceBranchRemoving', () => { it('should correct value when fields changed', () => { vm.mr.sourceBranchRemoved = false; + expect(vm.shouldShowSourceBranchRemoving).toEqual(false); vm.mr.sourceBranchRemoved = true; + expect(vm.shouldShowRemoveSourceBranch).toEqual(false); vm.mr.sourceBranchRemoved = false; vm.isMakingRequest = true; + expect(vm.shouldShowSourceBranchRemoving).toEqual(true); vm.isMakingRequest = false; vm.mr.isRemovingSourceBranch = true; + expect(vm.shouldShowSourceBranchRemoving).toEqual(true); }); }); @@ -124,6 +133,7 @@ describe('MRWidgetMerged', () => { vm.removeSourceBranch(); setTimeout(() => { const args = eventHub.$emit.calls.argsFor(0); + expect(vm.isMakingRequest).toEqual(true); expect(args[0]).toEqual('MRWidgetUpdateRequested'); expect(args[1]).not.toThrow(); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js index d2d219e4bdb..0781cd389fc 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js @@ -27,6 +27,7 @@ describe('MRWidgetMerging', () => { expect( vm.$el.querySelector('.mr-info-list').textContent.trim().replace(/\s\s+/g, ' ').replace(/[\r\n]+/g, ' '), ).toEqual('The changes will be merged into branch'); + expect( vm.$el.querySelector('a').getAttribute('href'), ).toEqual('/branch-path'); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js index 34f76b39b28..096301837c4 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js @@ -20,6 +20,7 @@ describe('MRWidgetMissingBranch', () => { expect(vm.missingBranchName).toEqual('source'); vm.mr.sourceBranchRemoved = false; + expect(vm.missingBranchName).toEqual('target'); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index 81c16593eb4..b795ce680ce 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -76,11 +76,13 @@ describe('ReadyToMerge', () => { describe('shouldShowMergeWhenPipelineSucceedsText', () => { it('should return true with active pipeline', () => { vm.mr.isPipelineActive = true; + expect(vm.shouldShowMergeWhenPipelineSucceedsText).toBeTruthy(); }); it('should return false with inactive pipeline', () => { vm.mr.isPipelineActive = false; + expect(vm.shouldShowMergeWhenPipelineSucceedsText).toBeFalsy(); }); }); @@ -95,6 +97,7 @@ describe('ReadyToMerge', () => { it('should return message without description', () => { vm.useCommitMessageWithDescription = true; + expect(vm.commitMessageLinkTitle).toEqual(withoutDesc); }); }); @@ -102,11 +105,13 @@ describe('ReadyToMerge', () => { describe('status', () => { it('defaults to success', () => { vm.mr.pipeline = true; + expect(vm.status).toEqual('success'); }); it('returns failed when MR has CI but also has an unknown status', () => { vm.mr.hasCI = true; + expect(vm.status).toEqual('failed'); }); @@ -117,12 +122,14 @@ describe('ReadyToMerge', () => { it('returns pending when pipeline is active', () => { vm.mr.pipeline = {}; vm.mr.isPipelineActive = true; + expect(vm.status).toEqual('pending'); }); it('returns failed when pipeline is failed', () => { vm.mr.pipeline = {}; vm.mr.isPipelineFailed = true; + expect(vm.status).toEqual('failed'); }); }); @@ -138,17 +145,20 @@ describe('ReadyToMerge', () => { it('returns success class for success status', () => { vm.mr.pipeline = true; + expect(vm.mergeButtonClass).toEqual(defaultClass); }); it('returns info class for pending status', () => { vm.mr.pipeline = {}; vm.mr.isPipelineActive = true; + expect(vm.mergeButtonClass).toEqual(inActionClass); }); it('returns failed class for failed status', () => { vm.mr.hasCI = true; + expect(vm.mergeButtonClass).toEqual(failedClass); }); }); @@ -160,22 +170,26 @@ describe('ReadyToMerge', () => { it('shows tick for success status', () => { vm.mr.pipeline = true; + expect(vm.iconClass).toEqual('success'); }); it('shows tick for pending status', () => { vm.mr.pipeline = {}; vm.mr.isPipelineActive = true; + expect(vm.iconClass).toEqual('success'); }); it('shows warning icon for failed status', () => { vm.mr.hasCI = true; + expect(vm.iconClass).toEqual('warning'); }); it('shows warning icon for merge not allowed', () => { vm.mr.hasCI = true; + expect(vm.iconClass).toEqual('warning'); }); }); @@ -187,12 +201,14 @@ describe('ReadyToMerge', () => { it('should return Merge in progress', () => { vm.isMergingImmediately = true; + expect(vm.mergeButtonText).toEqual('Merge in progress'); }); it('should return Merge when pipeline succeeds', () => { vm.isMergingImmediately = false; vm.mr.isPipelineActive = true; + expect(vm.mergeButtonText).toEqual('Merge when pipeline succeeds'); }); }); @@ -204,12 +220,14 @@ describe('ReadyToMerge', () => { it('should return true when pipeline active', () => { vm.mr.isPipelineActive = true; + expect(vm.shouldShowMergeOptionsDropdown).toBeTruthy(); }); it('should return false when pipeline active but only merge when pipeline succeeds set in project options', () => { vm.mr.isPipelineActive = true; vm.mr.onlyAllowMergeIfPipelineSucceeds = true; + expect(vm.shouldShowMergeOptionsDropdown).toBeFalsy(); }); }); @@ -217,24 +235,28 @@ describe('ReadyToMerge', () => { describe('isMergeButtonDisabled', () => { it('should return false with initial data', () => { vm.mr.isMergeAllowed = true; + expect(vm.isMergeButtonDisabled).toBeFalsy(); }); it('should return true when there is no commit message', () => { vm.mr.isMergeAllowed = true; vm.commitMessage = ''; + expect(vm.isMergeButtonDisabled).toBeTruthy(); }); it('should return true if merge is not allowed', () => { vm.mr.isMergeAllowed = false; vm.mr.onlyAllowMergeIfPipelineSucceeds = true; + expect(vm.isMergeButtonDisabled).toBeTruthy(); }); it('should return true when the vm instance is making request', () => { vm.mr.isMergeAllowed = true; vm.isMakingRequest = true; + expect(vm.isMergeButtonDisabled).toBeTruthy(); }); }); @@ -245,24 +267,28 @@ describe('ReadyToMerge', () => { it('should return false when an external pipeline is running and required to succeed', () => { vm.mr.isMergeAllowed = false; vm.mr.isPipelineActive = false; + expect(vm.shouldShowMergeControls()).toBeFalsy(); }); it('should return true when the build succeeded or build not required to succeed', () => { vm.mr.isMergeAllowed = true; vm.mr.isPipelineActive = false; + expect(vm.shouldShowMergeControls()).toBeTruthy(); }); it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => { vm.mr.isMergeAllowed = false; vm.mr.isPipelineActive = true; + expect(vm.shouldShowMergeControls()).toBeTruthy(); }); it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => { vm.mr.isMergeAllowed = true; vm.mr.isPipelineActive = true; + expect(vm.shouldShowMergeControls()).toBeTruthy(); }); }); @@ -272,9 +298,11 @@ describe('ReadyToMerge', () => { expect(vm.useCommitMessageWithDescription).toBeFalsy(); expect(vm.commitMessage).toEqual(commitMessage); vm.updateCommitMessage(); + expect(vm.useCommitMessageWithDescription).toBeTruthy(); expect(vm.commitMessage).toEqual(commitMessageWithDescription); vm.updateCommitMessage(); + expect(vm.useCommitMessageWithDescription).toBeFalsy(); expect(vm.commitMessage).toEqual(commitMessage); }); @@ -284,6 +312,7 @@ describe('ReadyToMerge', () => { it('should toggle showCommitMessageEditor flag', () => { expect(vm.showCommitMessageEditor).toBeFalsy(); vm.toggleCommitMessageEditor(); + expect(vm.showCommitMessageEditor).toBeTruthy(); }); }); @@ -309,6 +338,7 @@ describe('ReadyToMerge', () => { expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested'); const params = vm.service.merge.calls.argsFor(0)[0]; + expect(params.sha).toEqual(vm.mr.sha); expect(params.commit_message).toEqual(vm.mr.commitMessage); expect(params.should_remove_source_branch).toBeFalsy(); @@ -328,6 +358,7 @@ describe('ReadyToMerge', () => { expect(eventHub.$emit).toHaveBeenCalledWith('FailedToMerge', undefined); const params = vm.service.merge.calls.argsFor(0)[0]; + expect(params.should_remove_source_branch).toBeTruthy(); expect(params.merge_when_pipeline_succeeds).toBeFalsy(); done(); @@ -345,6 +376,7 @@ describe('ReadyToMerge', () => { expect(vm.initiateMergePolling).toHaveBeenCalled(); const params = vm.service.merge.calls.argsFor(0)[0]; + expect(params.should_remove_source_branch).toBeTruthy(); expect(params.merge_when_pipeline_succeeds).toBeFalsy(); done(); @@ -356,6 +388,7 @@ describe('ReadyToMerge', () => { it('should call simplePoll', () => { const simplePoll = spyOnDependency(ReadyToMerge, 'simplePoll'); vm.initiateMergePolling(); + expect(simplePoll).toHaveBeenCalled(); }); }); @@ -403,6 +436,7 @@ describe('ReadyToMerge', () => { setTimeout(() => { const statusBox = document.querySelector('.status-box'); + expect(statusBox.classList.contains('status-box-mr-merged')).toBeTruthy(); expect(statusBox.textContent).toContain('Merged'); @@ -459,6 +493,7 @@ describe('ReadyToMerge', () => { const simplePoll = spyOnDependency(ReadyToMerge, 'simplePoll'); vm.initiateRemoveSourceBranchPolling(); + expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [true]); expect(simplePoll).toHaveBeenCalled(); }); @@ -485,9 +520,11 @@ describe('ReadyToMerge', () => { expect(vm.service.poll).toHaveBeenCalled(); const args = eventHub.$emit.calls.argsFor(0); + expect(args[0]).toEqual('MRWidgetUpdateRequested'); expect(args[1]).toBeDefined(); args[1](); + expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [false]); expect(cpc).toBeFalsy(); @@ -518,6 +555,7 @@ describe('ReadyToMerge', () => { describe('when user can merge but cannot delete branch', () => { it('should be disabled in the rendered output', () => { const checkboxElement = vm.$el.querySelector('#remove-source-branch-input'); + expect(checkboxElement).toBeNull(); }); }); @@ -537,6 +575,7 @@ describe('ReadyToMerge', () => { it('should be enabled in rendered output', () => { const checkboxElement = customVm.$el.querySelector('#remove-source-branch-input'); + expect(checkboxElement).not.toBeNull(); }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js index cea603368bf..518466cea8b 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js @@ -33,6 +33,7 @@ describe('Wip', () => { describe('data', () => { it('should have default data', () => { const vm = createComponent(); + expect(vm.isMakingRequest).toBeFalsy(); }); }); diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index 6ac7138743b..6b5e32fdfd5 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -46,6 +46,7 @@ describe('mrWidgetOptions', () => { it('should return conflicts component', () => { vm.mr.state = 'conflicts'; + expect(vm.componentName).toEqual('mr-widget-conflicts'); }); }); @@ -57,6 +58,7 @@ describe('mrWidgetOptions', () => { it('should return true for a state which requires help widget', () => { vm.mr.state = 'conflicts'; + expect(vm.shouldRenderMergeHelp).toBeTruthy(); }); }); @@ -82,6 +84,7 @@ describe('mrWidgetOptions', () => { it('should return true if there is relatedLinks in MR', () => { Vue.set(vm.mr, 'relatedLinks', {}); + expect(vm.shouldRenderRelatedLinks).toBeTruthy(); }); }); @@ -223,18 +226,23 @@ describe('mrWidgetOptions', () => { vm.bindEventHubListeners(); eventHub.$emit('SetBranchRemoveFlag', ['flag']); + expect(vm.mr.isRemovingSourceBranch).toEqual('flag'); eventHub.$emit('FailedToMerge'); + expect(vm.mr.state).toEqual('failedToMerge'); eventHub.$emit('UpdateWidgetData', mockData); + expect(vm.mr.setData).toHaveBeenCalledWith(mockData); eventHub.$emit('EnablePolling'); + expect(vm.resumePolling).toHaveBeenCalled(); eventHub.$emit('DisablePolling'); + expect(vm.stopPolling).toHaveBeenCalled(); const listenersWithServiceRequest = { @@ -253,9 +261,11 @@ describe('mrWidgetOptions', () => { }); listenersWithServiceRequest.MRWidgetUpdateRequested(); + expect(vm.checkStatus).toHaveBeenCalled(); listenersWithServiceRequest.FetchActionsContent(); + expect(vm.fetchActionsContent).toHaveBeenCalled(); }); }); @@ -352,6 +362,7 @@ describe('mrWidgetOptions', () => { spyOn(vm.pollingInterval, 'resume'); vm.resumePolling(); + expect(vm.pollingInterval.resume).toHaveBeenCalled(); }); }); @@ -361,6 +372,7 @@ describe('mrWidgetOptions', () => { spyOn(vm.pollingInterval, 'stopTimer'); vm.stopPolling(); + expect(vm.pollingInterval.stopTimer).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js index 179e42a7cc4..9d34bdd1084 100644 --- a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js @@ -20,46 +20,60 @@ describe('getStateKey', () => { work_in_progress: false, }; const bound = getStateKey.bind(context, data); + expect(bound()).toEqual(null); context.canBeMerged = true; + expect(bound()).toEqual('readyToMerge'); context.canMerge = false; + expect(bound()).toEqual('notAllowedToMerge'); context.mergeWhenPipelineSucceeds = true; + expect(bound()).toEqual('mergeWhenPipelineSucceeds'); context.hasSHAChanged = true; + expect(bound()).toEqual('shaMismatch'); context.isPipelineBlocked = true; + expect(bound()).toEqual('pipelineBlocked'); context.hasMergeableDiscussionsState = true; + expect(bound()).toEqual('unresolvedDiscussions'); context.onlyAllowMergeIfPipelineSucceeds = true; context.isPipelineFailed = true; + expect(bound()).toEqual('pipelineFailed'); data.work_in_progress = true; + expect(bound()).toEqual('workInProgress'); data.has_conflicts = true; + expect(bound()).toEqual('conflicts'); context.mergeStatus = 'unchecked'; + expect(bound()).toEqual('checking'); data.commits_count = 0; + expect(bound()).toEqual('nothingToMerge'); data.branch_missing = true; + expect(bound()).toEqual('missingBranch'); data.project_archived = true; + expect(bound()).toEqual('archived'); }); }); diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js index 33d052aceb2..f5079147f60 100644 --- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js +++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js @@ -12,32 +12,38 @@ describe('MergeRequestStore', () => { it('should set hasSHAChanged when the diff SHA changes', () => { store.setData({ ...mockData, diff_head_sha: 'a-different-string' }); + expect(store.hasSHAChanged).toBe(true); }); it('should not set hasSHAChanged when other data changes', () => { store.setData({ ...mockData, work_in_progress: !mockData.work_in_progress }); + expect(store.hasSHAChanged).toBe(false); }); describe('isPipelinePassing', () => { it('is true when the CI status is `success`', () => { store.setData({ ...mockData, ci_status: 'success' }); + expect(store.isPipelinePassing).toBe(true); }); it('is true when the CI status is `success_with_warnings`', () => { store.setData({ ...mockData, ci_status: 'success_with_warnings' }); + expect(store.isPipelinePassing).toBe(true); }); it('is false when the CI status is `failed`', () => { store.setData({ ...mockData, ci_status: 'failed' }); + expect(store.isPipelinePassing).toBe(false); }); it('is false when the CI status is anything except `success`', () => { store.setData({ ...mockData, ci_status: 'foobarbaz' }); + expect(store.isPipelinePassing).toBe(false); }); }); @@ -45,11 +51,13 @@ describe('MergeRequestStore', () => { describe('isPipelineSkipped', () => { it('should set isPipelineSkipped=true when the CI status is `skipped`', () => { store.setData({ ...mockData, ci_status: 'skipped' }); + expect(store.isPipelineSkipped).toBe(true); }); it('should set isPipelineSkipped=false when the CI status is anything except `skipped`', () => { store.setData({ ...mockData, ci_status: 'foobarbaz' }); + expect(store.isPipelineSkipped).toBe(false); }); }); @@ -57,11 +65,13 @@ describe('MergeRequestStore', () => { describe('isNothingToMergeState', () => { it('returns true when nothingToMerge', () => { store.state = stateKey.nothingToMerge; + expect(store.isNothingToMergeState).toEqual(true); }); it('returns false when not nothingToMerge', () => { store.state = 'state'; + expect(store.isNothingToMergeState).toEqual(false); }); }); diff --git a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js index 668742ebaee..55b19989bc7 100644 --- a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js +++ b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js @@ -83,6 +83,7 @@ describe('CI Badge Link Component', () => { it('should render each status badge', () => { Object.keys(statuses).map((status) => { vm = mountComponent(CIBadge, { status: statuses[status] }); + expect(vm.$el.getAttribute('href')).toEqual(statuses[status].details_path); expect(vm.$el.textContent.trim()).toEqual(statuses[status].text); expect(vm.$el.getAttribute('class')).toEqual(`ci-status ci-${statuses[status].group}`); @@ -93,6 +94,7 @@ describe('CI Badge Link Component', () => { it('should not render label', () => { vm = mountComponent(CIBadge, { status: statuses.canceled, showText: false }); + expect(vm.$el.textContent.trim()).toEqual(''); }); }); diff --git a/spec/javascripts/vue_shared/components/clipboard_button_spec.js b/spec/javascripts/vue_shared/components/clipboard_button_spec.js index ea525b1e44f..2f7ea077b54 100644 --- a/spec/javascripts/vue_shared/components/clipboard_button_spec.js +++ b/spec/javascripts/vue_shared/components/clipboard_button_spec.js @@ -44,6 +44,7 @@ describe('clipboard button', () => { title: 'Copy this value into Clipboard!', cssClass: 'btn-danger', }); + expect(vm.$el.getAttribute('data-clipboard-text')).toEqual( '{"text":"copy me","gfm":"`path/to/file`"}', ); diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js index 7189e8cfcfa..97dacec1fce 100644 --- a/spec/javascripts/vue_shared/components/commit_spec.js +++ b/spec/javascripts/vue_shared/components/commit_spec.js @@ -78,6 +78,7 @@ describe('Commit component', () => { expect(component.$el.querySelector('.commit-sha').getAttribute('href')).toEqual( props.commitUrl, ); + expect(component.$el.querySelector('.commit-sha').textContent).toContain(props.shortSha); }); @@ -100,6 +101,7 @@ describe('Commit component', () => { .querySelector('.commit-title .avatar-image-container img') .getAttribute('data-original-title'), ).toContain(props.author.username); + expect( component.$el .querySelector('.commit-title .avatar-image-container img') @@ -112,6 +114,7 @@ describe('Commit component', () => { expect(component.$el.querySelector('a.commit-row-message').getAttribute('href')).toEqual( props.commitUrl, ); + expect(component.$el.querySelector('a.commit-row-message').textContent).toContain( props.title, ); diff --git a/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js b/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js index 71d9145bf22..fcd231ec693 100644 --- a/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js +++ b/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js @@ -55,6 +55,7 @@ describe('DiffViewer', () => { expect(vm.$el.querySelector('.deleted .file-info').textContent.trim()).toContain( 'testold.abc', ); + expect(vm.$el.querySelector('.deleted .btn.btn-default').textContent.trim()).toContain( 'Download', ); diff --git a/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js b/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js index dde49b4a5d7..380effdb669 100644 --- a/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js +++ b/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js @@ -55,6 +55,7 @@ describe('ImageDiffViewer', () => { expect(vm.$el.querySelector('.added .image_file img').getAttribute('src')).toBe( GREEN_BOX_IMAGE_URL, ); + expect(vm.$el.querySelector('.deleted .image_file img').getAttribute('src')).toBe( RED_BOX_IMAGE_URL, ); @@ -63,6 +64,7 @@ describe('ImageDiffViewer', () => { expect(vm.$el.querySelector('.view-modes-menu li:nth-child(2)').textContent.trim()).toBe( 'Swipe', ); + expect(vm.$el.querySelector('.view-modes-menu li:nth-child(3)').textContent.trim()).toBe( 'Onion skin', ); diff --git a/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js b/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js index 2796cd088c6..6965677c5ef 100644 --- a/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js +++ b/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js @@ -55,6 +55,7 @@ describe('DropdownButtonComponent', () => { it('renders dropdown toggle text element', () => { const dropdownToggleTextEl = vm.$el.querySelector('.dropdown-toggle-text'); + expect(dropdownToggleTextEl).not.toBeNull(); expect(dropdownToggleTextEl.innerText.trim()).toBe(defaultLabel); }); diff --git a/spec/javascripts/vue_shared/components/file_icon_spec.js b/spec/javascripts/vue_shared/components/file_icon_spec.js index f2a09d08829..8c1345ff52a 100644 --- a/spec/javascripts/vue_shared/components/file_icon_spec.js +++ b/spec/javascripts/vue_shared/components/file_icon_spec.js @@ -63,6 +63,7 @@ describe('File Icon component', () => { }); const { classList } = vm.$el.querySelector('i'); + expect(classList.contains('fa')).toEqual(true); expect(classList.contains('fa-spin')).toEqual(true); expect(classList.contains('fa-spinner')).toEqual(true); @@ -79,6 +80,7 @@ describe('File Icon component', () => { const { classList } = vm.$el.firstChild; const containsSizeClass = classList.contains('s120'); const containsCustomClass = classList.contains('extraclasses'); + expect(containsSizeClass).toBe(true); expect(containsCustomClass).toBe(true); }); diff --git a/spec/javascripts/vue_shared/components/gl_modal_spec.js b/spec/javascripts/vue_shared/components/gl_modal_spec.js index 263824a102a..19af8b5d2f7 100644 --- a/spec/javascripts/vue_shared/components/gl_modal_spec.js +++ b/spec/javascripts/vue_shared/components/gl_modal_spec.js @@ -48,6 +48,7 @@ describe('GlModal', () => { it('sets the modal title', () => { const modalTitle = vm.$el.querySelector('.modal-title'); + expect(modalTitle.innerHTML.trim()).toBe(props.headerTitleText); }); }); @@ -63,6 +64,7 @@ describe('GlModal', () => { it('sets the primary button class', () => { const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type'); + expect(primaryButton).toHaveClass(`btn-${props.footerPrimaryButtonVariant}`); }); }); @@ -78,6 +80,7 @@ describe('GlModal', () => { it('sets the primary button text', () => { const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type'); + expect(primaryButton.innerHTML.trim()).toBe(props.footerPrimaryButtonText); }); }); @@ -173,6 +176,7 @@ describe('GlModal', () => { it('sets the modal body', () => { const modalBody = vm.$el.querySelector('.modal-body'); + expect(modalBody.innerHTML).toBe(slotContent); }); }); @@ -184,6 +188,7 @@ describe('GlModal', () => { it('sets the modal header', () => { const modalHeader = vm.$el.querySelector('.modal-header'); + expect(modalHeader.innerHTML).toBe(slotContent); }); }); @@ -195,6 +200,7 @@ describe('GlModal', () => { it('sets the modal title', () => { const modalTitle = vm.$el.querySelector('.modal-title'); + expect(modalTitle.innerHTML).toBe(slotContent); }); }); @@ -206,6 +212,7 @@ describe('GlModal', () => { it('sets the modal footer', () => { const modalFooter = vm.$el.querySelector('.modal-footer'); + expect(modalFooter.innerHTML).toBe(slotContent); }); }); diff --git a/spec/javascripts/vue_shared/components/icon_spec.js b/spec/javascripts/vue_shared/components/icon_spec.js index 01f4649339e..f2ae6997c2a 100644 --- a/spec/javascripts/vue_shared/components/icon_spec.js +++ b/spec/javascripts/vue_shared/components/icon_spec.js @@ -48,6 +48,7 @@ describe('Sprite Icon Component', function () { const { classList } = icon.$el; const containsSizeClass = classList.contains('s32'); const containsCustomClass = classList.contains('extraclasses'); + expect(containsSizeClass).toBe(true); expect(containsCustomClass).toBe(true); }); diff --git a/spec/javascripts/vue_shared/components/loading_button_spec.js b/spec/javascripts/vue_shared/components/loading_button_spec.js index 51c19cd4080..44e3fcab77e 100644 --- a/spec/javascripts/vue_shared/components/loading_button_spec.js +++ b/spec/javascripts/vue_shared/components/loading_button_spec.js @@ -69,6 +69,7 @@ describe('LoadingButton', function () { describe('container class', () => { it('should default to btn btn-align-content', () => { vm = mountComponent(LoadingButton, {}); + expect(vm.$el.classList.contains('btn')).toEqual(true); expect(vm.$el.classList.contains('btn-align-content')).toEqual(true); }); @@ -77,6 +78,7 @@ describe('LoadingButton', function () { vm = mountComponent(LoadingButton, { containerClass: 'test-class', }); + expect(vm.$el.classList.contains('btn')).toEqual(false); expect(vm.$el.classList.contains('btn-align-content')).toEqual(false); expect(vm.$el.classList.contains('test-class')).toEqual(true); diff --git a/spec/javascripts/vue_shared/components/memory_graph_spec.js b/spec/javascripts/vue_shared/components/memory_graph_spec.js index 0982b3e1f38..588f05970f6 100644 --- a/spec/javascripts/vue_shared/components/memory_graph_spec.js +++ b/spec/javascripts/vue_shared/components/memory_graph_spec.js @@ -52,6 +52,7 @@ describe('MemoryGraph', () => { it('should show human readable median value based on provided median timestamp', () => { vm.deploymentTime = mockMedian; const formattedMedian = vm.getFormattedMedian; + expect(formattedMedian.indexOf('Deployed')).toBeGreaterThan(-1); expect(formattedMedian.indexOf('ago')).toBeGreaterThan(-1); }); @@ -62,6 +63,7 @@ describe('MemoryGraph', () => { describe('getMedianMetricIndex', () => { it('should return index of closest metric timestamp to that of median', () => { const matchingIndex = vm.getMedianMetricIndex(mockMedian, mockMetrics); + expect(matchingIndex).toBe(mockMedianIndex); }); }); @@ -69,6 +71,7 @@ describe('MemoryGraph', () => { describe('getGraphPlotValues', () => { it('should return Object containing values to plot graph', () => { const plotValues = vm.getGraphPlotValues(mockMedian, mockMetrics); + expect(plotValues.pathD).toBeDefined(); expect(Array.isArray(plotValues.pathD)).toBeTruthy(); @@ -101,16 +104,19 @@ describe('MemoryGraph', () => { Vue.nextTick(() => { const svgEl = el.querySelector('svg'); + expect(svgEl).toBeDefined(); expect(svgEl.getAttribute('height')).toBe(defaultHeight); expect(svgEl.getAttribute('width')).toBe(defaultWidth); const pathEl = el.querySelector('path'); + expect(pathEl).toBeDefined(); expect(pathEl.getAttribute('d')).toBe(`M ${pathD}`); expect(pathEl.getAttribute('viewBox')).toBe(`0 0 ${pathViewBox.lineWidth} ${pathViewBox.diff}`); const circleEl = el.querySelector('circle'); + expect(circleEl).toBeDefined(); expect(circleEl.getAttribute('r')).toBe('1.5'); expect(circleEl.getAttribute('transform')).toBe('translate(0 -1)'); diff --git a/spec/javascripts/vue_shared/components/navigation_tabs_spec.js b/spec/javascripts/vue_shared/components/navigation_tabs_spec.js index 09fda95d7d3..77e15425d85 100644 --- a/spec/javascripts/vue_shared/components/navigation_tabs_spec.js +++ b/spec/javascripts/vue_shared/components/navigation_tabs_spec.js @@ -56,6 +56,7 @@ describe('navigation tabs component', () => { it('should trigger onTabClick', () => { spyOn(vm, '$emit'); vm.$el.querySelector('.js-pipelines-tab-pending').click(); + expect(vm.$emit).toHaveBeenCalledWith('onChangeTab', 'pending'); }); }); diff --git a/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js b/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js index db665fdaad3..45f131194ca 100644 --- a/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js +++ b/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js @@ -26,6 +26,7 @@ describe('issue placeholder system note component', () => { expect(vm.$el.querySelector('.user-avatar-link').getAttribute('href')).toEqual( userDataMock.path, ); + expect(vm.$el.querySelector('.user-avatar-link img').getAttribute('src')).toEqual( `${userDataMock.avatar_url}?width=40`, ); @@ -37,6 +38,7 @@ describe('issue placeholder system note component', () => { expect(vm.$el.querySelector('.note-header-info a').getAttribute('href')).toEqual( userDataMock.path, ); + expect( vm.$el.querySelector('.note-header-info .note-headline-light').textContent.trim(), ).toEqual(`@${userDataMock.username}`); diff --git a/spec/javascripts/vue_shared/components/pagination_links_spec.js b/spec/javascripts/vue_shared/components/pagination_links_spec.js index c9d183872b4..a27dc3bfbbb 100644 --- a/spec/javascripts/vue_shared/components/pagination_links_spec.js +++ b/spec/javascripts/vue_shared/components/pagination_links_spec.js @@ -39,11 +39,11 @@ describe('Pagination links component', () => { }); it('should provide translated text to GitLab UI pagination', () => { - Object.entries(translations).forEach(entry => + Object.entries(translations).forEach(entry => { expect( - destinationComponent[entry[0]], - ).toBe(entry[1]), - ); + destinationComponent[entry[0]], + ).toBe(entry[1]) + }); }); it('should pass change to GitLab UI pagination', () => { diff --git a/spec/javascripts/vue_shared/components/panel_resizer_spec.js b/spec/javascripts/vue_shared/components/panel_resizer_spec.js index f1e62069462..58505a9df4d 100644 --- a/spec/javascripts/vue_shared/components/panel_resizer_spec.js +++ b/spec/javascripts/vue_shared/components/panel_resizer_spec.js @@ -53,6 +53,7 @@ describe('Panel Resizer component', () => { triggerEvent('mousedown', vm.$el); triggerEvent('mousemove', document); triggerEvent('mouseup', document); + expect(vm.$emit.calls.allArgs()).toEqual([['resize-start', 100], ['update:size', 100], ['resize-end', 100]]); expect(vm.size).toBe(100); }); diff --git a/spec/javascripts/vue_shared/components/pikaday_spec.js b/spec/javascripts/vue_shared/components/pikaday_spec.js index b349e2a2a81..61f05e7a230 100644 --- a/spec/javascripts/vue_shared/components/pikaday_spec.js +++ b/spec/javascripts/vue_shared/components/pikaday_spec.js @@ -24,6 +24,7 @@ describe('datePicker', () => { vm.$on('hidePicker', hidePicker); vm.$el.querySelector('.dropdown-menu-toggle').click(); + expect(hidePicker).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js b/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js index 8c296af6652..6bff1521695 100644 --- a/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js @@ -30,6 +30,7 @@ describe('collapsedCalendarIcon', () => { vm.$on('click', click); vm.$el.click(); + expect(click).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js b/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js index 9d60f9c758f..026a0c7ea09 100644 --- a/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js @@ -30,11 +30,13 @@ describe('collapsedGroupedDatePicker', () => { it('should emit when sidebar is toggled', () => { vm.$el.querySelector('.gutter-toggle').click(); + expect(vm.toggleSidebar).toHaveBeenCalled(); }); it('should emit when collapsed-calendar-icon is clicked', () => { vm.$el.querySelector('.sidebar-collapsed-icon').click(); + expect(vm.toggleSidebar).toHaveBeenCalled(); }); }); @@ -48,6 +50,7 @@ describe('collapsedGroupedDatePicker', () => { it('should render both collapsed-calendar-icon', () => { const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon'); + expect(icons.length).toEqual(2); expect(icons[0].innerText.trim()).toEqual('Jul 17 2016'); expect(icons[1].innerText.trim()).toEqual('Jul 17 2017'); @@ -62,6 +65,7 @@ describe('collapsedGroupedDatePicker', () => { it('should render minDate in collapsed-calendar-icon', () => { const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon'); + expect(icons.length).toEqual(1); expect(icons[0].innerText.trim()).toEqual('From Jul 17 2016'); }); @@ -75,6 +79,7 @@ describe('collapsedGroupedDatePicker', () => { it('should render maxDate in collapsed-calendar-icon', () => { const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon'); + expect(icons.length).toEqual(1); expect(icons[0].innerText.trim()).toEqual('Until Jul 17 2017'); }); @@ -83,6 +88,7 @@ describe('collapsedGroupedDatePicker', () => { describe('no dates', () => { it('should render None', () => { const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon'); + expect(icons.length).toEqual(1); expect(icons[0].innerText.trim()).toEqual('None'); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js b/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js index 8840a5a9dbf..1581f4e3eb1 100644 --- a/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js @@ -17,6 +17,7 @@ describe('sidebarDatePicker', () => { vm.$on('toggleCollapse', toggleCollapse); vm.$el.querySelector('.issuable-sidebar-header .gutter-toggle').click(); + expect(toggleCollapse).toHaveBeenCalled(); }); @@ -62,6 +63,7 @@ describe('sidebarDatePicker', () => { vm.isLoading = false; Vue.nextTick(() => { vm.$el.querySelector('.title .btn-blank').click(); + expect(vm.editing).toEqual(true); done(); }); @@ -92,6 +94,7 @@ describe('sidebarDatePicker', () => { vm.$on('saveDate', saveDate); vm.$el.querySelector('.value-content .btn-blank').click(); + expect(saveDate).toHaveBeenCalled(); }); }); @@ -111,6 +114,7 @@ describe('sidebarDatePicker', () => { vm.$on('toggleCollapse', toggleCollapse); vm.$el.querySelector('.title .gutter-toggle').click(); + expect(toggleCollapse).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js index e8685ab48be..c44b04009ca 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js @@ -33,6 +33,7 @@ describe('BaseComponent', () => { it('returns correct string when showCreate prop is `false`', () => { const mockConfigNonEditable = Object.assign({}, mockConfig, { showCreate: false }); const vmNonEditable = createComponent(mockConfigNonEditable); + expect(vmNonEditable.hiddenInputName).toBe('label_id[]'); vmNonEditable.$destroy(); }); @@ -46,6 +47,7 @@ describe('BaseComponent', () => { it('return `Create group label` when `isProject` prop is false', () => { const mockConfigGroup = Object.assign({}, mockConfig, { isProject: false }); const vmGroup = createComponent(mockConfigGroup); + expect(vmGroup.createLabelTitle).toBe('Create group label'); vmGroup.$destroy(); }); @@ -59,6 +61,7 @@ describe('BaseComponent', () => { it('return `Manage group labels` when `isProject` prop is false', () => { const mockConfigGroup = Object.assign({}, mockConfig, { isProject: false }); const vmGroup = createComponent(mockConfigGroup); + expect(vmGroup.manageLabelsTitle).toBe('Manage group labels'); vmGroup.$destroy(); }); @@ -70,6 +73,7 @@ describe('BaseComponent', () => { it('emits onLabelClick event with label and list of labels as params', () => { spyOn(vm, '$emit'); vm.handleClick(mockLabels[0]); + expect(vm.$emit).toHaveBeenCalledWith('onLabelClick', mockLabels[0]); }); }); @@ -78,6 +82,7 @@ describe('BaseComponent', () => { it('emits toggleCollapse event on component', () => { spyOn(vm, '$emit'); vm.handleCollapsedValueClick(); + expect(vm.$emit).toHaveBeenCalledWith('toggleCollapse'); }); }); @@ -86,6 +91,7 @@ describe('BaseComponent', () => { it('emits onDropdownClose event on component', () => { spyOn(vm, '$emit'); vm.handleDropdownHidden(); + expect(vm.$emit).toHaveBeenCalledWith('onDropdownClose'); }); }); @@ -114,6 +120,7 @@ describe('BaseComponent', () => { it('renders `.dropdown-menu` element', () => { const dropdownMenuEl = vm.$el.querySelector('.dropdown-menu'); + expect(dropdownMenuEl).not.toBeNull(); expect(dropdownMenuEl.querySelector('.dropdown-page-one')).not.toBeNull(); expect(dropdownMenuEl.querySelector('.dropdown-content')).not.toBeNull(); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js index f25c70db125..5cf6afebd7e 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js @@ -34,6 +34,7 @@ describe('DropdownButtonComponent', () => { it('returns text as `Label` when `labels` prop is empty array', () => { const mockEmptyLabels = Object.assign({}, componentConfig, { labels: [] }); const vmEmptyLabels = createComponent(mockEmptyLabels); + expect(vmEmptyLabels.dropdownToggleText).toBe('Label'); vmEmptyLabels.$destroy(); }); @@ -43,6 +44,7 @@ describe('DropdownButtonComponent', () => { labels: mockLabels.concat(mockLabels), }); const vmMoreLabels = createComponent(mockMoreLabels); + expect(vmMoreLabels.dropdownToggleText).toBe('Foo Label +1 more'); vmMoreLabels.$destroy(); }); @@ -69,12 +71,14 @@ describe('DropdownButtonComponent', () => { it('renders dropdown toggle text element', () => { const dropdownToggleTextEl = vm.$el.querySelector('.dropdown-toggle-text'); + expect(dropdownToggleTextEl).not.toBeNull(); expect(dropdownToggleTextEl.innerText.trim()).toBe('Foo Label'); }); it('renders dropdown button icon', () => { const dropdownIconEl = vm.$el.querySelector('i.fa'); + expect(dropdownIconEl).not.toBeNull(); expect(dropdownIconEl.classList.contains('fa-chevron-down')).toBe(true); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js index ce559fe0335..d729848a184 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js @@ -39,12 +39,14 @@ describe('DropdownCreateLabelComponent', () => { it('renders `Go back` button on component header', () => { const backButtonEl = vm.$el.querySelector('.dropdown-title button.dropdown-title-button.dropdown-menu-back'); + expect(backButtonEl).not.toBe(null); expect(backButtonEl.querySelector('.fa-arrow-left')).not.toBe(null); }); it('renders component header element as `Create new label` when `headerTitle` prop is not provided', () => { const headerEl = vm.$el.querySelector('.dropdown-title'); + expect(headerEl.innerText.trim()).toContain('Create new label'); }); @@ -52,12 +54,14 @@ describe('DropdownCreateLabelComponent', () => { const headerTitle = 'Create project label'; const vmWithHeaderTitle = createComponent(headerTitle); const headerEl = vmWithHeaderTitle.$el.querySelector('.dropdown-title'); + expect(headerEl.innerText.trim()).toContain(headerTitle); vmWithHeaderTitle.$destroy(); }); it('renders `Close` button on component header', () => { const closeButtonEl = vm.$el.querySelector('.dropdown-title button.dropdown-title-button.dropdown-menu-close'); + expect(closeButtonEl).not.toBe(null); expect(closeButtonEl.querySelector('.fa-times.dropdown-menu-close-icon')).not.toBe(null); }); @@ -69,10 +73,12 @@ describe('DropdownCreateLabelComponent', () => { it('renders suggested colors list elements', () => { const colorsListContainerEl = vm.$el.querySelector('.suggest-colors.suggest-colors-dropdown'); + expect(colorsListContainerEl).not.toBe(null); expect(colorsListContainerEl.querySelectorAll('a').length).toBe(mockSuggestedColors.length); const colorItemEl = colorsListContainerEl.querySelectorAll('a')[0]; + expect(colorItemEl.dataset.color).toBe(vm.suggestedColors[0]); expect(colorItemEl.getAttribute('style')).toBe('background-color: rgb(0, 51, 204);'); }); @@ -86,6 +92,7 @@ describe('DropdownCreateLabelComponent', () => { it('renders component action buttons', () => { const createBtnEl = vm.$el.querySelector('button.js-new-label-btn'); const cancelBtnEl = vm.$el.querySelector('button.js-cancel-label-btn'); + expect(createBtnEl).not.toBe(null); expect(createBtnEl.innerText.trim()).toBe('Create'); expect(cancelBtnEl.innerText.trim()).toBe('Cancel'); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js index debeab25bd6..e242dfbfe87 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js @@ -36,6 +36,7 @@ describe('DropdownFooterComponent', () => { describe('template', () => { it('renders link element with `Create new label` when `createLabelTitle` prop is not provided', () => { const createLabelEl = vm.$el.querySelector('.dropdown-footer-list .dropdown-toggle-page'); + expect(createLabelEl).not.toBeNull(); expect(createLabelEl.innerText.trim()).toBe('Create new label'); }); @@ -43,12 +44,14 @@ describe('DropdownFooterComponent', () => { it('renders link element with value of `createLabelTitle` prop', () => { const vmWithCreateLabelTitle = createComponent(mockConfig.labelsWebUrl, createLabelTitle); const createLabelEl = vmWithCreateLabelTitle.$el.querySelector('.dropdown-footer-list .dropdown-toggle-page'); + expect(createLabelEl.innerText.trim()).toBe(createLabelTitle); vmWithCreateLabelTitle.$destroy(); }); it('renders link element with `Manage labels` when `manageLabelsTitle` prop is not provided', () => { const manageLabelsEl = vm.$el.querySelector('.dropdown-footer-list .dropdown-external-link'); + expect(manageLabelsEl).not.toBeNull(); expect(manageLabelsEl.getAttribute('href')).toBe(vm.labelsWebUrl); expect(manageLabelsEl.innerText.trim()).toBe('Manage labels'); @@ -61,6 +64,7 @@ describe('DropdownFooterComponent', () => { manageLabelsTitle, ); const manageLabelsEl = vmWithManageLabelsTitle.$el.querySelector('.dropdown-footer-list .dropdown-external-link'); + expect(manageLabelsEl.innerText.trim()).toBe(manageLabelsTitle); vmWithManageLabelsTitle.$destroy(); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js index cdf234bb0c4..e8fcf51135c 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js @@ -24,11 +24,13 @@ describe('DropdownHeaderComponent', () => { describe('template', () => { it('renders header text element', () => { const headerEl = vm.$el.querySelector('.dropdown-title span'); + expect(headerEl.innerText.trim()).toBe('Assign labels'); }); it('renders `Close` button element', () => { const closeBtnEl = vm.$el.querySelector('.dropdown-title button.dropdown-title-button.dropdown-menu-close'); + expect(closeBtnEl).not.toBeNull(); expect(closeBtnEl.querySelector('.fa-times.dropdown-menu-close-icon')).not.toBeNull(); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js index 57608d957e7..deef7dc5eeb 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js @@ -24,6 +24,7 @@ describe('DropdownSearchInputComponent', () => { describe('template', () => { it('renders input element with type `search`', () => { const inputEl = vm.$el.querySelector('input.dropdown-input-field'); + expect(inputEl).not.toBeNull(); expect(inputEl.getAttribute('type')).toBe('search'); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js index 7c3d2711f65..6c84d2e167c 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js @@ -35,6 +35,7 @@ describe('DropdownTitleComponent', () => { it('renders `Edit` button element', () => { const editBtnEl = vm.$el.querySelector('button.edit-link.js-sidebar-dropdown-toggle'); + expect(editBtnEl).not.toBeNull(); expect(editBtnEl.innerText.trim()).toBe('Edit'); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js index da74595bcdc..9a691116cf8 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js @@ -29,12 +29,14 @@ describe('DropdownValueCollapsedComponent', () => { describe('labelsList', () => { it('returns empty text when `labels` prop is empty array', () => { const vmEmptyLabels = createComponent([]); + expect(vmEmptyLabels.labelsList).toBe(''); vmEmptyLabels.$destroy(); }); it('returns labels names separated by coma when `labels` prop has more than one item', () => { const vmMoreLabels = createComponent(mockLabels.concat(mockLabels)); + expect(vmMoreLabels.labelsList).toBe('Foo Label, Foo Label'); vmMoreLabels.$destroy(); }); @@ -46,6 +48,7 @@ describe('DropdownValueCollapsedComponent', () => { } const vmMoreLabels = createComponent(mockMoreLabels); + expect(vmMoreLabels.labelsList).toBe('Foo Label, Foo Label, Foo Label, Foo Label, Foo Label, and 2 more'); vmMoreLabels.$destroy(); }); @@ -61,6 +64,7 @@ describe('DropdownValueCollapsedComponent', () => { it('emits onValueClick event on component', () => { spyOn(vm, '$emit'); vm.handleClick(); + expect(vm.$emit).toHaveBeenCalledWith('onValueClick'); }); }); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js index 370a296bd8f..bef7143da42 100644 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js +++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js @@ -33,6 +33,7 @@ describe('DropdownValueComponent', () => { describe('isEmpty', () => { it('returns true if `labels` prop is empty', () => { const vmEmptyLabels = createComponent([]); + expect(vmEmptyLabels.isEmpty).toBe(true); vmEmptyLabels.$destroy(); }); @@ -73,6 +74,7 @@ describe('DropdownValueComponent', () => { it('render slot content inside component when `labels` prop is empty', () => { const vmEmptyLabels = createComponent([]); + expect(vmEmptyLabels.$el.querySelector('.text-secondary').innerText.trim()).toBe(mockConfig.emptyValueText); vmEmptyLabels.$destroy(); }); @@ -83,6 +85,7 @@ describe('DropdownValueComponent', () => { it('renders label element with tooltip and styles based on label details', () => { const labelEl = vm.$el.querySelector('a span.badge.color-label'); + expect(labelEl).not.toBeNull(); expect(labelEl.dataset.placement).toBe('bottom'); expect(labelEl.dataset.container).toBe('body'); diff --git a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js index f1fe2e996fc..568bc502119 100644 --- a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js +++ b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js @@ -72,6 +72,7 @@ describe('StackedProgressBarComponent', () => { it('renders empty state when count is unavailable', () => { const vmX = createComponent({ totalCount: 0, successCount: 0, failureCount: 0 }); + expect(vmX.$el.querySelectorAll('.status-unavailable').length).not.toBe(0); vmX.$destroy(); }); diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js b/spec/javascripts/vue_shared/components/table_pagination_spec.js index d193667210b..8dfcfb82ba4 100644 --- a/spec/javascripts/vue_shared/components/table_pagination_spec.js +++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js @@ -72,6 +72,7 @@ describe('Pagination component', () => { }); component.$el.querySelector('.js-previous-button a').click(); + expect(spy).toHaveBeenCalledWith(1); }); }); diff --git a/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js b/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js index b4fb568f1d4..1c7c88f4bda 100644 --- a/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js +++ b/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js @@ -25,6 +25,7 @@ describe('Time ago with tooltip component', () => { expect( vm.$el.getAttribute('data-original-title'), ).toEqual(formatDate('2017-05-08T14:57:39.781Z')); + expect(vm.$el.getAttribute('data-placement')).toEqual('top'); const timeago = getTimeago(); diff --git a/spec/javascripts/vue_shared/components/toggle_button_spec.js b/spec/javascripts/vue_shared/components/toggle_button_spec.js index 71952cc39e0..444ca451534 100644 --- a/spec/javascripts/vue_shared/components/toggle_button_spec.js +++ b/spec/javascripts/vue_shared/components/toggle_button_spec.js @@ -51,9 +51,11 @@ describe('Toggle Button', () => { it('sets aria-label representing toggle state', () => { vm.value = true; + expect(vm.ariaLabel).toEqual('Toggle Status: ON'); vm.value = false; + expect(vm.ariaLabel).toEqual('Toggle Status: OFF'); }); diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js index 4c5c242cbb3..1b496bbabca 100644 --- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js +++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js @@ -59,6 +59,7 @@ describe('User Avatar Link Component', function () { it('should only render image tag in link', function () { const childElements = this.userAvatarLink.$el.childNodes; + expect(childElements[0].tagName).toBe('IMG'); // Vue will render the hidden component as <!----> diff --git a/spec/javascripts/zen_mode_spec.js b/spec/javascripts/zen_mode_spec.js index bdeebe0de75..e5f1e6ae937 100644 --- a/spec/javascripts/zen_mode_spec.js +++ b/spec/javascripts/zen_mode_spec.js @@ -46,12 +46,14 @@ describe('ZenMode', () => { it('should not call dropzone if element is not dropzone valid', () => { $('.div-dropzone').addClass('js-invalid-dropzone'); exitZen(); + expect(dropzoneForElementSpy.calls.count()).toEqual(0); }); it('should call dropzone if element is dropzone valid', () => { $('.div-dropzone').removeClass('js-invalid-dropzone'); exitZen(); + expect(dropzoneForElementSpy.calls.count()).toEqual(2); }); }); @@ -60,12 +62,14 @@ describe('ZenMode', () => { it('pauses Mousetrap', () => { const mouseTrapPauseSpy = spyOn(Mousetrap, 'pause'); enterZen(); + expect(mouseTrapPauseSpy).toHaveBeenCalled(); }); it('removes textarea styling', () => { $('.notes-form textarea').attr('style', 'height: 400px'); enterZen(); + expect($('.notes-form textarea')).not.toHaveAttr('style'); }); }); @@ -75,6 +79,7 @@ describe('ZenMode', () => { it('exits on Escape', () => { escapeKeydown(); + expect($('.notes-form .zen-backdrop')).not.toHaveClass('fullscreen'); }); }); @@ -85,12 +90,14 @@ describe('ZenMode', () => { it('unpauses Mousetrap', () => { const mouseTrapUnpauseSpy = spyOn(Mousetrap, 'unpause'); exitZen(); + expect(mouseTrapUnpauseSpy).toHaveBeenCalled(); }); it('restores the scroll position', () => { spyOn(zen, 'scrollTo'); exitZen(); + expect(zen.scrollTo).toHaveBeenCalled(); }); }); |