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( , ) 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( , ) 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( , ) await user.click(screen.getByRole('button', { name: /silver/i })) await waitFor(() => { expect(fetchMock).toHaveBeenCalledTimes(1) }) expect(screen.queryByRole('dialog')).toBeNull() }) })