Skip to content

Commit

Permalink
Merge pull request #898 from Ekep-Obasi/test-trending
Browse files Browse the repository at this point in the history
[Component Tests] Trending - Sidebar
  • Loading branch information
Rassl authored Feb 15, 2024
2 parents 8b22058 + e9bb57e commit 7a25824
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 7 deletions.
173 changes: 173 additions & 0 deletions src/components/App/SideBar/Trending/__tests__/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import '@testing-library/jest-dom'
import { fireEvent, render, waitFor } from '@testing-library/react'
import React from 'react'
import { Trending } from '..'
import * as fetchGraphData from '../../../../../network/fetchGraphData'
import { useDataStore } from '../../../../../stores/useDataStore'
import { useModal } from '../../../../../stores/useModalStore'
import * as utils from '../../../../../utils/trending'

jest.mock('d3-force-3d', () => ({
forceSimulation: jest.fn(() => ({
stop: jest.fn(),
})),
forceCollide: jest.fn(),
}))

jest.mock('~/components/Icons/SentimentDataIcon', () => jest.fn(() => <div data-testid="SentimentDataIcon" />))
jest.mock('~/components/Icons/PlayIcon', () => jest.fn(() => <div data-testid="PlayIcon" />))

jest.mock('react-markdown', () => jest.fn(() => null))

jest.mock('react-hook-form', () => ({
useFormContext: jest.fn(() => ({
setValue: jest.fn(),
})),
}))

jest.mock('~/stores/useModalStore', () => ({
useModal: jest.fn((id) => ({
open: jest.fn(), // Mock the open function
visible: id === availableModal.some((modal) => modal === id),
})),
}))

jest.mock('~/stores/useDataStore', () => ({
useDataStore: jest.fn(),
}))

const mockedGetTrends = jest.spyOn(fetchGraphData, 'getTrends')
const mockedUseDataStore = useDataStore as jest.MockedFunction<typeof useDataStore>
const mockedUseModal = useModal as jest.MockedFunction<typeof useModal>
const availableModal = ['briefDescription', 'addContent']

const mockTrends = [
{ topic: 'Drivechain', count: 10, audio_EN: 'drivechain.mp3', tldr: 'Drivechain TLDR' },
{ topic: 'Ordinals', count: 10, audio_EN: 'ordinals.mp3', tldr: 'Ordinals TLDR' },
]

describe('Trending Component', () => {
beforeEach(() => {
jest.clearAllMocks()

mockedUseDataStore.mockImplementation(() => [
mockTrends,
jest.fn().mockImplementation((trendingTopics) => trendingTopics),
])
})

it('asserts that the component renders correctly', () => {
const { getByText, getByTestId } = render(<Trending />)

expect(getByText('Trending Topics')).toBeInTheDocument()
expect(getByTestId('SentimentDataIcon')).toBeInTheDocument()
})

it('verifies that the component fetches trending topics on mount and updates the state accordingly', () => {
const mockedSetTrendingTopics = jest.fn()

mockedUseDataStore.mockReturnValue([mockTrends, mockedSetTrendingTopics])

render(<Trending />)

;(async () => {
await waitFor(() => {
expect(mockedGetTrends).toHaveBeenCalled()
expect(mockedSetTrendingTopics).toHaveBeenCalledWith(mockTrends)
})
})()
})

it('verifies the display of skeletons during loading.', () => {
mockedUseDataStore.mockReturnValue([mockTrends, jest.fn()])

const loading = true

jest.spyOn(React, 'useState').mockImplementationOnce(() => [loading, jest.fn()])

const { getAllByTestId } = render(<Trending />)

expect(getAllByTestId('loading-skeleton').length).toEqual(5)
})

it('checks that the component renders a list of trending topics when data is available', () => {
mockedUseDataStore.mockReturnValue([mockTrends, jest.fn()])

const { getByText } = render(<Trending />)

mockTrends.forEach(({ topic }) => {
expect(getByText(`#${topic}`)).toBeInTheDocument()
})
})

it('ensures that the "Add Content" button calls the openContentAddModal function', () => {
mockedUseDataStore.mockReturnValue([[], jest.fn()])

const loading = false

jest.spyOn(React, 'useState').mockImplementationOnce(() => [loading, jest.fn()])

const { getByText, getByRole } = render(<Trending />)

expect(getByText('No new trending topics in the last 24 hours')).toBeInTheDocument()

expect(getByRole('button', { name: 'Add Content' })).toBeInTheDocument()

fireEvent.click(getByRole('button', { name: 'Add Content' }))

const { open: openAddContentMock } = mockedUseModal('addContent')

expect(mockedUseModal).toHaveBeenCalledWith('addContent')

;(async () => {
await waitFor(() => expect(openAddContentMock).toHaveBeenCalled())
})()
})

it('confirms the rendering of the BriefDescriptionModal when a TLDR button is clicked', () => {
mockedUseDataStore.mockReturnValue([[mockTrends[0]], jest.fn()])

const { getByRole } = render(<Trending />)

fireEvent.click(getByRole('button', { name: 'TLDR' }))

const { open: openBriefDescriptionModal } = mockedUseModal('briefDescription')

expect(mockedUseModal).toHaveBeenCalledWith('briefDescription')

;(async () => {
await waitFor(() => expect(openBriefDescriptionModal).toHaveBeenCalled())
})()
})

it('validates the play/pause functionality of the audio', () => {
mockedUseDataStore.mockReturnValue([mockTrends, jest.fn()])

jest.spyOn(utils, 'showPlayButton')

const { getByText, getByTestId, container } = render(<Trending />)

expect(getByText('Play All')).toBeInTheDocument()
expect(getByTestId('PlayIcon')).toBeInTheDocument()

const audio = container.querySelector('audio') as HTMLAudioElement

expect(audio).toHaveAttribute('src', mockTrends[0].audio_EN)

expect(audio.paused).toBeTruthy()
})

test('tests the behavior when a user selects a trending topic', () => {
const mockedSelectTrendingTopic = jest.fn()

mockedUseDataStore.mockReturnValue([mockTrends, mockedSelectTrendingTopic])

const { getByText } = render(<Trending />)

fireEvent.click(getByText(`#${mockTrends[0].topic}`))

;(async () => {
await waitFor(() => expect(mockedSelectTrendingTopic).toHaveBeenCalled())
})()
})
})
18 changes: 11 additions & 7 deletions src/components/App/SideBar/Trending/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,17 @@ export const Trending = ({ onSubmit }: Props) => {
{loading ? (
<div>
<ClipLoader color={colors.PRIMARY_BLUE} size={16} />
<>
<StyledSkeleton animation="wave" height={47} variant="rectangular" width={382} />
<StyledSkeleton animation="wave" height={47} variant="rectangular" width={382} />
<StyledSkeleton animation="wave" height={47} variant="rectangular" width={382} />
<StyledSkeleton animation="wave" height={47} variant="rectangular" width={382} />
<StyledSkeleton animation="wave" height={47} variant="rectangular" width={382} />
</>
{[...Array(5)].map((_, i) => (
<StyledSkeleton
// eslint-disable-next-line
key={i}
animation="wave"
data-testid="loading-skeleton"
height={47}
variant="rectangular"
width={382}
/>
))}
</div>
) : (
<>
Expand Down

0 comments on commit 7a25824

Please sign in to comment.