Skip to content

Commit

Permalink
Merge pull request #4266 from alphagov/bk-accordion-errors
Browse files Browse the repository at this point in the history
Throw errors during accordion initialisation
  • Loading branch information
domoscargin authored Oct 23, 2023
2 parents 891b112 + c632049 commit 4714006
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@ export class Accordion extends GOVUKFrontendComponent {

const $sections = this.$module.querySelectorAll(`.${this.sectionClass}`)
if (!$sections.length) {
return this
throw new ElementError({
componentName: 'Accordion',
identifier: `Sections (\`<div class="${this.sectionClass}">\`)`
})
}

this.$sections = $sections
Expand Down Expand Up @@ -203,7 +206,10 @@ export class Accordion extends GOVUKFrontendComponent {
this.$sections.forEach(($section, i) => {
const $header = $section.querySelector(`.${this.sectionHeaderClass}`)
if (!$header) {
return
throw new ElementError({
componentName: 'Accordion',
identifier: `Section headers (\`<div class="${this.sectionHeaderClass}">\`)`
})
}

// Set header attributes
Expand Down Expand Up @@ -231,8 +237,18 @@ export class Accordion extends GOVUKFrontendComponent {
const $heading = $header.querySelector(`.${this.sectionHeadingClass}`)
const $summary = $header.querySelector(`.${this.sectionSummaryClass}`)

if (!$span || !$heading) {
return
if (!$heading) {
throw new ElementError({
componentName: 'Accordion',
identifier: `Section heading (\`.${this.sectionHeadingClass}\`)`
})
}

if (!$span) {
throw new ElementError({
componentName: 'Accordion',
identifier: `Section button placeholder (\`<span class="${this.sectionButtonClass}">\`)`
})
}

// Create a button element that will replace the
Expand Down Expand Up @@ -395,7 +411,15 @@ export class Accordion extends GOVUKFrontendComponent {
const $button = $section.querySelector(`.${this.sectionButtonClass}`)
const $content = $section.querySelector(`.${this.sectionContentClass}`)

if (!$showHideIcon || !$showHideText || !$button || !$content) {
if (!$content) {
throw new ElementError({
componentName: 'Accordion',
identifier: `Section content (\`<div class="${this.sectionContentClass}">\`)`
})
}

if (!$showHideIcon || !$showHideText || !$button) {
// Return early for elements we create
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -711,59 +711,158 @@ describe('/components/accordion', () => {
)
})
})
})

describe('errors at instantiation', () => {
let examples
describe('errors at instantiation', () => {
let examples

beforeAll(async () => {
examples = await getExamples('accordion')
beforeAll(async () => {
examples = await getExamples('accordion')
})

it('throws when GOV.UK Frontend is not supported', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation() {
document.body.classList.remove('govuk-frontend-supported')
}
})
).rejects.toMatchObject({
cause: {
name: 'SupportError',
message: 'GOV.UK Frontend is not supported in this browser'
}
})
})

it('throws when GOV.UK Frontend is not supported', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation() {
document.body.classList.remove('govuk-frontend-supported')
}
})
).rejects.toMatchObject({
cause: {
name: 'SupportError',
message: 'GOV.UK Frontend is not supported in this browser'
it('throws when $module is not set', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module) {
$module.remove()
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message: 'Accordion: Root element (`$module`) not found'
}
})
})

it('throws when $module is not set', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module) {
$module.remove()
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message: 'Accordion: Root element (`$module`) not found'
it('throws when receiving the wrong type for $module', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module) {
// Replace with an `<svg>` element which is not an `HTMLElement` in the DOM (but an `SVGElement`)
$module.outerHTML = `<svg data-module="govuk-accordion"></svg>`
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Accordion: Root element (`$module`) is not of type HTMLElement'
}
})
})

it('throws when receiving the wrong type for $module', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module) {
// Replace with an `<svg>` element which is not an `HTMLElement` in the DOM (but an `SVGElement`)
$module.outerHTML = `<svg data-module="govuk-accordion"></svg>`
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Accordion: Root element (`$module`) is not of type HTMLElement'
it('throws when the accordion sections are missing', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module, { selector }) {
$module
.querySelectorAll(selector)
.forEach((item) => item.remove())
},
context: {
selector: '.govuk-accordion__section'
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Accordion: Sections (`<div class="govuk-accordion__section">`) not found'
}
})
})

it('throws when section header is missing', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module, { selector }) {
$module
.querySelectorAll(selector)
.forEach((item) => item.remove())
},
context: {
selector: '.govuk-accordion__section-header'
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Accordion: Section headers (`<div class="govuk-accordion__section-header">`) not found'
}
})
})

it('throws when any section heading is missing', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module, { selector }) {
$module.querySelector(selector).remove()
},
context: {
selector: '.govuk-accordion__section-heading'
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Accordion: Section heading (`.govuk-accordion__section-heading`) not found'
}
})
})

it('throws when any section button placeholder span is missing', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module, { selector }) {
$module.querySelector(selector).remove()
},
context: {
selector: '.govuk-accordion__section-button'
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Accordion: Section button placeholder (`<span class="govuk-accordion__section-button">`) not found'
}
})
})

it('throws when any section content is missing', async () => {
await expect(
render(page, 'accordion', examples.default, {
beforeInitialisation($module, { selector }) {
$module.querySelector(selector).remove()
},
context: {
selector: '.govuk-accordion__section-content'
}
})
).rejects.toMatchObject({
cause: {
name: 'ElementError',
message:
'Accordion: Section content (`<div class="govuk-accordion__section-content">`) not found'
}
})
})
})
Expand Down

0 comments on commit 4714006

Please sign in to comment.