From a906015cb1ad724b2f0726a40ac4a013443b1d6a Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Mon, 16 Oct 2017 16:04:17 -0500 Subject: Move user avatar specs to folder to mimic javascript directory --- .../user_avatar/user_avatar_image_spec.js | 54 ++++++++++++++++++++++ .../user_avatar/user_avatar_link_spec.js | 50 ++++++++++++++++++++ .../components/user_avatar/user_avatar_svg_spec.js | 29 ++++++++++++ .../components/user_avatar_image_spec.js | 54 ---------------------- .../vue_shared/components/user_avatar_link_spec.js | 50 -------------------- .../vue_shared/components/user_avatar_svg_spec.js | 29 ------------ 6 files changed, 133 insertions(+), 133 deletions(-) create mode 100644 spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js create mode 100644 spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js create mode 100644 spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js delete mode 100644 spec/javascripts/vue_shared/components/user_avatar_image_spec.js delete mode 100644 spec/javascripts/vue_shared/components/user_avatar_link_spec.js delete mode 100644 spec/javascripts/vue_shared/components/user_avatar_svg_spec.js (limited to 'spec/javascripts/vue_shared') diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js new file mode 100644 index 00000000000..8daa7610274 --- /dev/null +++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js @@ -0,0 +1,54 @@ +import Vue from 'vue'; +import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue'; + +const UserAvatarImageComponent = Vue.extend(UserAvatarImage); + +describe('User Avatar Image Component', function () { + describe('Initialization', function () { + beforeEach(function () { + this.propsData = { + size: 99, + imgSrc: 'myavatarurl.com', + imgAlt: 'mydisplayname', + cssClasses: 'myextraavatarclass', + tooltipText: 'tooltip text', + tooltipPlacement: 'bottom', + }; + + this.userAvatarImage = new UserAvatarImageComponent({ + propsData: this.propsData, + }).$mount(); + }); + + it('should return a defined Vue component', function () { + expect(this.userAvatarImage).toBeDefined(); + }); + + it('should have as a child element', function () { + expect(this.userAvatarImage.$el.tagName).toBe('IMG'); + }); + + it('should properly compute tooltipContainer', function () { + expect(this.userAvatarImage.tooltipContainer).toBe('body'); + }); + + it('should properly render tooltipContainer', function () { + expect(this.userAvatarImage.$el.getAttribute('data-container')).toBe('body'); + }); + + it('should properly compute avatarSizeClass', function () { + expect(this.userAvatarImage.avatarSizeClass).toBe('s99'); + }); + + it('should properly render img css', function () { + const classList = this.userAvatarImage.$el.classList; + const containsAvatar = classList.contains('avatar'); + const containsSizeClass = classList.contains('s99'); + const containsCustomClass = classList.contains('myextraavatarclass'); + + expect(containsAvatar).toBe(true); + expect(containsSizeClass).toBe(true); + expect(containsCustomClass).toBe(true); + }); + }); +}); diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js new file mode 100644 index 00000000000..52e450e9ba5 --- /dev/null +++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js @@ -0,0 +1,50 @@ +import Vue from 'vue'; +import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; + +describe('User Avatar Link Component', function () { + beforeEach(function () { + this.propsData = { + linkHref: 'myavatarurl.com', + imgSize: 99, + imgSrc: 'myavatarurl.com', + imgAlt: 'mydisplayname', + imgCssClasses: 'myextraavatarclass', + tooltipText: 'tooltip text', + tooltipPlacement: 'bottom', + }; + + const UserAvatarLinkComponent = Vue.extend(UserAvatarLink); + + this.userAvatarLink = new UserAvatarLinkComponent({ + propsData: this.propsData, + }).$mount(); + + this.userAvatarImage = this.userAvatarLink.$children[0]; + }); + + it('should return a defined Vue component', function () { + expect(this.userAvatarLink).toBeDefined(); + }); + + it('should have user-avatar-image registered as child component', function () { + expect(this.userAvatarLink.$options.components.userAvatarImage).toBeDefined(); + }); + + it('user-avatar-link should have user-avatar-image as child component', function () { + expect(this.userAvatarImage).toBeDefined(); + }); + + it('should render as a child element', function () { + expect(this.userAvatarLink.$el.tagName).toBe('A'); + }); + + it('should have as a child element', function () { + expect(this.userAvatarLink.$el.querySelector('img')).not.toBeNull(); + }); + + it('should return neccessary props as defined', function () { + _.each(this.propsData, (val, key) => { + expect(this.userAvatarLink[key]).toBeDefined(); + }); + }); +}); 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 new file mode 100644 index 00000000000..b8d639ffbec --- /dev/null +++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js @@ -0,0 +1,29 @@ +import Vue from 'vue'; +import UserAvatarSvg from '~/vue_shared/components/user_avatar/user_avatar_svg.vue'; +import avatarSvg from 'icons/_icon_random.svg'; + +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 as a child element', function () { + expect(this.userAvatarSvg.$el.tagName).toEqual('svg'); + expect(this.userAvatarSvg.$el.innerHTML).toContain(' as a child element', function () { - expect(this.userAvatarImage.$el.tagName).toBe('IMG'); - }); - - it('should properly compute tooltipContainer', function () { - expect(this.userAvatarImage.tooltipContainer).toBe('body'); - }); - - it('should properly render tooltipContainer', function () { - expect(this.userAvatarImage.$el.getAttribute('data-container')).toBe('body'); - }); - - it('should properly compute avatarSizeClass', function () { - expect(this.userAvatarImage.avatarSizeClass).toBe('s99'); - }); - - it('should properly render img css', function () { - const classList = this.userAvatarImage.$el.classList; - const containsAvatar = classList.contains('avatar'); - const containsSizeClass = classList.contains('s99'); - const containsCustomClass = classList.contains('myextraavatarclass'); - - expect(containsAvatar).toBe(true); - expect(containsSizeClass).toBe(true); - expect(containsCustomClass).toBe(true); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar_link_spec.js deleted file mode 100644 index 52e450e9ba5..00000000000 --- a/spec/javascripts/vue_shared/components/user_avatar_link_spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import Vue from 'vue'; -import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; - -describe('User Avatar Link Component', function () { - beforeEach(function () { - this.propsData = { - linkHref: 'myavatarurl.com', - imgSize: 99, - imgSrc: 'myavatarurl.com', - imgAlt: 'mydisplayname', - imgCssClasses: 'myextraavatarclass', - tooltipText: 'tooltip text', - tooltipPlacement: 'bottom', - }; - - const UserAvatarLinkComponent = Vue.extend(UserAvatarLink); - - this.userAvatarLink = new UserAvatarLinkComponent({ - propsData: this.propsData, - }).$mount(); - - this.userAvatarImage = this.userAvatarLink.$children[0]; - }); - - it('should return a defined Vue component', function () { - expect(this.userAvatarLink).toBeDefined(); - }); - - it('should have user-avatar-image registered as child component', function () { - expect(this.userAvatarLink.$options.components.userAvatarImage).toBeDefined(); - }); - - it('user-avatar-link should have user-avatar-image as child component', function () { - expect(this.userAvatarImage).toBeDefined(); - }); - - it('should render as a child element', function () { - expect(this.userAvatarLink.$el.tagName).toBe('A'); - }); - - it('should have as a child element', function () { - expect(this.userAvatarLink.$el.querySelector('img')).not.toBeNull(); - }); - - it('should return neccessary props as defined', function () { - _.each(this.propsData, (val, key) => { - expect(this.userAvatarLink[key]).toBeDefined(); - }); - }); -}); diff --git a/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js b/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js deleted file mode 100644 index b8d639ffbec..00000000000 --- a/spec/javascripts/vue_shared/components/user_avatar_svg_spec.js +++ /dev/null @@ -1,29 +0,0 @@ -import Vue from 'vue'; -import UserAvatarSvg from '~/vue_shared/components/user_avatar/user_avatar_svg.vue'; -import avatarSvg from 'icons/_icon_random.svg'; - -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 as a child element', function () { - expect(this.userAvatarSvg.$el.tagName).toEqual('svg'); - expect(this.userAvatarSvg.$el.innerHTML).toContain(' Date: Mon, 16 Oct 2017 10:58:55 -0500 Subject: Add lazy option to UserAvatarImage --- .../user_avatar/user_avatar_image_spec.js | 70 +++++++++++++++------- 1 file changed, 50 insertions(+), 20 deletions(-) (limited to 'spec/javascripts/vue_shared') diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js index 8daa7610274..aa93134f2dd 100644 --- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js +++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_image_spec.js @@ -1,54 +1,84 @@ import Vue from 'vue'; -import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue'; +import { placeholderImage } from '~/lazy_loader'; +import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue'; +import mountComponent from '../../../helpers/vue_mount_component_helper'; -const UserAvatarImageComponent = Vue.extend(UserAvatarImage); +const DEFAULT_PROPS = { + size: 99, + imgSrc: 'myavatarurl.com', + imgAlt: 'mydisplayname', + cssClasses: 'myextraavatarclass', + tooltipText: 'tooltip text', + tooltipPlacement: 'bottom', +}; describe('User Avatar Image Component', function () { + let vm; + let UserAvatarImage; + + beforeEach(() => { + UserAvatarImage = Vue.extend(userAvatarImage); + }); + describe('Initialization', function () { beforeEach(function () { - this.propsData = { - size: 99, - imgSrc: 'myavatarurl.com', - imgAlt: 'mydisplayname', - cssClasses: 'myextraavatarclass', - tooltipText: 'tooltip text', - tooltipPlacement: 'bottom', - }; - - this.userAvatarImage = new UserAvatarImageComponent({ - propsData: this.propsData, + vm = mountComponent(UserAvatarImage, { + ...DEFAULT_PROPS, }).$mount(); }); it('should return a defined Vue component', function () { - expect(this.userAvatarImage).toBeDefined(); + expect(vm).toBeDefined(); }); it('should have as a child element', function () { - expect(this.userAvatarImage.$el.tagName).toBe('IMG'); + expect(vm.$el.tagName).toBe('IMG'); + expect(vm.$el.getAttribute('src')).toBe(DEFAULT_PROPS.imgSrc); + expect(vm.$el.getAttribute('data-src')).toBe(DEFAULT_PROPS.imgSrc); + expect(vm.$el.getAttribute('alt')).toBe(DEFAULT_PROPS.imgAlt); }); it('should properly compute tooltipContainer', function () { - expect(this.userAvatarImage.tooltipContainer).toBe('body'); + expect(vm.tooltipContainer).toBe('body'); }); it('should properly render tooltipContainer', function () { - expect(this.userAvatarImage.$el.getAttribute('data-container')).toBe('body'); + expect(vm.$el.getAttribute('data-container')).toBe('body'); }); it('should properly compute avatarSizeClass', function () { - expect(this.userAvatarImage.avatarSizeClass).toBe('s99'); + expect(vm.avatarSizeClass).toBe('s99'); }); it('should properly render img css', function () { - const classList = this.userAvatarImage.$el.classList; + const classList = vm.$el.classList; const containsAvatar = classList.contains('avatar'); const containsSizeClass = classList.contains('s99'); - const containsCustomClass = classList.contains('myextraavatarclass'); + const containsCustomClass = classList.contains(DEFAULT_PROPS.cssClasses); + const lazyClass = classList.contains('lazy'); expect(containsAvatar).toBe(true); expect(containsSizeClass).toBe(true); expect(containsCustomClass).toBe(true); + expect(lazyClass).toBe(false); + }); + }); + + describe('Initialization when lazy', function () { + beforeEach(function () { + vm = mountComponent(UserAvatarImage, { + ...DEFAULT_PROPS, + lazy: true, + }).$mount(); + }); + + it('should add lazy attributes', function () { + const classList = vm.$el.classList; + const lazyClass = classList.contains('lazy'); + + expect(lazyClass).toBe(true); + expect(vm.$el.getAttribute('src')).toBe(placeholderImage); + expect(vm.$el.getAttribute('data-src')).toBe(DEFAULT_PROPS.imgSrc); }); }); }); -- cgit v1.2.1 From bf4a3ac23e8ffd2dc5cff4b585bf3d3c074a91d6 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Wed, 18 Oct 2017 17:30:31 +0100 Subject: Make pipelines table in MR view usable --- .../vue_shared/components/ci_badge_link_spec.js | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'spec/javascripts/vue_shared') diff --git a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js index daed4da3e15..ba303738f71 100644 --- a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js +++ b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js @@ -1,8 +1,10 @@ import Vue from 'vue'; import ciBadge from '~/vue_shared/components/ci_badge_link.vue'; +import mountComponent from '../../helpers/vue_mount_component_helper'; describe('CI Badge Link Component', () => { let CIBadge; + let vm; const statuses = { canceled: { @@ -70,15 +72,17 @@ describe('CI Badge Link Component', () => { }, }; - it('should render each status badge', () => { + beforeEach(() => { CIBadge = Vue.extend(ciBadge); - Object.keys(statuses).map((status) => { - const vm = new CIBadge({ - propsData: { - status: statuses[status], - }, - }).$mount(); + }); + + 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')).toEqual(`ci-status ci-${statuses[status].group}`); @@ -86,4 +90,9 @@ describe('CI Badge Link Component', () => { return vm; }); }); + + it('should not render label', () => { + vm = mountComponent(CIBadge, { status: statuses.canceled, showText: false }); + expect(vm.$el.textContent.trim()).toEqual(''); + }); }); -- cgit v1.2.1 From 69be3ce86f1fc8c2273870a92b597399cedf2480 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Fri, 13 Oct 2017 17:01:21 -0500 Subject: Add loading button Encompasses designs from - https://gitlab.com/gitlab-org/gitlab-ce/issues/23206#note_43355199 - https://gitlab.com/gitlab-org/gitlab-ce/issues/29985#note_30417407 --- .../vue_shared/components/loading_button_spec.js | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 spec/javascripts/vue_shared/components/loading_button_spec.js (limited to 'spec/javascripts/vue_shared') diff --git a/spec/javascripts/vue_shared/components/loading_button_spec.js b/spec/javascripts/vue_shared/components/loading_button_spec.js new file mode 100644 index 00000000000..97c8a08fcdd --- /dev/null +++ b/spec/javascripts/vue_shared/components/loading_button_spec.js @@ -0,0 +1,93 @@ +import Vue from 'vue'; +import loadingButton from '~/vue_shared/components/loading_button.vue'; +import mountComponent from '../../helpers/vue_mount_component_helper'; + +const LABEL = 'Hello'; + +describe('LoadingButton', function () { + let vm; + let LoadingButton; + + beforeEach(() => { + LoadingButton = Vue.extend(loadingButton); + }); + + afterEach(() => { + vm.$destroy(); + }); + + describe('loading spinner', () => { + it('shown when loading', () => { + vm = mountComponent(LoadingButton, { + loading: true, + }); + + expect(vm.$el.querySelector('.js-loading-button-icon')).toBeDefined(); + }); + }); + + describe('disabled state', () => { + it('disabled when loading', () => { + vm = mountComponent(LoadingButton, { + loading: true, + }); + + expect(vm.$el.disabled).toEqual(true); + }); + + it('not disabled when normal', () => { + vm = mountComponent(LoadingButton, { + loading: false, + }); + + expect(vm.$el.disabled).toEqual(false); + }); + }); + + describe('label', () => { + it('shown when normal', () => { + vm = mountComponent(LoadingButton, { + loading: false, + label: LABEL, + }); + const label = vm.$el.querySelector('.js-loading-button-label'); + + expect(label.textContent.trim()).toEqual(LABEL); + }); + + it('shown when loading', () => { + vm = mountComponent(LoadingButton, { + loading: true, + label: LABEL, + }); + const label = vm.$el.querySelector('.js-loading-button-label'); + + expect(label.textContent.trim()).toEqual(LABEL); + }); + }); + + describe('click callback prop', () => { + it('calls given callback when normal', () => { + vm = mountComponent(LoadingButton, { + loading: false, + }); + spyOn(vm, '$emit'); + + vm.$el.click(); + + expect(vm.$emit).toHaveBeenCalledWith('click', jasmine.any(Object)); + }); + + it('does not call given callback when disabled because of loading', () => { + vm = mountComponent(LoadingButton, { + loading: true, + indeterminate: true, + }); + spyOn(vm, '$emit'); + + vm.$el.click(); + + expect(vm.$emit).not.toHaveBeenCalled(); + }); + }); +}); -- cgit v1.2.1