@ons/design-system 50.0.1 → 53.0.0

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.
Files changed (182) hide show
  1. package/README.md +35 -15
  2. package/components/access-code/_macro.njk +1 -1
  3. package/components/access-code/_macro.spec.js +162 -0
  4. package/components/access-code/uac.spec.js +26 -0
  5. package/components/accordion/_macro.spec.js +224 -0
  6. package/components/accordion/accordion.spec.js +134 -0
  7. package/components/address-input/_macro.njk +1 -1
  8. package/components/address-input/_macro.spec.js +465 -0
  9. package/components/address-input/autosuggest.address.js +5 -4
  10. package/components/address-input/autosuggest.address.setter.js +9 -3
  11. package/components/address-input/autosuggest.address.spec.js +733 -0
  12. package/components/address-output/_macro.njk +6 -6
  13. package/components/address-output/_macro.spec.js +122 -0
  14. package/components/autosuggest/_macro.njk +1 -1
  15. package/components/autosuggest/_macro.spec.js +229 -0
  16. package/components/autosuggest/autosuggest.helpers.js +2 -3
  17. package/components/autosuggest/autosuggest.helpers.spec.js +85 -0
  18. package/components/autosuggest/autosuggest.js +4 -2
  19. package/components/autosuggest/autosuggest.spec.js +625 -0
  20. package/components/autosuggest/autosuggest.ui.js +6 -2
  21. package/components/breadcrumbs/_macro.spec.js +129 -0
  22. package/components/button/_button.scss +75 -33
  23. package/components/button/_macro.njk +6 -6
  24. package/components/button/_macro.spec.js +446 -0
  25. package/components/button/button.spec.js +290 -0
  26. package/components/call-to-action/_macro.njk +3 -1
  27. package/components/call-to-action/_macro.spec.js +52 -0
  28. package/components/card/_macro.njk +26 -19
  29. package/components/card/_macro.spec.js +261 -0
  30. package/components/char-check-limit/_macro.spec.js +73 -0
  31. package/components/char-check-limit/character-check.spec.js +196 -0
  32. package/components/char-check-limit/character-limit.js +1 -1
  33. package/components/checkboxes/_checkbox-macro.spec.js +419 -0
  34. package/components/checkboxes/_macro.njk +1 -3
  35. package/components/checkboxes/_macro.spec.js +306 -0
  36. package/components/checkboxes/checkbox-with-autoselect.js +2 -1
  37. package/components/checkboxes/checkboxes.spec.js +208 -0
  38. package/components/code-highlight/_macro.spec.js +56 -0
  39. package/components/code-highlight/code-highlight.spec.js +18 -0
  40. package/components/collapsible/_macro.spec.js +204 -0
  41. package/components/collapsible/collapsible.js +2 -1
  42. package/components/collapsible/collapsible.spec.js +236 -0
  43. package/components/content-pagination/_macro.spec.js +199 -0
  44. package/components/cookies-banner/_macro.njk +1 -1
  45. package/components/cookies-banner/_macro.spec.js +171 -0
  46. package/components/cookies-banner/cookies-banner.spec.js +90 -0
  47. package/components/date-input/_macro.njk +6 -3
  48. package/components/date-input/_macro.spec.js +286 -0
  49. package/components/document-list/_macro.njk +3 -5
  50. package/components/document-list/_macro.spec.js +491 -0
  51. package/components/download-resources/download-resources.spec.js +540 -0
  52. package/components/duration/_macro.njk +7 -6
  53. package/components/duration/_macro.spec.js +251 -0
  54. package/components/error/_macro.spec.js +97 -0
  55. package/components/external-link/_macro.njk +5 -2
  56. package/components/external-link/_macro.spec.js +77 -0
  57. package/components/feedback/_macro.njk +5 -3
  58. package/components/feedback/_macro.spec.js +122 -0
  59. package/components/field/_macro.njk +2 -2
  60. package/components/field/_macro.spec.js +97 -0
  61. package/components/fieldset/_macro.njk +3 -3
  62. package/components/fieldset/_macro.spec.js +173 -0
  63. package/components/footer/_footer.scss +19 -4
  64. package/components/footer/_macro.njk +106 -137
  65. package/components/footer/_macro.spec.js +678 -0
  66. package/components/header/_header.scss +65 -46
  67. package/components/header/_macro.njk +173 -121
  68. package/components/header/_macro.spec.js +618 -0
  69. package/components/hero/_hero.scss +30 -143
  70. package/components/hero/_macro.njk +12 -23
  71. package/components/hero/_macro.spec.js +218 -0
  72. package/components/icons/_macro.njk +258 -30
  73. package/components/icons/_macro.spec.js +140 -0
  74. package/components/images/_macro.njk +1 -1
  75. package/components/images/_macro.spec.js +121 -0
  76. package/components/input/_input-type.scss +12 -5
  77. package/components/input/_input.scss +8 -0
  78. package/components/input/_macro.njk +4 -5
  79. package/components/input/_macro.spec.js +658 -0
  80. package/components/label/_macro.spec.js +189 -0
  81. package/components/language-selector/_macro.njk +1 -1
  82. package/components/language-selector/_macro.spec.js +137 -0
  83. package/components/lists/_list.scss +4 -0
  84. package/components/lists/_macro.njk +4 -7
  85. package/components/lists/_macro.spec.js +618 -0
  86. package/components/message/_macro.spec.js +137 -0
  87. package/components/message-list/_macro.njk +7 -7
  88. package/components/message-list/_macro.spec.js +159 -0
  89. package/components/metadata/_macro.spec.js +167 -0
  90. package/components/modal/_macro.njk +6 -6
  91. package/components/modal/_macro.spec.js +87 -0
  92. package/components/modal/modal.spec.js +59 -0
  93. package/components/mutually-exclusive/_macro.njk +2 -2
  94. package/components/mutually-exclusive/_macro.spec.js +184 -0
  95. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +203 -0
  96. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +142 -0
  97. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +141 -0
  98. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +117 -0
  99. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +213 -0
  100. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +125 -0
  101. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +131 -0
  102. package/components/navigation/_macro.njk +45 -38
  103. package/components/navigation/_macro.spec.js +329 -0
  104. package/components/navigation/_navigation.scss +20 -4
  105. package/components/navigation/navigation.dom.js +1 -1
  106. package/components/navigation/navigation.spec.js +232 -0
  107. package/components/pagination/_macro.njk +1 -1
  108. package/components/pagination/_macro.spec.js +411 -0
  109. package/components/panel/_macro.njk +6 -6
  110. package/components/panel/_macro.spec.js +423 -0
  111. package/components/password/_macro.spec.js +137 -0
  112. package/components/password/password.spec.js +40 -0
  113. package/components/phase-banner/_macro.spec.js +73 -0
  114. package/components/promotional-banner/_macro.spec.js +97 -0
  115. package/components/question/_macro.njk +16 -22
  116. package/components/question/_macro.spec.js +309 -0
  117. package/components/quote/_macro.spec.js +81 -0
  118. package/components/radios/_macro.njk +3 -6
  119. package/components/radios/_macro.spec.js +575 -0
  120. package/components/radios/radios.spec.js +180 -0
  121. package/components/related-content/_macro.njk +14 -21
  122. package/components/related-content/_macro.spec.js +133 -0
  123. package/components/related-content/_section-macro.njk +10 -0
  124. package/components/related-content/_section-macro.spec.js +43 -0
  125. package/components/relationships/_macro.spec.js +108 -0
  126. package/components/relationships/relationships.spec.js +84 -0
  127. package/components/reply/_macro.njk +2 -2
  128. package/components/reply/_macro.spec.js +69 -0
  129. package/components/reply/reply.spec.js +78 -0
  130. package/components/search/_macro.njk +14 -12
  131. package/components/search/_macro.spec.js +44 -0
  132. package/components/search/_search.scss +7 -7
  133. package/components/section-navigation/_macro.njk +7 -2
  134. package/components/section-navigation/_macro.spec.js +206 -0
  135. package/components/select/_macro.njk +3 -3
  136. package/components/select/_macro.spec.js +203 -0
  137. package/components/select/select.spec.js +56 -0
  138. package/components/share-page/_macro.njk +6 -4
  139. package/components/share-page/_macro.spec.js +110 -0
  140. package/components/skip-to-content/_macro.spec.js +57 -0
  141. package/components/skip-to-content/skip-to-content.spec.js +44 -0
  142. package/components/status/_macro.spec.js +77 -0
  143. package/components/summary/_macro.njk +5 -5
  144. package/components/summary/_macro.spec.js +472 -0
  145. package/components/table/_macro.njk +2 -2
  146. package/components/table/_macro.spec.js +557 -0
  147. package/components/table/table.spec.js +155 -0
  148. package/components/table-of-contents/_macro.njk +35 -35
  149. package/components/table-of-contents/_macro.spec.js +178 -0
  150. package/components/table-of-contents/toc.js +29 -25
  151. package/components/table-of-contents/toc.spec.js +61 -0
  152. package/components/tabs/_macro.njk +1 -1
  153. package/components/tabs/_macro.spec.js +79 -0
  154. package/components/tabs/tabs.spec.js +162 -0
  155. package/components/text-indent/_macro.spec.js +52 -0
  156. package/components/textarea/_macro.njk +5 -3
  157. package/components/textarea/_macro.spec.js +300 -0
  158. package/components/textarea/textarea.spec.js +98 -0
  159. package/components/timeline/_macro.njk +3 -3
  160. package/components/timeline/_macro.spec.js +81 -0
  161. package/components/timeout-modal/_macro.spec.js +68 -0
  162. package/components/timeout-modal/timeout-modal.spec.js +226 -0
  163. package/components/timeout-panel/_macro.njk +0 -1
  164. package/components/timeout-panel/_macro.spec.js +54 -0
  165. package/components/timeout-panel/timeout-panel.dom.js +1 -2
  166. package/components/timeout-panel/timeout-panel.spec.js +161 -0
  167. package/components/upload/_macro.spec.js +75 -0
  168. package/components/video/_macro.spec.js +34 -0
  169. package/css/census.css +3 -1
  170. package/css/ids.css +2 -0
  171. package/css/main.css +1 -1
  172. package/img/dummy-brand-logo.svg +1 -0
  173. package/js/cookies-settings.spec.js +154 -0
  174. package/layout/_template.njk +7 -4
  175. package/package.json +10 -23
  176. package/scripts/main.es5.js +2 -2
  177. package/scripts/main.js +1 -1
  178. package/scss/ids.scss +2 -0
  179. package/scss/settings/_census.scss +141 -0
  180. package/scss/settings/_ids.scss +48 -0
  181. package/scss/utilities/_margin.scss +1 -0
  182. package/scss/vars/_colors.scss +5 -2
@@ -0,0 +1,618 @@
1
+ /** @jest-environment jsdom */
2
+
3
+ import * as cheerio from 'cheerio';
4
+
5
+ import axe from '../../tests/helpers/axe';
6
+ import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
7
+ import { mapAll } from '../../tests/helpers/cheerio';
8
+
9
+ const EXAMPLE_HEADER_BASIC = {
10
+ title: 'Header title',
11
+ };
12
+
13
+ const EXAMPLE_SERVICE_LINKS_CONFIG = {
14
+ id: 'service-links',
15
+ ariaLabel: 'Services menu',
16
+ ariaListLabel: 'Menu',
17
+ classes: 'custom-class',
18
+ toggleServicesButton: {
19
+ text: 'Menu',
20
+ ariaLabel: 'Toggle services menu',
21
+ },
22
+ };
23
+
24
+ const EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE = {
25
+ ...EXAMPLE_HEADER_BASIC,
26
+ serviceLinks: {
27
+ ...EXAMPLE_SERVICE_LINKS_CONFIG,
28
+ itemsList: [
29
+ {
30
+ title: 'Title 1',
31
+ url: '#1',
32
+ },
33
+ {
34
+ title: 'Title 2',
35
+ url: '#2',
36
+ },
37
+ {
38
+ title: 'Title 3',
39
+ url: '#3',
40
+ },
41
+ ],
42
+ },
43
+ };
44
+
45
+ const EXAMPLE_HEADER_SERVICE_LINKS_SINGLE = {
46
+ ...EXAMPLE_HEADER_BASIC,
47
+ serviceLinks: {
48
+ ...EXAMPLE_SERVICE_LINKS_CONFIG,
49
+ itemsList: [
50
+ {
51
+ title: 'Title',
52
+ url: '#0',
53
+ },
54
+ ],
55
+ },
56
+ };
57
+
58
+ const EXAMPLE_HEADER_LANGUAGE_CONFIG = {
59
+ language: {
60
+ languages: [
61
+ {
62
+ url: '#0',
63
+ ISOCode: 'en',
64
+ text: 'English',
65
+ buttonAriaLabel: 'Language selector. Current language: English',
66
+ chooseLanguage: 'Choose language',
67
+ current: true,
68
+ },
69
+ {
70
+ url: '#0',
71
+ ISOCode: 'cy',
72
+ text: 'Cymraeg',
73
+ buttonAriaLabel: 'Dewisydd iaith. Iaith gyfredol: Cymraeg',
74
+ chooseLanguage: 'Dewiswch iaith',
75
+ current: false,
76
+ },
77
+ ],
78
+ },
79
+ };
80
+
81
+ const EXAMPLE_HEADER_NAVIGATION_CONFIG = {
82
+ navigation: {
83
+ id: 'main-nav',
84
+ ariaLabel: 'Main menu',
85
+ currentPath: '#home',
86
+ itemsList: [
87
+ {
88
+ title: 'Home',
89
+ url: '#home',
90
+ },
91
+ {
92
+ title: 'Guidance',
93
+ url: '#0',
94
+ },
95
+ ],
96
+ toggleNavigationButton: {
97
+ text: 'Menu',
98
+ ariaLabel: 'Toggle main menu',
99
+ },
100
+ },
101
+ };
102
+
103
+ describe('macro: header', () => {
104
+ describe('mode: basic', () => {
105
+ it('passes jest-axe checks', async () => {
106
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_BASIC));
107
+
108
+ const results = await axe($.html());
109
+ expect(results).toHaveNoViolations();
110
+ });
111
+
112
+ it('has provided variant style classes', () => {
113
+ const $ = cheerio.load(
114
+ renderComponent('header', {
115
+ ...EXAMPLE_HEADER_BASIC,
116
+ variants: ['variant-a', 'variant-b'],
117
+ }),
118
+ );
119
+
120
+ expect($('.ons-header--variant-a').length).toBe(1);
121
+ expect($('.ons-header--variant-b').length).toBe(1);
122
+ });
123
+
124
+ it('has additionally provided `classes`', () => {
125
+ const $ = cheerio.load(
126
+ renderComponent('header', {
127
+ ...EXAMPLE_HEADER_BASIC,
128
+ classes: 'extra-class another-extra-class',
129
+ }),
130
+ );
131
+
132
+ expect($('.ons-header').hasClass('extra-class')).toBe(true);
133
+ expect($('.ons-header').hasClass('another-extra-class')).toBe(true);
134
+ });
135
+
136
+ it('has the correct container if `fullWidth`', () => {
137
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, fullWidth: true }));
138
+
139
+ expect($('.ons-container').hasClass('ons-container--full-width')).toBe(true);
140
+ });
141
+
142
+ it('has the correct container if `wide`', () => {
143
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, wide: true }));
144
+
145
+ expect($('.ons-container').hasClass('ons-container--wide')).toBe(true);
146
+ });
147
+
148
+ it('has the correct masthead logo link', () => {
149
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, orgLogoHref: '#0' }));
150
+
151
+ expect($('.ons-header__org-logo-link').attr('href')).toBe('#0');
152
+ });
153
+
154
+ it('has the default masthead logo icon', () => {
155
+ const faker = templateFaker();
156
+ const iconsSpy = faker.spy('icons');
157
+
158
+ faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
159
+
160
+ expect(iconsSpy.occurrences[0].iconType).toBe('ons-logo-en');
161
+ });
162
+
163
+ it('has the provided masthead logo icon', () => {
164
+ const faker = templateFaker();
165
+ const iconsSpy = faker.spy('icons');
166
+
167
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, orgLogo: 'another-logo' });
168
+
169
+ expect(iconsSpy.occurrences[0].iconType).toBe('another-logo');
170
+ });
171
+
172
+ it('has the default masthead logo icon alt text', () => {
173
+ const faker = templateFaker();
174
+ const iconsSpy = faker.spy('icons');
175
+
176
+ faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
177
+
178
+ expect(iconsSpy.occurrences[0].altText).toBe('Office for National Statistics logo');
179
+ });
180
+
181
+ it('has the provided masthead logo icon alt text', () => {
182
+ const faker = templateFaker();
183
+ const iconsSpy = faker.spy('icons');
184
+
185
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, orgLogoAlt: 'Custom alt text' });
186
+
187
+ expect(iconsSpy.occurrences[0].altText).toBe('Custom alt text');
188
+ });
189
+
190
+ it('has the default masthead mobile logo icon', () => {
191
+ const faker = templateFaker();
192
+ const iconsSpy = faker.spy('icons');
193
+
194
+ faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
195
+
196
+ expect(iconsSpy.occurrences[1].iconType).toBe('ons-logo-stacked-en');
197
+ });
198
+
199
+ it('has the provided masthead mobile logo icon', () => {
200
+ const faker = templateFaker();
201
+ const iconsSpy = faker.spy('icons');
202
+
203
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, orgMobileLogo: 'another-mobile-logo' });
204
+
205
+ expect(iconsSpy.occurrences[1].iconType).toBe('another-mobile-logo');
206
+ });
207
+
208
+ it('has the default masthead mobile logo icon alt text', () => {
209
+ const faker = templateFaker();
210
+ const iconsSpy = faker.spy('icons');
211
+
212
+ faker.renderComponent('header', EXAMPLE_HEADER_BASIC);
213
+
214
+ expect(iconsSpy.occurrences[1].altText).toBe('Office for National Statistics logo');
215
+ });
216
+
217
+ it('has the provided masthead mobile logo icon alt text', () => {
218
+ const faker = templateFaker();
219
+ const iconsSpy = faker.spy('icons');
220
+
221
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, orgLogoAlt: 'Custom alt text' });
222
+
223
+ expect(iconsSpy.occurrences[1].altText).toBe('Custom alt text');
224
+ });
225
+
226
+ it('displays the `title` text', () => {
227
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_BASIC));
228
+
229
+ expect($('.ons-header__title').text()).toBe('Header title');
230
+ });
231
+
232
+ it('displays the `title` using the default tag', () => {
233
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_BASIC));
234
+
235
+ expect($('.ons-header__title')[0].tagName).toBe('div');
236
+ });
237
+
238
+ it('displays the `title` using a H1 if `titleAsH1`', () => {
239
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, titleAsH1: true }));
240
+
241
+ expect($('.ons-header__title')[0].tagName).toBe('h1');
242
+ });
243
+
244
+ it('has the correct `title` link', () => {
245
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, titleLogoHref: '#0' }));
246
+
247
+ expect($('.ons-header__title-link').attr('href')).toBe('#0');
248
+ });
249
+
250
+ it('has the provided title logo icon', () => {
251
+ const faker = templateFaker();
252
+ const iconsSpy = faker.spy('icons');
253
+
254
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, titleLogo: 'custom-title-logo', titleLogoAlt: 'custom logo alt' });
255
+
256
+ expect(iconsSpy.occurrences[2].iconType).toBe('custom-title-logo');
257
+ });
258
+
259
+ it('has the provided title logo classes', () => {
260
+ const $ = cheerio.load(
261
+ renderComponent('header', {
262
+ ...EXAMPLE_HEADER_BASIC,
263
+ titleLogo: 'custom-title-logo',
264
+ titleLogoClasses: 'custom-class',
265
+ titleLogoAlt: 'custom logo alt',
266
+ }),
267
+ );
268
+
269
+ expect($('.ons-header__title-logo--large').hasClass('custom-class')).toBe(true);
270
+ });
271
+
272
+ it('has the provided title logo mobile icon', () => {
273
+ const faker = templateFaker();
274
+ const iconsSpy = faker.spy('icons');
275
+
276
+ faker.renderComponent('header', {
277
+ ...EXAMPLE_HEADER_BASIC,
278
+ titleLogo: 'custom-title-logo',
279
+ titleLogoMobile: 'custom-title-mobile-logo',
280
+ titleLogoAlt: 'custom logo alt',
281
+ });
282
+
283
+ expect(iconsSpy.occurrences[3].iconType).toBe('custom-title-mobile-logo');
284
+ });
285
+
286
+ it('has the provided title logo mobile classes', () => {
287
+ const $ = cheerio.load(
288
+ renderComponent('header', {
289
+ ...EXAMPLE_HEADER_BASIC,
290
+ titleLogo: 'custom-title-logo',
291
+ titleLogoMobile: 'custom-title-mobile-logo',
292
+ titleLogoMobileClasses: 'custom-mobile-class',
293
+ titleLogoAlt: 'custom logo alt',
294
+ }),
295
+ );
296
+
297
+ expect($('.ons-header__title-logo--mobile').hasClass('custom-mobile-class')).toBe(true);
298
+ });
299
+
300
+ it('displays the `description` text', () => {
301
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, description: 'Header description' }));
302
+
303
+ expect($('.ons-header__description').text()).toBe('Header description');
304
+ });
305
+
306
+ it('renders a button with expected parameters', () => {
307
+ const faker = templateFaker();
308
+ const buttonSpy = faker.spy('button', { suppressOutput: true });
309
+
310
+ faker.renderComponent('header', {
311
+ ...EXAMPLE_HEADER_BASIC,
312
+ button: {
313
+ text: 'Save and sign out',
314
+ name: 'button-name',
315
+ attributes: {
316
+ a: 'b',
317
+ },
318
+ url: '#0',
319
+ iconType: 'button-icon',
320
+ iconPosition: 'before',
321
+ },
322
+ });
323
+
324
+ expect(buttonSpy.occurrences).toContainEqual({
325
+ text: 'Save and sign out',
326
+ classes: 'ons-u-d-no@xxs@m',
327
+ variants: 'ghost',
328
+ name: 'button-name',
329
+ attributes: {
330
+ a: 'b',
331
+ },
332
+ url: '#0',
333
+ iconType: 'button-icon',
334
+ iconPosition: 'before',
335
+ });
336
+ });
337
+
338
+ it('renders the phase banner with expected parameters', () => {
339
+ const faker = templateFaker();
340
+ const phaseSpy = faker.spy('phase-banner');
341
+
342
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, phase: { html: 'Example content with a <a href="#">link</a>' } });
343
+
344
+ expect(phaseSpy.occurrences).toContainEqual({
345
+ html: 'Example content with a <a href="#">link</a>',
346
+ });
347
+ });
348
+ });
349
+
350
+ describe('mode: with service links', () => {
351
+ it('has the correct display class when multiple links are provided', () => {
352
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
353
+
354
+ expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@m')).toBe(true);
355
+ });
356
+
357
+ it('has the correct display class when a single link and language is provided', () => {
358
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_SERVICE_LINKS_SINGLE, ...EXAMPLE_HEADER_LANGUAGE_CONFIG }));
359
+
360
+ expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@xs')).toBe(true);
361
+ });
362
+
363
+ it('does not have the display class when only single link is provided', () => {
364
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
365
+
366
+ expect($('.ons-header__links .ons-grid__col').hasClass('ons-u-d-no@xxs@')).toBe(false);
367
+ });
368
+
369
+ it('has the provided custom class', () => {
370
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
371
+
372
+ expect($('.ons-header-service-nav--main').hasClass('custom-class')).toBe(true);
373
+ });
374
+
375
+ it('has the provided `aria-label`', () => {
376
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
377
+
378
+ expect($('.ons-header-service-nav--main').attr('aria-label')).toBe('Services menu');
379
+ });
380
+
381
+ it('has the provided `aria-label` for the list', () => {
382
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
383
+
384
+ expect($('.ons-header-service-nav--main .ons-header-service-nav__list').attr('aria-label')).toBe('Menu');
385
+ });
386
+
387
+ it('has the link text for each list item', () => {
388
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
389
+
390
+ const values = mapAll($('.ons-header-service-nav--main .ons-header-service-nav__link'), node => node.text().trim());
391
+ expect(values).toEqual(['Title 1', 'Title 2', 'Title 3']);
392
+ });
393
+
394
+ it('has the link href for each list item', () => {
395
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
396
+
397
+ const values = mapAll($('.ons-header-service-nav--main .ons-header-service-nav__link'), node => node.attr('href'));
398
+ expect(values).toEqual(['#1', '#2', '#3']);
399
+ });
400
+
401
+ it('has the provided custom class', () => {
402
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
403
+
404
+ expect($('.ons-header-service-nav--main').hasClass('custom-class')).toBe(true);
405
+ });
406
+
407
+ it('has the provided `aria-label` for the list for mobile', () => {
408
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
409
+
410
+ expect($('.ons-header-service-nav--mobile').attr('aria-label')).toBe('Services menu');
411
+ });
412
+
413
+ it('has the provided `aria-label` for the list for mobile', () => {
414
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
415
+
416
+ expect($('.ons-header-service-nav--mobile .ons-header-service-nav__list').attr('aria-label')).toBe('Menu');
417
+ });
418
+
419
+ it('has the link text for each list item for mobile', () => {
420
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
421
+
422
+ const values = mapAll($('.ons-header-service-nav--mobile .ons-header-service-nav__link'), node => node.text().trim());
423
+ expect(values).toEqual(['Title 1', 'Title 2', 'Title 3']);
424
+ });
425
+
426
+ it('has the link href for each list item for mobile', () => {
427
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE));
428
+
429
+ const values = mapAll($('.ons-header-service-nav--mobile .ons-header-service-nav__link'), node => node.attr('href'));
430
+ expect(values).toEqual(['#1', '#2', '#3']);
431
+ });
432
+
433
+ it('renders a button with expected parameters', () => {
434
+ const faker = templateFaker();
435
+ const buttonSpy = faker.spy('button', { suppressOutput: true });
436
+
437
+ faker.renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_MULTIPLE);
438
+
439
+ expect(buttonSpy.occurrences).toContainEqual({
440
+ text: 'Menu',
441
+ classes: 'ons-u-d-no ons-js-toggle-services',
442
+ type: 'button',
443
+ buttonStyle: 'mobile',
444
+ variants: 'text-link',
445
+ attributes: {
446
+ 'aria-label': 'Toggle services menu',
447
+ 'aria-controls': 'service-links',
448
+ 'aria-haspopup': 'true',
449
+ 'aria-expanded': 'false',
450
+ },
451
+ });
452
+ });
453
+
454
+ it('renders a button with correct variant if `internal`', () => {
455
+ const faker = templateFaker();
456
+ const buttonSpy = faker.spy('button');
457
+
458
+ faker.renderComponent('header', {
459
+ ...EXAMPLE_HEADER_BASIC,
460
+ variants: 'internal',
461
+ serviceLinks: {
462
+ ...EXAMPLE_SERVICE_LINKS_CONFIG,
463
+ itemsList: [
464
+ {
465
+ title: 'Title',
466
+ url: '#0',
467
+ },
468
+ {
469
+ title: 'Title 2',
470
+ url: '#0',
471
+ },
472
+ ],
473
+ },
474
+ });
475
+
476
+ expect(buttonSpy.occurrences[0]).toHaveProperty('variants', ['text-link', 'text-link-inverse']);
477
+ });
478
+
479
+ it('does not render a button for a single services link', () => {
480
+ const $ = cheerio.load(renderComponent('header', EXAMPLE_HEADER_SERVICE_LINKS_SINGLE));
481
+
482
+ expect($('.ons-js-toggle-services').length).toBe(0);
483
+ });
484
+ });
485
+
486
+ describe('mode: with language selector', () => {
487
+ it('displays the language selector with expected parameters', () => {
488
+ const faker = templateFaker();
489
+ const languageSpy = faker.spy('language-selector', { suppressOutput: true });
490
+
491
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_LANGUAGE_CONFIG });
492
+
493
+ expect(languageSpy.occurrences).toContainEqual({
494
+ languages: [
495
+ {
496
+ url: '#0',
497
+ ISOCode: 'en',
498
+ text: 'English',
499
+ buttonAriaLabel: 'Language selector. Current language: English',
500
+ chooseLanguage: 'Choose language',
501
+ current: true,
502
+ },
503
+ {
504
+ url: '#0',
505
+ ISOCode: 'cy',
506
+ text: 'Cymraeg',
507
+ buttonAriaLabel: 'Dewisydd iaith. Iaith gyfredol: Cymraeg',
508
+ chooseLanguage: 'Dewiswch iaith',
509
+ current: false,
510
+ },
511
+ ],
512
+ });
513
+ });
514
+ });
515
+
516
+ describe('mode: with navigation', () => {
517
+ it('renders the navigation with expected parameters', () => {
518
+ const faker = templateFaker();
519
+ const navigationSpy = faker.spy('navigation', { suppressOutput: true });
520
+
521
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_NAVIGATION_CONFIG });
522
+
523
+ expect(navigationSpy.occurrences[0]).toEqual({
524
+ navigation: {
525
+ id: 'main-nav',
526
+ ariaLabel: 'Main menu',
527
+ currentPath: '#home',
528
+ itemsList: [
529
+ {
530
+ title: 'Home',
531
+ url: '#home',
532
+ },
533
+ {
534
+ title: 'Guidance',
535
+ url: '#0',
536
+ },
537
+ ],
538
+ toggleNavigationButton: {
539
+ text: 'Menu',
540
+ ariaLabel: 'Toggle main menu',
541
+ },
542
+ },
543
+ title: 'Header title',
544
+ });
545
+ });
546
+
547
+ it('renders a button to toggle the menu on mobile', () => {
548
+ const faker = templateFaker();
549
+ const buttonSpy = faker.spy('button');
550
+
551
+ faker.renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_NAVIGATION_CONFIG });
552
+
553
+ expect(buttonSpy.occurrences[0]).toEqual({
554
+ text: 'Menu',
555
+ classes: 'ons-u-ml-xs ons-u-d-no ons-js-navigation-button ons-u-d-no@l',
556
+ buttonStyle: 'mobile',
557
+ variants: ['mobile', 'ghost'],
558
+ attributes: {
559
+ 'aria-label': 'Toggle main menu',
560
+ 'aria-controls': 'main-nav',
561
+ 'aria-haspopup': 'true',
562
+ 'aria-expanded': 'false',
563
+ },
564
+ });
565
+ });
566
+
567
+ it('renders a button to toggle the search on mobile', () => {
568
+ const faker = templateFaker();
569
+ const buttonSpy = faker.spy('button');
570
+
571
+ faker.renderComponent('header', {
572
+ ...EXAMPLE_HEADER_BASIC,
573
+ navigation: {
574
+ id: 'main-nav',
575
+ ariaLabel: 'Main menu',
576
+ currentPath: '#home',
577
+ itemsList: [
578
+ {
579
+ title: 'Home',
580
+ url: '#home',
581
+ },
582
+ {
583
+ title: 'Guidance',
584
+ url: '#0',
585
+ },
586
+ ],
587
+ toggleNavigationButton: {
588
+ text: 'Menu',
589
+ ariaLabel: 'Toggle main menu',
590
+ },
591
+ siteSearchAutosuggest: {},
592
+ },
593
+ });
594
+
595
+ expect(buttonSpy.occurrences[0]).toEqual({
596
+ text: 'Search',
597
+ classes: 'ons-btn--search ons-u-ml-xs ons-u-d-no ons-js-toggle-search',
598
+ variants: ['small', 'ghost'],
599
+ iconType: 'search',
600
+ iconPosition: 'only',
601
+ attributes: {
602
+ 'aria-label': 'Toggle search',
603
+ 'aria-controls': 'ons-site-search',
604
+ 'aria-haspopup': 'true',
605
+ 'aria-expanded': 'false',
606
+ },
607
+ });
608
+ });
609
+ });
610
+
611
+ describe('mode: without masthead', () => {
612
+ it('does not render the masthead', () => {
613
+ const $ = cheerio.load(renderComponent('header', { ...EXAMPLE_HEADER_BASIC, ...EXAMPLE_HEADER_LANGUAGE_CONFIG, noMasthead: true }));
614
+
615
+ expect($('.ons-header__top').length).toBe(0);
616
+ });
617
+ });
618
+ });