Skip to content

Commit

Permalink
feat: add html to image component (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
Raul Andrade authored Feb 28, 2022
1 parent b9b5df1 commit fa557ce
Show file tree
Hide file tree
Showing 19 changed files with 617 additions and 29 deletions.
4 changes: 4 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"plugins": [],
"presets": ["next/babel", "@babel/preset-typescript"]
}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
"dependencies": {
"@babel/preset-typescript": "^7.16.7",
"@heroicons/react": "^1.0.5",
"axios": "^0.26.0",
"html2canvas": "^1.4.1",
"next": "12.1.0",
"nextjs-progressbar": "^0.0.13",
"nookies": "^2.5.2",
Expand Down
81 changes: 81 additions & 0 deletions src/components/audio-player/audio-player.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { render, act } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import { AudioPlayer } from './audio-player'

const Component = () => <audio>audio</audio>

describe('<AudioPlayer />', () => {
const iconPath = 'div > div > svg > path'

const playMock = jest.fn()
const pauseMock = jest.fn()
const volumeMock = jest.fn()

const useAudioMock = jest.fn().mockReturnValue([
Component,
{ playing: false },
{
volume: volumeMock,
pause: pauseMock,
play: playMock
}
])

beforeEach(() => {
jest.clearAllMocks()
})

it('should be render a AudioPlayer component', () => {
const { container } = render(
<AudioPlayer src="audio" useAudio={useAudioMock} />
)

expect(useAudioMock).toHaveBeenCalled()
expect(volumeMock).toHaveBeenCalled()

expect(container.querySelector(iconPath)).toBeInTheDocument()
})

it('should be able to click in the play button', () => {
const { container } = render(
<AudioPlayer src="audio" useAudio={useAudioMock} />
)

expect(useAudioMock).toHaveBeenCalled()

const playButton = container.querySelector(iconPath)

act(() => {
if (playButton) userEvent.click(playButton)
})

expect(playMock).toHaveBeenCalled()
})

it('should be able to click in the pause button', () => {
const useAudioMock = jest.fn().mockReturnValue([
jest.fn(),
{ playing: true },
{
volume: volumeMock,
pause: pauseMock,
play: playMock
}
])

const { container } = render(
<AudioPlayer src="audio" useAudio={useAudioMock} />
)

expect(useAudioMock).toHaveBeenCalled()

const playButton = container.querySelector(iconPath)

act(() => {
if (playButton) userEvent.click(playButton)
})

expect(pauseMock).toHaveBeenCalled()
})
})
10 changes: 8 additions & 2 deletions src/components/audio-player/audio-player.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { useEffect } from 'react'
import { useAudio } from 'react-use'
import { useAudio as ReactUseAudio } from 'react-use'
import { PlayIcon, PauseIcon } from '@heroicons/react/solid'

type AudioPlayerProps = {
src: string
useAudio?: typeof ReactUseAudio
}

export const AudioPlayer = ({ src }: AudioPlayerProps) => {
export const AudioPlayer = ({
src,
useAudio = ReactUseAudio
}: AudioPlayerProps) => {
const [audio, state, controls] = useAudio({
src: src,
autoPlay: false
Expand All @@ -24,6 +28,7 @@ export const AudioPlayer = ({ src }: AudioPlayerProps) => {
{audio}
{state.playing ? (
<PauseIcon
aria-label="pause-icon"
className="h-20 w-20 sm:h-10 sm:w-10 dark:fill-gray-100 fill-gray-600 cursor-pointer
hover:scale-110
transition duration-200 ease-out hover:ease-in"
Expand All @@ -32,6 +37,7 @@ export const AudioPlayer = ({ src }: AudioPlayerProps) => {
/>
) : (
<PlayIcon
aria-label="play-icon"
className="h-20 w-20 sm:h-10 sm:w-10 dark:fill-gray-100 fill-gray-600 cursor-pointer
hover:scale-110
transition duration-200 ease-out hover:ease-in"
Expand Down
18 changes: 18 additions & 0 deletions src/components/content/content.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { render, screen } from '@testing-library/react'
import { Content } from './content'

describe('<Content/>', () => {
it('should be render a Content component', () => {
render(
<Content>
<h1>hello content testing</h1>
</Content>
)

expect(
screen.getByRole('heading', {
name: /hello content testing/i
})
).toBeInTheDocument()
})
})
18 changes: 18 additions & 0 deletions src/components/grid/grid.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { render, screen } from '@testing-library/react'
import { Grid } from './grid'

describe('<Grid/>', () => {
it('should be render a Grid component', () => {
render(
<Grid>
<h1>hello grid testing</h1>
</Grid>
)

expect(
screen.getByRole('heading', {
name: /hello grid testing/i
})
).toBeInTheDocument()
})
})
182 changes: 182 additions & 0 deletions src/components/html-to-image/html-to-image.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import { render, screen, act } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { HTMLToImage } from './html-to-image'

//TODO: MOVE THIS TO A MOCK DIRECTORY
const artistsMock = [
{
id: '7zejo99XCAwPzycPCCaoM8',
images: [
{
height: 640,
url: 'https://i.scdn.co/image/ab67616d0000b27355fd23d477d647c595c8ce5a',
width: 640
},
{
height: 300,
url: 'https://i.scdn.co/image/ab67616d00001e0255fd23d477d647c595c8ce5a',
width: 300
},
{
height: 64,
url: 'https://i.scdn.co/image/ab67616d0000485155fd23d477d647c595c8ce5a',
width: 64
}
],
type: 'artist',
name: 'Michael Nyman Band',
track: {
name: 'Fish Beach',
previewUrl:
'https://p.scdn.co/mp3-preview/4fb1c7db76d70da33d74db84f6863b1d4dc582ab?cid=c400423b160b43dcbb941e61d7d4cd60'
}
},
{
id: '0s1ec6aPpRZ4DCj15w1EFg',
images: [
{
height: 1000,
url: 'https://i.scdn.co/image/549e391d35cccd6f7eb602102dd1378d8afeb06a',
width: 1000
},
{
height: 640,
url: 'https://i.scdn.co/image/7390a60d0952bc2bf22ba4cb7c4f20f8bf6cb597',
width: 640
},
{
height: 200,
url: 'https://i.scdn.co/image/8b2da52578b6a565da52ae34db2aea368f1fdce0',
width: 200
},
{
height: 64,
url: 'https://i.scdn.co/image/3d19a0ded34b4ff9b4cac7ab77a15f26c2b0d7e6',
width: 64
}
],
type: 'artist',
name: 'Dario Marianelli',
track: {
name: 'Someone Loves Us',
previewUrl:
'https://p.scdn.co/mp3-preview/9be2d96c8237bbc39b1778e66f917a27363a9e22?cid=c400423b160b43dcbb941e61d7d4cd60'
}
},
{
id: '3gGbSXSwHWmrUBIG9IUAau',
images: [
{
height: 640,
url: 'https://i.scdn.co/image/ab6761610000e5eb2c64d38027090d363ea36044',
width: 640
},
{
height: 320,
url: 'https://i.scdn.co/image/ab676161000051742c64d38027090d363ea36044',
width: 320
},
{
height: 160,
url: 'https://i.scdn.co/image/ab6761610000f1782c64d38027090d363ea36044',
width: 160
}
],
type: 'artist',
name: 'Zbigniew Preisner',
track: {
name: 'Les marionnettes',
previewUrl:
'https://p.scdn.co/mp3-preview/5ef82ca0e722ef6e51359140ba4d5a319eb35383?cid=c400423b160b43dcbb941e61d7d4cd60'
}
},
{
id: '3gGbSXSwHWmrUBIG9IUAau2',
images: [
{
height: 640,
url: 'https://i.scdn.co/image/ab6761610000e5eb2c64d38027090d363ea36044',
width: 640
},
{
height: 320,
url: 'https://i.scdn.co/image/ab676161000051742c64d38027090d363ea36044',
width: 320
},
{
height: 160,
url: 'https://i.scdn.co/image/ab6761610000f1782c64d38027090d363ea36044',
width: 160
}
],
type: 'artist',
name: 'Zbigniew Preisner',
track: {
name: 'Les marionnettes',
previewUrl:
'https://p.scdn.co/mp3-preview/5ef82ca0e722ef6e51359140ba4d5a319eb35383?cid=c400423b160b43dcbb941e61d7d4cd60'
}
}
]

describe('<HTMLToImage />', () => {
it('should be render a HTMLToImage component', () => {
render(
<HTMLToImage
artists={[
...artistsMock,
...artistsMock,
...artistsMock,
...artistsMock,
...artistsMock
]}
/>
)

expect(
screen.getByRole('heading', {
name: /you can download your randomfy!/i
})
).toBeInTheDocument()

expect(
screen.getByRole('button', {
name: /download button/i
})
).toBeInTheDocument()
})

it('should be return null when artists lenght less than nine', () => {
const { container } = render(<HTMLToImage artists={[]} />)

expect(container.firstChild).toBeNull()
})

it('should be able to download the generated image', () => {
const html2canvasMock = jest
.fn()
.mockResolvedValue({ toDataURL: jest.fn() })
render(
<HTMLToImage
artists={[
...artistsMock,
...artistsMock,
...artistsMock,
...artistsMock,
...artistsMock
]}
html2canvas={html2canvasMock}
/>
)

const downloadButton = screen.getByRole('button', {
name: /download button/i
})

act(() => {
userEvent.click(downloadButton)
})

expect(html2canvasMock).toHaveBeenCalled()
})
})
Loading

1 comment on commit fa557ce

@vercel
Copy link

@vercel vercel bot commented on fa557ce Feb 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.