@eturnity/eturnity_reusable_components 9.28.1 → 9.28.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/inputs/toggle/Toggle.stories.js +73 -34
- package/src/components/inputs/toggle/toggle.spec.js +121 -82
- package/src/components/label/label.spec.js +55 -0
- package/src/components/label/label.stories.js +36 -0
- package/src/components/markerItem/markerItem.spec.js +46 -0
- package/src/components/markerItem/markerItem.stories.js +7 -0
- package/src/components/modals/modal/modal.stories.js +17 -7
- package/src/components/navigationTabs/navigationTabs.spec.js +95 -0
- package/src/components/pagination/pagination.spec.js +174 -0
- package/src/components/progressBar/progressBar.spec.js +40 -30
- package/src/components/projectMarker/projectMarker.spec.js +154 -0
- package/src/components/tableDropdown/tableDropdown.spec.js +193 -0
- package/src/components/tables/mainTable/mainTable.spec.js +101 -0
- package/src/components/threeDots/threeDots.spec.js +121 -0
- package/src/components/threeDots/threeDots.stories.js +49 -0
- package/src/components/videoThumbnail/videoThumbnail.spec.js +46 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import NavigationTabs from '@/components/navigationTabs'
|
|
4
|
+
|
|
5
|
+
// `theme` and `$gettext` are provided globally by jest.setup.js, so specs do
|
|
6
|
+
// not need to re-provide them. See the canonical example at
|
|
7
|
+
// src/components/buttons/closeButton/closeButton.spec.js.
|
|
8
|
+
//
|
|
9
|
+
// The component renders only styled-components (no data-test-id hooks) and must
|
|
10
|
+
// not be changed, so the tab elements are selected structurally: the root
|
|
11
|
+
// wrapper holds one Tab div per item followed by a trailing BottomLine div.
|
|
12
|
+
|
|
13
|
+
jest.mock('@/components/icon/iconCache.mjs', () => ({
|
|
14
|
+
// need to mock this due to how jest handles import.meta
|
|
15
|
+
fetchIcon: jest.fn(() => Promise.resolve('mocked-icon-url.svg')),
|
|
16
|
+
}))
|
|
17
|
+
|
|
18
|
+
const tabsData = [
|
|
19
|
+
{ id: 1, slug: 'overview', label: 'Overview' },
|
|
20
|
+
{
|
|
21
|
+
id: 2,
|
|
22
|
+
slug: 'billing',
|
|
23
|
+
label: 'Billing',
|
|
24
|
+
labelInfoText: 'Invoices and payment methods',
|
|
25
|
+
labelInfoAlign: 'left',
|
|
26
|
+
},
|
|
27
|
+
{ id: 3, slug: 'users', label: 'Users', isDisabled: true },
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
describe('NavigationTabs', () => {
|
|
31
|
+
const mountTabs = (props = {}) =>
|
|
32
|
+
mount(NavigationTabs, {
|
|
33
|
+
props: {
|
|
34
|
+
tabsData,
|
|
35
|
+
activeTab: 'billing',
|
|
36
|
+
tabKey: 'slug',
|
|
37
|
+
tabLabel: 'label',
|
|
38
|
+
...props,
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// The Tab divs are every direct child of the root except the trailing
|
|
43
|
+
// BottomLine div.
|
|
44
|
+
const getTabs = (wrapper) => {
|
|
45
|
+
const tabEls = Array.from(wrapper.element.children).slice(0, -1)
|
|
46
|
+
return wrapper.findAll('div').filter((d) => tabEls.includes(d.element))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
it('renders one tab per item with its label', () => {
|
|
50
|
+
const wrapper = mountTabs()
|
|
51
|
+
const tabs = getTabs(wrapper)
|
|
52
|
+
expect(tabs).toHaveLength(tabsData.length)
|
|
53
|
+
expect(wrapper.text()).toContain('Overview')
|
|
54
|
+
expect(wrapper.text()).toContain('Billing')
|
|
55
|
+
expect(wrapper.text()).toContain('Users')
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('emits tab-click with the tabKey value when isIndexKey is false', async () => {
|
|
59
|
+
const wrapper = mountTabs()
|
|
60
|
+
const tabs = getTabs(wrapper)
|
|
61
|
+
|
|
62
|
+
await tabs[0].trigger('click')
|
|
63
|
+
await tabs[2].trigger('click')
|
|
64
|
+
|
|
65
|
+
const emitted = wrapper.emitted('tab-click')
|
|
66
|
+
expect(emitted).toHaveLength(2)
|
|
67
|
+
expect(emitted[0]).toEqual(['overview'])
|
|
68
|
+
expect(emitted[1]).toEqual(['users'])
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('emits tab-click with the index when isIndexKey is true', async () => {
|
|
72
|
+
const wrapper = mountTabs({ activeTab: 0, isIndexKey: true })
|
|
73
|
+
const tabs = getTabs(wrapper)
|
|
74
|
+
|
|
75
|
+
await tabs[2].trigger('click')
|
|
76
|
+
|
|
77
|
+
const emitted = wrapper.emitted('tab-click')
|
|
78
|
+
expect(emitted).toHaveLength(1)
|
|
79
|
+
expect(emitted[0]).toEqual([2])
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('styles the active tab differently from an inactive tab', () => {
|
|
83
|
+
const wrapper = mountTabs()
|
|
84
|
+
const tabs = getTabs(wrapper)
|
|
85
|
+
// activeTab is 'billing' (index 1); its generated class must differ from an
|
|
86
|
+
// inactive tab's class.
|
|
87
|
+
expect(tabs[1].classes()).not.toEqual(tabs[0].classes())
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('renders info text only for tabs that provide labelInfoText', () => {
|
|
91
|
+
const wrapper = mountTabs()
|
|
92
|
+
const infoTexts = wrapper.findAll('[data-test-id="infoText_container"]')
|
|
93
|
+
expect(infoTexts).toHaveLength(1)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import Pagination from './index.vue'
|
|
4
|
+
import theme from '@/assets/theme'
|
|
5
|
+
|
|
6
|
+
jest.mock('@/components/icon/iconCache.mjs', () => ({
|
|
7
|
+
fetchIcon: jest.fn(() => Promise.resolve('')),
|
|
8
|
+
}))
|
|
9
|
+
|
|
10
|
+
describe('Pagination', () => {
|
|
11
|
+
const mountPagination = (props = {}) => {
|
|
12
|
+
const fetchPage = jest.fn()
|
|
13
|
+
const wrapper = mount(Pagination, {
|
|
14
|
+
props: {
|
|
15
|
+
fetchPage,
|
|
16
|
+
currentPage: 1,
|
|
17
|
+
paginationParams: { pages: 3, previous: null, next: 2 },
|
|
18
|
+
...props,
|
|
19
|
+
},
|
|
20
|
+
global: {
|
|
21
|
+
provide: { theme },
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
return { wrapper, fetchPage }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
it('does not render the nav when there is only one page', () => {
|
|
28
|
+
const { wrapper } = mountPagination({
|
|
29
|
+
paginationParams: { pages: 1, previous: null, next: null },
|
|
30
|
+
})
|
|
31
|
+
expect(wrapper.find('nav').exists()).toBe(false)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('does not render the nav when pages is zero', () => {
|
|
35
|
+
const { wrapper } = mountPagination({
|
|
36
|
+
paginationParams: { pages: 0, previous: null, next: null },
|
|
37
|
+
})
|
|
38
|
+
expect(wrapper.find('nav').exists()).toBe(false)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('renders the nav when there is more than one page', () => {
|
|
42
|
+
const { wrapper } = mountPagination()
|
|
43
|
+
expect(wrapper.find('nav').exists()).toBe(true)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('renders the back button and calls fetchPage(previous) on click', async () => {
|
|
47
|
+
const { wrapper, fetchPage } = mountPagination({
|
|
48
|
+
currentPage: 2,
|
|
49
|
+
paginationParams: { pages: 5, previous: 1, next: 3 },
|
|
50
|
+
})
|
|
51
|
+
const back = wrapper.find('[data-id="pagination_back_button"]')
|
|
52
|
+
expect(back.exists()).toBe(true)
|
|
53
|
+
await back.trigger('click')
|
|
54
|
+
expect(fetchPage).toHaveBeenCalledWith(1)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('omits the back button on the first page', () => {
|
|
58
|
+
const { wrapper } = mountPagination({
|
|
59
|
+
currentPage: 1,
|
|
60
|
+
paginationParams: { pages: 5, previous: null, next: 2 },
|
|
61
|
+
})
|
|
62
|
+
expect(wrapper.find('[data-id="pagination_back_button"]').exists()).toBe(
|
|
63
|
+
false
|
|
64
|
+
)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('renders the next button and calls fetchPage(next) on click', async () => {
|
|
68
|
+
const { wrapper, fetchPage } = mountPagination({
|
|
69
|
+
currentPage: 2,
|
|
70
|
+
paginationParams: { pages: 5, previous: 1, next: 3 },
|
|
71
|
+
})
|
|
72
|
+
const next = wrapper.find('[data-id="pagination_next_button"]')
|
|
73
|
+
expect(next.exists()).toBe(true)
|
|
74
|
+
await next.trigger('click')
|
|
75
|
+
expect(fetchPage).toHaveBeenCalledWith(3)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('omits the next button on the last page', () => {
|
|
79
|
+
const { wrapper } = mountPagination({
|
|
80
|
+
currentPage: 5,
|
|
81
|
+
paginationParams: { pages: 5, previous: 4, next: null },
|
|
82
|
+
})
|
|
83
|
+
expect(wrapper.find('[data-id="pagination_next_button"]').exists()).toBe(
|
|
84
|
+
false
|
|
85
|
+
)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('renders the first-page shortcut and calls fetchPage(1) on click', async () => {
|
|
89
|
+
const { wrapper, fetchPage } = mountPagination({
|
|
90
|
+
currentPage: 4,
|
|
91
|
+
paginationParams: { pages: 10, previous: 3, next: 5 },
|
|
92
|
+
})
|
|
93
|
+
const first = wrapper.find('[data-id="pagination_page_button_1"]')
|
|
94
|
+
expect(first.exists()).toBe(true)
|
|
95
|
+
await first.trigger('click')
|
|
96
|
+
expect(fetchPage).toHaveBeenCalledWith(1)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('renders the last-page shortcut and calls fetchPage(pages) on click', async () => {
|
|
100
|
+
const { wrapper, fetchPage } = mountPagination({
|
|
101
|
+
currentPage: 4,
|
|
102
|
+
paginationParams: { pages: 10, previous: 3, next: 5 },
|
|
103
|
+
})
|
|
104
|
+
const last = wrapper.find('[data-id="pagination_page_button_10"]')
|
|
105
|
+
expect(last.exists()).toBe(true)
|
|
106
|
+
await last.trigger('click')
|
|
107
|
+
expect(fetchPage).toHaveBeenCalledWith(10)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('shows both leading and trailing ellipses when the current page is in the middle', () => {
|
|
111
|
+
const { wrapper } = mountPagination({
|
|
112
|
+
currentPage: 5,
|
|
113
|
+
paginationParams: { pages: 10, previous: 4, next: 6 },
|
|
114
|
+
})
|
|
115
|
+
expect(wrapper.findAll('span').filter((s) => s.text() === '...')).toHaveLength(
|
|
116
|
+
2
|
|
117
|
+
)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('shows no ellipses on a small range', () => {
|
|
121
|
+
const { wrapper } = mountPagination({
|
|
122
|
+
currentPage: 1,
|
|
123
|
+
paginationParams: { pages: 3, previous: null, next: 2 },
|
|
124
|
+
})
|
|
125
|
+
expect(
|
|
126
|
+
wrapper.findAll('span').filter((s) => s.text() === '...')
|
|
127
|
+
).toHaveLength(0)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('renders the window of page numbers around the current page', () => {
|
|
131
|
+
const { wrapper } = mountPagination({
|
|
132
|
+
currentPage: 4,
|
|
133
|
+
paginationParams: { pages: 10, previous: 3, next: 5 },
|
|
134
|
+
})
|
|
135
|
+
;[3, 4, 5].forEach((n) => {
|
|
136
|
+
expect(
|
|
137
|
+
wrapper.find(`[data-id="pagination_page_button_${n}"]`).exists()
|
|
138
|
+
).toBe(true)
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it('marks the current page button as active', () => {
|
|
143
|
+
const { wrapper } = mountPagination({
|
|
144
|
+
currentPage: 4,
|
|
145
|
+
paginationParams: { pages: 10, previous: 3, next: 5 },
|
|
146
|
+
})
|
|
147
|
+
const current = wrapper.find('[data-id="pagination_page_button_4"]')
|
|
148
|
+
expect(current.classes()).toContain('active')
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('calls fetchPage with the clicked page number', async () => {
|
|
152
|
+
const { wrapper, fetchPage } = mountPagination({
|
|
153
|
+
currentPage: 4,
|
|
154
|
+
paginationParams: { pages: 10, previous: 3, next: 5 },
|
|
155
|
+
})
|
|
156
|
+
await wrapper.find('[data-id="pagination_page_button_5"]').trigger('click')
|
|
157
|
+
expect(fetchPage).toHaveBeenCalledWith(5)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('renders exactly two page numbers when there are only two pages', () => {
|
|
161
|
+
const { wrapper } = mountPagination({
|
|
162
|
+
currentPage: 1,
|
|
163
|
+
paginationParams: { pages: 2, previous: null, next: 2 },
|
|
164
|
+
})
|
|
165
|
+
;[1, 2].forEach((n) => {
|
|
166
|
+
expect(
|
|
167
|
+
wrapper.find(`[data-id="pagination_page_button_${n}"]`).exists()
|
|
168
|
+
).toBe(true)
|
|
169
|
+
})
|
|
170
|
+
expect(
|
|
171
|
+
wrapper.find('[data-id="pagination_page_button_3"]').exists()
|
|
172
|
+
).toBe(false)
|
|
173
|
+
})
|
|
174
|
+
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
1
2
|
import { mount } from '@vue/test-utils'
|
|
2
3
|
import RCProgressBar from '@/components/progressBar'
|
|
3
4
|
import defaultProps from './defaultProps'
|
|
@@ -9,44 +10,53 @@ jest.mock('@/components/icon/iconCache.mjs', () => ({
|
|
|
9
10
|
}))
|
|
10
11
|
|
|
11
12
|
describe('progressBar/index.vue', () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
props: { ...defaultProps, labelText },
|
|
17
|
-
global: {
|
|
18
|
-
provide: {
|
|
19
|
-
theme,
|
|
20
|
-
},
|
|
21
|
-
},
|
|
13
|
+
const mountBar = (props = {}) =>
|
|
14
|
+
mount(RCProgressBar, {
|
|
15
|
+
props,
|
|
16
|
+
global: { provide: { theme } },
|
|
22
17
|
})
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
it('renders the progress container and fill', () => {
|
|
20
|
+
const wrapper = mountBar()
|
|
21
|
+
expect(
|
|
22
|
+
wrapper.find('[data-test-id="progress_bar_container"]').exists()
|
|
23
|
+
).toBe(true)
|
|
24
|
+
expect(
|
|
25
|
+
wrapper.find('[data-test-id="progress_bar_progress"]').exists()
|
|
26
|
+
).toBe(true)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('renders the label when labelText is provided', () => {
|
|
30
|
+
const wrapper = mountBar({ labelText: 'test_label_text' })
|
|
31
|
+
const label = wrapper.find('[data-test-id="progress_bar_label"]')
|
|
32
|
+
expect(label.exists()).toBe(true)
|
|
33
|
+
expect(label.text()).toBe('test_label_text')
|
|
34
|
+
})
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
expect(
|
|
36
|
+
it('omits the label when labelText is empty (the default)', () => {
|
|
37
|
+
const wrapper = mountBar()
|
|
38
|
+
expect(wrapper.find('[data-test-id="progress_bar_label"]').exists()).toBe(
|
|
39
|
+
false
|
|
40
|
+
)
|
|
41
|
+
})
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
it('defaults fillProgress to 0', () => {
|
|
44
|
+
expect(mountBar().props('fillProgress')).toBe(0)
|
|
34
45
|
})
|
|
35
46
|
|
|
36
|
-
it('
|
|
37
|
-
const wrapper =
|
|
38
|
-
|
|
39
|
-
global: {
|
|
40
|
-
provide: {
|
|
41
|
-
theme,
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
})
|
|
47
|
+
it('accepts fillProgress as a string or a number', async () => {
|
|
48
|
+
const wrapper = mountBar({ fillProgress: defaultProps.fillProgress })
|
|
49
|
+
expect(wrapper.props('fillProgress')).toBe(defaultProps.fillProgress)
|
|
45
50
|
|
|
46
|
-
|
|
51
|
+
await wrapper.setProps({ fillProgress: 40 })
|
|
52
|
+
expect(wrapper.props('fillProgress')).toBe(40)
|
|
53
|
+
})
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
it('defaults appTheme to light and accepts dark', async () => {
|
|
56
|
+
const wrapper = mountBar()
|
|
57
|
+
expect(wrapper.props('appTheme')).toBe('light')
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
await wrapper.setProps({ appTheme: 'dark' })
|
|
60
|
+
expect(wrapper.props('appTheme')).toBe('dark')
|
|
51
61
|
})
|
|
52
62
|
})
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { mount, DOMWrapper } from '@vue/test-utils'
|
|
3
|
+
import ProjectMarker from './index.vue'
|
|
4
|
+
import Icon from '@/components/icon'
|
|
5
|
+
import MainButton from '@/components/buttons/mainButton'
|
|
6
|
+
|
|
7
|
+
jest.mock('@/components/icon/iconCache.mjs', () => ({
|
|
8
|
+
fetchIcon: jest.fn(() => Promise.resolve('')),
|
|
9
|
+
}))
|
|
10
|
+
|
|
11
|
+
const marker = (overrides = {}) => ({
|
|
12
|
+
choice: null,
|
|
13
|
+
color: '#9C27B0',
|
|
14
|
+
can_be_deleted: true,
|
|
15
|
+
translations: { 'en-us': { name: 'In progress' } },
|
|
16
|
+
...overrides,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const mountMarker = (props = {}) =>
|
|
20
|
+
mount(ProjectMarker, {
|
|
21
|
+
props: { markerData: marker(), activeLanguage: 'en-us', ...props },
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
/** The clickable pill is the first element child of the root container. */
|
|
25
|
+
const clickPill = (wrapper) =>
|
|
26
|
+
new DOMWrapper(wrapper.element.children[0]).trigger('click')
|
|
27
|
+
|
|
28
|
+
describe('ProjectMarker', () => {
|
|
29
|
+
it('does not render the pill when there is no translation for the active language', () => {
|
|
30
|
+
const wrapper = mountMarker({ activeLanguage: 'de-de' })
|
|
31
|
+
expect(wrapper.text()).not.toContain('In progress')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('renders the marker name from the active language translation', () => {
|
|
35
|
+
expect(mountMarker().text()).toContain('In progress')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('renders a color dot and no status icon for a plain marker', () => {
|
|
39
|
+
const wrapper = mountMarker()
|
|
40
|
+
expect(wrapper.findComponent(Icon).exists()).toBe(false)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('renders the checkmark icon for a sold marker', () => {
|
|
44
|
+
const wrapper = mountMarker({
|
|
45
|
+
markerData: marker({
|
|
46
|
+
choice: 'sold',
|
|
47
|
+
translations: { 'en-us': { name: 'Sold' } },
|
|
48
|
+
}),
|
|
49
|
+
})
|
|
50
|
+
const icon = wrapper.findComponent(Icon)
|
|
51
|
+
expect(icon.exists()).toBe(true)
|
|
52
|
+
expect(icon.attributes('name')).toBe('checkmark')
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('renders the cross_filled icon for a lost marker', () => {
|
|
56
|
+
const wrapper = mountMarker({
|
|
57
|
+
markerData: marker({
|
|
58
|
+
choice: 'lost',
|
|
59
|
+
translations: { 'en-us': { name: 'Lost' } },
|
|
60
|
+
}),
|
|
61
|
+
})
|
|
62
|
+
const icon = wrapper.findComponent(Icon)
|
|
63
|
+
expect(icon.exists()).toBe(true)
|
|
64
|
+
expect(icon.attributes('name')).toBe('cross_filled')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('renders the date only when a date is provided', () => {
|
|
68
|
+
expect(mountMarker({ date: '23.07.2022' }).text()).toContain('23.07.2022')
|
|
69
|
+
expect(mountMarker().text()).not.toContain('23.07.2022')
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
describe('edition', () => {
|
|
73
|
+
const editableProps = { isEditable: true }
|
|
74
|
+
|
|
75
|
+
it('shows the three-dots affordance when edition is allowed', () => {
|
|
76
|
+
const wrapper = mountMarker(editableProps)
|
|
77
|
+
expect(wrapper.find('.dotContainer').exists()).toBe(true)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('hides the affordance when isEditable is false', () => {
|
|
81
|
+
expect(mountMarker().find('.dotContainer').exists()).toBe(false)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('hides the affordance when the marker cannot be deleted', () => {
|
|
85
|
+
const wrapper = mountMarker({
|
|
86
|
+
...editableProps,
|
|
87
|
+
markerData: marker({ can_be_deleted: false }),
|
|
88
|
+
})
|
|
89
|
+
expect(wrapper.find('.dotContainer').exists()).toBe(false)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('hides the affordance for a limited partner without group support', () => {
|
|
93
|
+
const wrapper = mountMarker({ ...editableProps, isLimitedPartner: true })
|
|
94
|
+
expect(wrapper.find('.dotContainer').exists()).toBe(false)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('restores the affordance for a limited partner with group support', () => {
|
|
98
|
+
const wrapper = mountMarker({
|
|
99
|
+
...editableProps,
|
|
100
|
+
isLimitedPartner: true,
|
|
101
|
+
isGroupSupport: true,
|
|
102
|
+
})
|
|
103
|
+
expect(wrapper.find('.dotContainer').exists()).toBe(true)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('toggles the edit menu when the pill is clicked', async () => {
|
|
107
|
+
const wrapper = mountMarker(editableProps)
|
|
108
|
+
expect(wrapper.text()).not.toContain('Edit')
|
|
109
|
+
|
|
110
|
+
await clickPill(wrapper)
|
|
111
|
+
expect(wrapper.text()).toContain('Edit')
|
|
112
|
+
expect(wrapper.text()).toContain('Delete')
|
|
113
|
+
|
|
114
|
+
await clickPill(wrapper)
|
|
115
|
+
expect(wrapper.text()).not.toContain('Edit')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('does not open the menu when edition is not allowed', async () => {
|
|
119
|
+
const wrapper = mountMarker()
|
|
120
|
+
await clickPill(wrapper)
|
|
121
|
+
expect(wrapper.text()).not.toContain('Edit')
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('emits editHandler when the Edit action is clicked', async () => {
|
|
125
|
+
const wrapper = mountMarker(editableProps)
|
|
126
|
+
await clickPill(wrapper)
|
|
127
|
+
|
|
128
|
+
const editItem = wrapper
|
|
129
|
+
.findAll('div')
|
|
130
|
+
.find((d) => d.text() === 'Edit')
|
|
131
|
+
await editItem.trigger('click')
|
|
132
|
+
|
|
133
|
+
expect(wrapper.emitted('editHandler')).toHaveLength(1)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('opens the delete confirmation modal and emits deleteHandler on confirm', async () => {
|
|
137
|
+
const wrapper = mountMarker(editableProps)
|
|
138
|
+
await clickPill(wrapper)
|
|
139
|
+
|
|
140
|
+
const deleteItem = wrapper
|
|
141
|
+
.findAll('div')
|
|
142
|
+
.find((d) => d.text() === 'Delete')
|
|
143
|
+
await deleteItem.trigger('click')
|
|
144
|
+
expect(wrapper.text()).toContain('delete_confirm_text')
|
|
145
|
+
|
|
146
|
+
const confirm = wrapper
|
|
147
|
+
.findAllComponents(MainButton)
|
|
148
|
+
.find((b) => b.props('text') === 'Delete')
|
|
149
|
+
await confirm.trigger('click')
|
|
150
|
+
|
|
151
|
+
expect(wrapper.emitted('deleteHandler')).toHaveLength(1)
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
})
|