Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/tooltips/components/tooltips_spec.js')
-rw-r--r--spec/frontend/tooltips/components/tooltips_spec.js202
1 files changed, 202 insertions, 0 deletions
diff --git a/spec/frontend/tooltips/components/tooltips_spec.js b/spec/frontend/tooltips/components/tooltips_spec.js
new file mode 100644
index 00000000000..0edc5248629
--- /dev/null
+++ b/spec/frontend/tooltips/components/tooltips_spec.js
@@ -0,0 +1,202 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlTooltip } from '@gitlab/ui';
+import { useMockMutationObserver } from 'helpers/mock_dom_observer';
+import Tooltips from '~/tooltips/components/tooltips.vue';
+
+describe('tooltips/components/tooltips.vue', () => {
+ const { trigger: triggerMutate, observersCount } = useMockMutationObserver();
+ let wrapper;
+
+ const buildWrapper = () => {
+ wrapper = shallowMount(Tooltips);
+ };
+
+ const createTooltipTarget = (attributes = {}) => {
+ const target = document.createElement('button');
+ const defaults = {
+ title: 'default title',
+ ...attributes,
+ };
+
+ Object.keys(defaults).forEach(name => {
+ target.setAttribute(name, defaults[name]);
+ });
+
+ document.body.appendChild(target);
+
+ return target;
+ };
+
+ const allTooltips = () => wrapper.findAll(GlTooltip);
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('addTooltips', () => {
+ let target;
+
+ beforeEach(() => {
+ buildWrapper();
+
+ target = createTooltipTarget();
+ });
+
+ it('attaches tooltips to the targets specified', async () => {
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).props('target')).toBe(target);
+ });
+
+ it('does not attach a tooltip twice to the same element', async () => {
+ wrapper.vm.addTooltips([target]);
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.findAll(GlTooltip)).toHaveLength(1);
+ });
+
+ it('sets tooltip content from title attribute', async () => {
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).text()).toBe(target.getAttribute('title'));
+ });
+
+ it('supports HTML content', async () => {
+ target = createTooltipTarget({
+ title: 'content with <b>HTML</b>',
+ 'data-html': true,
+ });
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).html()).toContain(target.getAttribute('title'));
+ });
+
+ it.each`
+ attribute | value | prop
+ ${'data-placement'} | ${'bottom'} | ${'placement'}
+ ${'data-container'} | ${'custom-container'} | ${'container'}
+ ${'data-boundary'} | ${'viewport'} | ${'boundary'}
+ ${'data-triggers'} | ${'manual'} | ${'triggers'}
+ `(
+ 'sets $prop to $value when $attribute is set in target',
+ async ({ attribute, value, prop }) => {
+ target = createTooltipTarget({ [attribute]: value });
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).props(prop)).toBe(value);
+ },
+ );
+ });
+
+ describe('dispose', () => {
+ beforeEach(() => {
+ buildWrapper();
+ });
+
+ it('removes all tooltips when elements is nil', async () => {
+ wrapper.vm.addTooltips([createTooltipTarget(), createTooltipTarget()]);
+ await wrapper.vm.$nextTick();
+
+ wrapper.vm.dispose();
+ await wrapper.vm.$nextTick();
+
+ expect(allTooltips()).toHaveLength(0);
+ });
+
+ it('removes the tooltips that target the elements specified', async () => {
+ const target = createTooltipTarget();
+
+ wrapper.vm.addTooltips([target, createTooltipTarget()]);
+ await wrapper.vm.$nextTick();
+
+ wrapper.vm.dispose(target);
+ await wrapper.vm.$nextTick();
+
+ expect(allTooltips()).toHaveLength(1);
+ });
+ });
+
+ describe('observe', () => {
+ beforeEach(() => {
+ buildWrapper();
+ });
+
+ it('removes tooltip when target is removed from the document', async () => {
+ const target = createTooltipTarget();
+
+ wrapper.vm.addTooltips([target, createTooltipTarget()]);
+ await wrapper.vm.$nextTick();
+
+ triggerMutate(document.body, {
+ entry: { removedNodes: [target] },
+ options: { childList: true },
+ });
+ await wrapper.vm.$nextTick();
+
+ expect(allTooltips()).toHaveLength(1);
+ });
+ });
+
+ describe('triggerEvent', () => {
+ it('triggers a bootstrap-vue tooltip global event for the tooltip specified', async () => {
+ const target = createTooltipTarget();
+ const event = 'hide';
+
+ buildWrapper();
+
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ wrapper.vm.triggerEvent(target, event);
+
+ expect(wrapper.find(GlTooltip).emitted(event)).toHaveLength(1);
+ });
+ });
+
+ describe('fixTitle', () => {
+ it('updates tooltip content with the latest value the target title property', async () => {
+ const target = createTooltipTarget();
+ const currentTitle = 'title';
+ const newTitle = 'new title';
+
+ target.setAttribute('title', currentTitle);
+
+ buildWrapper();
+
+ wrapper.vm.addTooltips([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).text()).toBe(currentTitle);
+
+ target.setAttribute('title', newTitle);
+ wrapper.vm.fixTitle(target);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.find(GlTooltip).text()).toBe(newTitle);
+ });
+ });
+
+ it('disconnects mutation observer on beforeDestroy', () => {
+ buildWrapper();
+ wrapper.vm.addTooltips([createTooltipTarget()]);
+
+ expect(observersCount()).toBe(1);
+
+ wrapper.destroy();
+ expect(observersCount()).toBe(0);
+ });
+});