/** * Tests for TournamentDetail Component * * Verifies: * - Conditional rendering based on isExpanded * - Loading state display * - Error state display * - Empty state display * - Details content rendering * - JSON formatting * - Animation and styling */ import { describe, it, expect } from 'vitest'; import { mount } from '@vue/test-utils'; import TournamentDetail from '@/components/challonge/TournamentDetail.vue'; describe('TournamentDetail', () => { const mockTournamentDetails = { tournament: { id: 'abc123', name: 'Test Tournament', state: 'pending', url: 'test-tournament', tournament_type: 'single elimination', participants_count: 16, started_at: '2024-01-15T10:00:00Z', completed_at: null, description: 'A test tournament', game_name: 'Chess' } }; describe('Visibility Control', () => { it('does not render when isExpanded is false', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: false, tournamentDetails: mockTournamentDetails } }); expect(wrapper.find('.tournament-detail').exists()).toBe(false); }); it('renders when isExpanded is true', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: mockTournamentDetails } }); expect(wrapper.find('.tournament-detail').exists()).toBe(true); }); }); describe('Loading State', () => { it('displays loading spinner and message', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, loading: true } }); expect(wrapper.find('.detail-status.loading').exists()).toBe(true); expect(wrapper.find('.spinner').exists()).toBe(true); expect(wrapper.text()).toContain('Loading tournament details'); }); it('hides details content while loading', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, loading: true, tournamentDetails: mockTournamentDetails } }); expect(wrapper.find('.detail-content').exists()).toBe(false); }); }); describe('Error State', () => { it('displays error message', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, error: 'Failed to load tournament' } }); expect(wrapper.find('.detail-status.error').exists()).toBe(true); expect(wrapper.find('.error-icon').exists()).toBe(true); expect(wrapper.text()).toContain('Failed to load tournament'); }); it('hides details content when error exists', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, error: 'Network error', tournamentDetails: mockTournamentDetails } }); expect(wrapper.find('.detail-content').exists()).toBe(false); }); }); describe('Empty State', () => { it('displays empty message when no details and not loading', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, loading: false, tournamentDetails: null } }); expect(wrapper.find('.detail-status.empty').exists()).toBe(true); expect(wrapper.text()).toContain('No details available'); }); }); describe('Details Content', () => { it('displays tournament details when available', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: mockTournamentDetails } }); expect(wrapper.find('.detail-content').exists()).toBe(true); expect(wrapper.find('.detail-header').exists()).toBe(true); expect(wrapper.find('.detail-json').exists()).toBe(true); }); it('displays detail header with title', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: mockTournamentDetails } }); const header = wrapper.find('.detail-header h4'); expect(header.exists()).toBe(true); expect(header.text()).toBe('Full Tournament Details'); }); it('formats tournament details as JSON', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: mockTournamentDetails } }); const jsonPre = wrapper.find('.detail-json'); expect(jsonPre.exists()).toBe(true); const jsonText = jsonPre.text(); expect(jsonText).toContain('"tournament"'); expect(jsonText).toContain('"id"'); expect(jsonText).toContain('"abc123"'); expect(jsonText).toContain('"name"'); expect(jsonText).toContain('"Test Tournament"'); }); it('pretty-prints JSON with indentation', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: mockTournamentDetails } }); const jsonText = wrapper.find('.detail-json').text(); const parsed = JSON.parse(jsonText); // Verify it's valid JSON and properly formatted expect(parsed).toEqual(mockTournamentDetails); expect(jsonText).toContain(' '); // Contains indentation }); it('handles complex nested tournament data', () => { const complexDetails = { tournament: mockTournamentDetails.tournament, participants: [ { id: 1, name: 'Player 1' }, { id: 2, name: 'Player 2' } ], matches: [{ id: 'm1', player1_id: 1, player2_id: 2, state: 'pending' }] }; const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: complexDetails } }); const jsonText = wrapper.find('.detail-json').text(); expect(jsonText).toContain('"participants"'); expect(jsonText).toContain('"matches"'); expect(jsonText).toContain('"Player 1"'); }); }); describe('Computed Properties', () => { it('returns empty string when tournamentDetails is null', () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: null } }); // Component should show empty state, not crash expect(wrapper.find('.detail-status.empty').exists()).toBe(true); }); it('updates formatted details when prop changes', async () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: mockTournamentDetails } }); expect(wrapper.text()).toContain('Test Tournament'); const newDetails = { tournament: { ...mockTournamentDetails.tournament, name: 'Updated Tournament' } }; await wrapper.setProps({ tournamentDetails: newDetails }); expect(wrapper.text()).toContain('Updated Tournament'); expect(wrapper.text()).not.toContain('Test Tournament'); }); }); describe('State Transitions', () => { it('transitions from loading to content', async () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, loading: true } }); expect(wrapper.find('.detail-status.loading').exists()).toBe(true); await wrapper.setProps({ loading: false, tournamentDetails: mockTournamentDetails }); expect(wrapper.find('.detail-status.loading').exists()).toBe(false); expect(wrapper.find('.detail-content').exists()).toBe(true); }); it('transitions from loading to error', async () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, loading: true } }); expect(wrapper.find('.detail-status.loading').exists()).toBe(true); await wrapper.setProps({ loading: false, error: 'Network timeout' }); expect(wrapper.find('.detail-status.loading').exists()).toBe(false); expect(wrapper.find('.detail-status.error').exists()).toBe(true); }); it('transitions from content to hidden when collapsed', async () => { const wrapper = mount(TournamentDetail, { props: { isExpanded: true, tournamentDetails: mockTournamentDetails } }); expect(wrapper.find('.detail-content').exists()).toBe(true); await wrapper.setProps({ isExpanded: false }); expect(wrapper.find('.tournament-detail').exists()).toBe(false); }); }); });