|
1 |
| -import { loadFixture, testVM } from '../../../tests/utils' |
| 1 | +import Card from './card' |
| 2 | +import { mount } from '@vue/test-utils' |
2 | 3 |
|
3 | 4 | describe('card', () => {
|
4 |
| - beforeEach(loadFixture(__dirname, 'card')) |
5 |
| - testVM() |
| 5 | + it('default has expected structure', async () => { |
| 6 | + const wrapper = mount(Card) |
| 7 | + |
| 8 | + // Outer div |
| 9 | + expect(wrapper.is('div')).toBe(true) |
| 10 | + expect(wrapper.classes()).toContain('card') |
| 11 | + expect(wrapper.classes().length).toBe(1) |
| 12 | + |
| 13 | + // Should have one child div.card-body |
| 14 | + expect(wrapper.findAll('.card > .card-body').length).toBe(1) |
| 15 | + expect(wrapper.findAll('.card-body').length).toBe(1) |
| 16 | + expect(wrapper.find('.card-body').is('div')).toBe(true) |
| 17 | + expect(wrapper.find('.card-body').classes()).toContain('card-body') |
| 18 | + expect(wrapper.find('.card-body').classes().length).toBe(1) |
| 19 | + |
| 20 | + // Should have no content by default |
| 21 | + expect(wrapper.text()).toEqual('') |
| 22 | + }) |
6 | 23 |
|
7 |
| - it("should contain '.card-body' class in the default slot", async () => { |
8 |
| - const { |
9 |
| - app: { $refs } |
10 |
| - } = window |
| 24 | + it('should not contain "card-body" if prop no-body set', async () => { |
| 25 | + const wrapper = mount(Card, { |
| 26 | + propsData: { |
| 27 | + noBody: true |
| 28 | + } |
| 29 | + }) |
11 | 30 |
|
12 |
| - const refs = ['simple_card', 'standard_card', 'img_card', 'img_overlay_card'] |
| 31 | + // Outer div |
| 32 | + expect(wrapper.is('div')).toBe(true) |
| 33 | + expect(wrapper.classes()).toContain('card') |
| 34 | + expect(wrapper.classes().length).toBe(1) |
13 | 35 |
|
14 |
| - refs.forEach(ref => { |
15 |
| - const childNodes = [...$refs[ref].childNodes] |
16 |
| - const cardBody = childNodes.find(el => el.classList && el.classList.contains('card-body')) |
| 36 | + // Should no have a card body |
| 37 | + expect(wrapper.findAll('.card-body').length).toBe(0) |
| 38 | + // Should have no content by default |
| 39 | + expect(wrapper.text()).toEqual('') |
| 40 | + }) |
17 | 41 |
|
18 |
| - expect(cardBody).toBeDefined() |
| 42 | + it('renders custom root element when tag prop set', async () => { |
| 43 | + const wrapper = mount(Card, { |
| 44 | + propsData: { |
| 45 | + tag: 'article', |
| 46 | + noBody: true |
| 47 | + } |
19 | 48 | })
|
| 49 | + |
| 50 | + // Outer div |
| 51 | + expect(wrapper.is('article')).toBe(true) |
| 52 | + expect(wrapper.classes()).toContain('card') |
| 53 | + expect(wrapper.classes().length).toBe(1) |
| 54 | + expect(wrapper.text()).toEqual('') |
20 | 55 | })
|
21 | 56 |
|
22 |
| - it("should not contain '.card-body' class if no-body specified", async () => { |
23 |
| - const { |
24 |
| - app: { $refs } |
25 |
| - } = window |
| 57 | + it('applies variant classes to root element', async () => { |
| 58 | + const wrapper = mount(Card, { |
| 59 | + propsData: { |
| 60 | + noBody: true, |
| 61 | + bgVariant: 'info', |
| 62 | + borderVariant: 'danger', |
| 63 | + textVariant: 'dark' |
| 64 | + } |
| 65 | + }) |
26 | 66 |
|
27 |
| - expect($refs.no_body.classList.contains('card-body')).toBe(false) |
28 |
| - expect($refs.no_body_default_slot).toEqual($refs.no_body.children[0]) |
| 67 | + // Outer div |
| 68 | + expect(wrapper.is('div')).toBe(true) |
| 69 | + expect(wrapper.classes()).toContain('card') |
| 70 | + expect(wrapper.classes()).toContain('bg-info') |
| 71 | + expect(wrapper.classes()).toContain('border-danger') |
| 72 | + expect(wrapper.classes()).toContain('text-dark') |
| 73 | + expect(wrapper.classes().length).toBe(4) |
| 74 | + expect(wrapper.text()).toEqual('') |
29 | 75 | })
|
30 | 76 |
|
31 |
| - it('should contain class names', async () => { |
32 |
| - const { |
33 |
| - app: { $refs } |
34 |
| - } = window |
| 77 | + it('applies text align class to when align prop set', async () => { |
| 78 | + const wrapper = mount(Card, { |
| 79 | + propsData: { |
| 80 | + noBody: true, |
| 81 | + align: 'right' |
| 82 | + } |
| 83 | + }) |
35 | 84 |
|
36 |
| - expect($refs.simple_card).toHaveAllClasses(['card', 'bg-success', 'border-success']) |
37 |
| - expect($refs.standard_card).toHaveClass('card') |
38 |
| - expect($refs.img_card).toHaveClass('card') |
39 |
| - expect($refs.img_overlay_card).toHaveAllClasses(['card']) |
| 85 | + // Outer div |
| 86 | + expect(wrapper.is('div')).toBe(true) |
| 87 | + expect(wrapper.classes()).toContain('card') |
| 88 | + expect(wrapper.classes()).toContain('text-right') |
| 89 | + expect(wrapper.classes().length).toBe(2) |
| 90 | + expect(wrapper.text()).toEqual('') |
| 91 | + }) |
40 | 92 |
|
41 |
| - const cardBodyEl = [...$refs.img_overlay_card.childNodes].find( |
42 |
| - el => el.classList && el.classList.contains('card-body') |
43 |
| - ) |
| 93 | + it('should have content from default slot', async () => { |
| 94 | + const wrapperBody = mount(Card, { |
| 95 | + propsData: { |
| 96 | + noBody: false |
| 97 | + }, |
| 98 | + slots: { |
| 99 | + default: 'foobar' |
| 100 | + } |
| 101 | + }) |
| 102 | + const wrapperNoBody = mount(Card, { |
| 103 | + propsData: { |
| 104 | + noBody: true |
| 105 | + }, |
| 106 | + slots: { |
| 107 | + default: 'foobar' |
| 108 | + } |
| 109 | + }) |
| 110 | + |
| 111 | + // With body |
| 112 | + expect(wrapperBody.is('div')).toBe(true) |
| 113 | + expect(wrapperBody.findAll('.card-body').length).toBe(1) |
| 114 | + expect(wrapperBody.find('.card-body').text()).toBe('foobar') |
44 | 115 |
|
45 |
| - expect(cardBodyEl.classList.contains('card-img-overlay')).toBe(true) |
| 116 | + // With no body |
| 117 | + expect(wrapperNoBody.is('div')).toBe(true) |
| 118 | + expect(wrapperNoBody.findAll('.card-body').length).toBe(0) |
| 119 | + expect(wrapperNoBody.text()).toBe('foobar') |
46 | 120 | })
|
47 | 121 |
|
48 |
| - it('should contain text content', async () => { |
49 |
| - const { |
50 |
| - app: { $refs } |
51 |
| - } = window |
| 122 | + it('should have class flex-row when img-left set', async () => { |
| 123 | + const wrapper = mount(Card, { |
| 124 | + propsData: { |
| 125 | + noBody: true, |
| 126 | + imgLeft: true |
| 127 | + } |
| 128 | + }) |
52 | 129 |
|
53 |
| - expect($refs.simple_card.textContent).toContain('Simple Card') |
54 |
| - expect($refs.standard_card.textContent).toContain('Last updated 3 mins ago') |
55 |
| - expect($refs.img_card.textContent).toContain('This is my opinion :)') |
56 |
| - expect($refs.img_overlay_card.textContent).toContain('Overlay cards are cute!') |
| 130 | + expect(wrapper.is('div')).toBe(true) |
| 131 | + expect(wrapper.classes()).toContain('card') |
| 132 | + expect(wrapper.classes()).toContain('flex-row') |
| 133 | + expect(wrapper.classes().length).toBe(2) |
57 | 134 | })
|
58 | 135 |
|
59 |
| - it('standard_card should display card header', async () => { |
60 |
| - const { app } = window |
61 |
| - |
62 |
| - const childNodes = [...app.$refs.standard_card.childNodes] |
63 |
| - const headerEl = childNodes.find(el => el.classList && el.classList.contains('card-header')) |
| 136 | + it('should have class flex-row-reverse when img-right set', async () => { |
| 137 | + const wrapper = mount(Card, { |
| 138 | + propsData: { |
| 139 | + noBody: true, |
| 140 | + imgRight: true |
| 141 | + } |
| 142 | + }) |
64 | 143 |
|
65 |
| - expect(headerEl).toBeDefined() |
66 |
| - expect(headerEl.textContent).toContain(app.headerText) |
| 144 | + expect(wrapper.is('div')).toBe(true) |
| 145 | + expect(wrapper.classes()).toContain('card') |
| 146 | + expect(wrapper.classes()).toContain('flex-row-reverse') |
| 147 | + expect(wrapper.classes().length).toBe(2) |
67 | 148 | })
|
68 | 149 |
|
69 |
| - it('standard_card should display card footer', async () => { |
70 |
| - const { |
71 |
| - app: { $refs } |
72 |
| - } = window |
73 |
| - |
74 |
| - const childNodes = [...$refs.standard_card.childNodes] |
75 |
| - const footerEl = childNodes.find(el => el.classList && el.classList.contains('card-footer')) |
76 |
| - const footerText = 'Last updated 3 mins ago' |
| 150 | + it('should have class flex-row when img-left and img-right set', async () => { |
| 151 | + const wrapper = mount(Card, { |
| 152 | + propsData: { |
| 153 | + noBody: true, |
| 154 | + imgLeft: true, |
| 155 | + imgRight: true |
| 156 | + } |
| 157 | + }) |
77 | 158 |
|
78 |
| - expect(footerEl).toBeDefined() |
79 |
| - expect(footerEl.textContent).toContain(footerText) |
| 159 | + expect(wrapper.is('div')).toBe(true) |
| 160 | + expect(wrapper.classes()).toContain('card') |
| 161 | + expect(wrapper.classes()).toContain('flex-row') |
| 162 | + expect(wrapper.classes()).not.toContain('flex-row-reverse') |
| 163 | + expect(wrapper.classes().length).toBe(2) |
80 | 164 | })
|
81 | 165 |
|
82 |
| - it('should contain <img> with matching src', async () => { |
83 |
| - const { app } = window |
| 166 | + it('should have header and footer when header and footer props are set', async () => { |
| 167 | + const wrapper = mount(Card, { |
| 168 | + propsData: { |
| 169 | + header: 'foo', |
| 170 | + footer: 'bar' |
| 171 | + }, |
| 172 | + slots: { |
| 173 | + default: 'fizzle' |
| 174 | + } |
| 175 | + }) |
84 | 176 |
|
85 |
| - const refsWithImg = ['img_card', 'img_overlay_card'] |
| 177 | + expect(wrapper.is('div')).toBe(true) |
| 178 | + expect(wrapper.classes()).toContain('card') |
86 | 179 |
|
87 |
| - refsWithImg.forEach((ref, i) => { |
88 |
| - const node = app.$refs[ref] |
89 |
| - const src = app['img' + i] |
90 |
| - const childNodes = [...node.childNodes] |
91 |
| - const imgEl = childNodes.find(el => el.tagName && el.tagName === 'IMG') |
| 180 | + expect(wrapper.findAll('.card-header').length).toBe(1) |
| 181 | + expect(wrapper.find('.card-header').text()).toBe('foo') |
| 182 | + expect(wrapper.findAll('.card-body').length).toBe(1) |
| 183 | + expect(wrapper.find('.card-body').text()).toBe('fizzle') |
| 184 | + expect(wrapper.findAll('.card-footer').length).toBe(1) |
| 185 | + expect(wrapper.find('.card-footer').text()).toBe('bar') |
92 | 186 |
|
93 |
| - expect(imgEl).toBeDefined() |
94 |
| - expect(imgEl.src).toEqual(src) |
95 |
| - }) |
| 187 | + // Expected order |
| 188 | + expect(wrapper.find('.card-header+.card-body+.card-footer').exists()).toBe(true) |
96 | 189 | })
|
97 | 190 |
|
98 |
| - it('should add flex-row to a img-left or img-right image', async () => { |
99 |
| - const { app } = window |
100 |
| - const node = app.$refs['img_card'] |
101 |
| - const childNodes = [...node.childNodes] |
102 |
| - const imgEl = childNodes.find(el => el.tagName && el.tagName === 'IMG') |
| 191 | + it('should have img at top', async () => { |
| 192 | + const wrapper = mount(Card, { |
| 193 | + propsData: { |
| 194 | + imgSrc: '/foo/bar', |
| 195 | + imgAlt: 'foobar', |
| 196 | + imgTop: true |
| 197 | + } |
| 198 | + }) |
103 | 199 |
|
104 |
| - expect(imgEl).toBeDefined() |
105 |
| - expect(imgEl.classList).toEqual(expect.objectContaining(/^flex-row/)) |
106 |
| - }) |
| 200 | + expect(wrapper.is('div')).toBe(true) |
| 201 | + expect(wrapper.classes()).toContain('card') |
107 | 202 |
|
108 |
| - it("should use the 'tag' for element tag", async () => { |
109 |
| - const { |
110 |
| - app: { $refs } |
111 |
| - } = window |
112 |
| - const $titleCard = $refs.card_group.querySelector('#title-tag-test') |
113 |
| - // Card ref -> .card-body -> title el |
114 |
| - expect($titleCard).toBeElement('article') |
115 |
| - }) |
| 203 | + expect(wrapper.findAll('img').length).toBe(1) |
| 204 | + const $img = wrapper.find('img') |
| 205 | + expect($img.is('img')).toBe(true) |
| 206 | + expect($img.attributes('src')).toBe('/foo/bar') |
| 207 | + expect($img.attributes('alt')).toBe('foobar') |
| 208 | + expect($img.classes()).toContain('card-img-top') |
| 209 | + expect($img.classes().length).toBe(1) |
116 | 210 |
|
117 |
| - it("should use the 'title-tag' for element tag", async () => { |
118 |
| - const { |
119 |
| - app: { $refs } |
120 |
| - } = window |
121 |
| - const $titleCard = $refs.card_group.querySelector('#title-tag-test') |
122 |
| - // Card ref -> .card-body -> title el |
123 |
| - expect($titleCard.children[0].children[0]).toBeElement('h1') |
| 211 | + // Expected order |
| 212 | + expect(wrapper.find('img + .card-body').exists()).toBe(true) |
124 | 213 | })
|
125 | 214 |
|
126 |
| - it("should use the 'sub-title-tag' for element tag", async () => { |
127 |
| - const { |
128 |
| - app: { $refs } |
129 |
| - } = window |
130 |
| - const $subtitleCard = $refs.card_group.querySelector('#sub-title-tag-test') |
131 |
| - // Card ref -> .card-body -> subtitle el |
132 |
| - expect($subtitleCard.children[0].children[0]).toBeElement('h2') |
133 |
| - }) |
134 |
| - |
135 |
| - it("CardGroup: should apply '.card-group' class", async () => { |
136 |
| - const { |
137 |
| - app: { $refs } |
138 |
| - } = window |
| 215 | + it('should have img at bottom', async () => { |
| 216 | + const wrapper = mount(Card, { |
| 217 | + propsData: { |
| 218 | + imgSrc: '/foo/bar', |
| 219 | + imgAlt: 'foobar', |
| 220 | + imgBottom: true |
| 221 | + } |
| 222 | + }) |
139 | 223 |
|
140 |
| - expect($refs.card_group.classList.contains('card-group')).toBe(true) |
141 |
| - }) |
| 224 | + expect(wrapper.is('div')).toBe(true) |
| 225 | + expect(wrapper.classes()).toContain('card') |
142 | 226 |
|
143 |
| - it("CardGroup: should use the 'tag' for element tag", async () => { |
144 |
| - const { |
145 |
| - app: { $refs } |
146 |
| - } = window |
| 227 | + expect(wrapper.findAll('img').length).toBe(1) |
| 228 | + const $img = wrapper.find('img') |
| 229 | + expect($img.is('img')).toBe(true) |
| 230 | + expect($img.attributes('src')).toBe('/foo/bar') |
| 231 | + expect($img.attributes('alt')).toBe('foobar') |
| 232 | + expect($img.classes()).toContain('card-img-bottom') |
| 233 | + expect($img.classes().length).toBe(1) |
147 | 234 |
|
148 |
| - expect($refs.card_group).toBeElement('section') |
| 235 | + // Expected order |
| 236 | + expect(wrapper.find('.card-body + img').exists()).toBe(true) |
149 | 237 | })
|
150 | 238 |
|
151 |
| - it('CardBody should have assigned class', async () => { |
152 |
| - const { |
153 |
| - app: { $refs } |
154 |
| - } = window |
155 |
| - expect($refs.body).toHaveClass('card-text') |
| 239 | + it('should have img overlay', async () => { |
| 240 | + const wrapper = mount(Card, { |
| 241 | + propsData: { |
| 242 | + imgSrc: '/foo/bar', |
| 243 | + imgAlt: 'foobar', |
| 244 | + overlay: true |
| 245 | + } |
| 246 | + }) |
| 247 | + |
| 248 | + expect(wrapper.is('div')).toBe(true) |
| 249 | + expect(wrapper.classes()).toContain('card') |
| 250 | + expect(wrapper.classes().length).toBe(1) |
| 251 | + |
| 252 | + expect(wrapper.findAll('img').length).toBe(1) |
| 253 | + const $img = wrapper.find('img') |
| 254 | + expect($img.is('img')).toBe(true) |
| 255 | + expect($img.attributes('src')).toBe('/foo/bar') |
| 256 | + expect($img.attributes('alt')).toBe('foobar') |
| 257 | + expect($img.classes()).toContain('card-img') |
| 258 | + expect($img.classes().length).toBe(1) |
| 259 | + |
| 260 | + expect(wrapper.findAll('.card-body').length).toBe(1) |
| 261 | + const $body = wrapper.find('.card-body') |
| 262 | + expect($body.classes()).toContain('card-body') |
| 263 | + expect($body.classes()).toContain('card-img-overlay') |
| 264 | + expect($body.classes().length).toBe(2) |
| 265 | + |
| 266 | + // Expected order |
| 267 | + expect(wrapper.find('img + .card-body').exists()).toBe(true) |
156 | 268 | })
|
157 | 269 | })
|
0 commit comments