diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-11 09:09:45 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-11 09:09:45 +0000 |
commit | c7ba7b997608a103a0a9165b2e5cef9530c4ef53 (patch) | |
tree | 3af88eaacba25539b97da4ad358418b6a69c11d7 /spec/javascripts | |
parent | a031b1f4f34470fba578856dc7ab735a6f54733a (diff) | |
download | gitlab-ce-c7ba7b997608a103a0a9165b2e5cef9530c4ef53.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/javascripts')
31 files changed, 2 insertions, 3133 deletions
diff --git a/spec/javascripts/ide/stores/actions/tree_spec.js b/spec/javascripts/ide/stores/actions/tree_spec.js index fabe44ce333..2201a3b4b57 100644 --- a/spec/javascripts/ide/stores/actions/tree_spec.js +++ b/spec/javascripts/ide/stores/actions/tree_spec.js @@ -30,6 +30,7 @@ describe('Multi-file store tree actions', () => { store.state.currentBranchId = 'master'; store.state.projects.abcproject = { web_url: '', + path_with_namespace: 'foo/abcproject', }; }); @@ -57,7 +58,7 @@ describe('Multi-file store tree actions', () => { store .dispatch('getFiles', basicCallParameters) .then(() => { - expect(service.getFiles).toHaveBeenCalledWith('', '12345678'); + expect(service.getFiles).toHaveBeenCalledWith('foo/abcproject', '12345678'); done(); }) diff --git a/spec/javascripts/image_diff/helpers/badge_helper_spec.js b/spec/javascripts/image_diff/helpers/badge_helper_spec.js deleted file mode 100644 index b3001d45e3c..00000000000 --- a/spec/javascripts/image_diff/helpers/badge_helper_spec.js +++ /dev/null @@ -1,130 +0,0 @@ -import * as badgeHelper from '~/image_diff/helpers/badge_helper'; -import * as mockData from '../mock_data'; - -describe('badge helper', () => { - const { coordinate, noteId, badgeText, badgeNumber } = mockData; - let containerEl; - let buttonEl; - - beforeEach(() => { - containerEl = document.createElement('div'); - }); - - describe('createImageBadge', () => { - beforeEach(() => { - buttonEl = badgeHelper.createImageBadge(noteId, coordinate); - }); - - it('should create button', () => { - expect(buttonEl.tagName).toEqual('BUTTON'); - expect(buttonEl.getAttribute('type')).toEqual('button'); - }); - - it('should set disabled attribute', () => { - expect(buttonEl.hasAttribute('disabled')).toEqual(true); - }); - - it('should set noteId', () => { - expect(buttonEl.dataset.noteId).toEqual(noteId); - }); - - it('should set coordinate', () => { - expect(buttonEl.style.left).toEqual(`${coordinate.x}px`); - expect(buttonEl.style.top).toEqual(`${coordinate.y}px`); - }); - - describe('classNames', () => { - it('should set .js-image-badge by default', () => { - expect(buttonEl.className).toEqual('js-image-badge'); - }); - - it('should add additional class names if parameter is passed', () => { - const classNames = ['first-class', 'second-class']; - buttonEl = badgeHelper.createImageBadge(noteId, coordinate, classNames); - - expect(buttonEl.className).toEqual(classNames.concat('js-image-badge').join(' ')); - }); - }); - }); - - describe('addImageBadge', () => { - beforeEach(() => { - badgeHelper.addImageBadge(containerEl, { - coordinate, - badgeText, - noteId, - }); - buttonEl = containerEl.querySelector('button'); - }); - - it('should appends button to container', () => { - expect(buttonEl).toBeDefined(); - }); - - it('should add badge classes', () => { - expect(buttonEl.className).toContain('badge badge-pill'); - }); - - it('should set the badge text', () => { - expect(buttonEl.innerText).toEqual(badgeText); - }); - - it('should set the button coordinates', () => { - expect(buttonEl.style.left).toEqual(`${coordinate.x}px`); - expect(buttonEl.style.top).toEqual(`${coordinate.y}px`); - }); - - it('should set the button noteId', () => { - expect(buttonEl.dataset.noteId).toEqual(noteId); - }); - }); - - describe('addImageCommentBadge', () => { - beforeEach(() => { - badgeHelper.addImageCommentBadge(containerEl, { - coordinate, - noteId, - }); - buttonEl = containerEl.querySelector('button'); - }); - - it('should append icon button to container', () => { - expect(buttonEl).toBeDefined(); - }); - - it('should create icon comment button', () => { - const iconEl = buttonEl.querySelector('svg'); - - expect(iconEl).toBeDefined(); - }); - }); - - describe('addAvatarBadge', () => { - let avatarBadgeEl; - - beforeEach(() => { - containerEl.innerHTML = ` - <div id="${noteId}"> - <div class="badge hidden"> - </div> - </div> - `; - - badgeHelper.addAvatarBadge(containerEl, { - detail: { - noteId, - badgeNumber, - }, - }); - avatarBadgeEl = containerEl.querySelector(`#${noteId} .badge`); - }); - - it('should update badge number', () => { - expect(avatarBadgeEl.innerText).toEqual(badgeNumber.toString()); - }); - - it('should remove hidden class', () => { - expect(avatarBadgeEl.classList.contains('hidden')).toEqual(false); - }); - }); -}); diff --git a/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js b/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js deleted file mode 100644 index 8e3e7f1222e..00000000000 --- a/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js +++ /dev/null @@ -1,144 +0,0 @@ -import * as commentIndicatorHelper from '~/image_diff/helpers/comment_indicator_helper'; -import * as mockData from '../mock_data'; - -describe('commentIndicatorHelper', () => { - const { coordinate } = mockData; - let containerEl; - - beforeEach(() => { - containerEl = document.createElement('div'); - }); - - describe('addCommentIndicator', () => { - let buttonEl; - - beforeEach(() => { - commentIndicatorHelper.addCommentIndicator(containerEl, coordinate); - buttonEl = containerEl.querySelector('button'); - }); - - it('should append button to container', () => { - expect(buttonEl).toBeDefined(); - }); - - describe('button', () => { - it('should set coordinate', () => { - expect(buttonEl.style.left).toEqual(`${coordinate.x}px`); - expect(buttonEl.style.top).toEqual(`${coordinate.y}px`); - }); - - 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); - }); - }); - }); - - describe('removeCommentIndicator', () => { - it('should return removed false if there is no comment-indicator', () => { - const result = commentIndicatorHelper.removeCommentIndicator(containerEl); - - expect(result.removed).toEqual(false); - }); - - describe('has comment indicator', () => { - let result; - - beforeEach(() => { - containerEl.innerHTML = ` - <div class="comment-indicator" style="left:${coordinate.x}px; top: ${coordinate.y}px;"> - <img src="${gl.TEST_HOST}/image.png"> - </div> - `; - result = commentIndicatorHelper.removeCommentIndicator(containerEl); - }); - - it('should remove comment indicator', () => { - expect(containerEl.querySelector('.comment-indicator')).toBeNull(); - }); - - it('should return removed true', () => { - expect(result.removed).toEqual(true); - }); - - it('should return indicator meta', () => { - expect(result.x).toEqual(coordinate.x); - expect(result.y).toEqual(coordinate.y); - expect(result.image).toBeDefined(); - expect(result.image.width).toBeDefined(); - expect(result.image.height).toBeDefined(); - }); - }); - }); - - describe('showCommentIndicator', () => { - describe('commentIndicator exists', () => { - beforeEach(() => { - containerEl.innerHTML = ` - <button class="comment-indicator"></button> - `; - commentIndicatorHelper.showCommentIndicator(containerEl, coordinate); - }); - - 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`); - }); - }); - - describe('commentIndicator does not exist', () => { - beforeEach(() => { - commentIndicatorHelper.showCommentIndicator(containerEl, coordinate); - }); - - 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`); - }); - }); - }); - - describe('commentIndicatorOnClick', () => { - let event; - let textAreaEl; - - beforeEach(() => { - containerEl.innerHTML = ` - <div class="diff-viewer"> - <button></button> - <div class="note-container"> - <textarea class="note-textarea"></textarea> - </div> - </div> - `; - textAreaEl = containerEl.querySelector('textarea'); - - event = { - stopPropagation: () => {}, - currentTarget: containerEl.querySelector('button'), - }; - - spyOn(event, 'stopPropagation'); - spyOn(textAreaEl, 'focus'); - commentIndicatorHelper.commentIndicatorOnClick(event); - }); - - it('should stopPropagation', () => { - expect(event.stopPropagation).toHaveBeenCalled(); - }); - - it('should focus textAreaEl', () => { - expect(textAreaEl.focus).toHaveBeenCalled(); - }); - }); -}); diff --git a/spec/javascripts/image_diff/helpers/dom_helper_spec.js b/spec/javascripts/image_diff/helpers/dom_helper_spec.js deleted file mode 100644 index ffe712af2dd..00000000000 --- a/spec/javascripts/image_diff/helpers/dom_helper_spec.js +++ /dev/null @@ -1,120 +0,0 @@ -import * as domHelper from '~/image_diff/helpers/dom_helper'; -import * as mockData from '../mock_data'; - -describe('domHelper', () => { - const { imageMeta, badgeNumber } = mockData; - - describe('setPositionDataAttribute', () => { - let containerEl; - let attributeAfterCall; - const position = { - myProperty: 'myProperty', - }; - - beforeEach(() => { - containerEl = document.createElement('div'); - containerEl.dataset.position = JSON.stringify(position); - domHelper.setPositionDataAttribute(containerEl, imageMeta); - attributeAfterCall = JSON.parse(containerEl.dataset.position); - }); - - it('should set x, y, width, height', () => { - expect(attributeAfterCall.x).toEqual(imageMeta.x); - expect(attributeAfterCall.y).toEqual(imageMeta.y); - expect(attributeAfterCall.width).toEqual(imageMeta.width); - expect(attributeAfterCall.height).toEqual(imageMeta.height); - }); - - it('should not override other properties', () => { - expect(attributeAfterCall.myProperty).toEqual('myProperty'); - }); - }); - - describe('updateDiscussionAvatarBadgeNumber', () => { - let discussionEl; - - beforeEach(() => { - discussionEl = document.createElement('div'); - discussionEl.innerHTML = ` - <a href="#" class="image-diff-avatar-link"> - <div class="badge"></div> - </a> - `; - domHelper.updateDiscussionAvatarBadgeNumber(discussionEl, badgeNumber); - }); - - it('should update avatar badge number', () => { - expect(discussionEl.querySelector('.badge').innerText).toEqual(badgeNumber.toString()); - }); - }); - - describe('updateDiscussionBadgeNumber', () => { - let discussionEl; - - beforeEach(() => { - discussionEl = document.createElement('div'); - discussionEl.innerHTML = ` - <div class="badge"></div> - `; - domHelper.updateDiscussionBadgeNumber(discussionEl, badgeNumber); - }); - - it('should update discussion badge number', () => { - expect(discussionEl.querySelector('.badge').innerText).toEqual(badgeNumber.toString()); - }); - }); - - describe('toggleCollapsed', () => { - let element; - let discussionNotesEl; - - beforeEach(() => { - element = document.createElement('div'); - element.innerHTML = ` - <div class="discussion-notes"> - <button></button> - <form class="discussion-form"></form> - </div> - `; - discussionNotesEl = element.querySelector('.discussion-notes'); - }); - - describe('not collapsed', () => { - beforeEach(() => { - domHelper.toggleCollapsed({ - currentTarget: element.querySelector('button'), - }); - }); - - it('should add collapsed class', () => { - expect(discussionNotesEl.classList.contains('collapsed')).toEqual(true); - }); - - it('should force formEl to display none', () => { - const formEl = element.querySelector('.discussion-form'); - - expect(formEl.style.display).toEqual('none'); - }); - }); - - describe('collapsed', () => { - beforeEach(() => { - discussionNotesEl.classList.add('collapsed'); - - domHelper.toggleCollapsed({ - currentTarget: element.querySelector('button'), - }); - }); - - it('should remove collapsed class', () => { - expect(discussionNotesEl.classList.contains('collapsed')).toEqual(false); - }); - - 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 deleted file mode 100644 index 3b6378be883..00000000000 --- a/spec/javascripts/image_diff/helpers/utils_helper_spec.js +++ /dev/null @@ -1,152 +0,0 @@ -import * as utilsHelper from '~/image_diff/helpers/utils_helper'; -import ImageBadge from '~/image_diff/image_badge'; -import * as mockData from '../mock_data'; - -describe('utilsHelper', () => { - const { noteId, discussionId, image, imageProperties, imageMeta } = mockData; - - describe('resizeCoordinatesToImageElement', () => { - let result; - - beforeEach(() => { - result = utilsHelper.resizeCoordinatesToImageElement(image, imageMeta); - }); - - it('should return x based on widthRatio', () => { - expect(result.x).toEqual(imageMeta.x * 0.5); - }); - - it('should return y based on heightRatio', () => { - expect(result.y).toEqual(imageMeta.y * 0.5); - }); - - it('should return image width', () => { - expect(result.width).toEqual(image.width); - }); - - it('should return image height', () => { - expect(result.height).toEqual(image.height); - }); - }); - - describe('generateBadgeFromDiscussionDOM', () => { - let discussionEl; - let result; - - beforeEach(() => { - const imageFrameEl = document.createElement('div'); - imageFrameEl.innerHTML = ` - <img src="${gl.TEST_HOST}/image.png"> - `; - discussionEl = document.createElement('div'); - discussionEl.dataset.discussionId = discussionId; - discussionEl.innerHTML = ` - <div class="note" id="${noteId}"></div> - `; - discussionEl.dataset.position = JSON.stringify(imageMeta); - result = utilsHelper.generateBadgeFromDiscussionDOM(imageFrameEl, discussionEl); - }); - - 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); - expect(actual.height).toEqual(imageMeta.height); - }); - - it('should return browser image properties', () => { - const { browser } = result; - - expect(browser.x).toBeDefined(); - expect(browser.y).toBeDefined(); - expect(browser.width).toBeDefined(); - expect(browser.height).toBeDefined(); - }); - - it('should return instance of ImageBadge', () => { - expect(result instanceof ImageBadge).toEqual(true); - }); - - it('should return noteId', () => { - expect(result.noteId).toEqual(noteId); - }); - - it('should return discussionId', () => { - expect(result.discussionId).toEqual(discussionId); - }); - }); - - describe('getTargetSelection', () => { - let containerEl; - - beforeEach(() => { - containerEl = { - querySelector: () => imageProperties, - }; - }); - - function generateEvent(offsetX, offsetY) { - return { - currentTarget: containerEl, - offsetX, - offsetY, - }; - } - - it('should return browser properties', () => { - const event = generateEvent(25, 25); - 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); - expect(browser.height).toEqual(imageProperties.height); - }); - - it('should return resized actual image properties', () => { - const event = generateEvent(50, 50); - const result = utilsHelper.getTargetSelection(event); - - const { actual } = result; - - expect(actual.x).toEqual(100); - expect(actual.y).toEqual(100); - expect(actual.width).toEqual(imageProperties.naturalWidth); - expect(actual.height).toEqual(imageProperties.naturalHeight); - }); - - describe('normalize coordinates', () => { - 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); - }); - }); - }); -}); diff --git a/spec/javascripts/image_diff/image_badge_spec.js b/spec/javascripts/image_diff/image_badge_spec.js deleted file mode 100644 index a1589d7b7a0..00000000000 --- a/spec/javascripts/image_diff/image_badge_spec.js +++ /dev/null @@ -1,84 +0,0 @@ -import ImageBadge from '~/image_diff/image_badge'; -import imageDiffHelper from '~/image_diff/helpers/index'; -import * as mockData from './mock_data'; - -describe('ImageBadge', () => { - const { noteId, discussionId, imageMeta } = mockData; - const options = { - noteId, - discussionId, - }; - - it('should save actual property', () => { - const imageBadge = new ImageBadge({ ...options, actual: imageMeta }); - - const { actual } = imageBadge; - - expect(actual.x).toEqual(imageMeta.x); - expect(actual.y).toEqual(imageMeta.y); - expect(actual.width).toEqual(imageMeta.width); - expect(actual.height).toEqual(imageMeta.height); - }); - - it('should save browser property', () => { - const imageBadge = new ImageBadge({ ...options, browser: imageMeta }); - - const { browser } = imageBadge; - - expect(browser.x).toEqual(imageMeta.x); - expect(browser.y).toEqual(imageMeta.y); - expect(browser.width).toEqual(imageMeta.width); - expect(browser.height).toEqual(imageMeta.height); - }); - - 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); - }); - - describe('default values', () => { - let imageBadge; - - beforeEach(() => { - imageBadge = new ImageBadge(options); - }); - - 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); - expect(actual.height).toEqual(0); - }); - - 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); - expect(browser.height).toEqual(0); - }); - }); - - describe('imageEl property is provided and not browser property', () => { - beforeEach(() => { - spyOn(imageDiffHelper, 'resizeCoordinatesToImageElement').and.returnValue(true); - }); - - it('should generate browser property', () => { - const imageBadge = new ImageBadge({ ...options, imageEl: document.createElement('img') }); - - expect(imageDiffHelper.resizeCoordinatesToImageElement).toHaveBeenCalled(); - expect(imageBadge.browser).toEqual(true); - }); - }); -}); diff --git a/spec/javascripts/image_diff/image_diff_spec.js b/spec/javascripts/image_diff/image_diff_spec.js deleted file mode 100644 index 21e7b8e2e9b..00000000000 --- a/spec/javascripts/image_diff/image_diff_spec.js +++ /dev/null @@ -1,361 +0,0 @@ -import ImageDiff from '~/image_diff/image_diff'; -import * as imageUtility from '~/lib/utils/image_utility'; -import imageDiffHelper from '~/image_diff/helpers/index'; -import * as mockData from './mock_data'; - -describe('ImageDiff', () => { - let element; - let imageDiff; - - beforeEach(() => { - setFixtures(` - <div id="element"> - <div class="diff-file"> - <div class="js-image-frame"> - <img src="${gl.TEST_HOST}/image.png"> - <div class="comment-indicator"></div> - <div id="badge-1" class="badge">1</div> - <div id="badge-2" class="badge">2</div> - <div id="badge-3" class="badge">3</div> - </div> - <div class="note-container"> - <div class="discussion-notes"> - <div class="js-diff-notes-toggle"></div> - <div class="notes"></div> - </div> - <div class="discussion-notes"> - <div class="js-diff-notes-toggle"></div> - <div class="notes"></div> - </div> - </div> - </div> - </div> - `); - element = document.getElementById('element'); - }); - - describe('constructor', () => { - beforeEach(() => { - imageDiff = new ImageDiff(element, { - canCreateNote: true, - renderCommentBadge: true, - }); - }); - - it('should set el', () => { - expect(imageDiff.el).toEqual(element); - }); - - it('should set canCreateNote', () => { - expect(imageDiff.canCreateNote).toEqual(true); - }); - - it('should set renderCommentBadge', () => { - expect(imageDiff.renderCommentBadge).toEqual(true); - }); - - it('should set $noteContainer', () => { - expect(imageDiff.$noteContainer[0]).toEqual(element.querySelector('.note-container')); - }); - - describe('default', () => { - beforeEach(() => { - imageDiff = new ImageDiff(element); - }); - - it('should set canCreateNote as false', () => { - expect(imageDiff.canCreateNote).toEqual(false); - }); - - it('should set renderCommentBadge as false', () => { - expect(imageDiff.renderCommentBadge).toEqual(false); - }); - }); - }); - - describe('init', () => { - beforeEach(() => { - spyOn(ImageDiff.prototype, 'bindEvents').and.callFake(() => {}); - imageDiff = new ImageDiff(element); - imageDiff.init(); - }); - - it('should set imageFrameEl', () => { - expect(imageDiff.imageFrameEl).toEqual(element.querySelector('.diff-file .js-image-frame')); - }); - - it('should set imageEl', () => { - expect(imageDiff.imageEl).toEqual(element.querySelector('.diff-file .js-image-frame img')); - }); - - it('should call bindEvents', () => { - expect(imageDiff.bindEvents).toHaveBeenCalled(); - }); - }); - - describe('bindEvents', () => { - let imageEl; - - beforeEach(() => { - spyOn(imageDiffHelper, 'toggleCollapsed').and.callFake(() => {}); - spyOn(imageDiffHelper, 'commentIndicatorOnClick').and.callFake(() => {}); - spyOn(imageDiffHelper, 'removeCommentIndicator').and.callFake(() => {}); - spyOn(ImageDiff.prototype, 'imageClicked').and.callFake(() => {}); - spyOn(ImageDiff.prototype, 'addBadge').and.callFake(() => {}); - spyOn(ImageDiff.prototype, 'removeBadge').and.callFake(() => {}); - spyOn(ImageDiff.prototype, 'renderBadges').and.callFake(() => {}); - imageEl = element.querySelector('.diff-file .js-image-frame img'); - }); - - describe('default', () => { - beforeEach(() => { - spyOn(imageUtility, 'isImageLoaded').and.returnValue(false); - imageDiff = new ImageDiff(element); - imageDiff.imageEl = imageEl; - imageDiff.bindEvents(); - }); - - 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(); - }); - }); - - describe('image not loaded', () => { - beforeEach(() => { - spyOn(imageUtility, 'isImageLoaded').and.returnValue(false); - imageDiff = new ImageDiff(element); - imageDiff.imageEl = imageEl; - imageDiff.bindEvents(); - }); - - it('should registers load eventListener', () => { - const loadEvent = new Event('load'); - imageEl.dispatchEvent(loadEvent); - - expect(imageDiff.renderBadges).toHaveBeenCalled(); - }); - }); - - describe('canCreateNote', () => { - beforeEach(() => { - spyOn(imageUtility, 'isImageLoaded').and.returnValue(false); - imageDiff = new ImageDiff(element, { - canCreateNote: true, - }); - imageDiff.imageEl = imageEl; - imageDiff.bindEvents(); - }); - - 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(); - }); - }); - - describe('canCreateNote is false', () => { - beforeEach(() => { - spyOn(imageUtility, 'isImageLoaded').and.returnValue(false); - imageDiff = new ImageDiff(element); - imageDiff.imageEl = imageEl; - imageDiff.bindEvents(); - }); - - it('should not register click.imageDiff event', () => { - const event = new CustomEvent('click.imageDiff'); - element.dispatchEvent(event); - - expect(imageDiff.imageClicked).not.toHaveBeenCalled(); - }); - }); - }); - - describe('imageClicked', () => { - beforeEach(() => { - spyOn(imageDiffHelper, 'getTargetSelection').and.returnValue({ - actual: {}, - browser: {}, - }); - spyOn(imageDiffHelper, 'setPositionDataAttribute').and.callFake(() => {}); - spyOn(imageDiffHelper, 'showCommentIndicator').and.callFake(() => {}); - imageDiff = new ImageDiff(element); - imageDiff.imageClicked({ - detail: { - currentTarget: {}, - }, - }); - }); - - it('should call getTargetSelection', () => { - expect(imageDiffHelper.getTargetSelection).toHaveBeenCalled(); - }); - - it('should call setPositionDataAttribute', () => { - expect(imageDiffHelper.setPositionDataAttribute).toHaveBeenCalled(); - }); - - it('should call showCommentIndicator', () => { - expect(imageDiffHelper.showCommentIndicator).toHaveBeenCalled(); - }); - }); - - describe('renderBadges', () => { - beforeEach(() => { - spyOn(ImageDiff.prototype, 'renderBadge').and.callFake(() => {}); - imageDiff = new ImageDiff(element); - imageDiff.renderBadges(); - }); - - it('should call renderBadge for each discussionEl', () => { - const discussionEls = element.querySelectorAll('.note-container .discussion-notes .notes'); - - expect(imageDiff.renderBadge.calls.count()).toEqual(discussionEls.length); - }); - }); - - describe('renderBadge', () => { - let discussionEls; - - beforeEach(() => { - spyOn(imageDiffHelper, 'addImageBadge').and.callFake(() => {}); - spyOn(imageDiffHelper, 'addImageCommentBadge').and.callFake(() => {}); - spyOn(imageDiffHelper, 'generateBadgeFromDiscussionDOM').and.returnValue({ - browser: {}, - noteId: 'noteId', - }); - discussionEls = element.querySelectorAll('.note-container .discussion-notes .notes'); - imageDiff = new ImageDiff(element); - imageDiff.renderBadge(discussionEls[0], 0); - }); - - it('should populate imageBadges', () => { - expect(imageDiff.imageBadges.length).toEqual(1); - }); - - describe('renderCommentBadge', () => { - beforeEach(() => { - imageDiff.renderCommentBadge = true; - imageDiff.renderBadge(discussionEls[0], 0); - }); - - it('should call addImageCommentBadge', () => { - expect(imageDiffHelper.addImageCommentBadge).toHaveBeenCalled(); - }); - }); - - describe('renderCommentBadge is false', () => { - it('should call addImageBadge', () => { - expect(imageDiffHelper.addImageBadge).toHaveBeenCalled(); - }); - }); - }); - - describe('addBadge', () => { - beforeEach(() => { - spyOn(imageDiffHelper, 'addImageBadge').and.callFake(() => {}); - spyOn(imageDiffHelper, 'addAvatarBadge').and.callFake(() => {}); - spyOn(imageDiffHelper, 'updateDiscussionBadgeNumber').and.callFake(() => {}); - imageDiff = new ImageDiff(element); - imageDiff.imageFrameEl = element.querySelector('.diff-file .js-image-frame'); - imageDiff.addBadge({ - detail: { - x: 0, - y: 1, - width: 25, - height: 50, - noteId: 'noteId', - discussionId: 'discussionId', - }, - }); - }); - - it('should add imageBadge to imageBadges', () => { - expect(imageDiff.imageBadges.length).toEqual(1); - }); - - it('should call addImageBadge', () => { - expect(imageDiffHelper.addImageBadge).toHaveBeenCalled(); - }); - - it('should call addAvatarBadge', () => { - expect(imageDiffHelper.addAvatarBadge).toHaveBeenCalled(); - }); - - it('should call updateDiscussionBadgeNumber', () => { - expect(imageDiffHelper.updateDiscussionBadgeNumber).toHaveBeenCalled(); - }); - }); - - describe('removeBadge', () => { - beforeEach(() => { - const { imageMeta } = mockData; - - spyOn(imageDiffHelper, 'updateDiscussionBadgeNumber').and.callFake(() => {}); - spyOn(imageDiffHelper, 'updateDiscussionAvatarBadgeNumber').and.callFake(() => {}); - imageDiff = new ImageDiff(element); - imageDiff.imageBadges = [imageMeta, imageMeta, imageMeta]; - imageDiff.imageFrameEl = element.querySelector('.diff-file .js-image-frame'); - imageDiff.removeBadge({ - detail: { - badgeNumber: 2, - }, - }); - }); - - 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); - }); - - it('should call updateDiscussionBadgeNumber', () => { - expect(imageDiffHelper.updateDiscussionBadgeNumber).toHaveBeenCalled(); - }); - - it('should call updateDiscussionAvatarBadgeNumber', () => { - expect(imageDiffHelper.updateDiscussionAvatarBadgeNumber).toHaveBeenCalled(); - }); - }); - - it('should remove badge from imageBadges', () => { - expect(imageDiff.imageBadges.length).toEqual(2); - }); - - it('should remove imageBadgeEl', () => { - expect(imageDiff.imageFrameEl.querySelector('#badge-2')).toBeNull(); - }); - }); -}); diff --git a/spec/javascripts/image_diff/mock_data.js b/spec/javascripts/image_diff/mock_data.js deleted file mode 100644 index a0d1732dd0a..00000000000 --- a/spec/javascripts/image_diff/mock_data.js +++ /dev/null @@ -1,28 +0,0 @@ -export const noteId = 'noteId'; -export const discussionId = 'discussionId'; -export const badgeText = 'badgeText'; -export const badgeNumber = 5; - -export const coordinate = { - x: 100, - y: 100, -}; - -export const image = { - width: 100, - height: 100, -}; - -export const imageProperties = { - width: image.width, - height: image.height, - naturalWidth: image.width * 2, - naturalHeight: image.height * 2, -}; - -export const imageMeta = { - x: coordinate.x, - y: coordinate.y, - width: imageProperties.naturalWidth, - height: imageProperties.naturalHeight, -}; diff --git a/spec/javascripts/image_diff/replaced_image_diff_spec.js b/spec/javascripts/image_diff/replaced_image_diff_spec.js deleted file mode 100644 index 62e7c8b6c6a..00000000000 --- a/spec/javascripts/image_diff/replaced_image_diff_spec.js +++ /dev/null @@ -1,355 +0,0 @@ -import ReplacedImageDiff from '~/image_diff/replaced_image_diff'; -import ImageDiff from '~/image_diff/image_diff'; -import { viewTypes } from '~/image_diff/view_types'; -import imageDiffHelper from '~/image_diff/helpers/index'; - -describe('ReplacedImageDiff', () => { - let element; - let replacedImageDiff; - - beforeEach(() => { - setFixtures(` - <div id="element"> - <div class="two-up"> - <div class="js-image-frame"> - <img src="${gl.TEST_HOST}/image.png"> - </div> - </div> - <div class="swipe"> - <div class="js-image-frame"> - <img src="${gl.TEST_HOST}/image.png"> - </div> - </div> - <div class="onion-skin"> - <div class="js-image-frame"> - <img src="${gl.TEST_HOST}/image.png"> - </div> - </div> - <div class="view-modes-menu"> - <div class="two-up">2-up</div> - <div class="swipe">Swipe</div> - <div class="onion-skin">Onion skin</div> - </div> - </div> - `); - element = document.getElementById('element'); - }); - - function setupImageFrameEls() { - replacedImageDiff.imageFrameEls = []; - replacedImageDiff.imageFrameEls[viewTypes.TWO_UP] = element.querySelector( - '.two-up .js-image-frame', - ); - replacedImageDiff.imageFrameEls[viewTypes.SWIPE] = element.querySelector( - '.swipe .js-image-frame', - ); - replacedImageDiff.imageFrameEls[viewTypes.ONION_SKIN] = element.querySelector( - '.onion-skin .js-image-frame', - ); - } - - function setupViewModesEls() { - replacedImageDiff.viewModesEls = []; - replacedImageDiff.viewModesEls[viewTypes.TWO_UP] = element.querySelector( - '.view-modes-menu .two-up', - ); - replacedImageDiff.viewModesEls[viewTypes.SWIPE] = element.querySelector( - '.view-modes-menu .swipe', - ); - replacedImageDiff.viewModesEls[viewTypes.ONION_SKIN] = element.querySelector( - '.view-modes-menu .onion-skin', - ); - } - - function setupImageEls() { - replacedImageDiff.imageEls = []; - replacedImageDiff.imageEls[viewTypes.TWO_UP] = element.querySelector('.two-up img'); - replacedImageDiff.imageEls[viewTypes.SWIPE] = element.querySelector('.swipe img'); - replacedImageDiff.imageEls[viewTypes.ONION_SKIN] = element.querySelector('.onion-skin img'); - } - - it('should extend ImageDiff', () => { - replacedImageDiff = new ReplacedImageDiff(element); - - expect(replacedImageDiff instanceof ImageDiff).toEqual(true); - }); - - describe('init', () => { - beforeEach(() => { - spyOn(ReplacedImageDiff.prototype, 'bindEvents').and.callFake(() => {}); - spyOn(ReplacedImageDiff.prototype, 'generateImageEls').and.callFake(() => {}); - - replacedImageDiff = new ReplacedImageDiff(element); - replacedImageDiff.init(); - }); - - 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'), - ); - - expect(imageFrameEls[viewTypes.ONION_SKIN]).toEqual( - element.querySelector('.onion-skin .js-image-frame'), - ); - }); - - 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'), - ); - - expect(viewModesEls[viewTypes.ONION_SKIN]).toEqual( - element.querySelector('.view-modes-menu .onion-skin'), - ); - }); - - it('should generateImageEls', () => { - expect(ReplacedImageDiff.prototype.generateImageEls).toHaveBeenCalled(); - }); - - it('should bindEvents', () => { - expect(ReplacedImageDiff.prototype.bindEvents).toHaveBeenCalled(); - }); - - describe('currentView', () => { - it('should set currentView', () => { - replacedImageDiff.init(viewTypes.ONION_SKIN); - - expect(replacedImageDiff.currentView).toEqual(viewTypes.ONION_SKIN); - }); - - it('should default to viewTypes.TWO_UP', () => { - expect(replacedImageDiff.currentView).toEqual(viewTypes.TWO_UP); - }); - }); - }); - - describe('generateImageEls', () => { - beforeEach(() => { - spyOn(ReplacedImageDiff.prototype, 'bindEvents').and.callFake(() => {}); - - replacedImageDiff = new ReplacedImageDiff(element, { - canCreateNote: false, - renderCommentBadge: false, - }); - - setupImageFrameEls(); - }); - - 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')); - expect(imageEls[viewTypes.ONION_SKIN]).toEqual(element.querySelector('.onion-skin img')); - }); - }); - - describe('bindEvents', () => { - beforeEach(() => { - spyOn(ImageDiff.prototype, 'bindEvents').and.callFake(() => {}); - replacedImageDiff = new ReplacedImageDiff(element); - - setupViewModesEls(); - }); - - it('should call super.bindEvents', () => { - replacedImageDiff.bindEvents(); - - expect(ImageDiff.prototype.bindEvents).toHaveBeenCalled(); - }); - - it('should register click eventlistener to 2-up view mode', done => { - spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake(viewMode => { - expect(viewMode).toEqual(viewTypes.TWO_UP); - done(); - }); - - replacedImageDiff.bindEvents(); - replacedImageDiff.viewModesEls[viewTypes.TWO_UP].click(); - }); - - it('should register click eventlistener to swipe view mode', done => { - spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake(viewMode => { - expect(viewMode).toEqual(viewTypes.SWIPE); - done(); - }); - - replacedImageDiff.bindEvents(); - replacedImageDiff.viewModesEls[viewTypes.SWIPE].click(); - }); - - it('should register click eventlistener to onion skin view mode', done => { - spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake(viewMode => { - expect(viewMode).toEqual(viewTypes.SWIPE); - done(); - }); - - replacedImageDiff.bindEvents(); - replacedImageDiff.viewModesEls[viewTypes.SWIPE].click(); - }); - }); - - describe('getters', () => { - describe('imageEl', () => { - beforeEach(() => { - replacedImageDiff = new ReplacedImageDiff(element); - replacedImageDiff.currentView = viewTypes.TWO_UP; - setupImageEls(); - }); - - it('should return imageEl based on currentView', () => { - expect(replacedImageDiff.imageEl).toEqual(element.querySelector('.two-up img')); - - replacedImageDiff.currentView = viewTypes.SWIPE; - - expect(replacedImageDiff.imageEl).toEqual(element.querySelector('.swipe img')); - }); - }); - - describe('imageFrameEl', () => { - beforeEach(() => { - replacedImageDiff = new ReplacedImageDiff(element); - replacedImageDiff.currentView = viewTypes.TWO_UP; - setupImageFrameEls(); - }); - - it('should return imageFrameEl based on currentView', () => { - 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'), - ); - }); - }); - }); - - describe('changeView', () => { - beforeEach(() => { - replacedImageDiff = new ReplacedImageDiff(element); - spyOn(imageDiffHelper, 'removeCommentIndicator').and.returnValue({ - removed: false, - }); - setupImageFrameEls(); - }); - - describe('invalid viewType', () => { - beforeEach(() => { - replacedImageDiff.changeView('some-view-name'); - }); - - it('should not call removeCommentIndicator', () => { - expect(imageDiffHelper.removeCommentIndicator).not.toHaveBeenCalled(); - }); - }); - - describe('valid viewType', () => { - beforeEach(() => { - jasmine.clock().install(); - spyOn(ReplacedImageDiff.prototype, 'renderNewView').and.callFake(() => {}); - replacedImageDiff.changeView(viewTypes.ONION_SKIN); - }); - - afterEach(() => { - jasmine.clock().uninstall(); - }); - - it('should call removeCommentIndicator', () => { - expect(imageDiffHelper.removeCommentIndicator).toHaveBeenCalled(); - }); - - it('should update currentView to newView', () => { - expect(replacedImageDiff.currentView).toEqual(viewTypes.ONION_SKIN); - }); - - it('should clear imageBadges', () => { - expect(replacedImageDiff.imageBadges.length).toEqual(0); - }); - - it('should call renderNewView', () => { - jasmine.clock().tick(251); - - expect(replacedImageDiff.renderNewView).toHaveBeenCalled(); - }); - }); - }); - - describe('renderNewView', () => { - beforeEach(() => { - replacedImageDiff = new ReplacedImageDiff(element); - }); - - it('should call renderBadges', () => { - spyOn(ReplacedImageDiff.prototype, 'renderBadges').and.callFake(() => {}); - - replacedImageDiff.renderNewView({ - removed: false, - }); - - expect(replacedImageDiff.renderBadges).toHaveBeenCalled(); - }); - - describe('removeIndicator', () => { - const indicator = { - removed: true, - x: 0, - y: 1, - image: { - width: 50, - height: 100, - }, - }; - - beforeEach(() => { - setupImageEls(); - setupImageFrameEls(); - }); - - it('should pass showCommentIndicator normalized indicator values', done => { - spyOn(imageDiffHelper, 'showCommentIndicator').and.callFake(() => {}); - spyOn(imageDiffHelper, 'resizeCoordinatesToImageElement').and.callFake((imageEl, meta) => { - expect(meta.x).toEqual(indicator.x); - expect(meta.y).toEqual(indicator.y); - expect(meta.width).toEqual(indicator.image.width); - expect(meta.height).toEqual(indicator.image.height); - done(); - }); - replacedImageDiff.renderNewView(indicator); - }); - - it('should call showCommentIndicator', done => { - const normalized = { - normalized: true, - }; - spyOn(imageDiffHelper, 'resizeCoordinatesToImageElement').and.returnValue(normalized); - spyOn(imageDiffHelper, 'showCommentIndicator').and.callFake( - (imageFrameEl, normalizedIndicator) => { - expect(normalizedIndicator).toEqual(normalized); - done(); - }, - ); - replacedImageDiff.renderNewView(indicator); - }); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js deleted file mode 100644 index 367e07d3ad3..00000000000 --- a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import ciBadge from '~/vue_shared/components/ci_badge_link.vue'; - -describe('CI Badge Link Component', () => { - let CIBadge; - let vm; - - const statuses = { - canceled: { - text: 'canceled', - label: 'canceled', - group: 'canceled', - icon: 'status_canceled', - details_path: 'status/canceled', - }, - created: { - text: 'created', - label: 'created', - group: 'created', - icon: 'status_created', - details_path: 'status/created', - }, - failed: { - text: 'failed', - label: 'failed', - group: 'failed', - icon: 'status_failed', - details_path: 'status/failed', - }, - manual: { - text: 'manual', - label: 'manual action', - group: 'manual', - icon: 'status_manual', - details_path: 'status/manual', - }, - pending: { - text: 'pending', - label: 'pending', - group: 'pending', - icon: 'status_pending', - details_path: 'status/pending', - }, - running: { - text: 'running', - label: 'running', - group: 'running', - icon: 'status_running', - details_path: 'status/running', - }, - skipped: { - text: 'skipped', - label: 'skipped', - group: 'skipped', - icon: 'status_skipped', - details_path: 'status/skipped', - }, - success_warining: { - text: 'passed', - label: 'passed', - group: 'success-with-warnings', - icon: 'status_warning', - details_path: 'status/warning', - }, - success: { - text: 'passed', - label: 'passed', - group: 'passed', - icon: 'status_success', - details_path: 'status/passed', - }, - }; - - beforeEach(() => { - CIBadge = Vue.extend(ciBadge); - }); - - afterEach(() => { - vm.$destroy(); - }); - - 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')).toContain(`ci-status ci-${statuses[status].group}`); - expect(vm.$el.querySelector('svg')).toBeDefined(); - return vm; - }); - }); - - 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/ci_icon_spec.js b/spec/javascripts/vue_shared/components/ci_icon_spec.js deleted file mode 100644 index 9486d7d4f23..00000000000 --- a/spec/javascripts/vue_shared/components/ci_icon_spec.js +++ /dev/null @@ -1,122 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import ciIcon from '~/vue_shared/components/ci_icon.vue'; - -describe('CI Icon component', () => { - const Component = Vue.extend(ciIcon); - let vm; - - afterEach(() => { - vm.$destroy(); - }); - - it('should render a span element with an svg', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_success', - }, - }); - - expect(vm.$el.tagName).toEqual('SPAN'); - expect(vm.$el.querySelector('span > svg')).toBeDefined(); - }); - - it('should render a success status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_success', - group: 'success', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-success')).toEqual(true); - }); - - it('should render a failed status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_failed', - group: 'failed', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-failed')).toEqual(true); - }); - - it('should render success with warnings status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_warning', - group: 'warning', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-warning')).toEqual(true); - }); - - it('should render pending status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_pending', - group: 'pending', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-pending')).toEqual(true); - }); - - it('should render running status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_running', - group: 'running', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-running')).toEqual(true); - }); - - it('should render created status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_created', - group: 'created', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-created')).toEqual(true); - }); - - it('should render skipped status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_skipped', - group: 'skipped', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-skipped')).toEqual(true); - }); - - it('should render canceled status', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_canceled', - group: 'canceled', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-canceled')).toEqual(true); - }); - - it('should render status for manual action', () => { - vm = mountComponent(Component, { - status: { - icon: 'status_manual', - group: 'manual', - }, - }); - - expect(vm.$el.classList.contains('ci-status-icon-manual')).toEqual(true); - }); -}); diff --git a/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js b/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js deleted file mode 100644 index fbe9337ecf4..00000000000 --- a/spec/javascripts/vue_shared/components/content_viewer/content_viewer_spec.js +++ /dev/null @@ -1,123 +0,0 @@ -import Vue from 'vue'; -import MockAdapter from 'axios-mock-adapter'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import waitForPromises from 'spec/helpers/wait_for_promises'; -import { GREEN_BOX_IMAGE_URL } from 'spec/test_constants'; -import axios from '~/lib/utils/axios_utils'; -import contentViewer from '~/vue_shared/components/content_viewer/content_viewer.vue'; -import '~/behaviors/markdown/render_gfm'; - -describe('ContentViewer', () => { - let vm; - let mock; - - function createComponent(props) { - const ContentViewer = Vue.extend(contentViewer); - vm = mountComponent(ContentViewer, props); - } - - afterEach(() => { - vm.$destroy(); - if (mock) mock.restore(); - }); - - it('markdown preview renders + loads rendered markdown from server', done => { - mock = new MockAdapter(axios); - mock.onPost(`${gon.relative_url_root}/testproject/preview_markdown`).replyOnce(200, { - body: '<b>testing</b>', - }); - - createComponent({ - path: 'test.md', - content: '* Test', - projectPath: 'testproject', - type: 'markdown', - }); - - waitForPromises() - .then(() => { - expect(vm.$el.querySelector('.md-previewer').textContent).toContain('testing'); - }) - .then(done) - .catch(done.fail); - }); - - it('renders image preview', done => { - createComponent({ - path: GREEN_BOX_IMAGE_URL, - fileSize: 1024, - type: 'image', - }); - - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelector('img').getAttribute('src')).toBe(GREEN_BOX_IMAGE_URL); - }) - .then(done) - .catch(done.fail); - }); - - it('renders fallback download control', done => { - createComponent({ - path: 'somepath/test.abc', - fileSize: 1024, - }); - - vm.$nextTick() - .then(() => { - expect( - vm.$el - .querySelector('.file-info') - .textContent.trim() - .replace(/\s+/, ' '), - ).toEqual('test.abc (1.00 KiB)'); - - expect(vm.$el.querySelector('.btn.btn-default').textContent.trim()).toEqual('Download'); - }) - .then(done) - .catch(done.fail); - }); - - it('renders fallback download control for file with a data URL path properly', done => { - createComponent({ - path: 'data:application/octet-stream;base64,U0VMRUNUICfEhHNnc2cnIGZyb20gVGFibGVuYW1lOwoK', - filePath: 'somepath/test.abc', - }); - - vm.$nextTick() - .then(() => { - expect(vm.$el.querySelector('.file-info').textContent.trim()).toEqual('test.abc'); - expect(vm.$el.querySelector('.btn.btn-default')).toHaveAttr('download', 'test.abc'); - expect(vm.$el.querySelector('.btn.btn-default').textContent.trim()).toEqual('Download'); - }) - .then(done) - .catch(done.fail); - }); - - it('markdown preview receives the file path as a parameter', done => { - mock = new MockAdapter(axios); - spyOn(axios, 'post').and.callThrough(); - mock.onPost(`${gon.relative_url_root}/testproject/preview_markdown`).reply(200, { - body: '<b>testing</b>', - }); - - createComponent({ - path: 'test.md', - content: '* Test', - projectPath: 'testproject', - type: 'markdown', - filePath: 'foo/test.md', - }); - - vm.$nextTick() - .then(() => { - expect(axios.post).toHaveBeenCalledWith( - `${gon.relative_url_root}/testproject/preview_markdown`, - { path: 'foo/test.md', text: '* Test' }, - jasmine.any(Object), - ); - }) - .then(done) - .catch(done.fail); - }); -}); 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 deleted file mode 100644 index a8acecdd3fc..00000000000 --- a/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js +++ /dev/null @@ -1,98 +0,0 @@ -import Vue from 'vue'; - -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { GREEN_BOX_IMAGE_URL, RED_BOX_IMAGE_URL } from 'spec/test_constants'; -import diffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue'; - -describe('DiffViewer', () => { - const requiredProps = { - diffMode: 'replaced', - diffViewerMode: 'image', - newPath: GREEN_BOX_IMAGE_URL, - newSha: 'ABC', - oldPath: RED_BOX_IMAGE_URL, - oldSha: 'DEF', - }; - let vm; - - function createComponent(props) { - const DiffViewer = Vue.extend(diffViewer); - - vm = mountComponent(DiffViewer, props); - } - - afterEach(() => { - vm.$destroy(); - }); - - it('renders image diff', done => { - window.gon = { - relative_url_root: '', - }; - - createComponent({ ...requiredProps, projectPath: '' }); - - setTimeout(() => { - expect(vm.$el.querySelector('.deleted img').getAttribute('src')).toBe( - `//-/raw/DEF/${RED_BOX_IMAGE_URL}`, - ); - - expect(vm.$el.querySelector('.added img').getAttribute('src')).toBe( - `//-/raw/ABC/${GREEN_BOX_IMAGE_URL}`, - ); - - done(); - }); - }); - - it('renders fallback download diff display', done => { - createComponent({ - ...requiredProps, - diffViewerMode: 'added', - newPath: 'test.abc', - oldPath: 'testold.abc', - }); - - setTimeout(() => { - expect(vm.$el.querySelector('.deleted .file-info').textContent.trim()).toContain( - 'testold.abc', - ); - - expect(vm.$el.querySelector('.deleted .btn.btn-default').textContent.trim()).toContain( - 'Download', - ); - - expect(vm.$el.querySelector('.added .file-info').textContent.trim()).toContain('test.abc'); - expect(vm.$el.querySelector('.added .btn.btn-default').textContent.trim()).toContain( - 'Download', - ); - - done(); - }); - }); - - it('renders renamed component', () => { - createComponent({ - ...requiredProps, - diffMode: 'renamed', - diffViewerMode: 'renamed', - newPath: 'test.abc', - oldPath: 'testold.abc', - }); - - expect(vm.$el.textContent).toContain('File moved'); - }); - - it('renders mode changed component', () => { - createComponent({ - ...requiredProps, - diffMode: 'mode_changed', - newPath: 'test.abc', - oldPath: 'testold.abc', - aMode: '123', - bMode: '321', - }); - - expect(vm.$el.textContent).toContain('File mode changed from 123 to 321'); - }); -}); diff --git a/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js b/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js deleted file mode 100644 index b00fa785a0e..00000000000 --- a/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js +++ /dev/null @@ -1,81 +0,0 @@ -import Vue from 'vue'; - -import { mountComponentWithSlots } from 'spec/helpers/vue_mount_component_helper'; -import dropdownButtonComponent from '~/vue_shared/components/dropdown/dropdown_button.vue'; - -const defaultLabel = 'Select'; -const customLabel = 'Select project'; - -const createComponent = (props, slots = {}) => { - const Component = Vue.extend(dropdownButtonComponent); - - return mountComponentWithSlots(Component, { props, slots }); -}; - -describe('DropdownButtonComponent', () => { - let vm; - - beforeEach(() => { - vm = createComponent(); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('computed', () => { - describe('dropdownToggleText', () => { - it('returns default toggle text', () => { - expect(vm.toggleText).toBe(defaultLabel); - }); - - it('returns custom toggle text when provided via props', () => { - const vmEmptyLabels = createComponent({ toggleText: customLabel }); - - expect(vmEmptyLabels.toggleText).toBe(customLabel); - vmEmptyLabels.$destroy(); - }); - }); - }); - - describe('template', () => { - it('renders component container element of type `button`', () => { - expect(vm.$el.nodeName).toBe('BUTTON'); - }); - - it('renders component container element with required data attributes', () => { - expect(vm.$el.dataset.abilityName).toBe(vm.abilityName); - expect(vm.$el.dataset.fieldName).toBe(vm.fieldName); - expect(vm.$el.dataset.issueUpdate).toBe(vm.updatePath); - expect(vm.$el.dataset.labels).toBe(vm.labelsPath); - expect(vm.$el.dataset.namespacePath).toBe(vm.namespace); - expect(vm.$el.dataset.showAny).not.toBeDefined(); - }); - - it('renders dropdown toggle text element', () => { - const dropdownToggleTextEl = vm.$el.querySelector('.dropdown-toggle-text'); - - expect(dropdownToggleTextEl).not.toBeNull(); - expect(dropdownToggleTextEl.innerText.trim()).toBe(defaultLabel); - }); - - it('renders dropdown button icon', () => { - const dropdownIconEl = vm.$el.querySelector('.dropdown-toggle-icon i.fa'); - - expect(dropdownIconEl).not.toBeNull(); - expect(dropdownIconEl.classList.contains('fa-chevron-down')).toBe(true); - }); - - it('renders slot, if default slot exists', () => { - vm = createComponent( - {}, - { - default: ['Lorem Ipsum Dolar'], - }, - ); - - expect(vm.$el).not.toContainElement('.dropdown-toggle-text'); - expect(vm.$el).toHaveText('Lorem Ipsum Dolar'); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/dropdown/dropdown_hidden_input_spec.js b/spec/javascripts/vue_shared/components/dropdown/dropdown_hidden_input_spec.js deleted file mode 100644 index 402de2a8788..00000000000 --- a/spec/javascripts/vue_shared/components/dropdown/dropdown_hidden_input_spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import Vue from 'vue'; - -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import dropdownHiddenInputComponent from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue'; - -import { mockLabels } from './mock_data'; - -const createComponent = (name = 'label_id[]', value = mockLabels[0].id) => { - const Component = Vue.extend(dropdownHiddenInputComponent); - - return mountComponent(Component, { - name, - value, - }); -}; - -describe('DropdownHiddenInputComponent', () => { - let vm; - - beforeEach(() => { - vm = createComponent(); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('template', () => { - it('renders input element of type `hidden`', () => { - expect(vm.$el.nodeName).toBe('INPUT'); - expect(vm.$el.getAttribute('type')).toBe('hidden'); - expect(vm.$el.getAttribute('name')).toBe(vm.name); - expect(vm.$el.getAttribute('value')).toBe(`${vm.value}`); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/dropdown/mock_data.js b/spec/javascripts/vue_shared/components/dropdown/mock_data.js deleted file mode 100644 index b09d42da401..00000000000 --- a/spec/javascripts/vue_shared/components/dropdown/mock_data.js +++ /dev/null @@ -1,11 +0,0 @@ -export const mockLabels = [ - { - id: 26, - title: 'Foo Label', - description: 'Foobar', - color: '#BADA55', - text_color: '#FFFFFF', - }, -]; - -export default mockLabels; diff --git a/spec/javascripts/vue_shared/components/file_finder/item_spec.js b/spec/javascripts/vue_shared/components/file_finder/item_spec.js deleted file mode 100644 index e18d0a46223..00000000000 --- a/spec/javascripts/vue_shared/components/file_finder/item_spec.js +++ /dev/null @@ -1,140 +0,0 @@ -import Vue from 'vue'; -import { file } from 'spec/ide/helpers'; -import ItemComponent from '~/vue_shared/components/file_finder/item.vue'; -import createComponent from '../../../helpers/vue_mount_component_helper'; - -describe('File finder item spec', () => { - const Component = Vue.extend(ItemComponent); - let vm; - let localFile; - - beforeEach(() => { - localFile = { - ...file(), - name: 'test file', - path: 'test/file', - }; - - vm = createComponent(Component, { - file: localFile, - focused: true, - searchText: '', - index: 0, - }); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders file name & path', () => { - expect(vm.$el.textContent).toContain('test file'); - expect(vm.$el.textContent).toContain('test/file'); - }); - - describe('focused', () => { - it('adds is-focused class', () => { - expect(vm.$el.classList).toContain('is-focused'); - }); - - it('does not have is-focused class when not focused', done => { - vm.focused = false; - - vm.$nextTick(() => { - expect(vm.$el.classList).not.toContain('is-focused'); - - done(); - }); - }); - }); - - describe('changed file icon', () => { - it('does not render when not a changed or temp file', () => { - expect(vm.$el.querySelector('.diff-changed-stats')).toBe(null); - }); - - it('renders when a changed file', done => { - vm.file.changed = true; - - vm.$nextTick(() => { - expect(vm.$el.querySelector('.diff-changed-stats')).not.toBe(null); - - done(); - }); - }); - - it('renders when a temp file', done => { - vm.file.tempFile = true; - - vm.$nextTick(() => { - expect(vm.$el.querySelector('.diff-changed-stats')).not.toBe(null); - - done(); - }); - }); - }); - - it('emits event when clicked', () => { - spyOn(vm, '$emit'); - - vm.$el.click(); - - expect(vm.$emit).toHaveBeenCalledWith('click', vm.file); - }); - - describe('path', () => { - let el; - - beforeEach(done => { - vm.searchText = 'file'; - - el = vm.$el.querySelector('.diff-changed-file-path'); - - vm.$nextTick(done); - }); - - it('highlights text', () => { - expect(el.querySelectorAll('.highlighted').length).toBe(4); - }); - - it('adds ellipsis to long text', done => { - vm.file.path = new Array(70) - .fill() - .map((_, i) => `${i}-`) - .join(''); - - vm.$nextTick(() => { - expect(el.textContent).toBe(`...${vm.file.path.substr(vm.file.path.length - 60)}`); - done(); - }); - }); - }); - - describe('name', () => { - let el; - - beforeEach(done => { - vm.searchText = 'file'; - - el = vm.$el.querySelector('.diff-changed-file-name'); - - vm.$nextTick(done); - }); - - it('highlights text', () => { - expect(el.querySelectorAll('.highlighted').length).toBe(4); - }); - - it('does not add ellipsis to long text', done => { - vm.file.name = new Array(70) - .fill() - .map((_, i) => `${i}-`) - .join(''); - - vm.$nextTick(() => { - expect(el.textContent).not.toBe(`...${vm.file.name.substr(vm.file.name.length - 60)}`); - done(); - }); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js b/spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js deleted file mode 100644 index 0bb4a04557b..00000000000 --- a/spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js +++ /dev/null @@ -1,190 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import component from '~/vue_shared/components/filtered_search_dropdown.vue'; - -describe('Filtered search dropdown', () => { - const Component = Vue.extend(component); - let vm; - - afterEach(() => { - vm.$destroy(); - }); - - describe('with an empty array of items', () => { - beforeEach(() => { - vm = mountComponent(Component, { - items: [], - filterKey: '', - }); - }); - - it('renders empty list', () => { - expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(0); - }); - - it('renders filter input', () => { - expect(vm.$el.querySelector('.js-filtered-dropdown-input')).not.toBeNull(); - }); - }); - - describe('when visible numbers is less than the items length', () => { - beforeEach(() => { - vm = mountComponent(Component, { - items: [{ title: 'One' }, { title: 'Two' }, { title: 'Three' }], - visibleItems: 2, - filterKey: 'title', - }); - }); - - it('it renders only the maximum number provided', () => { - expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(2); - }); - }); - - describe('when visible number is bigger than the items length', () => { - beforeEach(() => { - vm = mountComponent(Component, { - items: [{ title: 'One' }, { title: 'Two' }, { title: 'Three' }], - filterKey: 'title', - }); - }); - - it('it renders the full list of items the maximum number provided', () => { - expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(3); - }); - }); - - describe('while filtering', () => { - beforeEach(() => { - vm = mountComponent(Component, { - items: [ - { title: 'One' }, - { title: 'Two/three' }, - { title: 'Three four' }, - { title: 'Five' }, - ], - filterKey: 'title', - }); - }); - - it('updates the results to match the typed value', done => { - vm.$el.querySelector('.js-filtered-dropdown-input').value = 'three'; - vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input')); - vm.$nextTick(() => { - expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(2); - done(); - }); - }); - - describe('when no value matches the typed one', () => { - it('does not render any result', done => { - vm.$el.querySelector('.js-filtered-dropdown-input').value = 'six'; - vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input')); - - vm.$nextTick(() => { - expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(0); - done(); - }); - }); - }); - }); - - describe('with create mode enabled', () => { - describe('when there are no matches', () => { - beforeEach(() => { - vm = mountComponent(Component, { - items: [ - { title: 'One' }, - { title: 'Two/three' }, - { title: 'Three four' }, - { title: 'Five' }, - ], - filterKey: 'title', - showCreateMode: true, - }); - - vm.$el.querySelector('.js-filtered-dropdown-input').value = 'eleven'; - vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input')); - }); - - it('renders a create button', done => { - vm.$nextTick(() => { - expect(vm.$el.querySelector('.js-dropdown-create-button')).not.toBeNull(); - done(); - }); - }); - - it('renders computed button text', done => { - vm.$nextTick(() => { - expect(vm.$el.querySelector('.js-dropdown-create-button').textContent.trim()).toEqual( - 'Create eleven', - ); - done(); - }); - }); - - describe('on click create button', () => { - it('emits createItem event with the filter', done => { - spyOn(vm, '$emit'); - vm.$nextTick(() => { - vm.$el.querySelector('.js-dropdown-create-button').click(); - - expect(vm.$emit).toHaveBeenCalledWith('createItem', 'eleven'); - done(); - }); - }); - }); - }); - - describe('when there are matches', () => { - beforeEach(() => { - vm = mountComponent(Component, { - items: [ - { title: 'One' }, - { title: 'Two/three' }, - { title: 'Three four' }, - { title: 'Five' }, - ], - filterKey: 'title', - showCreateMode: true, - }); - - vm.$el.querySelector('.js-filtered-dropdown-input').value = 'one'; - vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input')); - }); - - it('does not render a create button', done => { - vm.$nextTick(() => { - expect(vm.$el.querySelector('.js-dropdown-create-button')).toBeNull(); - done(); - }); - }); - }); - }); - - describe('with create mode disabled', () => { - describe('when there are no matches', () => { - beforeEach(() => { - vm = mountComponent(Component, { - items: [ - { title: 'One' }, - { title: 'Two/three' }, - { title: 'Three four' }, - { title: 'Five' }, - ], - filterKey: 'title', - }); - - vm.$el.querySelector('.js-filtered-dropdown-input').value = 'eleven'; - vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input')); - }); - - it('does not render a create button', done => { - vm.$nextTick(() => { - expect(vm.$el.querySelector('.js-dropdown-create-button')).toBeNull(); - done(); - }); - }); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/gl_countdown_spec.js b/spec/javascripts/vue_shared/components/gl_countdown_spec.js deleted file mode 100644 index 929ffe219f4..00000000000 --- a/spec/javascripts/vue_shared/components/gl_countdown_spec.js +++ /dev/null @@ -1,77 +0,0 @@ -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import Vue from 'vue'; -import GlCountdown from '~/vue_shared/components/gl_countdown.vue'; - -describe('GlCountdown', () => { - const Component = Vue.extend(GlCountdown); - let vm; - let now = '2000-01-01T00:00:00Z'; - - beforeEach(() => { - spyOn(Date, 'now').and.callFake(() => new Date(now).getTime()); - jasmine.clock().install(); - }); - - afterEach(() => { - vm.$destroy(); - jasmine.clock().uninstall(); - }); - - describe('when there is time remaining', () => { - beforeEach(done => { - vm = mountComponent(Component, { - endDateString: '2000-01-01T01:02:03Z', - }); - - Vue.nextTick() - .then(done) - .catch(done.fail); - }); - - it('displays remaining time', () => { - expect(vm.$el).toContainText('01:02:03'); - }); - - it('updates remaining time', done => { - now = '2000-01-01T00:00:01Z'; - jasmine.clock().tick(1000); - - Vue.nextTick() - .then(() => { - expect(vm.$el).toContainText('01:02:02'); - done(); - }) - .catch(done.fail); - }); - }); - - describe('when there is no time remaining', () => { - beforeEach(done => { - vm = mountComponent(Component, { - endDateString: '1900-01-01T00:00:00Z', - }); - - Vue.nextTick() - .then(done) - .catch(done.fail); - }); - - it('displays 00:00:00', () => { - expect(vm.$el).toContainText('00:00:00'); - }); - }); - - describe('when an invalid date is passed', () => { - it('throws a validation error', () => { - spyOn(Vue.config, 'warnHandler').and.stub(); - vm = mountComponent(Component, { - endDateString: 'this is invalid', - }); - - expect(Vue.config.warnHandler).toHaveBeenCalledTimes(1); - const [errorMessage] = Vue.config.warnHandler.calls.argsFor(0); - - expect(errorMessage).toMatch(/^Invalid prop: .* "endDateString"/); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/header_ci_component_spec.js b/spec/javascripts/vue_shared/components/header_ci_component_spec.js deleted file mode 100644 index b1abc972e1d..00000000000 --- a/spec/javascripts/vue_shared/components/header_ci_component_spec.js +++ /dev/null @@ -1,93 +0,0 @@ -import Vue from 'vue'; -import mountComponent, { mountComponentWithSlots } from 'spec/helpers/vue_mount_component_helper'; -import headerCi from '~/vue_shared/components/header_ci_component.vue'; - -describe('Header CI Component', () => { - let HeaderCi; - let vm; - let props; - - beforeEach(() => { - HeaderCi = Vue.extend(headerCi); - props = { - status: { - group: 'failed', - icon: 'status_failed', - label: 'failed', - text: 'failed', - details_path: 'path', - }, - itemName: 'job', - itemId: 123, - time: '2017-05-08T14:57:39.781Z', - user: { - web_url: 'path', - name: 'Foo', - username: 'foobar', - email: 'foo@bar.com', - avatar_url: 'link', - }, - hasSidebarButton: true, - }; - }); - - afterEach(() => { - vm.$destroy(); - }); - - const findActionButtons = () => vm.$el.querySelector('.header-action-buttons'); - - describe('render', () => { - beforeEach(() => { - vm = mountComponent(HeaderCi, props); - }); - - it('should render status badge', () => { - expect(vm.$el.querySelector('.ci-failed')).toBeDefined(); - expect(vm.$el.querySelector('.ci-status-icon-failed svg')).toBeDefined(); - expect(vm.$el.querySelector('.ci-failed').getAttribute('href')).toEqual( - props.status.details_path, - ); - }); - - it('should render item name and id', () => { - expect(vm.$el.querySelector('strong').textContent.trim()).toEqual('job #123'); - }); - - it('should render timeago date', () => { - expect(vm.$el.querySelector('time')).toBeDefined(); - }); - - it('should render user icon and name', () => { - expect(vm.$el.querySelector('.js-user-link').innerText.trim()).toContain(props.user.name); - }); - - it('should render sidebar toggle button', () => { - expect(vm.$el.querySelector('.js-sidebar-build-toggle')).not.toBeNull(); - }); - - it('should not render header action buttons when empty', () => { - expect(findActionButtons()).toBeNull(); - }); - }); - - describe('slot', () => { - it('should render header action buttons', () => { - vm = mountComponentWithSlots(HeaderCi, { props, slots: { default: 'Test Actions' } }); - - const buttons = findActionButtons(); - - expect(buttons).not.toBeNull(); - expect(buttons.textContent).toEqual('Test Actions'); - }); - }); - - describe('shouldRenderTriggeredLabel', () => { - it('should rendered created keyword when the shouldRenderTriggeredLabel is false', () => { - vm = mountComponent(HeaderCi, { ...props, shouldRenderTriggeredLabel: false }); - - expect(vm.$el.textContent).toContain('created'); - expect(vm.$el.textContent).not.toContain('triggered'); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js b/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js deleted file mode 100644 index a87998aa72f..00000000000 --- a/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import toolbar from '~/vue_shared/components/markdown/toolbar.vue'; - -describe('toolbar', () => { - let vm; - const Toolbar = Vue.extend(toolbar); - const props = { - markdownDocsPath: '', - }; - - afterEach(() => { - vm.$destroy(); - }); - - describe('user can attach file', () => { - beforeEach(() => { - vm = mountComponent(Toolbar, props); - }); - - it('should render uploading-container', () => { - expect(vm.$el.querySelector('.uploading-container')).not.toBeNull(); - }); - }); - - describe('user cannot attach file', () => { - beforeEach(() => { - vm = mountComponent(Toolbar, { ...props, canAttachFile: false }); - }); - - it('should not render uploading-container', () => { - expect(vm.$el.querySelector('.uploading-container')).toBeNull(); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/navigation_tabs_spec.js b/spec/javascripts/vue_shared/components/navigation_tabs_spec.js deleted file mode 100644 index beb980a6556..00000000000 --- a/spec/javascripts/vue_shared/components/navigation_tabs_spec.js +++ /dev/null @@ -1,64 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import navigationTabs from '~/vue_shared/components/navigation_tabs.vue'; - -describe('navigation tabs component', () => { - let vm; - let Component; - let data; - - beforeEach(() => { - data = [ - { - name: 'All', - scope: 'all', - count: 1, - isActive: true, - }, - { - name: 'Pending', - scope: 'pending', - count: 0, - isActive: false, - }, - { - name: 'Running', - scope: 'running', - isActive: false, - }, - ]; - - Component = Vue.extend(navigationTabs); - vm = mountComponent(Component, { tabs: data, scope: 'pipelines' }); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('should render tabs', () => { - expect(vm.$el.querySelectorAll('li').length).toEqual(data.length); - }); - - it('should render active tab', () => { - expect(vm.$el.querySelector('.active .js-pipelines-tab-all')).toBeDefined(); - }); - - it('should render badge', () => { - expect(vm.$el.querySelector('.js-pipelines-tab-all .badge').textContent.trim()).toEqual('1'); - expect(vm.$el.querySelector('.js-pipelines-tab-pending .badge').textContent.trim()).toEqual( - '0', - ); - }); - - it('should not render badge', () => { - expect(vm.$el.querySelector('.js-pipelines-tab-running .badge')).toEqual(null); - }); - - 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/pikaday_spec.js b/spec/javascripts/vue_shared/components/pikaday_spec.js deleted file mode 100644 index b787ba7596f..00000000000 --- a/spec/javascripts/vue_shared/components/pikaday_spec.js +++ /dev/null @@ -1,30 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import datePicker from '~/vue_shared/components/pikaday.vue'; - -describe('datePicker', () => { - let vm; - beforeEach(() => { - const DatePicker = Vue.extend(datePicker); - vm = mountComponent(DatePicker, { - label: 'label', - }); - }); - - it('should render label text', () => { - expect(vm.$el.querySelector('.dropdown-toggle-text').innerText.trim()).toEqual('label'); - }); - - it('should show calendar', () => { - expect(vm.$el.querySelector('.pika-single')).toBeDefined(); - }); - - it('should toggle when dropdown is clicked', () => { - const hidePicker = jasmine.createSpy(); - vm.$on('hidePicker', hidePicker); - - vm.$el.querySelector('.dropdown-menu-toggle').click(); - - expect(hidePicker).toHaveBeenCalled(); - }); -}); diff --git a/spec/javascripts/vue_shared/components/project_avatar/default_spec.js b/spec/javascripts/vue_shared/components/project_avatar/default_spec.js deleted file mode 100644 index 2ec19ebf80e..00000000000 --- a/spec/javascripts/vue_shared/components/project_avatar/default_spec.js +++ /dev/null @@ -1,58 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { projectData } from 'spec/ide/mock_data'; -import { TEST_HOST } from 'spec/test_constants'; -import { getFirstCharacterCapitalized } from '~/lib/utils/text_utility'; -import ProjectAvatarDefault from '~/vue_shared/components/project_avatar/default.vue'; - -describe('ProjectAvatarDefault component', () => { - const Component = Vue.extend(ProjectAvatarDefault); - let vm; - - beforeEach(() => { - vm = mountComponent(Component, { - project: projectData, - }); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders identicon if project has no avatar_url', done => { - const expectedText = getFirstCharacterCapitalized(projectData.name); - - vm.project = { - ...vm.project, - avatar_url: null, - }; - - vm.$nextTick() - .then(() => { - const identiconEl = vm.$el.querySelector('.identicon'); - - expect(identiconEl).not.toBe(null); - expect(identiconEl.textContent.trim()).toEqual(expectedText); - }) - .then(done) - .catch(done.fail); - }); - - it('renders avatar image if project has avatar_url', done => { - const avatarUrl = `${TEST_HOST}/images/home/nasa.svg`; - - vm.project = { - ...vm.project, - avatar_url: avatarUrl, - }; - - vm.$nextTick() - .then(() => { - expect(vm.$el).toContainElement('.avatar'); - expect(vm.$el).not.toContainElement('.identicon'); - expect(vm.$el.querySelector('img')).toHaveAttr('src', avatarUrl); - }) - .then(done) - .catch(done.fail); - }); -}); diff --git a/spec/javascripts/vue_shared/components/project_selector/project_list_item_spec.js b/spec/javascripts/vue_shared/components/project_selector/project_list_item_spec.js deleted file mode 100644 index e73fb97b741..00000000000 --- a/spec/javascripts/vue_shared/components/project_selector/project_list_item_spec.js +++ /dev/null @@ -1,109 +0,0 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { trimText } from 'spec/helpers/text_helper'; -import ProjectListItem from '~/vue_shared/components/project_selector/project_list_item.vue'; - -const localVue = createLocalVue(); - -describe('ProjectListItem component', () => { - const Component = localVue.extend(ProjectListItem); - let wrapper; - let vm; - let options; - loadJSONFixtures('static/projects.json'); - const project = getJSONFixture('static/projects.json')[0]; - - beforeEach(() => { - options = { - propsData: { - project, - selected: false, - }, - localVue, - }; - }); - - afterEach(() => { - wrapper.vm.$destroy(); - }); - - it('does not render a check mark icon if selected === false', () => { - wrapper = shallowMount(Component, options); - - expect(wrapper.contains('.js-selected-icon.js-unselected')).toBe(true); - }); - - it('renders a check mark icon if selected === true', () => { - options.propsData.selected = true; - - wrapper = shallowMount(Component, options); - - expect(wrapper.contains('.js-selected-icon.js-selected')).toBe(true); - }); - - it(`emits a "clicked" event when clicked`, () => { - wrapper = shallowMount(Component, options); - ({ vm } = wrapper); - - spyOn(vm, '$emit'); - wrapper.vm.onClick(); - - expect(wrapper.vm.$emit).toHaveBeenCalledWith('click'); - }); - - it(`renders the project avatar`, () => { - wrapper = shallowMount(Component, options); - - expect(wrapper.contains('.js-project-avatar')).toBe(true); - }); - - it(`renders a simple namespace name with a trailing slash`, () => { - options.propsData.project.name_with_namespace = 'a / b'; - - wrapper = shallowMount(Component, options); - const renderedNamespace = trimText(wrapper.find('.js-project-namespace').text()); - - expect(renderedNamespace).toBe('a /'); - }); - - it(`renders a properly truncated namespace with a trailing slash`, () => { - options.propsData.project.name_with_namespace = 'a / b / c / d / e / f'; - - wrapper = shallowMount(Component, options); - const renderedNamespace = trimText(wrapper.find('.js-project-namespace').text()); - - expect(renderedNamespace).toBe('a / ... / e /'); - }); - - it(`renders the project name`, () => { - options.propsData.project.name = 'my-test-project'; - - wrapper = shallowMount(Component, options); - const renderedName = trimText(wrapper.find('.js-project-name').text()); - - expect(renderedName).toBe('my-test-project'); - }); - - it(`renders the project name with highlighting in the case of a search query match`, () => { - options.propsData.project.name = 'my-test-project'; - options.propsData.matcher = 'pro'; - - wrapper = shallowMount(Component, options); - const renderedName = trimText(wrapper.find('.js-project-name').html()); - const expected = 'my-test-<b>p</b><b>r</b><b>o</b>ject'; - - expect(renderedName).toContain(expected); - }); - - it('prevents search query and project name XSS', () => { - const alertSpy = spyOn(window, 'alert'); - options.propsData.project.name = "my-xss-pro<script>alert('XSS');</script>ject"; - options.propsData.matcher = "pro<script>alert('XSS');</script>"; - - wrapper = shallowMount(Component, options); - const renderedName = trimText(wrapper.find('.js-project-name').html()); - const expected = 'my-xss-project'; - - expect(renderedName).toContain(expected); - expect(alertSpy).not.toHaveBeenCalled(); - }); -}); diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data.js deleted file mode 100644 index 6564c012e67..00000000000 --- a/spec/javascripts/vue_shared/components/sidebar/labels_select/mock_data.js +++ /dev/null @@ -1,57 +0,0 @@ -export const mockLabels = [ - { - id: 26, - title: 'Foo Label', - description: 'Foobar', - color: '#BADA55', - text_color: '#FFFFFF', - }, - { - id: 27, - title: 'Foo::Bar', - description: 'Foobar', - color: '#0033CC', - text_color: '#FFFFFF', - }, -]; - -export const mockSuggestedColors = [ - '#0033CC', - '#428BCA', - '#44AD8E', - '#A8D695', - '#5CB85C', - '#69D100', - '#004E00', - '#34495E', - '#7F8C8D', - '#A295D6', - '#5843AD', - '#8E44AD', - '#FFECDB', - '#AD4363', - '#D10069', - '#CC0033', - '#FF0000', - '#D9534F', - '#D1D100', - '#F0AD4E', - '#AD8D43', -]; - -export const mockConfig = { - showCreate: true, - isProject: true, - abilityName: 'issue', - context: { - labels: mockLabels, - }, - namespace: 'gitlab-org', - updatePath: '/gitlab-org/my-project/issue/1', - labelsPath: '/gitlab-org/my-project/-/labels.json', - labelsWebUrl: '/gitlab-org/my-project/-/labels', - labelFilterBasePath: '/gitlab-org/my-project/issues', - canEdit: true, - suggestedColors: mockSuggestedColors, - emptyValueText: 'None', -}; diff --git a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js deleted file mode 100644 index 3e044f47a3f..00000000000 --- a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js +++ /dev/null @@ -1,104 +0,0 @@ -import Vue from 'vue'; - -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import stackedProgressBarComponent from '~/vue_shared/components/stacked_progress_bar.vue'; - -const createComponent = config => { - const Component = Vue.extend(stackedProgressBarComponent); - const defaultConfig = { - successLabel: 'Synced', - failureLabel: 'Failed', - neutralLabel: 'Out of sync', - successCount: 25, - failureCount: 10, - totalCount: 5000, - ...config, - }; - - return mountComponent(Component, defaultConfig); -}; - -describe('StackedProgressBarComponent', () => { - let vm; - - beforeEach(() => { - vm = createComponent(); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('computed', () => { - describe('neutralCount', () => { - it('returns neutralCount based on totalCount, successCount and failureCount', () => { - expect(vm.neutralCount).toBe(4965); // 5000 - 25 - 10 - }); - }); - }); - - describe('methods', () => { - describe('getPercent', () => { - it('returns percentage from provided count based on `totalCount`', () => { - expect(vm.getPercent(500)).toBe(10); - }); - - it('returns percentage with decimal place from provided count based on `totalCount`', () => { - expect(vm.getPercent(67)).toBe(1.3); - }); - - it('returns percentage as `< 1` from provided count based on `totalCount` when evaluated value is less than 1', () => { - expect(vm.getPercent(10)).toBe('< 1'); - }); - - it('returns 0 if totalCount is falsy', () => { - vm = createComponent({ totalCount: 0 }); - - expect(vm.getPercent(100)).toBe(0); - }); - }); - - describe('barStyle', () => { - it('returns style string based on percentage provided', () => { - expect(vm.barStyle(50)).toBe('width: 50%;'); - }); - }); - - describe('getTooltip', () => { - describe('when hideTooltips is false', () => { - it('returns label string based on label and count provided', () => { - expect(vm.getTooltip('Synced', 10)).toBe('Synced: 10'); - }); - }); - - describe('when hideTooltips is true', () => { - beforeEach(() => { - vm = createComponent({ hideTooltips: true }); - }); - - it('returns an empty string', () => { - expect(vm.getTooltip('Synced', 10)).toBe(''); - }); - }); - }); - }); - - describe('template', () => { - it('renders container element', () => { - expect(vm.$el.classList.contains('stacked-progress-bar')).toBeTruthy(); - }); - - 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(); - }); - - it('renders bar elements when count is available', () => { - expect(vm.$el.querySelectorAll('.status-green').length).not.toBe(0); - expect(vm.$el.querySelectorAll('.status-neutral').length).not.toBe(0); - expect(vm.$el.querySelectorAll('.status-red').length).not.toBe(0); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/tabs/tab_spec.js b/spec/javascripts/vue_shared/components/tabs/tab_spec.js deleted file mode 100644 index 8437fe37738..00000000000 --- a/spec/javascripts/vue_shared/components/tabs/tab_spec.js +++ /dev/null @@ -1,32 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import Tab from '~/vue_shared/components/tabs/tab.vue'; - -describe('Tab component', () => { - const Component = Vue.extend(Tab); - let vm; - - beforeEach(() => { - vm = mountComponent(Component); - }); - - it('sets localActive to equal active', done => { - vm.active = true; - - vm.$nextTick(() => { - expect(vm.localActive).toBe(true); - - done(); - }); - }); - - it('sets active class', done => { - vm.active = true; - - vm.$nextTick(() => { - expect(vm.$el.classList).toContain('active'); - - done(); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/tabs/tabs_spec.js b/spec/javascripts/vue_shared/components/tabs/tabs_spec.js deleted file mode 100644 index 50ba18cd338..00000000000 --- a/spec/javascripts/vue_shared/components/tabs/tabs_spec.js +++ /dev/null @@ -1,68 +0,0 @@ -import Vue from 'vue'; -import Tabs from '~/vue_shared/components/tabs/tabs'; -import Tab from '~/vue_shared/components/tabs/tab.vue'; - -describe('Tabs component', () => { - let vm; - - beforeEach(done => { - vm = new Vue({ - components: { - Tabs, - Tab, - }, - template: ` - <div> - <tabs> - <tab title="Testing" active> - First tab - </tab> - <tab> - <template slot="title">Test slot</template> - Second tab - </tab> - </tabs> - </div> - `, - }).$mount(); - - setTimeout(done); - }); - - describe('tab links', () => { - it('renders links for tabs', () => { - expect(vm.$el.querySelectorAll('a').length).toBe(2); - }); - - it('renders link titles from props', () => { - expect(vm.$el.querySelector('a').textContent).toContain('Testing'); - }); - - it('renders link titles from slot', () => { - expect(vm.$el.querySelectorAll('a')[1].textContent).toContain('Test slot'); - }); - - it('renders active class', () => { - expect(vm.$el.querySelector('a').classList).toContain('active'); - }); - - it('updates active class on click', done => { - vm.$el.querySelectorAll('a')[1].click(); - - setTimeout(() => { - expect(vm.$el.querySelector('a').classList).not.toContain('active'); - expect(vm.$el.querySelectorAll('a')[1].classList).toContain('active'); - - done(); - }); - }); - }); - - describe('content', () => { - it('renders content panes', () => { - expect(vm.$el.querySelectorAll('.tab-pane').length).toBe(2); - expect(vm.$el.querySelectorAll('.tab-pane')[0].textContent).toContain('First tab'); - expect(vm.$el.querySelectorAll('.tab-pane')[1].textContent).toContain('Second tab'); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/toggle_button_spec.js b/spec/javascripts/vue_shared/components/toggle_button_spec.js deleted file mode 100644 index ea0a89a3ab5..00000000000 --- a/spec/javascripts/vue_shared/components/toggle_button_spec.js +++ /dev/null @@ -1,101 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import toggleButton from '~/vue_shared/components/toggle_button.vue'; - -describe('Toggle Button', () => { - let vm; - let Component; - - beforeEach(() => { - Component = Vue.extend(toggleButton); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('render output', () => { - beforeEach(() => { - vm = mountComponent(Component, { - value: true, - name: 'foo', - }); - }); - - it('renders input with provided name', () => { - expect(vm.$el.querySelector('input').getAttribute('name')).toEqual('foo'); - }); - - it('renders input with provided value', () => { - expect(vm.$el.querySelector('input').getAttribute('value')).toEqual('true'); - }); - - it('renders input status icon', () => { - expect(vm.$el.querySelectorAll('span.toggle-icon').length).toEqual(1); - expect(vm.$el.querySelectorAll('svg.s16.toggle-icon-svg').length).toEqual(1); - }); - }); - - describe('is-checked', () => { - beforeEach(() => { - vm = mountComponent(Component, { - value: true, - }); - - spyOn(vm, '$emit'); - }); - - it('renders is checked class', () => { - expect(vm.$el.querySelector('button').classList.contains('is-checked')).toEqual(true); - }); - - 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'); - }); - - it('emits change event when clicked', () => { - vm.$el.querySelector('button').click(); - - expect(vm.$emit).toHaveBeenCalledWith('change', false); - }); - }); - - describe('is-disabled', () => { - beforeEach(() => { - vm = mountComponent(Component, { - value: true, - disabledInput: true, - }); - spyOn(vm, '$emit'); - }); - - it('renders disabled button', () => { - expect(vm.$el.querySelector('button').classList.contains('is-disabled')).toEqual(true); - }); - - it('does not emit change event when clicked', () => { - vm.$el.querySelector('button').click(); - - expect(vm.$emit).not.toHaveBeenCalled(); - }); - }); - - describe('is-loading', () => { - beforeEach(() => { - vm = mountComponent(Component, { - value: true, - isLoading: true, - }); - }); - - it('renders loading class', () => { - expect(vm.$el.querySelector('button').classList.contains('is-loading')).toEqual(true); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js deleted file mode 100644 index 31644416439..00000000000 --- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js +++ /dev/null @@ -1,29 +0,0 @@ -import Vue from 'vue'; -import avatarSvg from 'icons/_icon_random.svg'; -import UserAvatarSvg from '~/vue_shared/components/user_avatar/user_avatar_svg.vue'; - -const UserAvatarSvgComponent = Vue.extend(UserAvatarSvg); - -describe('User Avatar Svg Component', function() { - describe('Initialization', function() { - beforeEach(function() { - this.propsData = { - size: 99, - svg: avatarSvg, - }; - - this.userAvatarSvg = new UserAvatarSvgComponent({ - propsData: this.propsData, - }).$mount(); - }); - - it('should return a defined Vue component', function() { - expect(this.userAvatarSvg).toBeDefined(); - }); - - it('should have <svg> as a child element', function() { - expect(this.userAvatarSvg.$el.tagName).toEqual('svg'); - expect(this.userAvatarSvg.$el.innerHTML).toContain('<path'); - }); - }); -}); |