diff options
-rw-r--r-- | app/assets/javascripts/feature_highlight/feature_highlight.js | 7 | ||||
-rw-r--r-- | spec/javascripts/feature_highlight/feature_highlight_spec.js | 122 |
2 files changed, 127 insertions, 2 deletions
diff --git a/app/assets/javascripts/feature_highlight/feature_highlight.js b/app/assets/javascripts/feature_highlight/feature_highlight.js index f5e38fc8879..800ca05cd11 100644 --- a/app/assets/javascripts/feature_highlight/feature_highlight.js +++ b/app/assets/javascripts/feature_highlight/feature_highlight.js @@ -9,12 +9,12 @@ import { mouseleave, } from './feature_highlight_helper'; -export const setupFeatureHighlightPopover = (id) => { +export const setupFeatureHighlightPopover = (id, debounceTimeout = 300) => { const $selector = $(getSelector(id)); const $parent = $selector.parent(); const $popoverContent = $parent.siblings('.feature-highlight-popover-content'); const hideOnScroll = hidePopover.bind($selector); - const debouncedMouseleave = _.debounce(mouseleave, 300); + const debouncedMouseleave = _.debounce(mouseleave, debounceTimeout); $selector // Setup popover @@ -54,5 +54,8 @@ export const highlightFeatures = (highlightOrder) => { if (featureId) { setupFeatureHighlightPopover(featureId); + return true; } + + return false; }; diff --git a/spec/javascripts/feature_highlight/feature_highlight_spec.js b/spec/javascripts/feature_highlight/feature_highlight_spec.js new file mode 100644 index 00000000000..a48d6c88aee --- /dev/null +++ b/spec/javascripts/feature_highlight/feature_highlight_spec.js @@ -0,0 +1,122 @@ +import Cookies from 'js-cookie'; +import { + showPopover, + hidePopover, +} from '~/feature_highlight/feature_highlight_helper'; +import * as featureHighlight from '~/feature_highlight/feature_highlight'; + +fdescribe('feature highlight', () => { + describe('setupFeatureHighlightPopover', () => { + const selector = '.js-feature-highlight[data-highlight=test]'; + beforeEach(() => { + setFixtures(` + <div> + <div class="js-feature-highlight" data-highlight="test" disabled> + Trigger + </div> + </div> + <div class="feature-highlight-popover-content"> + Content + <div class="dismiss-feature-highlight"> + Dismiss + </div> + </div> + `); + spyOn(window, 'addEventListener'); + spyOn(window, 'removeEventListener'); + featureHighlight.setupFeatureHighlightPopover('test', 0); + }); + + it('setups popover content', () => { + const $popoverContent = $('.feature-highlight-popover-content'); + const outerHTML = $popoverContent.prop('outerHTML'); + expect($(selector).data('content')).toEqual(outerHTML); + }); + + it('setups mouseenter', () => { + const showSpy = spyOn(showPopover, 'call'); + $(selector).trigger('mouseenter'); + + expect(showSpy).toHaveBeenCalled(); + }); + + it('setups debounced mouseleave', (done) => { + const hideSpy = spyOn(hidePopover, 'call'); + $(selector).trigger('mouseleave'); + + setTimeout(() => { + expect(hideSpy).toHaveBeenCalled(); + done(); + }, 0); + }); + + it('setups inserted.bs.popover', () => { + $(selector).trigger('mouseenter'); + const popoverId = $(selector).attr('aria-describedby'); + const spyEvent = spyOnEvent(`#${popoverId} .dismiss-feature-highlight`, 'click'); + $(`#${popoverId} .dismiss-feature-highlight`).click(); + expect(spyEvent).toHaveBeenTriggered(); + }); + + it('setups show.bs.popover', () => { + $(selector).trigger('show.bs.popover'); + expect(window.addEventListener).toHaveBeenCalledWith('scroll', jasmine.any(Function)); + }); + + it('setups hide.bs.popover', () => { + $(selector).trigger('hide.bs.popover'); + expect(window.removeEventListener).toHaveBeenCalledWith('scroll', jasmine.any(Function)); + }); + + it('removes disabled attribute', () => { + expect($('.js-feature-highlight').is(':disabled')).toEqual(false); + }); + + it('displays popover', () => { + expect($(selector).attr('aria-describedby')).toBeFalsy(); + $(selector).trigger('mouseenter'); + expect($(selector).attr('aria-describedby')).toBeTruthy(); + }); + }); + + describe('shouldHighlightFeature', () => { + it('should return false if element is not found', () => { + spyOn(document, 'querySelector').and.returnValue(null); + spyOn(Cookies, 'get').and.returnValue(null); + + expect(featureHighlight.shouldHighlightFeature()).toBeFalsy(); + }); + + it('should return false if previouslyDismissed', () => { + spyOn(document, 'querySelector').and.returnValue(document.createElement('div')); + spyOn(Cookies, 'get').and.returnValue('true'); + + expect(featureHighlight.shouldHighlightFeature()).toBeFalsy(); + }); + + it('should return true if element is found and not previouslyDismissed', () => { + spyOn(document, 'querySelector').and.returnValue(document.createElement('div')); + spyOn(Cookies, 'get').and.returnValue(null); + + expect(featureHighlight.shouldHighlightFeature()).toBeTruthy(); + }); + }); + + describe('highlightFeatures', () => { + it('calls setupFeatureHighlightPopover if shouldHighlightFeature returns true', () => { + // Mimic shouldHighlightFeature set to true + const highlightOrder = ['issue-boards']; + spyOn(highlightOrder, 'find').and.returnValue(highlightOrder[0]); + + expect(featureHighlight.highlightFeatures(highlightOrder)).toEqual(true); + }); + + it('does not call setupFeatureHighlightPopover if shouldHighlightFeature returns false', () => { + // Mimic shouldHighlightFeature set to false + const highlightOrder = ['issue-boards']; + spyOn(highlightOrder, 'find').and.returnValue(null); + + expect(featureHighlight.highlightFeatures(highlightOrder)).toEqual(false); + }); + }); +}); |