diff --git a/package-lock.json b/package-lock.json
index 2500db4a6d..9e3f2e9acd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -53918,10 +53918,13 @@
"prop-types": "^15.8.1"
},
"devDependencies": {
+ "@instructure/ui-axe-check": "8.45.0",
"@instructure/ui-babel-preset": "8.45.0",
"@instructure/ui-color-utils": "8.45.0",
"@instructure/ui-test-utils": "8.45.0",
- "@instructure/ui-themes": "8.45.0"
+ "@instructure/ui-themes": "8.45.0",
+ "@testing-library/jest-dom": "^5.17.0",
+ "@testing-library/react": "^14.0.0"
},
"peerDependencies": {
"react": ">=16.8 <=18"
@@ -59631,6 +59634,7 @@
"@babel/runtime": "^7.22.15",
"@instructure/emotion": "8.45.0",
"@instructure/shared-types": "8.45.0",
+ "@instructure/ui-axe-check": "8.45.0",
"@instructure/ui-babel-preset": "8.45.0",
"@instructure/ui-color-utils": "8.45.0",
"@instructure/ui-react-utils": "8.45.0",
@@ -59638,6 +59642,8 @@
"@instructure/ui-testable": "8.45.0",
"@instructure/ui-themes": "8.45.0",
"@instructure/ui-view": "8.45.0",
+ "@testing-library/jest-dom": "^5.17.0",
+ "@testing-library/react": "^14.0.0",
"prop-types": "^15.8.1"
}
},
diff --git a/packages/ui-byline/package.json b/packages/ui-byline/package.json
index a6b79457ed..754bc308fd 100644
--- a/packages/ui-byline/package.json
+++ b/packages/ui-byline/package.json
@@ -32,10 +32,13 @@
"prop-types": "^15.8.1"
},
"devDependencies": {
+ "@instructure/ui-axe-check": "8.45.0",
"@instructure/ui-babel-preset": "8.45.0",
"@instructure/ui-color-utils": "8.45.0",
"@instructure/ui-test-utils": "8.45.0",
- "@instructure/ui-themes": "8.45.0"
+ "@instructure/ui-themes": "8.45.0",
+ "@testing-library/jest-dom": "^5.17.0",
+ "@testing-library/react": "^14.0.0"
},
"peerDependencies": {
"react": ">=16.8 <=18"
diff --git a/packages/ui-byline/src/Byline/__new-tests__/Byline.test.tsx b/packages/ui-byline/src/Byline/__new-tests__/Byline.test.tsx
new file mode 100644
index 0000000000..e4927f03ee
--- /dev/null
+++ b/packages/ui-byline/src/Byline/__new-tests__/Byline.test.tsx
@@ -0,0 +1,157 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - present Instructure, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import React, { ComponentType } from 'react'
+import { render, screen } from '@testing-library/react'
+import '@testing-library/jest-dom/extend-expect'
+
+import { Byline } from '../index'
+import { BylineProps } from '../props'
+import { runAxeCheck } from '@instructure/ui-axe-check'
+import { View } from '@instructure/ui-view'
+
+const TEST_TITLE = 'Test-title'
+const TEST_DESCRIPTION = 'Test-description'
+const TEST_HEADING = 'Test-heading'
+const TEST_PARAGRAPH = 'Lorem Ipsum...'
+const TEST_LINK = 'http://instructure-test.com'
+const TEST_IMAGE = (
+
+)
+
+const initProps = {
+ title: TEST_TITLE,
+ description: TEST_DESCRIPTION
+}
+
+const renderByline = (props: Partial = { ...initProps }) => {
+ return render({TEST_IMAGE})
+}
+
+const originalOmitViewProps = View.omitViewProps
+
+describe('', () => {
+ beforeAll(() => {
+ // View component read Component.name instead of Component.displayName
+ // causing [undefined] in error messages
+ type BylineComponentType = ComponentType & {
+ name: 'Byline'
+ }
+
+ View.omitViewProps = (props, Component) => {
+ const ModifiedComponent = {
+ ...Component,
+ name: 'Byline'
+ } as BylineComponentType
+ return originalOmitViewProps(props, ModifiedComponent)
+ }
+ })
+
+ afterAll(() => {
+ View.omitViewProps = originalOmitViewProps
+ })
+
+ it('should render', () => {
+ const { container } = renderByline()
+
+ expect(container.firstChild).toBeInTheDocument()
+ })
+
+ it('should pass down div and its contents via the description property', () => {
+ const descriptionElement = (
+
+ )
+ renderByline({ description: descriptionElement })
+ const clickableHeading = screen.getByText(TEST_HEADING)
+ const descriptionText = screen.getByText(TEST_PARAGRAPH)
+
+ expect(clickableHeading.tagName).toBe('A')
+ expect(clickableHeading).toHaveAttribute('href', TEST_LINK)
+ expect(clickableHeading?.parentElement?.tagName).toBe('H2')
+
+ expect(descriptionText).toBeInTheDocument()
+ expect(descriptionText.tagName).toBe('P')
+ })
+
+ it('should meet a11y standards', async () => {
+ const { container } = renderByline()
+ const axeCheck = await runAxeCheck(container)
+
+ expect(axeCheck).toBe(true)
+ })
+
+ it(`should render a figure by default`, () => {
+ renderByline()
+ const figureElement = screen.getByRole('figure')
+
+ expect(figureElement).toBeInTheDocument()
+ })
+
+ describe('when passing down props to View', () => {
+ let spyOnConsoleError: jest.SpyInstance
+ const customAllowedProps: { [key: string]: string } = { margin: 'small' }
+ const customIgnoredProps = ['elementRef', 'children']
+
+ const allProps = View.allowedProps as Array
+ const testPropsToAllow = Object.keys(customAllowedProps)
+ const testPropsToDisallow = allProps.filter((prop) => {
+ return !(prop in customAllowedProps) && !customIgnoredProps.includes(prop)
+ })
+
+ beforeEach(() => {
+ spyOnConsoleError = jest.spyOn(console, 'error').mockImplementation()
+ })
+
+ afterEach(() => {
+ spyOnConsoleError.mockRestore()
+ })
+
+ testPropsToAllow.forEach((prop) => {
+ it(`should allow the '${prop}' prop`, () => {
+ renderByline({ [prop]: customAllowedProps[prop] })
+
+ expect(spyOnConsoleError).not.toHaveBeenCalled()
+ })
+ })
+
+ testPropsToDisallow.forEach((prop) => {
+ it(`should NOT allow the '${prop}' prop`, () => {
+ renderByline({ [prop]: 'foo' })
+ const expectedWarningMessage = `Warning: [Byline] prop '${prop}' is not allowed.`
+ const warningMessage = spyOnConsoleError.mock.calls[0][0]
+
+ expect(warningMessage).toBe(expectedWarningMessage)
+ expect(spyOnConsoleError).toHaveBeenCalledTimes(1)
+ })
+ })
+ })
+})
diff --git a/packages/ui-byline/src/Byline/__tests__/Byline.test.tsx b/packages/ui-byline/src/Byline/__tests__/Byline.test.tsx
deleted file mode 100644
index 9eaa5f62d3..0000000000
--- a/packages/ui-byline/src/Byline/__tests__/Byline.test.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 - present Instructure, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-import React from 'react'
-
-import { expect, find, mount, stub, within } from '@instructure/ui-test-utils'
-import { Byline } from '../index'
-import { View } from '@instructure/ui-view'
-
-describe('', async () => {
- // eslint-disable-next-line max-len
- const image = (
-
- )
-
- it('should render', async () => {
- const subject = await mount(
-
- {image}
-
- )
-
- expect(subject.getDOMNode()).to.exist()
- })
-
- it('should pass down div and its contents via the description property', async () => {
- const description = (
-
- )
-
- const subject = await mount(
- {image}
- )
-
- const media = within(subject.getDOMNode())
- expect(await media.find(':contains(Clickable Heading)')).to.exist()
- })
-
- it('should meet a11y standards', async () => {
- const subject = await mount(
-
- {image}
-
- )
-
- const media = within(subject.getDOMNode())
- expect(await media.accessible()).to.be.true()
- })
-
- it(`should render a figure by default`, async () => {
- expect(await mount({image}))
- expect(await find('figure')).to.exist()
- })
-
- it(`should not allow the 'as' prop`, async () => {
- const consoleError = stub(console, 'error')
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore intentionally wrong prop
- await mount({image})
- expect(consoleError).to.be.calledWith(
- "Warning: [Byline] prop 'as' is not allowed."
- )
- })
-
- describe('when passing down props to View', async () => {
- const allowedProps: Record = {
- margin: 'small'
- }
-
- const ignoreProps = ['elementRef', 'children']
-
- View.allowedProps
- .filter((prop) => !ignoreProps.includes(prop))
- .forEach((prop) => {
- if (Object.keys(allowedProps).indexOf(prop) < 0) {
- it(`should NOT allow the '${prop}' prop`, async () => {
- const consoleError = stub(console, 'error')
- const warning = `Warning: [Byline] prop '${prop}' is not allowed.`
- const props = {
- [prop]: 'foo'
- }
-
- await mount({image})
- expect(consoleError).to.be.calledWith(warning)
- })
- } else {
- it(`should allow the '${prop}' prop`, async () => {
- const props = { [prop]: allowedProps[prop] }
- const consoleError = stub(console, 'error')
-
- await mount({image})
- expect(consoleError).to.not.be.called()
- })
- }
- })
- })
-})
diff --git a/packages/ui-byline/tsconfig.build.json b/packages/ui-byline/tsconfig.build.json
index 55c37f6eeb..c0d2e7233c 100644
--- a/packages/ui-byline/tsconfig.build.json
+++ b/packages/ui-byline/tsconfig.build.json
@@ -15,6 +15,7 @@
{ "path": "../ui-babel-preset/tsconfig.build.json" },
{ "path": "../ui-color-utils/tsconfig.build.json" },
{ "path": "../ui-test-utils/tsconfig.build.json" },
- { "path": "../ui-themes/tsconfig.build.json" }
+ { "path": "../ui-themes/tsconfig.build.json" },
+ { "path": "../ui-axe-check/tsconfig.build.json" }
]
}