Skip to content

Commit

Permalink
refactor: add SearchMatch
Browse files Browse the repository at this point in the history
  • Loading branch information
luanrv00 committed Oct 15, 2024
1 parent a80424f commit 2fdb6c7
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 36 deletions.
4 changes: 3 additions & 1 deletion fixtures/watchItem.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export const watchItemFixture = {
import type {WatchItemFullType} from '@/app/types/types'

export const watchItemFixture: WatchItemFullType = {
tmdbId: 0,
posterUrl:
'https://image.tmdb.org/t/p/w300_and_h450_bestv2/5KGQEaE519pOD9DltmWBo6OcuH1.jpg',
Expand Down
66 changes: 66 additions & 0 deletions src/app/(home)/ui/SearchMatch/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {fireEvent, render, screen, waitFor} from '@testing-library/react'
import {watchItemFixture} from '../../../../../fixtures'
import {SearchMatch} from '.'

describe(SearchMatch, () => {
beforeEach(() => {
render(<SearchMatch matchItem={watchItemFixture} />)
})

it('renders match poster', () => {
const parsedImageUrl =
'/_next/image?url=https%3A%2F%2Fimage.tmdb.org%2Ft%2Fp%2Fw300_and_h450_bestv2%2F5KGQEaE519pOD9DltmWBo6OcuH1.jpg&w=256&q=75'

expect(screen.getByRole('img')).toHaveAttribute('src', parsedImageUrl)
})

it('renders match title', () => {
expect(screen.getByText(watchItemFixture.title)).toBeInTheDocument()
})

it('renders match release year', () => {
expect(screen.getByText(watchItemFixture.releaseYear)).toBeInTheDocument()
})

it('renders match media type', () => {
expect(screen.getByText(watchItemFixture.mediaType)).toBeInTheDocument()
})

it('renders button to add watched item', () => {
expect(screen.getByRole('button', {name: /add/i})).toBeInTheDocument()
})

describe('when match is an anime or tv show', () => {
const matchItemFull = {
...watchItemFixture,
seasonsCount: 1,
episodesCount: 10,
}

beforeEach(() => {
render(<SearchMatch matchItem={matchItemFull} />)
})

it('renders match seasons count', () => {
const expectedText = `seasons: ${matchItemFull.seasonsCount}`
expect(screen.getByText(expectedText)).toBeInTheDocument()
})

it('renders match episodes count', () => {
const expectedText = `episodes: ${matchItemFull.episodesCount}`
expect(screen.getByText(expectedText)).toBeInTheDocument()
})
})

describe('when clicking on add button', () => {
beforeEach(() => {
render(<SearchMatch matchItem={watchItemFixture} />)
})

it('calls post watched_items api', async () => {
fireEvent.click(screen.getAllByRole('button', {name: /add/i})[0])
// TODO: expect service post watched item to have been called
//expect().toHaveBeenCalled()
})
})
})
32 changes: 32 additions & 0 deletions src/app/(home)/ui/SearchMatch/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use client'
import {useState} from 'react'
import Image from 'next/image'
import {Button} from '@/app/ui'
import type {WatchItemFullType} from '@/app/types/types'

export function SearchMatch({matchItem}: {matchItem: WatchItemFullType}) {
const [isLoading, setIsLoading] = useState<boolean>(false)

async function onAdd() {
console.log('---onAdd')
//await fetch('/api/shows/watched_items')
}

return (
<li key={matchItem.tmdbId} className='flex flex-row border w-96'>
<Image src={matchItem.posterUrl} width='100' height='150' alt='cover' />
<div className='ml-2 w-full flex flex-col'>
<p>{matchItem.title}</p>
<p>{matchItem.releaseYear}</p>
<p>{matchItem.mediaType}</p>
{matchItem.seasonsCount && <p>seasons: {matchItem.seasonsCount}</p>}
{matchItem.episodesCount && <p>episodes: {matchItem.episodesCount}</p>}
<div className='self-end content-end grow m-2'>
<Button onClick={onAdd} isLoading={isLoading}>
Add
</Button>
</div>
</div>
</li>
)
}
16 changes: 16 additions & 0 deletions src/app/(home)/ui/SearchMatches/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {render, screen} from '@testing-library/react'
import {SearchMatches} from '.'
import {watchItemFixture} from '../../../../../fixtures'
import type {WatchItemFullType} from '@/app/types/types'

describe(SearchMatches, () => {
const matchesList: WatchItemFullType[] = [watchItemFixture]

beforeEach(() => {
render(<SearchMatches matchesList={matchesList} />)
})

it('renders match items', () => {
expect(screen.getAllByRole('listitem')).toHaveLength(matchesList.length)
})
})
35 changes: 2 additions & 33 deletions src/app/(home)/ui/SearchMatches/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import {useState} from 'react'
import Image from 'next/image'
import {Button} from '@/app/ui'
import type {WatchItemFullType} from '@/app/types/types'
import {SearchMatch} from '../SearchMatch'

export function SearchMatches({
matchesList,
}: {
matchesList: null | WatchItemFullType[]
}) {
const [isLoading, setIsLoading] = useState<boolean>(false)

async function onAdd() {
setIsLoading(true)
await fetch('/api/shows/watched_items')
setIsLoading(false)
}

const areMatchesNotFound = matchesList?.length === 0

if (areMatchesNotFound) {
Expand All @@ -25,28 +15,7 @@ export function SearchMatches({
return (
<ul className='mt-5 flex flex-col gap-3 md:flex-row md:flex-wrap'>
{matchesList?.map((matchItem: WatchItemFullType) => (
<li key={matchItem.tmdbId} className='flex flex-row border w-96'>
<Image
src={matchItem.posterUrl}
width='100'
height='150'
alt='cover'
/>
<div className='ml-2 w-full flex flex-col'>
<p>{matchItem.title}</p>
<p>{matchItem.releaseYear}</p>
<p>{matchItem.mediaType}</p>
{matchItem.seasonsCount && <p>seasons: {matchItem.seasonsCount}</p>}
{matchItem.episodesCount && (
<p>episodes: {matchItem.episodesCount}</p>
)}
<div className='self-end content-end grow m-2'>
<Button onClick={onAdd} isLoading={isLoading}>
Add
</Button>
</div>
</div>
</li>
<SearchMatch key={matchItem.tmdbId} matchItem={matchItem} />
))}
</ul>
)
Expand Down
4 changes: 2 additions & 2 deletions src/app/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export type WatchItemType = {
}

export type WatchItemDetailsType = {
seasonsCount: number
episodesCount: number
seasonsCount?: number
episodesCount?: number
}

export type WatchItemFullType = WatchItemType & WatchItemDetailsType

0 comments on commit 2fdb6c7

Please sign in to comment.