summaryrefslogtreecommitdiff
path: root/spec/frontend/popovers/components/popovers_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/popovers/components/popovers_spec.js')
-rw-r--r--spec/frontend/popovers/components/popovers_spec.js129
1 files changed, 129 insertions, 0 deletions
diff --git a/spec/frontend/popovers/components/popovers_spec.js b/spec/frontend/popovers/components/popovers_spec.js
new file mode 100644
index 00000000000..63e0b3d9c49
--- /dev/null
+++ b/spec/frontend/popovers/components/popovers_spec.js
@@ -0,0 +1,129 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlPopover } from '@gitlab/ui';
+import { useMockMutationObserver } from 'helpers/mock_dom_observer';
+import Popovers from '~/popovers/components/popovers.vue';
+
+describe('popovers/components/popovers.vue', () => {
+ const { trigger: triggerMutate, observersCount } = useMockMutationObserver();
+ let wrapper;
+
+ const buildWrapper = (...targets) => {
+ wrapper = shallowMount(Popovers);
+ wrapper.vm.addPopovers(targets);
+ return wrapper.vm.$nextTick();
+ };
+
+ const createPopoverTarget = (options = {}) => {
+ const target = document.createElement('button');
+ const dataset = {
+ title: 'default title',
+ content: 'some content',
+ ...options,
+ };
+
+ Object.entries(dataset).forEach(([key, value]) => {
+ target.dataset[key] = value;
+ });
+
+ document.body.appendChild(target);
+
+ return target;
+ };
+
+ const allPopovers = () => wrapper.findAll(GlPopover);
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('addPopovers', () => {
+ it('attaches popovers to the targets specified', async () => {
+ const target = createPopoverTarget();
+ await buildWrapper(target);
+ expect(wrapper.find(GlPopover).props('target')).toBe(target);
+ });
+
+ it('does not attach a popover twice to the same element', async () => {
+ const target = createPopoverTarget();
+ buildWrapper(target);
+ wrapper.vm.addPopovers([target]);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.findAll(GlPopover)).toHaveLength(1);
+ });
+
+ it('supports HTML content', async () => {
+ const content = 'content with <b>HTML</b>';
+ await buildWrapper(
+ createPopoverTarget({
+ content,
+ html: true,
+ }),
+ );
+ const html = wrapper.find(GlPopover).html();
+
+ expect(html).toContain(content);
+ });
+
+ it.each`
+ option | value
+ ${'placement'} | ${'bottom'}
+ ${'triggers'} | ${'manual'}
+ `('sets $option to $value when data-$option is set in target', async ({ option, value }) => {
+ await buildWrapper(createPopoverTarget({ [option]: value }));
+
+ expect(wrapper.find(GlPopover).props(option)).toBe(value);
+ });
+ });
+
+ describe('dispose', () => {
+ it('removes all popovers when elements is nil', async () => {
+ await buildWrapper(createPopoverTarget(), createPopoverTarget());
+
+ wrapper.vm.dispose();
+ await wrapper.vm.$nextTick();
+
+ expect(allPopovers()).toHaveLength(0);
+ });
+
+ it('removes the popovers that target the elements specified', async () => {
+ const target = createPopoverTarget();
+
+ await buildWrapper(target, createPopoverTarget());
+
+ wrapper.vm.dispose(target);
+ await wrapper.vm.$nextTick();
+
+ expect(allPopovers()).toHaveLength(1);
+ });
+ });
+
+ describe('observe', () => {
+ it('removes popover when target is removed from the document', async () => {
+ const target = createPopoverTarget();
+ await buildWrapper(target);
+
+ wrapper.vm.addPopovers([target, createPopoverTarget()]);
+ await wrapper.vm.$nextTick();
+
+ triggerMutate(document.body, {
+ entry: { removedNodes: [target] },
+ options: { childList: true },
+ });
+ await wrapper.vm.$nextTick();
+
+ expect(allPopovers()).toHaveLength(1);
+ });
+ });
+
+ it('disconnects mutation observer on beforeDestroy', async () => {
+ await buildWrapper(createPopoverTarget());
+
+ expect(observersCount()).toBe(1);
+
+ wrapper.destroy();
+ expect(observersCount()).toBe(0);
+ });
+});