Files
SkinbaseNova/resources/js/components/artwork/ArtworkAwards.test.jsx

125 lines
3.5 KiB
JavaScript

import React from 'react'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { cleanup, render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import ArtworkAwards from './ArtworkAwards'
describe('ArtworkAwards medal confirmations', () => {
beforeEach(() => {
vi.stubGlobal('fetch', vi.fn())
})
afterEach(() => {
cleanup()
vi.unstubAllGlobals()
vi.clearAllMocks()
})
it('asks for confirmation before removing the active medal', async () => {
const user = userEvent.setup()
const fetchMock = vi.mocked(fetch)
fetchMock.mockResolvedValue({
ok: true,
json: async () => ({
medals: { gold: 0, silver: 0, bronze: 0, score: 0 },
current_user_medal: null,
}),
})
render(
<ArtworkAwards
artwork={{ id: 69461, viewer: { id: 2 }, user: { id: 7 } }}
isAuthenticated
initialAwards={{ gold: 1, silver: 0, bronze: 0, score: 5, current_user_medal: 'gold' }}
/>,
)
await user.click(screen.getByRole('button', { name: /gold/i }))
expect(screen.getByRole('dialog', { name: /remove gold medal\?/i })).not.toBeNull()
expect(fetchMock).not.toHaveBeenCalled()
await user.click(screen.getByRole('button', { name: /remove medal/i }))
await waitFor(() => {
expect(fetchMock).toHaveBeenCalledTimes(1)
})
expect(fetchMock).toHaveBeenCalledWith(
'/api/artworks/69461/medal',
expect.objectContaining({
method: 'DELETE',
}),
)
})
it('asks for confirmation before changing an existing medal', async () => {
const user = userEvent.setup()
const fetchMock = vi.mocked(fetch)
fetchMock.mockResolvedValue({
ok: true,
json: async () => ({
medals: { gold: 0, silver: 1, bronze: 0, score: 3 },
current_user_medal: 'silver',
}),
})
render(
<ArtworkAwards
artwork={{ id: 69461, viewer: { id: 2 }, user: { id: 7 } }}
isAuthenticated
initialAwards={{ gold: 1, silver: 0, bronze: 0, score: 5, current_user_medal: 'gold' }}
/>,
)
await user.click(screen.getByRole('button', { name: /silver/i }))
expect(screen.getByRole('dialog', { name: /change medal to silver\?/i })).not.toBeNull()
expect(fetchMock).not.toHaveBeenCalled()
await user.click(screen.getByRole('button', { name: /change to silver/i }))
await waitFor(() => {
expect(fetchMock).toHaveBeenCalledTimes(1)
})
expect(fetchMock).toHaveBeenCalledWith(
'/api/artworks/69461/medal',
expect.objectContaining({
method: 'POST',
body: JSON.stringify({ medal_type: 'silver' }),
}),
)
})
it('still awards a new medal immediately when the viewer has not voted yet', async () => {
const user = userEvent.setup()
const fetchMock = vi.mocked(fetch)
fetchMock.mockResolvedValue({
ok: true,
json: async () => ({
medals: { gold: 0, silver: 1, bronze: 0, score: 3 },
current_user_medal: 'silver',
}),
})
render(
<ArtworkAwards
artwork={{ id: 69461, viewer: { id: 2 }, user: { id: 7 } }}
isAuthenticated
initialAwards={{ gold: 0, silver: 0, bronze: 0, score: 0, current_user_medal: null }}
/>,
)
await user.click(screen.getByRole('button', { name: /silver/i }))
await waitFor(() => {
expect(fetchMock).toHaveBeenCalledTimes(1)
})
expect(screen.queryByRole('dialog')).toBeNull()
})
})