diff options
Diffstat (limited to 'spec/javascripts')
39 files changed, 227 insertions, 88 deletions
diff --git a/spec/javascripts/.eslintrc.yml b/spec/javascripts/.eslintrc.yml index 9b2c84ce9f5..1448849a0b7 100644 --- a/spec/javascripts/.eslintrc.yml +++ b/spec/javascripts/.eslintrc.yml @@ -37,7 +37,5 @@ rules: - 'fixtures/blob' # Temporarily disabled to facilitate an upgrade to eslint-plugin-jasmine jasmine/new-line-before-expect: off - jasmine/new-line-between-declarations: off jasmine/no-promise-without-done-fail: off - jasmine/prefer-jasmine-matcher: off jasmine/prefer-toHaveBeenCalledWith: off diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js index 0c5d68990d5..3f84a46e8d9 100644 --- a/spec/javascripts/awards_handler_spec.js +++ b/spec/javascripts/awards_handler_spec.js @@ -55,6 +55,7 @@ import '~/lib/utils/common_utils'; }); }; }); + afterEach(function() { // restore original url root value gon.relative_url_root = urlRoot; @@ -64,6 +65,7 @@ import '~/lib/utils/common_utils'; awardsHandler.destroy(); }); + describe('::showEmojiMenu', function() { it('should show emoji menu when Add emoji button clicked', function(done) { $('.js-add-award') @@ -78,6 +80,7 @@ import '~/lib/utils/common_utils'; return expect($('.js-awards-block.current').length).toBe(1); }); }); + it('should also show emoji menu for the smiley icon in notes', function(done) { $('.js-add-award.note-action-button').click(); return lazyAssert(done, function() { @@ -85,6 +88,7 @@ import '~/lib/utils/common_utils'; return expect($emojiMenu.length).toBe(1); }); }); + it('should remove emoji menu when body is clicked', function(done) { $('.js-add-award') .eq(0) @@ -98,6 +102,7 @@ import '~/lib/utils/common_utils'; return expect($('.js-awards-block.current').length).toBe(0); }); }); + it('should not remove emoji menu when search is clicked', function(done) { $('.js-add-award') .eq(0) @@ -123,6 +128,7 @@ import '~/lib/utils/common_utils'; expect($emojiButton.next('.js-counter').text()).toBe('1'); return expect($votesBlock.hasClass('hidden')).toBe(false); }); + it('should remove the emoji when we click again', function() { var $emojiButton, $votesBlock; $votesBlock = $('.js-awards-block').eq(0); @@ -142,6 +148,7 @@ import '~/lib/utils/common_utils'; return expect($emojiButton.next('.js-counter').text()).toBe('4'); }); }); + describe('::userAuthored', function() { it('should update tooltip to user authored title', function() { var $thumbsUpEmoji, $votesBlock; @@ -153,6 +160,7 @@ import '~/lib/utils/common_utils'; 'You cannot vote on your own issue, MR and note', ); }); + it('should restore tooltip back to initial vote list', function() { var $thumbsUpEmoji, $votesBlock; jasmine.clock().install(); @@ -165,6 +173,7 @@ import '~/lib/utils/common_utils'; return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam'); }); }); + describe('::getAwardUrl', function() { return it('returns the url for request', function() { return expect(awardsHandler.getAwardUrl()).toBe( @@ -172,6 +181,7 @@ import '~/lib/utils/common_utils'; ); }); }); + describe('::addAward and ::checkMutuality', function() { return it('should handle :+1: and :-1: mutuality', function() { var $thumbsDownEmoji, $thumbsUpEmoji, $votesBlock, awardUrl; @@ -189,6 +199,7 @@ import '~/lib/utils/common_utils'; return expect($thumbsDownEmoji.hasClass('active')).toBe(true); }); }); + describe('::removeEmoji', function() { return it('should remove emoji', function() { var $votesBlock, awardUrl; @@ -200,6 +211,7 @@ import '~/lib/utils/common_utils'; return expect($votesBlock.find('[data-name=fire]').length).toBe(0); }); }); + describe('::addYouToUserList', function() { it('should prepend "You" to the award tooltip', function() { var $thumbsUpEmoji, $votesBlock, awardUrl; @@ -222,6 +234,7 @@ import '~/lib/utils/common_utils'; return expect($thumbsUpEmoji.data('originalTitle')).toBe('You and sam'); }); }); + describe('::removeYouToUserList', function() { it('removes "You" from the front of the tooltip', function() { var $thumbsUpEmoji, $votesBlock, awardUrl; @@ -246,6 +259,7 @@ import '~/lib/utils/common_utils'; return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam'); }); }); + describe('::searchEmojis', () => { it('should filter the emoji', function(done) { return openAndWaitForEmojiMenu() @@ -263,6 +277,7 @@ import '~/lib/utils/common_utils'; done.fail(`Failed to open and build emoji menu: ${err.message}`); }); }); + it('should clear the search when searching for nothing', function(done) { return openAndWaitForEmojiMenu() .then(() => { @@ -305,6 +320,7 @@ import '~/lib/utils/common_utils'; done.fail(`Failed to open and build emoji menu: ${err.message}`); }); }); + it('should remove already selected emoji', function(done) { return openEmojiMenuAndAddEmoji() .then(() => { diff --git a/spec/javascripts/behaviors/quick_submit_spec.js b/spec/javascripts/behaviors/quick_submit_spec.js index d8aa5c636da..b3a5eac8982 100644 --- a/spec/javascripts/behaviors/quick_submit_spec.js +++ b/spec/javascripts/behaviors/quick_submit_spec.js @@ -58,12 +58,14 @@ describe('Quick Submit behavior', function () { expect(submitButton).toBeDisabled(); }); + it('disables button of type submit', () => { const submitButton = $('.js-quick-submit input[type=submit]'); this.textarea.trigger(keydownEvent()); expect(submitButton).toBeDisabled(); }); + it('only clicks one submit', () => { const existingSubmit = $('.js-quick-submit input[type=submit]'); // Add an extra submit button diff --git a/spec/javascripts/bootstrap_jquery_spec.js b/spec/javascripts/bootstrap_jquery_spec.js index 052465d8d88..cd61d920fa0 100644 --- a/spec/javascripts/bootstrap_jquery_spec.js +++ b/spec/javascripts/bootstrap_jquery_spec.js @@ -9,6 +9,7 @@ import '~/commons/bootstrap'; beforeEach(function() { return setFixtures('<input type="text" />'); }); + it('adds the disabled attribute', function() { var $input; $input = $('input').first(); @@ -26,6 +27,7 @@ import '~/commons/bootstrap'; beforeEach(function() { return setFixtures('<input type="text" disabled="disabled" class="disabled" />'); }); + it('removes the disabled attribute', function() { var $input; $input = $('input').first(); diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js index 6c3e73f134e..24e4871ce44 100644 --- a/spec/javascripts/datetime_utility_spec.js +++ b/spec/javascripts/datetime_utility_spec.js @@ -158,9 +158,9 @@ describe('getTimeframeWindowFrom', () => { const timeframe = datetimeUtility.getTimeframeWindowFrom(startDate, 5); expect(timeframe.length).toBe(5); timeframe.forEach((timeframeItem, index) => { - expect(timeframeItem.getFullYear() === mockTimeframe[index].getFullYear()).toBe(true); - expect(timeframeItem.getMonth() === mockTimeframe[index].getMonth()).toBe(true); - expect(timeframeItem.getDate() === mockTimeframe[index].getDate()).toBeTruthy(); + expect(timeframeItem.getFullYear()).toBe(mockTimeframe[index].getFullYear()); + expect(timeframeItem.getMonth()).toBe(mockTimeframe[index].getMonth()); + expect(timeframeItem.getDate()).toBe(mockTimeframe[index].getDate()); }); }); }); diff --git a/spec/javascripts/diffs/components/diff_file_header_spec.js b/spec/javascripts/diffs/components/diff_file_header_spec.js index c986ea604b2..1f7d5f42322 100644 --- a/spec/javascripts/diffs/components/diff_file_header_spec.js +++ b/spec/javascripts/diffs/components/diff_file_header_spec.js @@ -6,6 +6,8 @@ import DiffFileHeader from '~/diffs/components/diff_file_header.vue'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; +Vue.use(Vuex); + const discussionFixture = 'merge_requests/diff_discussion.json'; describe('diff_file_header', () => { @@ -58,19 +60,19 @@ describe('diff_file_header', () => { describe('titleLink', () => { beforeEach(() => { + props.discussionPath = 'link://to/discussion'; Object.assign(props.diffFile, { - fileHash: 'badc0ffee', submoduleLink: 'link://to/submodule', submoduleTreeUrl: 'some://tree/url', }); }); - it('returns the fileHash for files', () => { + it('returns the discussionPath for files', () => { props.diffFile.submodule = false; vm = mountComponentWithStore(Component, { props, store }); - expect(vm.titleLink).toBe(`#${props.diffFile.fileHash}`); + expect(vm.titleLink).toBe(props.discussionPath); }); it('returns the submoduleTreeUrl for submodules', () => { @@ -91,6 +93,13 @@ describe('diff_file_header', () => { expect(vm.titleLink).toBe(props.diffFile.submoduleLink); }); + + it('sets the correct path to the discussion', () => { + 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); + }); }); describe('filePath', () => { diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/javascripts/diffs/components/diff_file_spec.js index 13859f43e98..b8d4b31ee04 100644 --- a/spec/javascripts/diffs/components/diff_file_spec.js +++ b/spec/javascripts/diffs/components/diff_file_spec.js @@ -24,14 +24,14 @@ describe('DiffFile', () => { expect(el.querySelectorAll('.diff-content.hidden').length).toEqual(0); expect(el.querySelector('.js-file-title')).toBeDefined(); - expect(el.querySelector('.file-title-name').innerText.indexOf(filePath) > -1).toEqual(true); + expect(el.querySelector('.file-title-name').innerText.indexOf(filePath)).toBeGreaterThan(-1); expect(el.querySelector('.js-syntax-highlight')).toBeDefined(); expect(vm.file.renderIt).toEqual(false); vm.file.renderIt = true; vm.$nextTick(() => { - expect(el.querySelectorAll('.line_content').length > 5).toEqual(true); + expect(el.querySelectorAll('.line_content').length).toBeGreaterThan(5); }); }); @@ -98,9 +98,7 @@ describe('DiffFile', () => { '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) > -1).toEqual( - true, - ); + expect(vm.$el.querySelector('.js-too-large-diff a').href.indexOf(BLOB_LINK)).toBeGreaterThan(-1); done(); }); 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 663c0680845..f36454cc23e 100644 --- a/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js +++ b/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js @@ -94,7 +94,7 @@ describe('DiffLineGutterContent', () => { const component = createComponent({ lineNumber, lineCode }); const link = component.$el.querySelector('a'); - expect(link.href.indexOf(`#${lineCode}`) > -1).toEqual(true); + expect(link.href.indexOf(`#${lineCode}`)).toBeGreaterThan(-1); expect(link.dataset.linenumber).toEqual(lineNumber.toString()); }); diff --git a/spec/javascripts/diffs/components/inline_diff_view_spec.js b/spec/javascripts/diffs/components/inline_diff_view_spec.js index b02328dd359..705558e860b 100644 --- a/spec/javascripts/diffs/components/inline_diff_view_spec.js +++ b/spec/javascripts/diffs/components/inline_diff_view_spec.js @@ -27,7 +27,7 @@ describe('InlineDiffView', () => { expect(el.querySelectorAll('tr.line_holder').length).toEqual(6); expect(el.querySelectorAll('tr.line_holder.new').length).toEqual(2); expect(el.querySelectorAll('tr.line_holder.match').length).toEqual(1); - expect(el.textContent.indexOf('Bad dates') > -1).toEqual(true); + expect(el.textContent.indexOf('Bad dates')).toBeGreaterThan(-1); }); it('should render discussions', done => { @@ -37,7 +37,7 @@ describe('InlineDiffView', () => { Vue.nextTick(() => { expect(el.querySelectorAll('.notes_holder').length).toEqual(1); expect(el.querySelectorAll('.notes_holder .note-discussion li').length).toEqual(5); - expect(el.innerText.indexOf('comment 5') > -1).toEqual(true); + expect(el.innerText.indexOf('comment 5')).toBeGreaterThan(-1); component.$store.dispatch('setInitialNotes', []); done(); diff --git a/spec/javascripts/emoji_spec.js b/spec/javascripts/emoji_spec.js index 124d91f4477..629422780e8 100644 --- a/spec/javascripts/emoji_spec.js +++ b/spec/javascripts/emoji_spec.js @@ -140,6 +140,7 @@ describe('gl_emoji', () => { }, ); }); + it('bomb emoji with sprite fallback', () => { const emojiKey = 'bomb'; const markup = glEmojiTag(emojiFixtureMap[emojiKey].name, { @@ -195,24 +196,31 @@ describe('gl_emoji', () => { it('should gracefully handle empty string', () => { expect(isFlagEmoji('')).toBeFalsy(); }); + it('should detect flag_ac', () => { expect(isFlagEmoji('🇦🇨')).toBeTruthy(); }); + it('should detect flag_us', () => { expect(isFlagEmoji('🇺🇸')).toBeTruthy(); }); + it('should detect flag_zw', () => { expect(isFlagEmoji('🇿🇼')).toBeTruthy(); }); + it('should not detect flags', () => { expect(isFlagEmoji('🎏')).toBeFalsy(); }); + it('should not detect triangular_flag_on_post', () => { expect(isFlagEmoji('🚩')).toBeFalsy(); }); + it('should not detect single letter', () => { expect(isFlagEmoji('🇦')).toBeFalsy(); }); + it('should not detect >2 letters', () => { expect(isFlagEmoji('🇦🇧🇨')).toBeFalsy(); }); @@ -222,15 +230,19 @@ describe('gl_emoji', () => { it('should gracefully handle empty string', () => { expect(isRainbowFlagEmoji('')).toBeFalsy(); }); + it('should detect rainbow_flag', () => { expect(isRainbowFlagEmoji('🏳🌈')).toBeTruthy(); }); + it('should not detect flag_white on its\' own', () => { expect(isRainbowFlagEmoji('🏳')).toBeFalsy(); }); + it('should not detect rainbow on its\' own', () => { expect(isRainbowFlagEmoji('🌈')).toBeFalsy(); }); + it('should not detect flag_white with something else', () => { expect(isRainbowFlagEmoji('🏳🔵')).toBeFalsy(); }); @@ -240,15 +252,19 @@ describe('gl_emoji', () => { it('should gracefully handle empty string', () => { expect(isKeycapEmoji('')).toBeFalsy(); }); + it('should detect one(keycap)', () => { expect(isKeycapEmoji('1️⃣')).toBeTruthy(); }); + it('should detect nine(keycap)', () => { expect(isKeycapEmoji('9️⃣')).toBeTruthy(); }); + it('should not detect ten(keycap)', () => { expect(isKeycapEmoji('🔟')).toBeFalsy(); }); + it('should not detect hash(keycap)', () => { expect(isKeycapEmoji('#⃣')).toBeFalsy(); }); @@ -258,24 +274,31 @@ describe('gl_emoji', () => { it('should gracefully handle empty string', () => { expect(isSkinToneComboEmoji('')).toBeFalsy(); }); + it('should detect hand_splayed_tone5', () => { expect(isSkinToneComboEmoji('🖐🏿')).toBeTruthy(); }); + it('should not detect hand_splayed', () => { expect(isSkinToneComboEmoji('🖐')).toBeFalsy(); }); + it('should detect lifter_tone1', () => { expect(isSkinToneComboEmoji('🏋🏻')).toBeTruthy(); }); + it('should not detect lifter', () => { expect(isSkinToneComboEmoji('🏋')).toBeFalsy(); }); + it('should detect rowboat_tone4', () => { expect(isSkinToneComboEmoji('🚣🏾')).toBeTruthy(); }); + it('should not detect rowboat', () => { expect(isSkinToneComboEmoji('🚣')).toBeFalsy(); }); + it('should not detect individual tone emoji', () => { expect(isSkinToneComboEmoji('🏻')).toBeFalsy(); }); @@ -285,9 +308,11 @@ describe('gl_emoji', () => { it('should gracefully handle empty string', () => { expect(isHorceRacingSkinToneComboEmoji('')).toBeFalsy(); }); + it('should detect horse_racing_tone2', () => { expect(isHorceRacingSkinToneComboEmoji('🏇🏼')).toBeTruthy(); }); + it('should not detect horse_racing', () => { expect(isHorceRacingSkinToneComboEmoji('🏇')).toBeFalsy(); }); @@ -297,36 +322,47 @@ describe('gl_emoji', () => { it('should gracefully handle empty string', () => { expect(isPersonZwjEmoji('')).toBeFalsy(); }); + it('should detect couple_mm', () => { expect(isPersonZwjEmoji('👨❤️👨')).toBeTruthy(); }); + it('should not detect couple_with_heart', () => { expect(isPersonZwjEmoji('💑')).toBeFalsy(); }); + it('should not detect couplekiss', () => { expect(isPersonZwjEmoji('💏')).toBeFalsy(); }); + it('should detect family_mmb', () => { expect(isPersonZwjEmoji('👨👨👦')).toBeTruthy(); }); + it('should detect family_mwgb', () => { expect(isPersonZwjEmoji('👨👩👧👦')).toBeTruthy(); }); + it('should not detect family', () => { expect(isPersonZwjEmoji('👪')).toBeFalsy(); }); + it('should detect kiss_ww', () => { expect(isPersonZwjEmoji('👩❤️💋👩')).toBeTruthy(); }); + it('should not detect girl', () => { expect(isPersonZwjEmoji('👧')).toBeFalsy(); }); + it('should not detect girl_tone5', () => { expect(isPersonZwjEmoji('👧🏿')).toBeFalsy(); }); + it('should not detect man', () => { expect(isPersonZwjEmoji('👨')).toBeFalsy(); }); + it('should not detect woman', () => { expect(isPersonZwjEmoji('👩')).toBeFalsy(); }); @@ -341,6 +377,7 @@ describe('gl_emoji', () => { ); expect(isSupported).toBeTruthy(); }); + it('should gracefully handle empty string without unicode support', () => { const isSupported = isEmojiUnicodeSupported( {}, @@ -349,6 +386,7 @@ describe('gl_emoji', () => { ); expect(isSupported).toBeFalsy(); }); + it('bomb(6.0) with 6.0 support', () => { const emojiKey = 'bomb'; const unicodeSupportMap = Object.assign({}, emptySupportMap, { diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js index 68bbbf838da..3dc8089cd83 100644 --- a/spec/javascripts/filtered_search/dropdown_utils_spec.js +++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js @@ -237,7 +237,7 @@ describe('Dropdown Utils', () => { it('should not linear-gradient more than 4 colors', () => { const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333', '#DDDDDD', '#EEEEEE']); - expect(gradient.indexOf('#EEEEEE') === -1).toEqual(true); + expect(gradient.indexOf('#EEEEEE')).toBe(-1); }); }); 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 ab0ab72720e..cf7789a1d57 100644 --- a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js @@ -19,7 +19,7 @@ describe('Filtered Search Token Keys', () => { describe('get', () => { it('should return tokenKeys', () => { - expect(new FilteredSearchTokenKeys().get() !== null).toBe(true); + expect(new FilteredSearchTokenKeys().get()).not.toBeNull(); }); it('should return tokenKeys as an array', () => { @@ -40,7 +40,7 @@ describe('Filtered Search Token Keys', () => { describe('getConditions', () => { it('should return conditions', () => { - expect(new FilteredSearchTokenKeys().getConditions() !== null).toBe(true); + expect(new FilteredSearchTokenKeys().getConditions()).not.toBeNull(); }); it('should return conditions as an array', () => { @@ -51,7 +51,7 @@ describe('Filtered Search Token Keys', () => { describe('searchByKey', () => { it('should return null when key not found', () => { const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchByKey('notakey'); - expect(tokenKey === null).toBe(true); + expect(tokenKey).toBeNull(); }); it('should return tokenKey when found by key', () => { @@ -63,7 +63,7 @@ describe('Filtered Search Token Keys', () => { describe('searchBySymbol', () => { it('should return null when symbol not found', () => { const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchBySymbol('notasymbol'); - expect(tokenKey === null).toBe(true); + expect(tokenKey).toBeNull(); }); it('should return tokenKey when found by symbol', () => { @@ -75,7 +75,7 @@ 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 === null).toBe(true); + expect(tokenKey).toBeNull(); }); it('should return tokenKey when found by key param', () => { @@ -92,7 +92,7 @@ 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 === null).toBe(true); + expect(condition).toBeNull(); }); it('should return condition when found by url', () => { @@ -106,7 +106,7 @@ 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 === null).toBe(true); + expect(condition).toBeNull(); }); it('should return condition when found by tokenKey and value', () => { diff --git a/spec/javascripts/gl_dropdown_spec.js b/spec/javascripts/gl_dropdown_spec.js index 25b819543da..62c87642184 100644 --- a/spec/javascripts/gl_dropdown_spec.js +++ b/spec/javascripts/gl_dropdown_spec.js @@ -168,9 +168,9 @@ describe('glDropdown', function describeDropdown() { it('should show loading indicator while search results are being fetched by backend', () => { const dropdownMenu = document.querySelector('.dropdown-menu'); - expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(true); + expect(dropdownMenu.className.indexOf('is-loading')).not.toBe(-1); remoteCallback(); - expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(false); + expect(dropdownMenu.className.indexOf('is-loading')).toBe(-1); }); it('should not focus search input while remote task is not complete', () => { diff --git a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js index 02d1ca1cc3b..8854d3d554a 100644 --- a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js +++ b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js @@ -205,10 +205,12 @@ describe("ContributorsStatGraphUtil", function () { it("returns true if date_range is null", function () { expect(ContributorsStatGraphUtil.in_range(date, null)).toEqual(true); }); + 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/group_item_spec.js b/spec/javascripts/groups/components/group_item_spec.js index d0cac5efc40..49d4f7efd72 100644 --- a/spec/javascripts/groups/components/group_item_spec.js +++ b/spec/javascripts/groups/components/group_item_spec.js @@ -45,7 +45,7 @@ describe('GroupItemComponent', () => { expect(Object.keys(rowClass).length).toBe(classes.length); Object.keys(rowClass).forEach((className) => { - expect(classes.indexOf(className) > -1).toBeTruthy(); + expect(classes.indexOf(className)).toBeGreaterThan(-1); }); }); }); diff --git a/spec/javascripts/groups/components/groups_spec.js b/spec/javascripts/groups/components/groups_spec.js index 793c4909d89..5af86b55532 100644 --- a/spec/javascripts/groups/components/groups_spec.js +++ b/spec/javascripts/groups/components/groups_spec.js @@ -53,7 +53,7 @@ describe('GroupsComponent', () => { expect(vm.$el.querySelector('.groups-list-tree-container')).toBeDefined(); expect(vm.$el.querySelector('.group-list-tree')).toBeDefined(); expect(vm.$el.querySelector('.gl-pagination')).toBeDefined(); - expect(vm.$el.querySelectorAll('.has-no-search-results').length === 0).toBeTruthy(); + expect(vm.$el.querySelectorAll('.has-no-search-results').length).toBe(0); done(); }); }); diff --git a/spec/javascripts/groups/components/item_stats_spec.js b/spec/javascripts/groups/components/item_stats_spec.js index ee7ee18259e..e6a57495eb1 100644 --- a/spec/javascripts/groups/components/item_stats_spec.js +++ b/spec/javascripts/groups/components/item_stats_spec.js @@ -107,7 +107,7 @@ describe('ItemStatsComponent', () => { const visibilityIconEl = vm.$el.querySelector('.item-visibility'); expect(visibilityIconEl).not.toBe(null); expect(visibilityIconEl.dataset.originalTitle).toBe(vm.visibilityTooltip); - expect(visibilityIconEl.querySelectorAll('svg').length > 0).toBeTruthy(); + expect(visibilityIconEl.querySelectorAll('svg').length).toBeGreaterThan(0); vm.$destroy(); }); @@ -120,10 +120,10 @@ describe('ItemStatsComponent', () => { const vm = createComponent(item); const projectStarIconEl = vm.$el.querySelector('.project-stars'); - expect(projectStarIconEl).not.toBe(null); - expect(projectStarIconEl.querySelectorAll('svg').length > 0).toBeTruthy(); - expect(projectStarIconEl.querySelectorAll('.stat-value').length > 0).toBeTruthy(); - expect(vm.$el.querySelectorAll('.last-updated').length > 0).toBeTruthy(); + expect(projectStarIconEl).not.toBeNull(); + expect(projectStarIconEl.querySelectorAll('svg').length).toBeGreaterThan(0); + expect(projectStarIconEl.querySelectorAll('.stat-value').length).toBeGreaterThan(0); + expect(vm.$el.querySelectorAll('.last-updated').length).toBeGreaterThan(0); vm.$destroy(); }); diff --git a/spec/javascripts/groups/components/item_stats_value_spec.js b/spec/javascripts/groups/components/item_stats_value_spec.js index 5e35ae4d36c..2a995e8efe6 100644 --- a/spec/javascripts/groups/components/item_stats_value_spec.js +++ b/spec/javascripts/groups/components/item_stats_value_spec.js @@ -57,8 +57,8 @@ describe('ItemStatsValueComponent', () => { it('renders component element correctly', () => { expect(vm.$el.classList.contains('number-subgroups')).toBeTruthy(); - expect(vm.$el.querySelectorAll('svg').length > 0).toBeTruthy(); - expect(vm.$el.querySelectorAll('.stat-value').length > 0).toBeTruthy(); + expect(vm.$el.querySelectorAll('svg').length).toBeGreaterThan(0); + expect(vm.$el.querySelectorAll('.stat-value').length).toBeGreaterThan(0); }); it('renders element tooltip correctly', () => { diff --git a/spec/javascripts/groups/store/groups_store_spec.js b/spec/javascripts/groups/store/groups_store_spec.js index d74f38f476e..78caf8f80bf 100644 --- a/spec/javascripts/groups/store/groups_store_spec.js +++ b/spec/javascripts/groups/store/groups_store_spec.js @@ -29,7 +29,7 @@ describe('ProjectsStore', () => { 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') > -1).toBeTruthy(); + expect(Object.keys(store.state.groups[0]).indexOf('fullName')).toBeGreaterThan(-1); }); }); @@ -41,8 +41,8 @@ describe('ProjectsStore', () => { 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') > -1).toBeTruthy(); - expect(Object.keys(store.state.groups[0].children[0]).indexOf('fullName') > -1).toBeTruthy(); + expect(Object.keys(store.state.groups[0]).indexOf('fullName')).toBeGreaterThan(-1); + expect(Object.keys(store.state.groups[0].children[0]).indexOf('fullName')).toBeGreaterThan(-1); }); }); @@ -54,7 +54,7 @@ describe('ProjectsStore', () => { 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') > -1).toBeTruthy(); + expect(Object.keys(mockParentGroupItem.children[0]).indexOf('fullName')).toBeGreaterThan(-1); expect(mockParentGroupItem.isOpen).toBeTruthy(); expect(mockParentGroupItem.isChildrenLoading).toBeFalsy(); }); @@ -81,14 +81,14 @@ describe('ProjectsStore', () => { store = new GroupsStore(); updatedGroupItem = store.formatGroupItem(mockRawChildren[0]); - expect(Object.keys(updatedGroupItem).indexOf('fullName') > -1).toBeTruthy(); + expect(Object.keys(updatedGroupItem).indexOf('fullName')).toBeGreaterThan(-1); expect(updatedGroupItem.childrenCount).toBe(mockRawChildren[0].children_count); expect(updatedGroupItem.isChildrenLoading).toBe(false); expect(updatedGroupItem.isBeingRemoved).toBe(false); store = new GroupsStore(true); updatedGroupItem = store.formatGroupItem(mockRawChildren[0]); - expect(Object.keys(updatedGroupItem).indexOf('fullName') > -1).toBeTruthy(); + expect(Object.keys(updatedGroupItem).indexOf('fullName')).toBeGreaterThan(-1); expect(updatedGroupItem.childrenCount).toBe(mockRawChildren[0].subgroup_count); }); }); 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 a284b981d2a..9d05c6859df 100644 --- a/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js +++ b/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js @@ -32,7 +32,7 @@ describe('commentIndicatorHelper', () => { expect(svgEl).toBeDefined(); const svgLink = svgEl.querySelector('use').getAttribute('xlink:href'); - expect(svgLink.indexOf('image-comment-dark') !== -1).toEqual(true); + expect(svgLink.indexOf('image-comment-dark')).not.toBe(-1); }); }); }); diff --git a/spec/javascripts/jobs/components/job_app_spec.js b/spec/javascripts/jobs/components/job_app_spec.js index e02eb9723fe..6e0bcf801cd 100644 --- a/spec/javascripts/jobs/components/job_app_spec.js +++ b/spec/javascripts/jobs/components/job_app_spec.js @@ -41,7 +41,7 @@ describe('Job App ', () => { }; const props = { - runnerHelpUrl: 'help/runners', + runnerSettingsUrl: 'settings/ci-cd/runners', }; beforeEach(() => { @@ -223,7 +223,6 @@ describe('Job App ', () => { store.dispatch( 'receiveJobSuccess', Object.assign({}, job, { - erased: true, erased_by: { username: 'root', web_url: 'gitlab.com/root', @@ -237,18 +236,18 @@ describe('Job App ', () => { store, }); - expect(vm.$el.querySelector('.js-job-erased')).not.toBeNull(); + expect(vm.$el.querySelector('.js-job-erased-block')).not.toBeNull(); }); it('does not render erased block when `erased` is false', () => { - store.dispatch('receiveJobSuccess', Object.assign({}, job, { erased: false })); + store.dispatch('receiveJobSuccess', Object.assign({}, job, { erased_at: null })); vm = mountComponentWithStore(Component, { props, store, }); - expect(vm.$el.querySelector('.js-job-erased')).toBeNull(); + expect(vm.$el.querySelector('.js-job-erased-block')).toBeNull(); }); }); diff --git a/spec/javascripts/jobs/components/job_log_controllers_spec.js b/spec/javascripts/jobs/components/job_log_controllers_spec.js index 099aca602c4..3dcb57d23ce 100644 --- a/spec/javascripts/jobs/components/job_log_controllers_spec.js +++ b/spec/javascripts/jobs/components/job_log_controllers_spec.js @@ -25,6 +25,7 @@ describe('Job log controllers', () => { beforeEach(() => { vm = mountComponent(Component, props); }); + it('renders size information', () => { expect(vm.$el.querySelector('.js-truncated-info').textContent).toContain('499.95 KiB'); }); diff --git a/spec/javascripts/jobs/components/sidebar_spec.js b/spec/javascripts/jobs/components/sidebar_spec.js index 2f5c4245ced..a113377b19f 100644 --- a/spec/javascripts/jobs/components/sidebar_spec.js +++ b/spec/javascripts/jobs/components/sidebar_spec.js @@ -161,9 +161,9 @@ describe('Sidebar details block', () => { vm = mountComponentWithStore(SidebarComponent, { store }); }); - it('renders first stage as selected', () => { + it('renders value provided as selectedStage as selected', () => { expect(vm.$el.querySelector('.js-selected-stage').textContent.trim()).toEqual( - stages[0].name, + vm.selectedStage, ); }); }); diff --git a/spec/javascripts/jobs/components/stages_dropdown_spec.js b/spec/javascripts/jobs/components/stages_dropdown_spec.js index aa6cc0f1b1a..fcff78b943e 100644 --- a/spec/javascripts/jobs/components/stages_dropdown_spec.js +++ b/spec/javascripts/jobs/components/stages_dropdown_spec.js @@ -2,7 +2,7 @@ import Vue from 'vue'; import component from '~/jobs/components/stages_dropdown.vue'; import mountComponent from '../../helpers/vue_mount_component_helper'; -describe('Artifacts block', () => { +describe('Stages Dropdown', () => { const Component = Vue.extend(component); let vm; @@ -23,10 +23,6 @@ describe('Artifacts block', () => { }, path: 'pipeline/28029444', }, - ref: { - path: 'commits/50101-truncated-job-information', - name: '50101-truncated-job-information', - }, stages: [ { name: 'build', @@ -35,6 +31,7 @@ describe('Artifacts block', () => { name: 'test', }, ], + selectedStage: 'deploy' }); }); @@ -53,17 +50,10 @@ describe('Artifacts block', () => { }); it('renders dropdown with stages', () => { - expect(vm.$el.querySelector('.dropdown button').textContent).toContain('build'); + expect(vm.$el.querySelector('.dropdown .js-stage-item').textContent).toContain('build'); }); - it('updates selected stage on click', done => { - vm.$el.querySelectorAll('.stage-item')[1].click(); - vm - .$nextTick() - .then(() => { - expect(vm.$el.querySelector('.dropdown button').textContent).toContain('test'); - }) - .then(done) - .catch(done.fail); + it('rendes selected stage', () => { + expect(vm.$el.querySelector('.dropdown .js-selected-stage').textContent).toContain('deploy'); }); }); diff --git a/spec/javascripts/jobs/store/actions_spec.js b/spec/javascripts/jobs/store/actions_spec.js index 5ab1f75d0d6..bc410ae614c 100644 --- a/spec/javascripts/jobs/store/actions_spec.js +++ b/spec/javascripts/jobs/store/actions_spec.js @@ -422,8 +422,9 @@ describe('Job State actions', () => { beforeEach(() => { mockedState.job.pipeline = { - path: `${TEST_HOST}/endpoint.json/stages`, + path: `${TEST_HOST}/endpoint`, }; + mockedState.selectedStage = 'deploy' mock = new MockAdapter(axios); }); @@ -434,8 +435,8 @@ describe('Job State actions', () => { describe('success', () => { it('dispatches requestStages and receiveStagesSuccess, fetchJobsForStage ', done => { mock - .onGet(`${TEST_HOST}/endpoint.json/stages`) - .replyOnce(200, { details: { stages: [{ id: 121212, name: 'build' }] } }); + .onGet(`${TEST_HOST}/endpoint.json`) + .replyOnce(200, { details: { stages: [{ name: 'build' }, { name: 'deploy' }] } }); testAction( fetchStages, @@ -447,11 +448,11 @@ describe('Job State actions', () => { type: 'requestStages', }, { - payload: [{ id: 121212, name: 'build' }], + payload: [{ name: 'build' }, { name: 'deploy' }], type: 'receiveStagesSuccess', }, { - payload: { id: 121212, name: 'build' }, + payload: { name: 'deploy' }, type: 'fetchJobsForStage', }, ], @@ -515,9 +516,9 @@ describe('Job State actions', () => { it('should commit REQUEST_JOBS_FOR_STAGE mutation ', done => { testAction( requestJobsForStage, - null, + { name: 'deploy' }, mockedState, - [{ type: types.REQUEST_JOBS_FOR_STAGE }], + [{ type: types.REQUEST_JOBS_FOR_STAGE, payload: { name: 'deploy' } }], [], done, ); @@ -549,6 +550,7 @@ describe('Job State actions', () => { [ { type: 'requestJobsForStage', + payload: { dropdown_path: `${TEST_HOST}/jobs.json` }, }, { payload: [{ id: 121212, name: 'build' }], @@ -574,6 +576,7 @@ describe('Job State actions', () => { [ { type: 'requestJobsForStage', + payload: { dropdown_path: `${TEST_HOST}/jobs.json` }, }, { type: 'receiveJobsForStageError', diff --git a/spec/javascripts/jobs/store/getters_spec.js b/spec/javascripts/jobs/store/getters_spec.js index 160b2f4b34a..e262a47b837 100644 --- a/spec/javascripts/jobs/store/getters_spec.js +++ b/spec/javascripts/jobs/store/getters_spec.js @@ -77,18 +77,18 @@ describe('Job Store Getters', () => { }); }); - describe('jobHasStarted', () => { - describe('when started equals false', () => { + describe('shouldRenderTriggeredLabel', () => { + describe('when started equals null', () => { it('returns false', () => { - localState.job.started = false; - expect(getters.jobHasStarted(localState)).toEqual(false); + localState.job.started = null; + expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(false); }); }); describe('when started equals string', () => { it('returns true', () => { localState.job.started = '2018-08-31T16:20:49.023Z'; - expect(getters.jobHasStarted(localState)).toEqual(true); + expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(true); }); }); }); diff --git a/spec/javascripts/jobs/store/mutations_spec.js b/spec/javascripts/jobs/store/mutations_spec.js index 9ba543d32a8..701fcc7f4c8 100644 --- a/spec/javascripts/jobs/store/mutations_spec.js +++ b/spec/javascripts/jobs/store/mutations_spec.js @@ -108,21 +108,33 @@ describe('Jobs Store Mutations', () => { }); describe('RECEIVE_JOB_SUCCESS', () => { - beforeEach(() => { - mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321 }); - }); - 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'); + }); }); describe('RECEIVE_JOB_ERROR', () => { @@ -200,9 +212,14 @@ describe('Jobs Store Mutations', () => { describe('REQUEST_JOBS_FOR_STAGE', () => { it('sets isLoadingStages to true', () => { - mutations[types.REQUEST_JOBS_FOR_STAGE](stateCopy); + 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'); + }) }); describe('RECEIVE_JOBS_FOR_STAGE_SUCCESS', () => { diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js index 28151c7e658..c34622203f7 100644 --- a/spec/javascripts/lib/utils/common_utils_spec.js +++ b/spec/javascripts/lib/utils/common_utils_spec.js @@ -9,6 +9,7 @@ describe('common_utils', () => { it('returns an anchor tag with url', () => { expect(commonUtils.parseUrl('/some/absolute/url').pathname).toContain('some/absolute/url'); }); + it('url is escaped', () => { // IE11 will return a relative pathname while other browsers will return a full pathname. // parseUrl uses an anchor element for parsing an url. With relative urls, the anchor @@ -42,7 +43,7 @@ describe('common_utils', () => { it('should remove the question mark from the search params', () => { const paramsArray = commonUtils.urlParamsToArray('?test=thing'); - expect(paramsArray[0][0] !== '?').toBe(true); + expect(paramsArray[0][0]).not.toBe('?'); }); }); diff --git a/spec/javascripts/line_highlighter_spec.js b/spec/javascripts/line_highlighter_spec.js index c32ecb17e89..15bb78032b2 100644 --- a/spec/javascripts/line_highlighter_spec.js +++ b/spec/javascripts/line_highlighter_spec.js @@ -23,17 +23,20 @@ import LineHighlighter from '~/line_highlighter'; __setLocationHash__: spyOn(this["class"], '__setLocationHash__').and.callFake(function() {}) }; }); + describe('behavior', function() { it('highlights one line given in the URL hash', function() { new LineHighlighter({ hash: '#L13' }); return 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; new LineHighlighter({ hash: '#L5-25' }); @@ -44,18 +47,21 @@ import LineHighlighter from '~/line_highlighter'; } 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()); }); + it('discards click events', function() { var spy; spy = spyOnEvent('a[data-line-number]', 'click'); clickLine(13); return expect(spy).toHaveBeenPrevented(); }); + it('handles garbage input from the hash', function() { var func; func = function() { @@ -64,6 +70,7 @@ import LineHighlighter from '~/line_highlighter'; return expect(func).not.toThrow(); }); }); + describe('clickHandler', function() { it('handles clicking on a child icon element', function() { var spy; @@ -72,11 +79,13 @@ import LineHighlighter from '~/line_highlighter'; expect(spy).toHaveBeenCalledWith(13); return expect($('#LC13')).toHaveClass(this.css); }); + describe('without shiftKey', function() { it('highlights one line when clicked', function() { clickLine(13); return expect($('#LC13')).toHaveClass(this.css); }); + it('unhighlights previously highlighted lines', function() { clickLine(13); clickLine(20); @@ -101,6 +110,7 @@ import LineHighlighter from '~/line_highlighter'; expect(spy).toHaveBeenCalledWith(13); return expect(spy).toHaveBeenCalledWith(13, 20); }); + describe('without existing highlight', function() { it('highlights the clicked line', function() { clickLine(13, { @@ -118,6 +128,7 @@ import LineHighlighter from '~/line_highlighter'; return 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; @@ -155,6 +166,7 @@ import LineHighlighter from '~/line_highlighter'; shiftKey: true }); }); + it('uses target as first line when it is less than existing first line', function() { var line, results; clickLine(5, { @@ -182,13 +194,16 @@ import LineHighlighter from '~/line_highlighter'; }); }); }); + describe('hashToRange', function() { beforeEach(function() { return this.subject = this["class"].hashToRange; }); + it('extracts a single line number from the hash', function() { return 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]); }); @@ -196,10 +211,12 @@ import LineHighlighter from '~/line_highlighter'; return expect(this.subject('#foo')).toEqual([null, null]); }); }); + describe('highlightLine', function() { beforeEach(function() { return this.subject = this["class"].highlightLine; }); + it('highlights the specified line', function() { this.subject(13); return expect($('#LC13')).toHaveClass(this.css); @@ -213,6 +230,7 @@ import LineHighlighter from '~/line_highlighter'; beforeEach(function() { return 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'); diff --git a/spec/javascripts/new_branch_spec.js b/spec/javascripts/new_branch_spec.js index e52ac686435..85419e640d8 100644 --- a/spec/javascripts/new_branch_spec.js +++ b/spec/javascripts/new_branch_spec.js @@ -21,18 +21,22 @@ import NewBranchForm from '~/new_branch_form'; }); return this.form = new NewBranchForm($('.js-create-branch-form'), []); }); + it("can't start with a dot", function() { fillNameWith('.foo'); return expectToHaveError("can't start with '.'"); }); + it("can't start with a slash", function() { fillNameWith('/foo'); return expectToHaveError("can't start with '/'"); }); + it("can't have two consecutive dots", function() { fillNameWith('foo..bar'); return expectToHaveError("can't contain '..'"); }); + it("can't have spaces anywhere", function() { fillNameWith(' foo'); expectToHaveError("can't contain spaces"); @@ -41,6 +45,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo '); return expectToHaveError("can't contain spaces"); }); + it("can't have ~ anywhere", function() { fillNameWith('~foo'); expectToHaveError("can't contain '~'"); @@ -49,6 +54,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo~'); return expectToHaveError("can't contain '~'"); }); + it("can't have tilde anwhere", function() { fillNameWith('~foo'); expectToHaveError("can't contain '~'"); @@ -57,6 +63,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo~'); return expectToHaveError("can't contain '~'"); }); + it("can't have caret anywhere", function() { fillNameWith('^foo'); expectToHaveError("can't contain '^'"); @@ -65,6 +72,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo^'); return expectToHaveError("can't contain '^'"); }); + it("can't have : anywhere", function() { fillNameWith(':foo'); expectToHaveError("can't contain ':'"); @@ -73,6 +81,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith(':foo'); return expectToHaveError("can't contain ':'"); }); + it("can't have question mark anywhere", function() { fillNameWith('?foo'); expectToHaveError("can't contain '?'"); @@ -81,6 +90,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo?'); return expectToHaveError("can't contain '?'"); }); + it("can't have asterisk anywhere", function() { fillNameWith('*foo'); expectToHaveError("can't contain '*'"); @@ -89,6 +99,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo*'); return expectToHaveError("can't contain '*'"); }); + it("can't have open bracket anywhere", function() { fillNameWith('[foo'); expectToHaveError("can't contain '['"); @@ -97,6 +108,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo['); return expectToHaveError("can't contain '['"); }); + it("can't have a backslash anywhere", function() { fillNameWith('\\foo'); expectToHaveError("can't contain '\\'"); @@ -105,6 +117,7 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo\\'); return expectToHaveError("can't contain '\\'"); }); + it("can't contain a sequence @{ anywhere", function() { fillNameWith('@{foo'); expectToHaveError("can't contain '@{'"); @@ -113,48 +126,59 @@ import NewBranchForm from '~/new_branch_form'; fillNameWith('foo@{'); return expectToHaveError("can't contain '@{'"); }); + it("can't have consecutive slashes", function() { fillNameWith('foo//bar'); return expectToHaveError("can't contain consecutive slashes"); }); + it("can't end with a slash", function() { fillNameWith('foo/'); return expectToHaveError("can't end in '/'"); }); + it("can't end with a dot", function() { fillNameWith('foo.'); return expectToHaveError("can't end in '.'"); }); + it("can't end with .lock", function() { fillNameWith('foo.lock'); return expectToHaveError("can't end in '.lock'"); }); + it("can't be the single character @", function() { fillNameWith('@'); return expectToHaveError("can't be '@'"); }); + it("concatenates all error messages", function() { fillNameWith('/foo bar?~.'); return expectToHaveError("can't start with '/', can't contain spaces, '?', '~', can't end in '.'"); }); + it("doesn't duplicate error messages", function() { fillNameWith('?foo?bar?zoo?'); return expectToHaveError("can't contain '?'"); }); + 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); }); + it("can have dashes anywhere", function() { fillNameWith('-foo-bar-zoo-'); return 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); }); + it("can have numbers anywhere", function() { fillNameWith('1foo2bar3zoo4'); return expect($('.js-branch-name-error span').length).toEqual(0); diff --git a/spec/javascripts/notes/components/note_form_spec.js b/spec/javascripts/notes/components/note_form_spec.js index 147ffcf1b81..eefd9ddd63c 100644 --- a/spec/javascripts/notes/components/note_form_spec.js +++ b/spec/javascripts/notes/components/note_form_spec.js @@ -100,6 +100,7 @@ describe('issue_note_form component', () => { expect(vm.handleUpdate).toHaveBeenCalled(); }); + it('should save note when ctrl+enter is pressed', () => { spyOn(vm, 'handleUpdate').and.callThrough(); vm.$el.querySelector('textarea').value = 'Foo'; diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js index faeedae40e9..7bfbca83c77 100644 --- a/spec/javascripts/notes_spec.js +++ b/spec/javascripts/notes_spec.js @@ -538,7 +538,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; mockNotesPost(); $('.js-comment-button').click(); - expect($notesContainer.find('.note.being-posted').length > 0).toEqual(true); + expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0); }); it('should remove placeholder note when new comment is done posting', done => { @@ -582,7 +582,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; $('.js-comment-button').click(); setTimeout(() => { - expect($notesContainer.find(`#note_${note.id}`).length > 0).toEqual(true); + expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0); done(); }); @@ -776,7 +776,7 @@ import timeoutPromise from './helpers/set_timeout_promise_helper'; $form.find('textarea.js-note-text').val(sampleComment); const { formData, formContent, formAction } = this.notes.getFormData($form); - expect(formData.indexOf(sampleComment) > -1).toBe(true); + expect(formData.indexOf(sampleComment)).toBeGreaterThan(-1); expect(formContent).toEqual(sampleComment); expect(formAction).toEqual($form.attr('action')); }); diff --git a/spec/javascripts/reports/components/report_section_spec.js b/spec/javascripts/reports/components/report_section_spec.js index 6f6eb161d14..bf11dbea386 100644 --- a/spec/javascripts/reports/components/report_section_spec.js +++ b/spec/javascripts/reports/components/report_section_spec.js @@ -86,6 +86,7 @@ describe('Report section', () => { }); }); }); + describe('when it is loading', () => { it('should render loading indicator', () => { vm = mountComponent(ReportSection, { diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js index f9395eedfea..936e8f16c52 100644 --- a/spec/javascripts/right_sidebar_spec.js +++ b/spec/javascripts/right_sidebar_spec.js @@ -60,10 +60,12 @@ import Sidebar from '~/right_sidebar'; $toggle.click(); assertSidebarState('expanded'); }); + it('should float over the page and when sidebar icons clicked', function() { $labelsIcon.click(); return assertSidebarState('expanded'); }); + it('should collapse when the icon arrow clicked while it is floating on page', function() { $labelsIcon.click(); assertSidebarState('expanded'); diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js index b96023a33c4..bc1bb50dc5c 100644 --- a/spec/javascripts/search_autocomplete_spec.js +++ b/spec/javascripts/search_autocomplete_spec.js @@ -140,6 +140,7 @@ describe('Search autocomplete dropdown', () => { removeBodyAttributes(); window.gon = {}; }); + it('should show Dashboard specific dropdown menu', function() { var list; addBodyAttributes(); @@ -148,6 +149,7 @@ describe('Search autocomplete dropdown', () => { list = widget.wrap.find('.dropdown-menu').find('ul'); return assertLinks(list, dashboardIssuesPath, dashboardMRsPath); }); + it('should show Group specific dropdown menu', function() { var list; addBodyAttributes('group'); @@ -156,6 +158,7 @@ describe('Search autocomplete dropdown', () => { list = widget.wrap.find('.dropdown-menu').find('ul'); return assertLinks(list, groupIssuesPath, groupMRsPath); }); + it('should show Project specific dropdown menu', function() { var list; addBodyAttributes('project'); @@ -164,6 +167,7 @@ describe('Search autocomplete dropdown', () => { list = widget.wrap.find('.dropdown-menu').find('ul'); return assertLinks(list, projectIssuesPath, projectMRsPath); }); + it('should show only Project mergeRequest dropdown menu items when project issues are disabled', function() { addBodyAttributes('project'); disableProjectIssues(); @@ -172,6 +176,7 @@ describe('Search autocomplete dropdown', () => { const list = widget.wrap.find('.dropdown-menu').find('ul'); assertLinks(list, null, projectMRsPath); }); + it('should not show category related menu if there is text in the input', function() { var link, list; addBodyAttributes('project'); @@ -182,6 +187,7 @@ describe('Search autocomplete dropdown', () => { link = "a[href='" + projectIssuesPath + '/?assignee_id=' + userId + "']"; return expect(list.find(link).length).toBe(0); }); + it('should not submit the search form when selecting an autocomplete row with the keyboard', function() { var ENTER = 13; var DOWN = 40; diff --git a/spec/javascripts/syntax_highlight_spec.js b/spec/javascripts/syntax_highlight_spec.js index af3a5d58ba7..512be88c24c 100644 --- a/spec/javascripts/syntax_highlight_spec.js +++ b/spec/javascripts/syntax_highlight_spec.js @@ -25,6 +25,7 @@ describe('Syntax Highlighter', 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>"); }); + it('applies highlighting to all applicable children', function() { stubUserColorScheme('monokai'); syntaxHighlight($('.parent')); 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 91e81a0675a..305cee94f57 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 @@ -137,7 +137,7 @@ describe('MemoryUsage', () => { } = vm; expect(hasMetrics).toBeTruthy(); - expect(memoryMetrics.length > 0).toBeTruthy(); + expect(memoryMetrics.length).toBeGreaterThan(0); expect(deploymentTime).toEqual(deployment_time); expect(memoryFrom).toEqual('9.13'); expect(memoryTo).toEqual('4.28'); 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 efa5c878678..033cb694249 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 @@ -157,6 +157,16 @@ describe('MRWidgetMerged', () => { expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(vm.mr.mergeCommitSha); }); + it('hides button to copy commit SHA if SHA does not exist', (done) => { + vm.mr.mergeCommitSha = null; + + Vue.nextTick(() => { + expect(selectors.copyMergeShaButton).not.toExist(); + expect(vm.$el.querySelector('.mr-info-list').innerText).not.toContain('with'); + done(); + }); + }); + it('shows merge commit SHA link', () => { expect(selectors.mergeCommitShaLink).toExist(); expect(selectors.mergeCommitShaLink.text).toContain(vm.mr.shortMergeCommitSha); diff --git a/spec/javascripts/vue_shared/components/memory_graph_spec.js b/spec/javascripts/vue_shared/components/memory_graph_spec.js index 65d8ed39ade..0982b3e1f38 100644 --- a/spec/javascripts/vue_shared/components/memory_graph_spec.js +++ b/spec/javascripts/vue_shared/components/memory_graph_spec.js @@ -52,8 +52,8 @@ 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') > -1).toBeTruthy(); - expect(formattedMedian.indexOf('ago') > -1).toBeTruthy(); + expect(formattedMedian.indexOf('Deployed')).toBeGreaterThan(-1); + expect(formattedMedian.indexOf('ago')).toBeGreaterThan(-1); }); }); }); |