diff options
Diffstat (limited to 'spec/frontend/feature_highlight')
4 files changed, 104 insertions, 188 deletions
diff --git a/spec/frontend/feature_highlight/feature_highlight_helper_spec.js b/spec/frontend/feature_highlight/feature_highlight_helper_spec.js index beae5041156..1b5bffc1f9b 100644 --- a/spec/frontend/feature_highlight/feature_highlight_helper_spec.js +++ b/spec/frontend/feature_highlight/feature_highlight_helper_spec.js @@ -1,62 +1,40 @@ -import $ from 'jquery'; +import MockAdapter from 'axios-mock-adapter'; +import { dismiss } from '~/feature_highlight/feature_highlight_helper'; +import { deprecatedCreateFlash as Flash } from '~/flash'; import axios from '~/lib/utils/axios_utils'; -import { getSelector, dismiss, inserted } from '~/feature_highlight/feature_highlight_helper'; -import { togglePopover } from '~/shared/popover'; +import httpStatusCodes from '~/lib/utils/http_status'; -describe('feature highlight helper', () => { - describe('getSelector', () => { - it('returns js-feature-highlight selector', () => { - const highlightId = 'highlightId'; - - expect(getSelector(highlightId)).toEqual( - `.js-feature-highlight[data-highlight=${highlightId}]`, - ); - }); - }); +jest.mock('~/flash'); +describe('feature highlight helper', () => { describe('dismiss', () => { - const context = { - hide: () => {}, - attr: () => '/-/callouts/dismiss', - }; + let mockAxios; + const endpoint = '/-/callouts/dismiss'; + const highlightId = '123'; + const { CREATED, INTERNAL_SERVER_ERROR } = httpStatusCodes; beforeEach(() => { - jest.spyOn(axios, 'post').mockResolvedValue(); - jest.spyOn(togglePopover, 'call').mockImplementation(() => {}); - jest.spyOn(context, 'hide').mockImplementation(() => {}); - dismiss.call(context); + mockAxios = new MockAdapter(axios); }); - it('calls persistent dismissal endpoint', () => { - expect(axios.post).toHaveBeenCalledWith( - '/-/callouts/dismiss', - expect.objectContaining({ feature_name: undefined }), - ); + afterEach(() => { + mockAxios.reset(); }); - it('calls hide popover', () => { - expect(togglePopover.call).toHaveBeenCalledWith(context, false); - }); + it('calls persistent dismissal endpoint with highlightId', async () => { + mockAxios.onPost(endpoint, { feature_name: highlightId }).replyOnce(CREATED); - it('calls hide', () => { - expect(context.hide).toHaveBeenCalled(); + await expect(dismiss(endpoint, highlightId)).resolves.toEqual(expect.anything()); }); - }); - describe('inserted', () => { - it('registers click event callback', (done) => { - const context = { - getAttribute: () => 'popoverId', - dataset: { - highlight: 'some-feature', - }, - }; - - jest.spyOn($.fn, 'on').mockImplementation((event) => { - expect(event).toEqual('click'); - done(); - }); - inserted.call(context); + it('triggers flash when dismiss request fails', async () => { + mockAxios.onPost(endpoint, { feature_name: highlightId }).replyOnce(INTERNAL_SERVER_ERROR); + + await dismiss(endpoint, highlightId); + + expect(Flash).toHaveBeenCalledWith( + 'An error occurred while dismissing the feature highlight. Refresh the page and try dismissing again.', + ); }); }); }); diff --git a/spec/frontend/feature_highlight/feature_highlight_options_spec.js b/spec/frontend/feature_highlight/feature_highlight_options_spec.js deleted file mode 100644 index f82f984cb7f..00000000000 --- a/spec/frontend/feature_highlight/feature_highlight_options_spec.js +++ /dev/null @@ -1,22 +0,0 @@ -import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils'; -import domContentLoaded from '~/feature_highlight/feature_highlight_options'; - -describe('feature highlight options', () => { - describe('domContentLoaded', () => { - it.each` - breakPoint | shouldCall - ${'xs'} | ${false} - ${'sm'} | ${false} - ${'md'} | ${false} - ${'lg'} | ${false} - ${'xl'} | ${true} - `( - 'when breakpoint is $breakPoint should call highlightFeatures is $shouldCall', - ({ breakPoint, shouldCall }) => { - jest.spyOn(bp, 'getBreakpointSize').mockReturnValue(breakPoint); - - expect(domContentLoaded()).toBe(shouldCall); - }, - ); - }); -}); diff --git a/spec/frontend/feature_highlight/feature_highlight_popover_spec.js b/spec/frontend/feature_highlight/feature_highlight_popover_spec.js new file mode 100644 index 00000000000..1d558366ce8 --- /dev/null +++ b/spec/frontend/feature_highlight/feature_highlight_popover_spec.js @@ -0,0 +1,80 @@ +import { GlPopover, GlLink, GlButton } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; +import { POPOVER_TARGET_ID } from '~/feature_highlight/constants'; +import { dismiss } from '~/feature_highlight/feature_highlight_helper'; +import FeatureHighlightPopover from '~/feature_highlight/feature_highlight_popover.vue'; + +jest.mock('~/feature_highlight/feature_highlight_helper'); + +describe('feature_highlight/feature_highlight_popover', () => { + let wrapper; + const props = { + autoDevopsHelpPath: '/help/autodevops', + highlightId: '123', + dismissEndpoint: '/api/dismiss', + }; + + const buildWrapper = (propsData = props) => { + wrapper = mount(FeatureHighlightPopover, { + propsData, + }); + }; + const findPopoverTarget = () => wrapper.find(`#${POPOVER_TARGET_ID}`); + const findPopover = () => wrapper.findComponent(GlPopover); + const findAutoDevopsHelpLink = () => wrapper.findComponent(GlLink); + const findDismissButton = () => wrapper.findComponent(GlButton); + + beforeEach(() => { + buildWrapper(); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + it('renders popover target', () => { + expect(findPopoverTarget().exists()).toBe(true); + }); + + it('renders popover', () => { + expect(findPopover().props()).toMatchObject({ + target: POPOVER_TARGET_ID, + cssClasses: ['feature-highlight-popover'], + triggers: 'hover', + container: 'body', + placement: 'right', + boundary: 'viewport', + }); + }); + + it('renders link that points to the autodevops help page', () => { + expect(findAutoDevopsHelpLink().attributes().href).toBe(props.autoDevopsHelpPath); + expect(findAutoDevopsHelpLink().text()).toBe('Auto DevOps'); + }); + + it('renders dismiss button', () => { + expect(findDismissButton().props()).toMatchObject({ + size: 'small', + icon: 'thumb-up', + variant: 'confirm', + }); + }); + + it('dismisses popover when dismiss button is clicked', async () => { + await findDismissButton().trigger('click'); + + expect(findPopover().emitted('close')).toHaveLength(1); + expect(dismiss).toHaveBeenCalledWith(props.dismissEndpoint, props.highlightId); + }); + + describe('when popover is dismissed and hidden', () => { + it('hides the popover target', async () => { + await findDismissButton().trigger('click'); + findPopover().vm.$emit('hidden'); + await wrapper.vm.$nextTick(); + + expect(findPopoverTarget().exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/feature_highlight/feature_highlight_spec.js b/spec/frontend/feature_highlight/feature_highlight_spec.js deleted file mode 100644 index 79c4050c8c4..00000000000 --- a/spec/frontend/feature_highlight/feature_highlight_spec.js +++ /dev/null @@ -1,120 +0,0 @@ -import $ from 'jquery'; -import MockAdapter from 'axios-mock-adapter'; -import * as featureHighlight from '~/feature_highlight/feature_highlight'; -import * as popover from '~/shared/popover'; -import axios from '~/lib/utils/axios_utils'; - -jest.mock('~/shared/popover'); - -describe('feature highlight', () => { - beforeEach(() => { - setFixtures(` - <div> - <div class="js-feature-highlight" data-highlight="test" data-highlight-priority="10" data-dismiss-endpoint="/test" disabled> - Trigger - </div> - </div> - <div class="feature-highlight-popover-content"> - Content - <div class="dismiss-feature-highlight"> - Dismiss - </div> - </div> - `); - }); - - describe('setupFeatureHighlightPopover', () => { - let mock; - const selector = '.js-feature-highlight[data-highlight=test]'; - - beforeEach(() => { - mock = new MockAdapter(axios); - mock.onGet('/test').reply(200); - jest.spyOn(window, 'addEventListener').mockImplementation(() => {}); - featureHighlight.setupFeatureHighlightPopover('test', 0); - }); - - afterEach(() => { - mock.restore(); - }); - - it('setup popover content', () => { - const $popoverContent = $('.feature-highlight-popover-content'); - const outerHTML = $popoverContent.prop('outerHTML'); - - expect($(selector).data('content')).toEqual(outerHTML); - }); - - it('setup mouseenter', () => { - $(selector).trigger('mouseenter'); - - expect(popover.mouseenter).toHaveBeenCalledWith(expect.any(Object)); - }); - - it('setup debounced mouseleave', () => { - $(selector).trigger('mouseleave'); - - expect(popover.debouncedMouseleave).toHaveBeenCalled(); - }); - - it('setup show.bs.popover', () => { - $(selector).trigger('show.bs.popover'); - - expect(window.addEventListener).toHaveBeenCalledWith('scroll', expect.any(Function), { - once: true, - }); - }); - - it('removes disabled attribute', () => { - expect($('.js-feature-highlight').is(':disabled')).toEqual(false); - }); - }); - - describe('findHighestPriorityFeature', () => { - beforeEach(() => { - setFixtures(` - <div class="js-feature-highlight" data-highlight="test" data-highlight-priority="10" disabled></div> - <div class="js-feature-highlight" data-highlight="test-high-priority" data-highlight-priority="20" disabled></div> - <div class="js-feature-highlight" data-highlight="test-low-priority" data-highlight-priority="0" disabled></div> - `); - }); - - it('should pick the highest priority feature highlight', () => { - setFixtures(` - <div class="js-feature-highlight" data-highlight="test" data-highlight-priority="10" disabled></div> - <div class="js-feature-highlight" data-highlight="test-high-priority" data-highlight-priority="20" disabled></div> - <div class="js-feature-highlight" data-highlight="test-low-priority" data-highlight-priority="0" disabled></div> - `); - - expect($('.js-feature-highlight').length).toBeGreaterThan(1); - expect(featureHighlight.findHighestPriorityFeature()).toEqual('test-high-priority'); - }); - - it('should work when no priority is set', () => { - setFixtures(` - <div class="js-feature-highlight" data-highlight="test" disabled></div> - `); - - expect(featureHighlight.findHighestPriorityFeature()).toEqual('test'); - }); - - it('should pick the highest priority feature highlight when some have no priority set', () => { - setFixtures(` - <div class="js-feature-highlight" data-highlight="test-no-priority1" disabled></div> - <div class="js-feature-highlight" data-highlight="test" data-highlight-priority="10" disabled></div> - <div class="js-feature-highlight" data-highlight="test-no-priority2" disabled></div> - <div class="js-feature-highlight" data-highlight="test-high-priority" data-highlight-priority="20" disabled></div> - <div class="js-feature-highlight" data-highlight="test-low-priority" data-highlight-priority="0" disabled></div> - `); - - expect($('.js-feature-highlight').length).toBeGreaterThan(1); - expect(featureHighlight.findHighestPriorityFeature()).toEqual('test-high-priority'); - }); - }); - - describe('highlightFeatures', () => { - it('calls setupFeatureHighlightPopover', () => { - expect(featureHighlight.highlightFeatures()).toEqual('test'); - }); - }); -}); |