Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement generic YouTube block #889

Merged
merged 3 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion e2e-tests/about-us.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ test.describe('About us', () => {
it('should have the correct content', async ({ page }) => {
await page.goto(new URL('/about-us/', base).toString())

expect(await page.getByTitle('YouTube embed')).toHaveAttribute(
expect(await page.getByTitle('About Distribute Aid!')).toHaveAttribute(
'src',
'https://www.youtube.com/embed/msizPweg3kE',
)
Expand Down
2 changes: 1 addition & 1 deletion gatsby/generic-pages/content-blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export const deriveBlockNode: DeriveBlockFn = (
case 'block-text':
return deriveTextBlockNode(block, parentId, createNodeArgs)

case 'block-youtube':
case 'block-youtube-embed':
return deriveYoutubeBlockNode(block, parentId, createNodeArgs)

case 'block-timeline':
Expand Down
5 changes: 4 additions & 1 deletion src/components/about-us/AboutHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { FC } from 'react'

const AboutHero: FC = () => (
<div className="py-8 md:py-20 mx-auto" style={{ maxWidth: 800 }}>
<YouTubeEmbed videoUrl="https://www.youtube.com/embed/msizPweg3kE" />
<YouTubeEmbed
title="About Distribute Aid!"
url="https://www.youtube.com/embed/msizPweg3kE"
/>
</div>
)

Expand Down
16 changes: 11 additions & 5 deletions src/components/section/ContentBlock.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('Blocks', () => {
blocks = [
factory.getBlockTitleNode({ text: 'My Title' }),
factory.getBlockTextNode({ text: 'My text.' }),
factory.getBlockYoutubeNode({ title: 'My video.' }),
]
})

Expand All @@ -25,11 +26,13 @@ describe('Blocks', () => {

const text = getByText('My text.')
expect(text).toBeTruthy()

const youTubeTitle = getByText('My video.')
expect(youTubeTitle).toBeTruthy()
})

it('gracefully drops unimplemented block types', () => {
blocks = blocks.concat([
factory.getBlockYoutubeNode(),
factory.getBlockTimelineNode(),
factory.getBlockImageNode(),
factory.getBlockCardNode(),
Expand All @@ -42,9 +45,6 @@ describe('Blocks', () => {
const text = getByText('My text.')
expect(text).toBeTruthy()

const youtube = queryByText('youtube')
expect(youtube).toBeFalsy()

const timelineEntry = queryByText('2020')
expect(timelineEntry).toBeFalsy()

Expand Down Expand Up @@ -84,7 +84,13 @@ describe('Block', () => {
expect(text).toBeTruthy()
})

test.todo('can render a youtube block')
it('can render a youtube block', () => {
const block = factory.getBlockYoutubeNode({ title: 'My video.' })
const { getByText } = render(<Block block={block} />)
const text = getByText('My video.')
expect(text).toBeTruthy()
})

test.todo('can render a timeline block')
test.todo('can render a links list block')
test.todo('can render an updates list block')
Expand Down
14 changes: 11 additions & 3 deletions src/components/section/ContentBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,25 @@ import {
BlockText as BlockTextType,
BlockTitle as BlockTitleType,
BlockUpdatesList as BlockUpdatesListType,
BlockYoutube as BlockYoutubeType,
} from '../../types/generic-page.d'
import { BlockLinksList } from './blocks/BlockLinksList'
import { BlockText } from './blocks/BlockText'
import { BlockTitle } from './blocks/BlockTitle'
import { BlockUpdatesList } from './blocks/BlockUpdatesList'
import { BlockYouTube } from './blocks/BlockYouTube'

type BlocksProps = {
blocks: BlockNode[]
}

export const Blocks: FC<BlocksProps> = ({ blocks }) => {
const blockElems = blocks.map((block, i) => (
<Block className="mb-8 last:mb-0" key={i} block={block} />
<Block
className="mb-8 last:mb-0 border-l-2 pl-4 border-navy-400"
key={i}
block={block}
/>
))

return <>{blockElems}</>
Expand Down Expand Up @@ -50,10 +56,12 @@ export const Block: FC<BlockProps> = ({ block, className }) => {
className={className}
/>
)
case 'DABlockYoutube':
return (
<BlockYouTube block={block as BlockYoutubeType} className={className} />
)

// wishlist
case 'DABlockYoutube':
return null
case 'DABlockTimeline':
return null
case 'DABlockImage':
Expand Down
4 changes: 0 additions & 4 deletions src/components/section/Section.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ describe('Sections', () => {

sections[1] = factory.getSectionGridNode({
blocks: [
factory.getBlockYoutubeNode(),
factory.getBlockTimelineNode(),
factory.getBlockImageNode(),
factory.getBlockCardNode(),
Expand All @@ -56,9 +55,6 @@ describe('Sections', () => {
const text = getByText('My text.')
expect(text).toBeTruthy()

const youtube = queryByText('youtube')
expect(youtube).toBeFalsy()

const timelineEntry = queryByText('2020')
expect(timelineEntry).toBeFalsy()

Expand Down
3 changes: 1 addition & 2 deletions src/components/section/blocks/BlockLinksList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ type BlockTextProps = {
export const BlockLinksList: FC<BlockTextProps> = ({ block, className }) => {
return (
<>
{/* TODO: replace w/ <BlockTitle> once that no longer needs a full Node */}
{block.title && (
<BlockTitle className={className} block={{ text: block.title }} />
)}
<div className={`${className} border-l-2 pl-4 border-navy-400`}>
<div className={`${className}`}>
{/* NOTE: we're intentionally dropping the title so it doesn't get repeated */}
<LinksList list={{ links: block.links }} />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/section/blocks/BlockText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type BlockTextProps = {

export const BlockText: FC<BlockTextProps> = ({ block, className }) => {
return (
<div className={`${className} border-l-2 pl-4 border-navy-400`}>
<div className={`${className}`}>
<MarkdownContent content={block.text} />
</div>
)
Expand Down
6 changes: 1 addition & 5 deletions src/components/section/blocks/BlockTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,5 @@ type BlockTitleProps = {
}

export const BlockTitle: FC<BlockTitleProps> = ({ block, className }) => {
return (
<h2 className={`${className} pl-4 border-l-2 border-navy-600`}>
{block.text}
</h2>
)
return <h2 className={`${className} border-navy-600`}>{block.text}</h2>
}
3 changes: 1 addition & 2 deletions src/components/section/blocks/BlockUpdatesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ type BlockTextProps = {
export const BlockUpdatesList: FC<BlockTextProps> = ({ block, className }) => {
return (
<>
{/* TODO: replace w/ <BlockTitle> once that no longer needs a full Node */}
{block.title && (
<BlockTitle className={className} block={{ text: block.title }} />
)}
<div className={`${className} border-l-2 pl-4 border-navy-400`}>
<div className={`${className}`}>
{/* NOTE: we're intentionally dropping the title so it doesn't get repeated */}
<UpdatesList list={{ visibleCount: 10, updates: block.updates }} />
</div>
Expand Down
15 changes: 15 additions & 0 deletions src/components/section/blocks/BlockYouTube.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { render } from '@testing-library/react'
import { BlockYoutubeNode } from '../../../types/generic-page.d'
import { BlockYouTube } from './BlockYouTube'

describe('BlockYouTube', () => {
it('renders the title', () => {
const block = {
embedUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
title: 'My video',
} as BlockYoutubeNode
const { getByText } = render(<BlockYouTube block={block} />)
const title = getByText('My video')
expect(title).toBeTruthy()
})
})
23 changes: 23 additions & 0 deletions src/components/section/blocks/BlockYouTube.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { YouTubeEmbed } from '@components/youtube-embed/YouTubeEmbed'
import { FC } from 'react'
import { BlockYoutube as BlockYoutubeType } from '../../../types/generic-page.d'
import { BlockTitle } from './BlockTitle'

type BlockYouTubeProps = {
block: BlockYoutubeType
className?: string | undefined
}

export const BlockYouTube: FC<BlockYouTubeProps> = ({ block, className }) => {
return (
<>
{block.title && (
<BlockTitle className={className} block={{ text: block.title }} />
)}
<div className={`${className}`}>
{/* NOTE: we're intentionally dropping the title so it doesn't get repeated */}
<YouTubeEmbed url={block.embedUrl} />
</div>
</>
)
}
14 changes: 7 additions & 7 deletions src/components/youtube-embed/YouTubeEmbed.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ describe('<YouTubeEmbed/>', () => {
it('renders the video and title', () => {
render(
<YouTubeEmbed
videoTitle="the title of the video"
videoUrl="https://example.com/video"
title="the title of the video"
url="https://example.com/video"
/>,
)

expect(screen.getByText('the title of the video'))
expect(screen.getByTitle('YouTube embed')).toBeInTheDocument()
expect(screen.getByText('the title of the video')).toBeInTheDocument()
expect(screen.getByTitle('the title of the video')).toBeInTheDocument()
})

it('does not render title when none is given', () => {
render(<YouTubeEmbed videoUrl="https://example.com/video" />)
render(<YouTubeEmbed url="https://example.com/video" />)

expect(screen.getByTitle('YouTube embed')).toBeInTheDocument()
expect(screen.queryByTestId('videoTitle')).not.toBeInTheDocument()
expect(screen.getByTitle('Youtube Video')).toBeInTheDocument()
expect(screen.queryByTestId('YouTubeEmbed-Title')).not.toBeInTheDocument()
})
})
18 changes: 9 additions & 9 deletions src/components/youtube-embed/YouTubeEmbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@ import { FC, PropsWithChildren } from 'react'

export const YouTubeEmbed: FC<
PropsWithChildren<{
videoUrl: string
videoTitle?: string
url: string
title?: string | undefined
}>
> = ({ videoUrl, videoTitle }) => (
<figure>
> = ({ url, title }) => (
<figure className="first:mt-0 last:mb-0">
<iframe
className="aspect-video w-full"
src={videoUrl}
title="YouTube embed"
src={url}
title={title || 'Youtube Video'}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
frameBorder="0"
allowFullScreen
/>
{videoTitle && (
<figcaption data-testid="videoTitle" className="text-sm mt-4">
{videoTitle}
{title && (
<figcaption data-testid="YouTubeEmbed-Title" className="text-sm mt-4">
{title}
</figcaption>
)}
</figure>
Expand Down