1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
import Vue, { nextTick } from 'vue';
import { createWrapper } from '@vue/test-utils';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action';
import ConfirmModal from '~/lib/utils/confirm_via_gl_modal/confirm_modal.vue';
const originalMount = Vue.prototype.$mount;
describe('confirmAction', () => {
let modalWrapper;
let confirActionPromise;
let modal;
const findConfirmModal = () => modalWrapper.findComponent(ConfirmModal);
const renderRootComponent = async (message, opts) => {
confirActionPromise = confirmAction(message, opts);
// We have to wait for two ticks here.
// The first one is to wait for rendering of the root component
// The second one to wait for rendering of the dynamically
// loaded confirm-modal component
await nextTick();
await nextTick();
modal = findConfirmModal();
};
const mockMount = (vm, el) => {
originalMount.call(vm, el);
modalWrapper = createWrapper(vm);
return vm;
};
beforeEach(() => {
setHTMLFixture('<div id="component"></div>');
const el = document.getElementById('component');
// We mock the implementation only once to make sure that we mock
// it only for the root component in confirm_action.
// Mounting other components (like confirm-modal) should not be affected with
// this mock
jest.spyOn(Vue.prototype, '$mount').mockImplementationOnce(function mock() {
return mockMount(this, el);
});
});
afterEach(() => {
resetHTMLFixture();
Vue.prototype.$mount.mockRestore();
modalWrapper?.destroy();
modalWrapper = null;
modal?.destroy();
modal = null;
});
it('creats a ConfirmModal with message as slot', async () => {
const message = 'Bonjour le monde!';
await renderRootComponent(message);
expect(modal.vm.$slots.default[0].text).toBe(message);
});
it('creats a ConfirmModal with props', async () => {
const options = {
primaryBtnText: 'primaryBtnText',
primaryBtnVariant: 'info',
secondaryBtnText: 'secondaryBtnText',
secondaryBtnVariant: 'success',
cancelBtnText: 'cancelBtnText',
cancelBtnVariant: 'danger',
modalHtmlMessage: '<strong>Hello</strong>',
title: 'title',
hideCancel: true,
};
await renderRootComponent('', options);
expect(modal.props()).toEqual(
expect.objectContaining({
primaryText: options.primaryBtnText,
primaryVariant: options.primaryBtnVariant,
secondaryText: options.secondaryBtnText,
secondaryVariant: options.secondaryBtnVariant,
cancelText: options.cancelBtnText,
cancelVariant: options.cancelBtnVariant,
modalHtmlMessage: options.modalHtmlMessage,
title: options.title,
hideCancel: options.hideCancel,
}),
);
});
it('resolves promise when modal emit `closed`', async () => {
await renderRootComponent('');
modal.vm.$emit('closed');
await expect(confirActionPromise).resolves.toBe(false);
});
it('confirms when modal emit `confirmed` before `closed`', async () => {
await renderRootComponent('');
modal.vm.$emit('confirmed');
modal.vm.$emit('closed');
await expect(confirActionPromise).resolves.toBe(true);
});
});
|