@ons/design-system 70.0.6 → 70.0.8

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 (308) hide show
  1. package/README.md +11 -17
  2. package/components/access-code/_macro.spec.js +145 -145
  3. package/components/access-code/access-code.dom.js +5 -5
  4. package/components/access-code/access-code.js +16 -16
  5. package/components/access-code/access-code.scss +22 -22
  6. package/components/access-code/access-code.spec.js +17 -17
  7. package/components/accordion/_macro.spec.js +154 -154
  8. package/components/accordion/accordion.dom.js +10 -10
  9. package/components/accordion/accordion.js +50 -50
  10. package/components/accordion/accordion.spec.js +104 -104
  11. package/components/address-input/_macro.spec.js +420 -420
  12. package/components/address-input/autosuggest.address.dom.js +5 -5
  13. package/components/address-input/autosuggest.address.error.js +77 -77
  14. package/components/address-input/autosuggest.address.js +357 -357
  15. package/components/address-input/autosuggest.address.setter.js +95 -95
  16. package/components/address-input/autosuggest.address.spec.js +668 -651
  17. package/components/address-input/example-address-input-editable.njk +1 -1
  18. package/components/address-input/example-address-input.njk +1 -1
  19. package/components/address-output/_address-output.scss +3 -3
  20. package/components/address-output/_macro.spec.js +84 -84
  21. package/components/autosuggest/_autosuggest.scss +114 -114
  22. package/components/autosuggest/_macro.spec.js +255 -255
  23. package/components/autosuggest/autosuggest.dom.js +5 -5
  24. package/components/autosuggest/autosuggest.helpers.js +11 -11
  25. package/components/autosuggest/autosuggest.helpers.spec.js +73 -73
  26. package/components/autosuggest/autosuggest.js +20 -20
  27. package/components/autosuggest/autosuggest.spec.js +542 -536
  28. package/components/autosuggest/autosuggest.ui.js +478 -475
  29. package/components/autosuggest/fuse-config.js +17 -17
  30. package/components/back-to-top/_back-to-top.scss +27 -27
  31. package/components/back-to-top/_macro.spec.js +49 -49
  32. package/components/back-to-top/back-to-top.dom.js +5 -5
  33. package/components/back-to-top/back-to-top.js +52 -52
  34. package/components/back-to-top/back-to-top.spec.js +106 -106
  35. package/components/back-to-top/example-back-to-top.njk +6 -6
  36. package/components/breadcrumbs/_breadcrumbs.scss +63 -65
  37. package/components/breadcrumbs/_macro.spec.js +91 -91
  38. package/components/browser-banner/_browser-banner.scss +23 -23
  39. package/components/browser-banner/_macro.spec.js +92 -92
  40. package/components/button/_button.scss +482 -483
  41. package/components/button/_macro.spec.js +363 -363
  42. package/components/button/button.dom.js +15 -15
  43. package/components/button/button.js +53 -53
  44. package/components/button/button.spec.js +248 -240
  45. package/components/call-to-action/_call-to-action.scss +5 -5
  46. package/components/call-to-action/_macro.spec.js +28 -28
  47. package/components/card/_card.scss +23 -23
  48. package/components/card/_macro.spec.js +180 -180
  49. package/components/char-check-limit/_macro.spec.js +48 -48
  50. package/components/char-check-limit/character-check.js +58 -58
  51. package/components/char-check-limit/character-check.spec.js +173 -173
  52. package/components/char-check-limit/character-limit.js +40 -40
  53. package/components/checkboxes/_checkbox-macro.spec.js +355 -355
  54. package/components/checkboxes/_checkbox.scss +180 -180
  55. package/components/checkboxes/_checkboxes.scss +37 -27
  56. package/components/checkboxes/_macro.spec.js +261 -261
  57. package/components/checkboxes/checkbox-with-autoselect.js +32 -32
  58. package/components/checkboxes/checkbox-with-fieldset.js +21 -21
  59. package/components/checkboxes/checkboxes-with-reveal.js +10 -10
  60. package/components/checkboxes/checkboxes.dom.js +27 -27
  61. package/components/checkboxes/checkboxes.spec.js +183 -183
  62. package/components/content-pagination/_content-pagination.scss +41 -41
  63. package/components/content-pagination/_macro.spec.js +159 -159
  64. package/components/cookies-banner/_cookies-banner.scss +22 -22
  65. package/components/cookies-banner/_macro.spec.js +177 -177
  66. package/components/cookies-banner/cookies-banner.dom.js +7 -7
  67. package/components/cookies-banner/cookies-banner.js +76 -76
  68. package/components/cookies-banner/cookies-banner.spec.js +72 -68
  69. package/components/date-input/_macro.spec.js +338 -338
  70. package/components/description-list/_description-list.scss +23 -23
  71. package/components/description-list/_macro.spec.js +144 -144
  72. package/components/details/_details.scss +109 -109
  73. package/components/details/_macro.spec.js +132 -132
  74. package/components/details/details.dom.js +6 -6
  75. package/components/details/details.js +60 -60
  76. package/components/details/details.spec.js +106 -106
  77. package/components/document-list/_macro.spec.js +444 -444
  78. package/components/document-list/document-list.scss +145 -149
  79. package/components/download-resources/_download-resources.scss +109 -108
  80. package/components/download-resources/download-resources.js +907 -900
  81. package/components/download-resources/download-resources.spec.js +461 -461
  82. package/components/duration/_macro.spec.js +291 -291
  83. package/components/error/_macro.spec.js +72 -72
  84. package/components/external-link/_external-link.scss +19 -19
  85. package/components/external-link/_macro.spec.js +68 -68
  86. package/components/feedback/_feedback.scss +31 -31
  87. package/components/feedback/_macro.spec.js +72 -72
  88. package/components/field/_field-group.scss +10 -10
  89. package/components/field/_field.scss +16 -16
  90. package/components/field/_macro.spec.js +80 -80
  91. package/components/fieldset/_fieldset.scss +27 -27
  92. package/components/fieldset/_macro.spec.js +161 -161
  93. package/components/footer/_footer.scss +45 -45
  94. package/components/footer/_macro.spec.js +452 -452
  95. package/components/header/_header.scss +202 -202
  96. package/components/header/_macro.spec.js +833 -829
  97. package/components/helpers/_grid.scss +4 -4
  98. package/components/hero/_hero.scss +48 -48
  99. package/components/hero/_macro.spec.js +59 -59
  100. package/components/icon/_icon.scss +44 -44
  101. package/components/icon/_macro.spec.js +110 -110
  102. package/components/image/_image.scss +11 -11
  103. package/components/image/_macro.spec.js +81 -81
  104. package/components/input/_input-type.scss +86 -89
  105. package/components/input/_input.scss +123 -124
  106. package/components/input/_macro.spec.js +604 -604
  107. package/components/input/character-check.dom.js +5 -5
  108. package/components/input/input.dom.js +5 -5
  109. package/components/input/input.js +10 -10
  110. package/components/input/input.spec.js +18 -18
  111. package/components/label/_label.scss +24 -24
  112. package/components/label/_macro.spec.js +173 -170
  113. package/components/language-selector/_macro.spec.js +97 -97
  114. package/components/language-selector/language.scss +7 -7
  115. package/components/list/_list.scss +84 -84
  116. package/components/list/_macro.njk +2 -2
  117. package/components/list/_macro.spec.js +583 -583
  118. package/components/message/_macro.njk +5 -5
  119. package/components/message/_macro.spec.js +74 -74
  120. package/components/message/_message.scss +39 -39
  121. package/components/message-list/_macro.spec.js +86 -86
  122. package/components/message-list/_message-list.scss +16 -16
  123. package/components/modal/_macro.spec.js +69 -69
  124. package/components/modal/_modal.scss +36 -36
  125. package/components/modal/modal.dom.js +6 -6
  126. package/components/modal/modal.js +89 -89
  127. package/components/modal/modal.spec.js +50 -50
  128. package/components/mutually-exclusive/_macro.spec.js +140 -140
  129. package/components/mutually-exclusive/mutually-exclusive.checkboxes.spec.js +188 -188
  130. package/components/mutually-exclusive/mutually-exclusive.date.spec.js +211 -211
  131. package/components/mutually-exclusive/mutually-exclusive.dom.js +5 -5
  132. package/components/mutually-exclusive/mutually-exclusive.duration.spec.js +210 -210
  133. package/components/mutually-exclusive/mutually-exclusive.email.spec.js +90 -90
  134. package/components/mutually-exclusive/mutually-exclusive.js +137 -137
  135. package/components/mutually-exclusive/mutually-exclusive.multiple-options.checkboxes.spec.js +197 -197
  136. package/components/mutually-exclusive/mutually-exclusive.number.spec.js +96 -96
  137. package/components/mutually-exclusive/mutually-exclusive.textarea.spec.js +102 -102
  138. package/components/navigation/_macro.spec.js +360 -354
  139. package/components/navigation/_navigation.scss +122 -123
  140. package/components/navigation/navigation.dom.js +35 -35
  141. package/components/navigation/navigation.js +49 -49
  142. package/components/navigation/navigation.spec.js +249 -249
  143. package/components/pagination/_macro.spec.js +342 -335
  144. package/components/pagination/_pagination.scss +58 -58
  145. package/components/panel/_macro.spec.js +372 -372
  146. package/components/panel/_panel.scss +200 -199
  147. package/components/password/_macro.spec.js +95 -95
  148. package/components/password/password.dom.js +5 -5
  149. package/components/password/password.js +10 -10
  150. package/components/password/password.spec.js +26 -26
  151. package/components/phase-banner/_macro.spec.js +86 -86
  152. package/components/phase-banner/_phase-banner.scss +16 -16
  153. package/components/question/_macro.spec.js +235 -235
  154. package/components/question/_question.scss +24 -24
  155. package/components/quote/_macro.spec.js +52 -52
  156. package/components/quote/_quote.scss +24 -24
  157. package/components/radios/_macro.spec.js +524 -524
  158. package/components/radios/_radio.scss +49 -48
  159. package/components/radios/_radios.scss +14 -20
  160. package/components/radios/check-radios.js +21 -21
  161. package/components/radios/clear-radios.js +45 -45
  162. package/components/radios/radio-with-fieldset.js +22 -22
  163. package/components/radios/radios.dom.js +32 -32
  164. package/components/radios/radios.spec.js +251 -251
  165. package/components/related-content/_macro.spec.js +109 -109
  166. package/components/related-content/_related-content.scss +12 -12
  167. package/components/related-content/_section-macro.spec.js +20 -20
  168. package/components/relationships/_macro.spec.js +94 -94
  169. package/components/relationships/_relationships.scss +9 -9
  170. package/components/relationships/relationships.dom.js +5 -5
  171. package/components/relationships/relationships.js +18 -18
  172. package/components/relationships/relationships.spec.js +71 -71
  173. package/components/reply/_macro.spec.js +47 -47
  174. package/components/reply/reply-input.js +15 -15
  175. package/components/reply/reply.dom.js +5 -5
  176. package/components/reply/reply.spec.js +57 -57
  177. package/components/section-navigation/_macro.spec.js +210 -210
  178. package/components/section-navigation/_section-navigation.scss +76 -76
  179. package/components/select/_macro.spec.js +166 -166
  180. package/components/share-page/_macro.spec.js +68 -68
  181. package/components/skip-to-content/_macro.spec.js +54 -54
  182. package/components/skip-to-content/_skip.scss +30 -30
  183. package/components/skip-to-content/skip-to-content.dom.js +6 -6
  184. package/components/skip-to-content/skip-to-content.js +7 -7
  185. package/components/skip-to-content/skip-to-content.spec.js +21 -21
  186. package/components/status/_macro.spec.js +53 -53
  187. package/components/status/_status.scss +32 -32
  188. package/components/summary/_macro.spec.js +551 -535
  189. package/components/summary/_summary.scss +191 -195
  190. package/components/table/_macro.spec.js +499 -499
  191. package/components/table/_table.scss +204 -201
  192. package/components/table/scrollable-table.dom.js +5 -5
  193. package/components/table/scrollable-table.js +60 -60
  194. package/components/table/sortable-table.dom.js +5 -5
  195. package/components/table/sortable-table.js +135 -135
  196. package/components/table/table.spec.js +144 -140
  197. package/components/table-of-contents/_macro.spec.js +125 -125
  198. package/components/table-of-contents/_toc.scss +9 -9
  199. package/components/table-of-contents/toc.dom.js +5 -5
  200. package/components/table-of-contents/toc.js +30 -30
  201. package/components/table-of-contents/toc.spec.js +88 -88
  202. package/components/tabs/_macro.spec.js +92 -92
  203. package/components/tabs/_tabs.scss +120 -115
  204. package/components/tabs/tabs.dom.js +5 -5
  205. package/components/tabs/tabs.js +266 -266
  206. package/components/tabs/tabs.spec.js +268 -268
  207. package/components/text-indent/_macro.spec.js +33 -33
  208. package/components/text-indent/_text-indent.scss +3 -3
  209. package/components/textarea/_macro.spec.js +238 -238
  210. package/components/textarea/textarea.dom.js +5 -5
  211. package/components/textarea/textarea.spec.js +78 -74
  212. package/components/timeline/_macro.spec.js +83 -83
  213. package/components/timeline/_timeline.scss +26 -26
  214. package/components/timeout-modal/_macro.spec.js +47 -47
  215. package/components/timeout-modal/timeout-modal.dom.js +9 -9
  216. package/components/timeout-modal/timeout-modal.js +66 -66
  217. package/components/timeout-modal/timeout-modal.spec.js +157 -157
  218. package/components/timeout-panel/_macro.spec.js +41 -41
  219. package/components/timeout-panel/timeout-panel.dom.js +8 -8
  220. package/components/timeout-panel/timeout-panel.spec.js +118 -118
  221. package/components/upload/_macro.spec.js +52 -52
  222. package/components/upload/_upload.scss +28 -28
  223. package/components/video/_macro.spec.js +42 -42
  224. package/components/video/_video.scss +16 -16
  225. package/components/video/video.dom.js +5 -5
  226. package/components/video/video.js +32 -32
  227. package/components/video/video.spec.js +103 -97
  228. package/css/main.css +1 -1
  229. package/favicons/android-chrome-192x192.png +0 -0
  230. package/favicons/android-chrome-512x512.png +0 -0
  231. package/favicons/apple-touch-icon.png +0 -0
  232. package/favicons/favicon-16x16.png +0 -0
  233. package/favicons/favicon-32x32.png +0 -0
  234. package/favicons/favicon.ico +0 -0
  235. package/favicons/manifest.json +25 -25
  236. package/favicons/maskable_icon.png +0 -0
  237. package/favicons/opengraph.png +0 -0
  238. package/favicons/twitter.png +0 -0
  239. package/img/large/alison-pritchard-featured.jpg +0 -0
  240. package/img/large/alison-pritchard.jpg +0 -0
  241. package/img/large/census-monuments-lights-featured.jpg +0 -0
  242. package/img/large/census-monuments-lights.jpg +0 -0
  243. package/img/large/mother-and-daughter-in-ireland.jpg +0 -0
  244. package/img/large/mum-and-child-healthcare-belfast.jpg +0 -0
  245. package/img/large/ons-award-winners.jpg +0 -0
  246. package/img/large/placeholder-card.png +0 -0
  247. package/img/large/placeholder-news-medium.png +0 -0
  248. package/img/large/placeholder-news.png +0 -0
  249. package/img/large/placeholder-portrait.png +0 -0
  250. package/img/large/students.jpg +0 -0
  251. package/img/large/woman-in-purple-dress-shirt.jpg +0 -0
  252. package/img/small/alison-pritchard-featured.jpg +0 -0
  253. package/img/small/alison-pritchard.jpg +0 -0
  254. package/img/small/census-monuments-lights-featured.jpg +0 -0
  255. package/img/small/census-monuments-lights.jpg +0 -0
  256. package/img/small/mother-and-daughter-in-ireland.jpg +0 -0
  257. package/img/small/mum-and-child-healthcare-belfast.jpg +0 -0
  258. package/img/small/ons-award-winners.jpg +0 -0
  259. package/img/small/placeholder-card.png +0 -0
  260. package/img/small/placeholder-news-medium.png +0 -0
  261. package/img/small/placeholder-news.png +0 -0
  262. package/img/small/placeholder-portrait.png +0 -0
  263. package/img/small/students.jpg +0 -0
  264. package/img/small/woman-in-purple-dress-shirt.jpg +0 -0
  265. package/js/abortable-fetch.js +23 -23
  266. package/js/analytics.js +53 -53
  267. package/js/cookies-functions.js +135 -135
  268. package/js/cookies-settings.dom.js +7 -7
  269. package/js/cookies-settings.js +77 -77
  270. package/js/cookies-settings.spec.js +106 -106
  271. package/js/domready.js +8 -8
  272. package/js/fetch.js +14 -14
  273. package/js/inpagelink.dom.js +5 -5
  274. package/js/inpagelink.js +19 -19
  275. package/js/polyfills.js +0 -1
  276. package/js/print-button.js +6 -6
  277. package/js/timeout.js +211 -211
  278. package/layout/_template.njk +5 -7
  279. package/package.json +131 -127
  280. package/scripts/main.es5.js +1 -1
  281. package/scripts/main.js +1 -1
  282. package/scss/base/_forms.scss +10 -10
  283. package/scss/base/_global.scss +45 -44
  284. package/scss/base/_typography.scss +20 -20
  285. package/scss/helpers/_functions.scss +18 -15
  286. package/scss/helpers/_mixins.scss +59 -53
  287. package/scss/helpers/_mq.scss +62 -65
  288. package/scss/objects/_container.scss +20 -20
  289. package/scss/objects/_page.scss +33 -33
  290. package/scss/objects/_spacing.scss +10 -10
  291. package/scss/overrides/hcm.scss +237 -237
  292. package/scss/overrides/rtl.scss +95 -95
  293. package/scss/print.scss +47 -47
  294. package/scss/utilities/_border.scss +7 -7
  295. package/scss/utilities/_colors.scss +6 -6
  296. package/scss/utilities/_display.scss +8 -8
  297. package/scss/utilities/_float.scss +7 -7
  298. package/scss/utilities/_grid.scss +144 -144
  299. package/scss/utilities/_highlight.scss +4 -4
  300. package/scss/utilities/_margin.scss +17 -17
  301. package/scss/utilities/_pad.scss +15 -15
  302. package/scss/utilities/_typography.scss +35 -33
  303. package/scss/utilities/_utilities.scss +8 -8
  304. package/scss/utilities/_visibility.scss +25 -25
  305. package/scss/vars/_colors.scss +116 -116
  306. package/scss/vars/_forms.scss +22 -22
  307. package/scss/vars/_grid.scss +11 -9
  308. package/scss/vars/_typography.scss +54 -54
@@ -7,566 +7,566 @@ import { mapAll } from '../../tests/helpers/cheerio';
7
7
  import { renderComponent, templateFaker } from '../../tests/helpers/rendering';
8
8
 
9
9
  const EXAMPLE_OGL_LINK_PARAM = {
10
- pre: 'All content is available under the',
11
- link: 'Open Government Licence v3.0',
12
- url: 'https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/',
13
- post: ', except where otherwise stated',
10
+ pre: 'All content is available under the',
11
+ link: 'Open Government Licence v3.0',
12
+ url: 'https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/',
13
+ post: ', except where otherwise stated',
14
14
  };
15
15
 
16
16
  const EXAMPLE_COLS_PARAM = [
17
- {
18
- title: 'First column',
19
- itemsList: [
20
- {
21
- url: '/example-link-a',
22
- text: 'Example Link A',
23
- },
24
- ],
25
- },
26
- {
27
- title: 'Second column',
28
- itemsList: [
29
- {
30
- url: '/example-link-b',
31
- text: 'Example Link B',
32
- },
33
- ],
34
- },
17
+ {
18
+ title: 'First column',
19
+ itemsList: [
20
+ {
21
+ url: '/example-link-a',
22
+ text: 'Example Link A',
23
+ },
24
+ ],
25
+ },
26
+ {
27
+ title: 'Second column',
28
+ itemsList: [
29
+ {
30
+ url: '/example-link-b',
31
+ text: 'Example Link B',
32
+ },
33
+ ],
34
+ },
35
35
  ];
36
36
 
37
37
  const EXAMPLE_ROWS_PARAM = [
38
- {
39
- itemsList: [
40
- {
41
- url: '/example-link-a',
42
- text: 'Example Link A',
43
- },
44
- ],
45
- },
46
- {
47
- itemsList: [
48
- {
49
- url: '/example-link-b',
50
- text: 'Example Link B',
51
- },
52
- ],
53
- },
38
+ {
39
+ itemsList: [
40
+ {
41
+ url: '/example-link-a',
42
+ text: 'Example Link A',
43
+ },
44
+ ],
45
+ },
46
+ {
47
+ itemsList: [
48
+ {
49
+ url: '/example-link-b',
50
+ text: 'Example Link B',
51
+ },
52
+ ],
53
+ },
54
54
  ];
55
55
 
56
56
  const EXAMPLE_LEGAL_PARAM = [
57
- {
58
- itemsList: [
59
- {
60
- url: '/example-legal-link-a',
61
- text: 'Example Legal Link A',
62
- },
63
- ],
64
- },
65
- {
66
- itemsList: [
67
- {
68
- url: '/example-legal-link-b',
69
- text: 'Example Legal Link B',
70
- },
71
- ],
72
- },
57
+ {
58
+ itemsList: [
59
+ {
60
+ url: '/example-legal-link-a',
61
+ text: 'Example Legal Link A',
62
+ },
63
+ ],
64
+ },
65
+ {
66
+ itemsList: [
67
+ {
68
+ url: '/example-legal-link-b',
69
+ text: 'Example Legal Link B',
70
+ },
71
+ ],
72
+ },
73
73
  ];
74
74
 
75
75
  describe('macro: footer', () => {
76
- it('decorates container block with `wide` modifier when the `wide` parameter is provided', () => {
77
- const $ = cheerio.load(
78
- renderComponent('footer', {
79
- wide: true,
80
- }),
81
- );
82
-
83
- const hasClass = $('.ons-container').hasClass('ons-container--wide');
84
- expect(hasClass).toBe(true);
85
- });
86
-
87
- it('does not decorate container block with `wide` modifier when the `wide` parameter is not provided', () => {
88
- const $ = cheerio.load(renderComponent('footer', {}));
89
-
90
- const hasClass = $('.ons-container').hasClass('ons-container--wide');
91
- expect(hasClass).toBe(false);
92
- });
93
-
94
- it('decorates container block with `fullWidth` modifier when the `fullWidth` parameter is provided', () => {
95
- const $ = cheerio.load(
96
- renderComponent('footer', {
97
- fullWidth: true,
98
- }),
99
- );
100
-
101
- const hasClass = $('.ons-container').hasClass('ons-container--full-width');
102
- expect(hasClass).toBe(true);
103
- });
104
-
105
- it('does not decorate container block with `fullWidth` modifier when the `fullWidth` parameter is not provided', () => {
106
- const $ = cheerio.load(renderComponent('footer', {}));
107
-
108
- const hasClass = $('.ons-container').hasClass('ons-container--full-width');
109
- expect(hasClass).toBe(false);
110
- });
111
-
112
- it('has additionally provided `attributes` on the `body` element', () => {
113
- const $ = cheerio.load(
114
- renderComponent('footer', {
115
- attributes: {
116
- a: '123',
117
- b: '456',
118
- },
119
- }),
120
- );
121
-
122
- expect($('.ons-footer__body').attr('a')).toBe('123');
123
- expect($('.ons-footer__body').attr('b')).toBe('456');
124
- });
125
-
126
- describe('OGL link', () => {
127
- const params = {
128
- OGLLink: EXAMPLE_OGL_LINK_PARAM,
129
- };
130
-
131
- it('passes jest-axe checks', async () => {
132
- const $ = cheerio.load(renderComponent('footer', params));
133
-
134
- const results = await axe($.html());
135
- expect(results).toHaveNoViolations();
136
- });
76
+ it('decorates container block with `wide` modifier when the `wide` parameter is provided', () => {
77
+ const $ = cheerio.load(
78
+ renderComponent('footer', {
79
+ wide: true,
80
+ }),
81
+ );
137
82
 
138
- it('renders OGL icon', () => {
139
- const faker = templateFaker();
140
- const iconsSpy = faker.spy('icon');
141
-
142
- faker.renderComponent('footer', params);
143
-
144
- expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining({ iconType: 'ogl' }));
145
- });
146
-
147
- it('renders raw HTML when `HTML` is provided', () => {
148
- const $ = cheerio.load(
149
- renderComponent('footer', {
150
- OGLLink: {
151
- ...params.OGLLink,
152
- HTML: '<strong>Bold text.</strong>',
153
- },
154
- }),
155
- );
156
-
157
- const licenseHtml = $('.ons-footer__license').html();
158
- expect(licenseHtml).toContain('<strong>Bold text.</strong>');
83
+ const hasClass = $('.ons-container').hasClass('ons-container--wide');
84
+ expect(hasClass).toBe(true);
159
85
  });
160
86
 
161
- it('renders link using the external link component', () => {
162
- const faker = templateFaker();
163
- const externalLinkSpy = faker.spy('external-link');
87
+ it('does not decorate container block with `wide` modifier when the `wide` parameter is not provided', () => {
88
+ const $ = cheerio.load(renderComponent('footer', {}));
164
89
 
165
- faker.renderComponent('footer', params);
166
-
167
- expect(externalLinkSpy.occurrences).toContainEqual(
168
- expect.objectContaining({
169
- url: 'https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/',
170
- linkText: 'Open Government Licence v3.0',
171
- }),
172
- );
90
+ const hasClass = $('.ons-container').hasClass('ons-container--wide');
91
+ expect(hasClass).toBe(false);
173
92
  });
174
93
 
175
- it('renders `post` content when provided', () => {
176
- const $ = cheerio.load(renderComponent('footer', params));
94
+ it('decorates container block with `fullWidth` modifier when the `fullWidth` parameter is provided', () => {
95
+ const $ = cheerio.load(
96
+ renderComponent('footer', {
97
+ fullWidth: true,
98
+ }),
99
+ );
177
100
 
178
- const licenseHtml = $('.ons-footer__license').html();
179
- expect(licenseHtml).toContain(', except where otherwise stated');
101
+ const hasClass = $('.ons-container').hasClass('ons-container--full-width');
102
+ expect(hasClass).toBe(true);
180
103
  });
181
104
 
182
- it('renders welsh `post` content when `lang:cy` provided and `OGLLink` is "true"', () => {
183
- const $ = cheerio.load(
184
- renderComponent('footer', {
185
- lang: 'cy',
186
- OGLLink: true,
187
- }),
188
- );
105
+ it('does not decorate container block with `fullWidth` modifier when the `fullWidth` parameter is not provided', () => {
106
+ const $ = cheerio.load(renderComponent('footer', {}));
189
107
 
190
- const licenseHtml = $('.ons-footer__license').html();
191
- expect(licenseHtml).toContain(', oni bai y nodir fel arall');
108
+ const hasClass = $('.ons-container').hasClass('ons-container--full-width');
109
+ expect(hasClass).toBe(false);
192
110
  });
193
- });
194
-
195
- describe('warning', () => {
196
- const params = {
197
- footerWarning: 'Footer warning text with <strong>bold</strong> content.',
198
- };
199
111
 
200
- it('passes jest-axe checks', async () => {
201
- const $ = cheerio.load(renderComponent('footer', params));
112
+ it('has additionally provided `attributes` on the `body` element', () => {
113
+ const $ = cheerio.load(
114
+ renderComponent('footer', {
115
+ attributes: {
116
+ a: '123',
117
+ b: '456',
118
+ },
119
+ }),
120
+ );
202
121
 
203
- const results = await axe($.html());
204
- expect(results).toHaveNoViolations();
122
+ expect($('.ons-footer__body').attr('a')).toBe('123');
123
+ expect($('.ons-footer__body').attr('b')).toBe('456');
205
124
  });
206
125
 
207
- it('renders warning element', () => {
208
- const $ = cheerio.load(renderComponent('footer', params));
126
+ describe('OGL link', () => {
127
+ const params = {
128
+ OGLLink: EXAMPLE_OGL_LINK_PARAM,
129
+ };
209
130
 
210
- const warningHtml = $('.ons-footer__warning').html();
211
- expect(warningHtml).toContain('Footer warning text with <strong>bold</strong> content.');
212
- });
131
+ it('passes jest-axe checks', async () => {
132
+ const $ = cheerio.load(renderComponent('footer', params));
213
133
 
214
- it('is not rendered when `footerWarning` is not provided', () => {
215
- const $ = cheerio.load(renderComponent('footer', {}));
134
+ const results = await axe($.html());
135
+ expect(results).toHaveNoViolations();
136
+ });
216
137
 
217
- expect($('.ons-footer__warning').length).toBe(0);
218
- });
138
+ it('renders OGL icon', () => {
139
+ const faker = templateFaker();
140
+ const iconsSpy = faker.spy('icon');
219
141
 
220
- it('renders warning text using the panel component', () => {
221
- const faker = templateFaker();
222
- const panelSpy = faker.spy('panel');
142
+ faker.renderComponent('footer', params);
223
143
 
224
- faker.renderComponent('footer', params);
144
+ expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining({ iconType: 'ogl' }));
145
+ });
225
146
 
226
- expect(panelSpy.occurrences).toContainEqual(
227
- expect.objectContaining({
228
- variant: 'warn',
229
- classes: 'ons-panel--warn--footer',
230
- }),
231
- );
232
- });
233
- });
147
+ it('renders raw HTML when `HTML` is provided', () => {
148
+ const $ = cheerio.load(
149
+ renderComponent('footer', {
150
+ OGLLink: {
151
+ ...params.OGLLink,
152
+ HTML: '<strong>Bold text.</strong>',
153
+ },
154
+ }),
155
+ );
156
+
157
+ const licenseHtml = $('.ons-footer__license').html();
158
+ expect(licenseHtml).toContain('<strong>Bold text.</strong>');
159
+ });
234
160
 
235
- describe('copyright', () => {
236
- const params = {
237
- copyrightDeclaration: {
238
- copyright: 'Crown copyright and database rights 2020 OS 100019153.',
239
- text: 'Use of address data is subject to the terms and conditions.',
240
- },
241
- };
161
+ it('renders link using the external link component', () => {
162
+ const faker = templateFaker();
163
+ const externalLinkSpy = faker.spy('external-link');
242
164
 
243
- it('passes jest-axe checks', async () => {
244
- const $ = cheerio.load(renderComponent('footer', params));
165
+ faker.renderComponent('footer', params);
245
166
 
246
- const results = await axe($.html());
247
- expect(results).toHaveNoViolations();
248
- });
167
+ expect(externalLinkSpy.occurrences).toContainEqual(
168
+ expect.objectContaining({
169
+ url: 'https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/',
170
+ linkText: 'Open Government Licence v3.0',
171
+ }),
172
+ );
173
+ });
249
174
 
250
- it('renders copyright declaration', () => {
251
- const $ = cheerio.load(renderComponent('footer', params));
175
+ it('renders `post` content when provided', () => {
176
+ const $ = cheerio.load(renderComponent('footer', params));
252
177
 
253
- const text = $('.ons-footer__copyright').text();
254
- expect(text).toBe(
255
- '© Crown copyright and database rights 2020 OS 100019153. Use of address data is subject to the terms and conditions.',
256
- );
257
- });
178
+ const licenseHtml = $('.ons-footer__license').html();
179
+ expect(licenseHtml).toContain(', except where otherwise stated');
180
+ });
258
181
 
259
- it('is not rendered when `copyrightDeclaration` is not provided', () => {
260
- const $ = cheerio.load(renderComponent('footer', {}));
182
+ it('renders welsh `post` content when `lang:cy` provided and `OGLLink` is "true"', () => {
183
+ const $ = cheerio.load(
184
+ renderComponent('footer', {
185
+ lang: 'cy',
186
+ OGLLink: true,
187
+ }),
188
+ );
261
189
 
262
- expect($('.ons-footer__copyright').length).toBe(0);
190
+ const licenseHtml = $('.ons-footer__license').html();
191
+ expect(licenseHtml).toContain(', oni bai y nodir fel arall');
192
+ });
263
193
  });
264
- });
265
194
 
266
- describe('cols', () => {
267
- const params = {
268
- cols: EXAMPLE_COLS_PARAM,
269
- };
195
+ describe('warning', () => {
196
+ const params = {
197
+ footerWarning: 'Footer warning text with <strong>bold</strong> content.',
198
+ };
270
199
 
271
- it('passes jest-axe checks', async () => {
272
- const $ = cheerio.load(renderComponent('footer', params));
200
+ it('passes jest-axe checks', async () => {
201
+ const $ = cheerio.load(renderComponent('footer', params));
273
202
 
274
- const results = await axe($.html());
275
- expect(results).toHaveNoViolations();
276
- });
203
+ const results = await axe($.html());
204
+ expect(results).toHaveNoViolations();
205
+ });
277
206
 
278
- it('renders expected column titles', () => {
279
- const $ = cheerio.load(renderComponent('footer', params));
207
+ it('renders warning element', () => {
208
+ const $ = cheerio.load(renderComponent('footer', params));
280
209
 
281
- const titleHeadings = mapAll($('.ons-footer__heading'), (node) => node.text().trim());
282
- expect(titleHeadings).toEqual(['First column', 'Second column']);
283
- });
210
+ const warningHtml = $('.ons-footer__warning').html();
211
+ expect(warningHtml).toContain('Footer warning text with <strong>bold</strong> content.');
212
+ });
284
213
 
285
- it('renders expected lists using list component', () => {
286
- const faker = templateFaker();
287
- const listsSpy = faker.spy('list');
214
+ it('is not rendered when `footerWarning` is not provided', () => {
215
+ const $ = cheerio.load(renderComponent('footer', {}));
288
216
 
289
- faker.renderComponent('footer', params);
217
+ expect($('.ons-footer__warning').length).toBe(0);
218
+ });
219
+
220
+ it('renders warning text using the panel component', () => {
221
+ const faker = templateFaker();
222
+ const panelSpy = faker.spy('panel');
290
223
 
291
- const itemsList1 = listsSpy.occurrences[0].itemsList;
292
- expect(itemsList1[0]).toHaveProperty('url', '/example-link-a');
293
- expect(itemsList1[0]).toHaveProperty('text', 'Example Link A');
224
+ faker.renderComponent('footer', params);
294
225
 
295
- const itemsList2 = listsSpy.occurrences[1].itemsList;
296
- expect(itemsList2[0]).toHaveProperty('url', '/example-link-b');
297
- expect(itemsList2[0]).toHaveProperty('text', 'Example Link B');
226
+ expect(panelSpy.occurrences).toContainEqual(
227
+ expect.objectContaining({
228
+ variant: 'warn',
229
+ classes: 'ons-panel--warn--footer',
230
+ }),
231
+ );
232
+ });
298
233
  });
299
- });
300
234
 
301
- describe('rows', () => {
302
- const params = {
303
- rows: EXAMPLE_ROWS_PARAM,
304
- };
235
+ describe('copyright', () => {
236
+ const params = {
237
+ copyrightDeclaration: {
238
+ copyright: 'Crown copyright and database rights 2020 OS 100019153.',
239
+ text: 'Use of address data is subject to the terms and conditions.',
240
+ },
241
+ };
305
242
 
306
- it('passes jest-axe checks', async () => {
307
- const $ = cheerio.load(renderComponent('footer', params));
243
+ it('passes jest-axe checks', async () => {
244
+ const $ = cheerio.load(renderComponent('footer', params));
308
245
 
309
- const results = await axe($.html());
310
- expect(results).toHaveNoViolations();
311
- });
246
+ const results = await axe($.html());
247
+ expect(results).toHaveNoViolations();
248
+ });
312
249
 
313
- it('renders expected lists using list component', () => {
314
- const faker = templateFaker();
315
- const listsSpy = faker.spy('list');
250
+ it('renders copyright declaration', () => {
251
+ const $ = cheerio.load(renderComponent('footer', params));
316
252
 
317
- faker.renderComponent('footer', params);
253
+ const text = $('.ons-footer__copyright').text();
254
+ expect(text).toBe(
255
+ '© Crown copyright and database rights 2020 OS 100019153. Use of address data is subject to the terms and conditions.',
256
+ );
257
+ });
318
258
 
319
- const itemsList1 = listsSpy.occurrences[0].itemsList;
320
- expect(itemsList1[0]).toHaveProperty('url', '/example-link-a');
321
- expect(itemsList1[0]).toHaveProperty('text', 'Example Link A');
259
+ it('is not rendered when `copyrightDeclaration` is not provided', () => {
260
+ const $ = cheerio.load(renderComponent('footer', {}));
322
261
 
323
- const itemsList2 = listsSpy.occurrences[1].itemsList;
324
- expect(itemsList2[0]).toHaveProperty('url', '/example-link-b');
325
- expect(itemsList2[0]).toHaveProperty('text', 'Example Link B');
262
+ expect($('.ons-footer__copyright').length).toBe(0);
263
+ });
326
264
  });
327
- });
328
265
 
329
- describe('legal', () => {
330
- const params = {
331
- legal: EXAMPLE_LEGAL_PARAM,
332
- };
266
+ describe('cols', () => {
267
+ const params = {
268
+ cols: EXAMPLE_COLS_PARAM,
269
+ };
333
270
 
334
- it('passes jest-axe checks', async () => {
335
- const $ = cheerio.load(renderComponent('footer', params));
271
+ it('passes jest-axe checks', async () => {
272
+ const $ = cheerio.load(renderComponent('footer', params));
336
273
 
337
- const results = await axe($.html());
338
- expect(results).toHaveNoViolations();
339
- });
274
+ const results = await axe($.html());
275
+ expect(results).toHaveNoViolations();
276
+ });
340
277
 
341
- it('renders expected lists using list component', () => {
342
- const faker = templateFaker();
343
- const listsSpy = faker.spy('list');
278
+ it('renders expected column titles', () => {
279
+ const $ = cheerio.load(renderComponent('footer', params));
344
280
 
345
- faker.renderComponent('footer', params);
281
+ const titleHeadings = mapAll($('.ons-footer__heading'), (node) => node.text().trim());
282
+ expect(titleHeadings).toEqual(['First column', 'Second column']);
283
+ });
346
284
 
347
- const itemsList1 = listsSpy.occurrences[0].itemsList;
348
- expect(itemsList1[0]).toHaveProperty('url', '/example-legal-link-a');
349
- expect(itemsList1[0]).toHaveProperty('text', 'Example Legal Link A');
285
+ it('renders expected lists using list component', () => {
286
+ const faker = templateFaker();
287
+ const listsSpy = faker.spy('list');
350
288
 
351
- const itemsList2 = listsSpy.occurrences[1].itemsList;
352
- expect(itemsList2[0]).toHaveProperty('url', '/example-legal-link-b');
353
- expect(itemsList2[0]).toHaveProperty('text', 'Example Legal Link B');
354
- });
355
- });
356
-
357
- describe('poweredBy logo', () => {
358
- describe('default poweredBy logo', () => {
359
- describe.each([
360
- [
361
- 'the `lang` parameter is not provided',
362
- {},
363
- {
364
- iconType: 'ons-logo-en',
365
- altText: 'Office for National Statistics',
366
- },
367
- ],
368
- [
369
- 'the `lang` parameter is "en"',
370
- { lang: 'en' },
371
- {
372
- iconType: 'ons-logo-en',
373
- altText: 'Office for National Statistics',
374
- },
375
- ],
376
- ])('where %s', (_, langParams, defaultIcon) => {
377
- const params = {
378
- ...langParams,
379
- };
380
- it('renders the expected icon', () => {
381
- const faker = templateFaker();
382
- const iconsSpy = faker.spy('icon');
289
+ faker.renderComponent('footer', params);
383
290
 
384
- faker.renderComponent('footer', params);
291
+ const itemsList1 = listsSpy.occurrences[0].itemsList;
292
+ expect(itemsList1[0]).toHaveProperty('url', '/example-link-a');
293
+ expect(itemsList1[0]).toHaveProperty('text', 'Example Link A');
385
294
 
386
- expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining(defaultIcon));
295
+ const itemsList2 = listsSpy.occurrences[1].itemsList;
296
+ expect(itemsList2[0]).toHaveProperty('url', '/example-link-b');
297
+ expect(itemsList2[0]).toHaveProperty('text', 'Example Link B');
387
298
  });
388
- });
389
299
  });
390
- describe('provided poweredBy logo', () => {
391
- describe.each([
392
- [
393
- 'the `lang` parameter is "cy"',
394
- { lang: 'cy' },
395
- {
396
- iconType: 'ons-logo-cy',
397
- altText: 'Swyddfa Ystadegau Gwladol',
398
- },
399
- ],
400
- ])('where %s', (_, langParams, defaultIcon) => {
300
+
301
+ describe('rows', () => {
401
302
  const params = {
402
- ...langParams,
303
+ rows: EXAMPLE_ROWS_PARAM,
403
304
  };
404
- it('renders the expected icon', () => {
405
- const faker = templateFaker();
406
- const iconsSpy = faker.spy('icon');
407
305
 
408
- faker.renderComponent('footer', params);
306
+ it('passes jest-axe checks', async () => {
307
+ const $ = cheerio.load(renderComponent('footer', params));
409
308
 
410
- expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining(defaultIcon));
309
+ const results = await axe($.html());
310
+ expect(results).toHaveNoViolations();
411
311
  });
412
- });
413
- });
414
- describe('correct link for language', () => {
415
- it('has the Welsh lang link when the default Welsh lang ons icon is present', () => {
416
- const $ = cheerio.load(renderComponent('footer', { lang: 'cy' }));
417
312
 
418
- expect($('.ons-footer__poweredBy-link').attr('href')).toBe('https://cy.ons.gov.uk/');
419
- });
420
- it('has the English lang link when the default English lang ons icon is present', () => {
421
- const $ = cheerio.load(renderComponent('footer', { lang: 'en' }));
313
+ it('renders expected lists using list component', () => {
314
+ const faker = templateFaker();
315
+ const listsSpy = faker.spy('list');
316
+
317
+ faker.renderComponent('footer', params);
318
+
319
+ const itemsList1 = listsSpy.occurrences[0].itemsList;
320
+ expect(itemsList1[0]).toHaveProperty('url', '/example-link-a');
321
+ expect(itemsList1[0]).toHaveProperty('text', 'Example Link A');
422
322
 
423
- expect($('.ons-footer__poweredBy-link').attr('href')).toBe('https://www.ons.gov.uk/');
424
- });
323
+ const itemsList2 = listsSpy.occurrences[1].itemsList;
324
+ expect(itemsList2[0]).toHaveProperty('url', '/example-link-b');
325
+ expect(itemsList2[0]).toHaveProperty('text', 'Example Link B');
326
+ });
425
327
  });
426
- describe('provided poweredBy logo', () => {
427
- describe.each([
428
- [
429
- 'the `poweredBy` and `OGLLink` parameters are provided',
430
- {
431
- poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
432
- OGLLink: EXAMPLE_OGL_LINK_PARAM,
433
- },
434
- ],
435
- [
436
- 'the `poweredBy` and `legal` parameters are provided',
437
- {
438
- poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
439
- legal: EXAMPLE_LEGAL_PARAM,
440
- },
441
- ],
442
- [
443
- 'the `poweredBy` and `crest` parameters are provided',
444
- {
445
- poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
446
- crest: true,
447
- },
448
- ],
449
- [
450
- 'the `poweredBy`, `legal` and `crest` parameters are provided',
451
- {
452
- poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
453
- legal: EXAMPLE_LEGAL_PARAM,
454
- crest: true,
455
- },
456
- ],
457
- [
458
- 'the `poweredBy` parameter is provided but the `legal` and `crest` parameters are not provided',
459
- {
460
- poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
461
- },
462
- ],
463
- ])('where %s', (_, poweredByParams) => {
328
+
329
+ describe('legal', () => {
464
330
  const params = {
465
- ...poweredByParams,
331
+ legal: EXAMPLE_LEGAL_PARAM,
466
332
  };
467
333
 
468
334
  it('passes jest-axe checks', async () => {
469
- const $ = cheerio.load(renderComponent('footer', params));
335
+ const $ = cheerio.load(renderComponent('footer', params));
470
336
 
471
- const results = await axe($.html());
472
- expect(results).toHaveNoViolations();
337
+ const results = await axe($.html());
338
+ expect(results).toHaveNoViolations();
473
339
  });
474
340
 
475
- it('renders the expected logo', () => {
476
- const $ = cheerio.load(renderComponent('footer', params));
341
+ it('renders expected lists using list component', () => {
342
+ const faker = templateFaker();
343
+ const listsSpy = faker.spy('list');
344
+
345
+ faker.renderComponent('footer', params);
477
346
 
478
- expect($('.custom-logo').length).toBe(1);
347
+ const itemsList1 = listsSpy.occurrences[0].itemsList;
348
+ expect(itemsList1[0]).toHaveProperty('url', '/example-legal-link-a');
349
+ expect(itemsList1[0]).toHaveProperty('text', 'Example Legal Link A');
350
+
351
+ const itemsList2 = listsSpy.occurrences[1].itemsList;
352
+ expect(itemsList2[0]).toHaveProperty('url', '/example-legal-link-b');
353
+ expect(itemsList2[0]).toHaveProperty('text', 'Example Legal Link B');
479
354
  });
480
- });
481
- });
482
- });
483
-
484
- describe('save and sign out button', () => {
485
- const params = {
486
- button: {
487
- id: 'save-and-sign-out',
488
- classes: 'extra-class',
489
- text: 'Save changes and sign out',
490
- name: 'button-name',
491
- attributes: { a: 42 },
492
- url: 'https://example.com/',
493
- },
494
- };
495
-
496
- it('passes jest-axe checks', async () => {
497
- const $ = cheerio.load(renderComponent('footer', params));
498
-
499
- const results = await axe($.html());
500
- expect(results).toHaveNoViolations();
501
355
  });
502
356
 
503
- it('renders "Save changes and sign out" button using the button component', () => {
504
- const faker = templateFaker();
505
- const buttonSpy = faker.spy('button');
357
+ describe('poweredBy logo', () => {
358
+ describe('default poweredBy logo', () => {
359
+ describe.each([
360
+ [
361
+ 'the `lang` parameter is not provided',
362
+ {},
363
+ {
364
+ iconType: 'ons-logo-en',
365
+ altText: 'Office for National Statistics',
366
+ },
367
+ ],
368
+ [
369
+ 'the `lang` parameter is "en"',
370
+ { lang: 'en' },
371
+ {
372
+ iconType: 'ons-logo-en',
373
+ altText: 'Office for National Statistics',
374
+ },
375
+ ],
376
+ ])('where %s', (_, langParams, defaultIcon) => {
377
+ const params = {
378
+ ...langParams,
379
+ };
380
+ it('renders the expected icon', () => {
381
+ const faker = templateFaker();
382
+ const iconsSpy = faker.spy('icon');
383
+
384
+ faker.renderComponent('footer', params);
385
+
386
+ expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining(defaultIcon));
387
+ });
388
+ });
389
+ });
390
+ describe('provided poweredBy logo', () => {
391
+ describe.each([
392
+ [
393
+ 'the `lang` parameter is "cy"',
394
+ { lang: 'cy' },
395
+ {
396
+ iconType: 'ons-logo-cy',
397
+ altText: 'Swyddfa Ystadegau Gwladol',
398
+ },
399
+ ],
400
+ ])('where %s', (_, langParams, defaultIcon) => {
401
+ const params = {
402
+ ...langParams,
403
+ };
404
+ it('renders the expected icon', () => {
405
+ const faker = templateFaker();
406
+ const iconsSpy = faker.spy('icon');
407
+
408
+ faker.renderComponent('footer', params);
409
+
410
+ expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining(defaultIcon));
411
+ });
412
+ });
413
+ });
414
+ describe('correct link for language', () => {
415
+ it('has the Welsh lang link when the default Welsh lang ons icon is present', () => {
416
+ const $ = cheerio.load(renderComponent('footer', { lang: 'cy' }));
506
417
 
507
- faker.renderComponent('footer', params);
418
+ expect($('.ons-footer__poweredBy-link').attr('href')).toBe('https://cy.ons.gov.uk/');
419
+ });
420
+ it('has the English lang link when the default English lang ons icon is present', () => {
421
+ const $ = cheerio.load(renderComponent('footer', { lang: 'en' }));
508
422
 
509
- expect(buttonSpy.occurrences).toContainEqual(
510
- expect.objectContaining({
511
- ...params.button,
512
- variants: 'ghost',
513
- }),
514
- );
423
+ expect($('.ons-footer__poweredBy-link').attr('href')).toBe('https://www.ons.gov.uk/');
424
+ });
425
+ });
426
+ describe('provided poweredBy logo', () => {
427
+ describe.each([
428
+ [
429
+ 'the `poweredBy` and `OGLLink` parameters are provided',
430
+ {
431
+ poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
432
+ OGLLink: EXAMPLE_OGL_LINK_PARAM,
433
+ },
434
+ ],
435
+ [
436
+ 'the `poweredBy` and `legal` parameters are provided',
437
+ {
438
+ poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
439
+ legal: EXAMPLE_LEGAL_PARAM,
440
+ },
441
+ ],
442
+ [
443
+ 'the `poweredBy` and `crest` parameters are provided',
444
+ {
445
+ poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
446
+ crest: true,
447
+ },
448
+ ],
449
+ [
450
+ 'the `poweredBy`, `legal` and `crest` parameters are provided',
451
+ {
452
+ poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
453
+ legal: EXAMPLE_LEGAL_PARAM,
454
+ crest: true,
455
+ },
456
+ ],
457
+ [
458
+ 'the `poweredBy` parameter is provided but the `legal` and `crest` parameters are not provided',
459
+ {
460
+ poweredBy: '<img src="logo.svg" class="custom-logo" alt="logo">',
461
+ },
462
+ ],
463
+ ])('where %s', (_, poweredByParams) => {
464
+ const params = {
465
+ ...poweredByParams,
466
+ };
467
+
468
+ it('passes jest-axe checks', async () => {
469
+ const $ = cheerio.load(renderComponent('footer', params));
470
+
471
+ const results = await axe($.html());
472
+ expect(results).toHaveNoViolations();
473
+ });
474
+
475
+ it('renders the expected logo', () => {
476
+ const $ = cheerio.load(renderComponent('footer', params));
477
+
478
+ expect($('.custom-logo').length).toBe(1);
479
+ });
480
+ });
481
+ });
515
482
  });
516
- });
517
483
 
518
- describe('new tab warning', () => {
519
- const params = {
520
- newTabWarning: 'The following links open in a <strong>new tab</strong>',
521
- };
484
+ describe('save and sign out button', () => {
485
+ const params = {
486
+ button: {
487
+ id: 'save-and-sign-out',
488
+ classes: 'extra-class',
489
+ text: 'Save changes and sign out',
490
+ name: 'button-name',
491
+ attributes: { a: 42 },
492
+ url: 'https://example.com/',
493
+ },
494
+ };
522
495
 
523
- it('passes jest-axe checks', async () => {
524
- const $ = cheerio.load(renderComponent('footer', params));
496
+ it('passes jest-axe checks', async () => {
497
+ const $ = cheerio.load(renderComponent('footer', params));
525
498
 
526
- const results = await axe($.html());
527
- expect(results).toHaveNoViolations();
528
- });
499
+ const results = await axe($.html());
500
+ expect(results).toHaveNoViolations();
501
+ });
502
+
503
+ it('renders "Save changes and sign out" button using the button component', () => {
504
+ const faker = templateFaker();
505
+ const buttonSpy = faker.spy('button');
529
506
 
530
- it('renders new tab warning element', () => {
531
- const $ = cheerio.load(renderComponent('footer', params));
507
+ faker.renderComponent('footer', params);
532
508
 
533
- const warningHtml = $('.ons-footer__new-tab-warning').html();
534
- expect(warningHtml).toContain('The following links open in a <strong>new tab</strong>');
509
+ expect(buttonSpy.occurrences).toContainEqual(
510
+ expect.objectContaining({
511
+ ...params.button,
512
+ variants: 'ghost',
513
+ }),
514
+ );
515
+ });
535
516
  });
536
517
 
537
- it('is not rendered when `newTabWarning` is not provided', () => {
538
- const $ = cheerio.load(renderComponent('footer', {}));
518
+ describe('new tab warning', () => {
519
+ const params = {
520
+ newTabWarning: 'The following links open in a <strong>new tab</strong>',
521
+ };
539
522
 
540
- expect($('.ons-footer__new-tab-warning').length).toBe(0);
541
- });
542
- });
523
+ it('passes jest-axe checks', async () => {
524
+ const $ = cheerio.load(renderComponent('footer', params));
543
525
 
544
- describe('crest', () => {
545
- const params = {
546
- crest: true,
547
- legal: true,
548
- };
526
+ const results = await axe($.html());
527
+ expect(results).toHaveNoViolations();
528
+ });
529
+
530
+ it('renders new tab warning element', () => {
531
+ const $ = cheerio.load(renderComponent('footer', params));
549
532
 
550
- it('passes jest-axe checks', async () => {
551
- const $ = cheerio.load(renderComponent('footer', params));
533
+ const warningHtml = $('.ons-footer__new-tab-warning').html();
534
+ expect(warningHtml).toContain('The following links open in a <strong>new tab</strong>');
535
+ });
552
536
 
553
- const results = await axe($.html());
554
- expect(results).toHaveNoViolations();
537
+ it('is not rendered when `newTabWarning` is not provided', () => {
538
+ const $ = cheerio.load(renderComponent('footer', {}));
539
+
540
+ expect($('.ons-footer__new-tab-warning').length).toBe(0);
541
+ });
555
542
  });
556
543
 
557
- it('renders crest icon when `crest` parameter is provided', () => {
558
- const faker = templateFaker();
559
- const iconsSpy = faker.spy('icon');
544
+ describe('crest', () => {
545
+ const params = {
546
+ crest: true,
547
+ legal: true,
548
+ };
560
549
 
561
- faker.renderComponent('footer', params);
550
+ it('passes jest-axe checks', async () => {
551
+ const $ = cheerio.load(renderComponent('footer', params));
562
552
 
563
- expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining({ iconType: 'crest' }));
564
- });
553
+ const results = await axe($.html());
554
+ expect(results).toHaveNoViolations();
555
+ });
556
+
557
+ it('renders crest icon when `crest` parameter is provided', () => {
558
+ const faker = templateFaker();
559
+ const iconsSpy = faker.spy('icon');
560
+
561
+ faker.renderComponent('footer', params);
565
562
 
566
- it('renders "crest" element', () => {
567
- const $ = cheerio.load(renderComponent('footer', params));
563
+ expect(iconsSpy.occurrences).toContainEqual(expect.objectContaining({ iconType: 'crest' }));
564
+ });
565
+
566
+ it('renders "crest" element', () => {
567
+ const $ = cheerio.load(renderComponent('footer', params));
568
568
 
569
- expect($('.ons-footer__crest').length).toBe(1);
569
+ expect($('.ons-footer__crest').length).toBe(1);
570
+ });
570
571
  });
571
- });
572
572
  });