/**
 * Tests for Comm Block Components — Phase 7 Task 7.6
 *
 * Tests BlockRenderer and all block types:
 * text, markdown, html, image, audio, video, file, action_card, contact_card, miniapp
 */
import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import BlockRenderer from '@/components/comm/blocks/BlockRenderer';
import MarkdownBlock from '@/components/comm/blocks/MarkdownBlock';
import HtmlBlock from '@/components/comm/blocks/HtmlBlock';
import ImageBlock from '@/components/comm/blocks/ImageBlock';
import AudioBlock from '@/components/comm/blocks/AudioBlock';
import VideoBlock from '@/components/comm/blocks/VideoBlock';
import FileBlock from '@/components/comm/blocks/FileBlock';
import ActionCardBlock from '@/components/comm/blocks/ActionCardBlock';
import ContactCardBlock from '@/components/comm/blocks/ContactCardBlock';
import MiniAppBlock from '@/components/comm/blocks/MiniAppBlock';
import type { MessageBlock } from '@/store/commStore';

// ─── Mock Data Helpers ───

function makeBlock(
  id: string,
  block_type: string,
  block_data: Record<string, any>,
  sort_order: number = 0,
): MessageBlock {
  return { id, block_type, block_data, sort_order };
}

// ─── BlockRenderer Tests ───

describe('BlockRenderer', () => {
  it('renders null when blocks array is empty', () => {
    const { container } = render(<BlockRenderer blocks={[]} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders null when blocks is undefined', () => {
    const { container } = render(<BlockRenderer blocks={undefined as any} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders a text block with content', () => {
    const blocks = [makeBlock('b1', 'text', { text: 'Hello World' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText('Hello World')).toBeInTheDocument();
  });

  it('renders text block using content fallback when text is missing', () => {
    const blocks = [makeBlock('b1', 'text', { content: 'Fallback content' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText('Fallback content')).toBeInTheDocument();
  });

  it('renders text block as empty string when no text or content', () => {
    const blocks = [makeBlock('b1', 'text', {})];
    const { container } = render(<BlockRenderer blocks={blocks} />);
    const textDiv = container.querySelector('.text-sm');
    expect(textDiv).toBeInTheDocument();
    expect(textDiv?.textContent).toBe('');
  });

  it('renders multiple blocks in sort_order sequence', () => {
    const blocks = [
      makeBlock('b2', 'text', { text: 'Second' }, 2),
      makeBlock('b1', 'text', { text: 'First' }, 1),
      makeBlock('b3', 'text', { text: 'Third' }, 3),
    ];
    const { container } = render(<BlockRenderer blocks={blocks} />);
    const wrappers = container.querySelectorAll('.block-wrapper');
    expect(wrappers).toHaveLength(3);
    expect(wrappers[0].textContent).toBe('First');
    expect(wrappers[1].textContent).toBe('Second');
    expect(wrappers[2].textContent).toBe('Third');
  });

  it('renders unknown block type with fallback message', () => {
    const blocks = [makeBlock('b1', 'unknown_type', {})];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText(/Unbekannter Block-Typ: unknown_type/)).toBeInTheDocument();
  });

  it('renders markdown block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'markdown', { markdown: '# Heading' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText('Heading')).toBeInTheDocument();
  });

  it('renders html block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'html', { html: '<p>HTML content</p>' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText('HTML content')).toBeInTheDocument();
  });

  it('renders image block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'image', { url: 'https://example.com/img.png', alt: 'Test Image' })];
    render(<BlockRenderer blocks={blocks} />);
    const img = screen.getByRole('img');
    expect(img).toHaveAttribute('src', 'https://example.com/img.png');
    expect(img).toHaveAttribute('alt', 'Test Image');
  });

  it('renders audio block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'audio', { url: 'https://example.com/audio.mp3' })];
    const { container } = render(<BlockRenderer blocks={blocks} />);
    const audio = container.querySelector('audio');
    expect(audio).toBeInTheDocument();
    expect(audio).toHaveAttribute('src', 'https://example.com/audio.mp3');
  });

  it('renders video block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'video', { url: 'https://example.com/video.mp4' })];
    const { container } = render(<BlockRenderer blocks={blocks} />);
    const video = container.querySelector('video');
    expect(video).toBeInTheDocument();
    expect(video).toHaveAttribute('src', 'https://example.com/video.mp4');
  });

  it('renders file block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'file', { url: 'https://example.com/doc.pdf', name: 'doc.pdf' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText('doc.pdf')).toBeInTheDocument();
  });

  it('renders action_card block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'action_card', { title: 'Action Title', body: 'Action Body' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText('Action Title')).toBeInTheDocument();
    expect(screen.getByText('Action Body')).toBeInTheDocument();
  });

  it('renders contact_card block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'contact_card', { contact_id: '123', name: 'John Doe' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText('John Doe')).toBeInTheDocument();
  });

  it('renders miniapp block via BlockRenderer', () => {
    const blocks = [makeBlock('b1', 'miniapp', { app_id: 'my-app' })];
    render(<BlockRenderer blocks={blocks} />);
    expect(screen.getByText(/Mini-App: my-app/)).toBeInTheDocument();
  });
});

// ─── MarkdownBlock Tests ───

describe('MarkdownBlock', () => {
  it('renders null when markdown content is empty', () => {
    const block = makeBlock('b1', 'markdown', {});
    const { container } = render(<MarkdownBlock block={block} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders heading from markdown', () => {
    const block = makeBlock('b1', 'markdown', { markdown: '# My Heading' });
    render(<MarkdownBlock block={block} />);
    expect(screen.getByText('My Heading')).toBeInTheDocument();
  });

  it('renders paragraph from markdown', () => {
    const block = makeBlock('b1', 'markdown', { markdown: 'This is a paragraph.' });
    render(<MarkdownBlock block={block} />);
    expect(screen.getByText('This is a paragraph.')).toBeInTheDocument();
  });

  it('renders unordered list from markdown', () => {
    const block = makeBlock('b1', 'markdown', { markdown: '- Item 1\n- Item 2' });
    render(<MarkdownBlock block={block} />);
    expect(screen.getByText('Item 1')).toBeInTheDocument();
    expect(screen.getByText('Item 2')).toBeInTheDocument();
  });

  it('renders ordered list from markdown', () => {
    const block = makeBlock('b1', 'markdown', { markdown: '1. First\n2. Second' });
    render(<MarkdownBlock block={block} />);
    expect(screen.getByText('First')).toBeInTheDocument();
    expect(screen.getByText('Second')).toBeInTheDocument();
  });

  it('renders link from markdown', () => {
    const block = makeBlock('b1', 'markdown', { markdown: '[Click here](https://example.com)' });
    render(<MarkdownBlock block={block} />);
    const link = screen.getByText('Click here');
    expect(link.closest('a')).toHaveAttribute('href', 'https://example.com');
  });

  it('renders blockquote from markdown', () => {
    const block = makeBlock('b1', 'markdown', { markdown: '> This is a quote' });
    render(<MarkdownBlock block={block} />);
    expect(screen.getByText('This is a quote')).toBeInTheDocument();
  });

  it('uses content fallback when markdown field is missing', () => {
    const block = makeBlock('b1', 'markdown', { content: 'Fallback markdown' });
    render(<MarkdownBlock block={block} />);
    expect(screen.getByText('Fallback markdown')).toBeInTheDocument();
  });
});

// ─── HtmlBlock Tests ───

describe('HtmlBlock', () => {
  it('renders null when html content is empty', () => {
    const block = makeBlock('b1', 'html', {});
    const { container } = render(<HtmlBlock block={block} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders basic HTML content', () => {
    const block = makeBlock('b1', 'html', { html: '<p>Simple HTML</p>' });
    render(<HtmlBlock block={block} />);
    expect(screen.getByText('Simple HTML')).toBeInTheDocument();
  });

  it('strips script tags from HTML', () => {
    const block = makeBlock('b1', 'html', {
      html: '<p>Safe content</p><script>alert("xss")</script>',
    });
    const { container } = render(<HtmlBlock block={block} />);
    expect(screen.getByText('Safe content')).toBeInTheDocument();
    expect(container.querySelector('script')).toBeNull();
  });

  it('strips onclick event handlers', () => {
    const block = makeBlock('b1', 'html', {
      html: '<p onclick="alert(1)">Clickable</p>',
    });
    const { container } = render(<HtmlBlock block={block} />);
    const p = container.querySelector('p');
    expect(p).not.toHaveAttribute('onclick');
  });

  it('replaces javascript: URLs in href', () => {
    const block = makeBlock('b1', 'html', {
      html: '<a href="javascript:alert(1)">Bad Link</a>',
    });
    const { container } = render(<HtmlBlock block={block} />);
    const link = container.querySelector('a');
    expect(link?.getAttribute('href')).not.toContain('javascript:');
  });

  it('renders div with dangerouslySetInnerHTML', () => {
    const block = makeBlock('b1', 'html', { html: '<span data-test="yes">Content</span>' });
    const { container } = render(<HtmlBlock block={block} />);
    expect(container.querySelector('[data-test="yes"]')).toBeInTheDocument();
  });
});

// ─── ImageBlock Tests ───

describe('ImageBlock', () => {
  it('renders null when url is missing', () => {
    const block = makeBlock('b1', 'image', {});
    const { container } = render(<ImageBlock block={block} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders image with url and alt text', () => {
    const block = makeBlock('b1', 'image', { url: 'https://example.com/img.png', alt: 'Description' });
    render(<ImageBlock block={block} />);
    const img = screen.getByRole('img');
    expect(img).toHaveAttribute('src', 'https://example.com/img.png');
    expect(img).toHaveAttribute('alt', 'Description');
  });

  it('renders image with empty alt when not provided', () => {
    const block = makeBlock('b1', 'image', { url: 'https://example.com/img.png' });
    const { container } = render(<ImageBlock block={block} />);
    const img = container.querySelector('img');
    expect(img).toBeInTheDocument();
    expect(img).toHaveAttribute('alt', '');
  });

  it('renders alt caption below image when alt is provided', () => {
    const block = makeBlock('b1', 'image', { url: 'https://example.com/img.png', alt: 'Caption text' });
    render(<ImageBlock block={block} />);
    expect(screen.getByText('Caption text')).toBeInTheDocument();
  });

  it('does not render caption when alt is empty', () => {
    const block = makeBlock('b1', 'image', { url: 'https://example.com/img.png', alt: '' });
    const { container } = render(<ImageBlock block={block} />);
    const captions = container.querySelectorAll('.text-xs.text-secondary-500.italic');
    expect(captions).toHaveLength(0);
  });

  it('renders image inside a link that opens in new tab', () => {
    const block = makeBlock('b1', 'image', { url: 'https://example.com/img.png' });
    const { container } = render(<ImageBlock block={block} />);
    const link = container.querySelector('a');
    expect(link).toHaveAttribute('target', '_blank');
    expect(link).toHaveAttribute('rel', 'noopener noreferrer');
  });

  it('applies width attribute when provided as number', () => {
    const block = makeBlock('b1', 'image', { url: 'https://example.com/img.png', width: 300 });
    const { container } = render(<ImageBlock block={block} />);
    const img = container.querySelector('img');
    expect(img).toHaveAttribute('width', '300');
  });
});

// ─── AudioBlock Tests ───

describe('AudioBlock', () => {
  it('renders null when url is missing', () => {
    const block = makeBlock('b1', 'audio', {});
    const { container } = render(<AudioBlock block={block} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders audio element with url', () => {
    const block = makeBlock('b1', 'audio', { url: 'https://example.com/audio.mp3' });
    const { container } = render(<AudioBlock block={block} />);
    const audio = container.querySelector('audio');
    expect(audio).toBeInTheDocument();
    expect(audio).toHaveAttribute('src', 'https://example.com/audio.mp3');
    expect(audio).toHaveAttribute('controls');
  });

  it('shows duration label when duration is provided', () => {
    const block = makeBlock('b1', 'audio', { url: 'https://example.com/audio.mp3', duration: 125 });
    render(<AudioBlock block={block} />);
    expect(screen.getByText(/Dauer: 2:05/)).toBeInTheDocument();
  });

  it('does not show duration label when duration is 0 or invalid', () => {
    const block = makeBlock('b1', 'audio', { url: 'https://example.com/audio.mp3', duration: 0 });
    const { container } = render(<AudioBlock block={block} />);
    expect(container.querySelector('.text-xs.text-secondary-500')).toBeNull();
  });

  it('formats duration correctly for single-digit seconds', () => {
    const block = makeBlock('b1', 'audio', { url: 'https://example.com/audio.mp3', duration: 65 });
    render(<AudioBlock block={block} />);
    expect(screen.getByText(/Dauer: 1:05/)).toBeInTheDocument();
  });
});

// ─── VideoBlock Tests ───

describe('VideoBlock', () => {
  it('renders null when url is missing', () => {
    const block = makeBlock('b1', 'video', {});
    const { container } = render(<VideoBlock block={block} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders video element with url and controls', () => {
    const block = makeBlock('b1', 'video', { url: 'https://example.com/video.mp4' });
    const { container } = render(<VideoBlock block={block} />);
    const video = container.querySelector('video');
    expect(video).toBeInTheDocument();
    expect(video).toHaveAttribute('src', 'https://example.com/video.mp4');
    expect(video).toHaveAttribute('controls');
  });

  it('sets poster attribute when thumbnail is provided', () => {
    const block = makeBlock('b1', 'video', { url: 'https://example.com/video.mp4', thumbnail: 'https://example.com/thumb.jpg' });
    const { container } = render(<VideoBlock block={block} />);
    const video = container.querySelector('video');
    expect(video).toHaveAttribute('poster', 'https://example.com/thumb.jpg');
  });

  it('does not set poster when thumbnail is not a string', () => {
    const block = makeBlock('b1', 'video', { url: 'https://example.com/video.mp4', thumbnail: 123 });
    const { container } = render(<VideoBlock block={block} />);
    const video = container.querySelector('video');
    expect(video).not.toHaveAttribute('poster');
  });
});

// ─── FileBlock Tests ───

describe('FileBlock', () => {
  it('renders null when both url and name are missing', () => {
    const block = makeBlock('b1', 'file', {});
    const { container } = render(<FileBlock block={block} />);
    expect(container.firstChild).toBeNull();
  });

  it('renders file name when provided', () => {
    const block = makeBlock('b1', 'file', { url: 'https://example.com/doc.pdf', name: 'document.pdf' });
    render(<FileBlock block={block} />);
    expect(screen.getByText('document.pdf')).toBeInTheDocument();
  });

  it('uses default name "Datei" when name is not provided', () => {
    const block = makeBlock('b1', 'file', { url: 'https://example.com/doc.pdf' });
    render(<FileBlock block={block} />);
    expect(screen.getByText('Datei')).toBeInTheDocument();
  });

  it('shows file size when size is provided', () => {
    const block = makeBlock('b1', 'file', { url: 'https://example.com/doc.pdf', name: 'doc.pdf', size: 1048576 });
    render(<FileBlock block={block} />);
    expect(screen.getByText('1.0 MB')).toBeInTheDocument();
  });

  it('formats file size in KB', () => {
    const block = makeBlock('b1', 'file', { url: 'https://example.com/doc.pdf', name: 'doc.pdf', size: 5120 });
    render(<FileBlock block={block} />);
    expect(screen.getByText('5.0 KB')).toBeInTheDocument();
  });

  it('formats file size in bytes', () => {
    const block = makeBlock('b1', 'file', { url: 'https://example.com/doc.pdf', name: 'doc.pdf', size: 512 });
    render(<FileBlock block={block} />);
    expect(screen.getByText('512 B')).toBeInTheDocument();
  });

  it('renders download link with aria-label', () => {
    const block = makeBlock('b1', 'file', { url: 'https://example.com/doc.pdf', name: 'doc.pdf' });
    render(<FileBlock block={block} />);
    const downloadLink = screen.getByLabelText('Datei herunterladen: doc.pdf');
    expect(downloadLink).toBeInTheDocument();
    expect(downloadLink).toHaveAttribute('href', 'https://example.com/doc.pdf');
  });

  it('does not render download link when url is missing', () => {
    const block = makeBlock('b1', 'file', { name: 'doc.pdf' });
    render(<FileBlock block={block} />);
    expect(screen.queryByLabelText(/Datei herunterladen/)).not.toBeInTheDocument();
  });
});

// ─── ActionCardBlock Tests ───

describe('ActionCardBlock', () => {
  beforeEach(() => {
    vi.restoreAllMocks();
  });

  it('renders title and body', () => {
    const block = makeBlock('b1', 'action_card', { title: 'Card Title', body: 'Card Body Text' });
    render(<ActionCardBlock block={block} />);
    expect(screen.getByText('Card Title')).toBeInTheDocument();
    expect(screen.getByText('Card Body Text')).toBeInTheDocument();
  });

  it('renders without title when not provided', () => {
    const block = makeBlock('b1', 'action_card', { body: 'Only body' });
    render(<ActionCardBlock block={block} />);
    expect(screen.getByText('Only body')).toBeInTheDocument();
    expect(screen.queryByRole('heading')).not.toBeInTheDocument();
  });

  it('renders action buttons', () => {
    const block = makeBlock('b1', 'action_card', {
      title: 'Title',
      body: 'Body',
      actions: [
        { label: 'Confirm', action: 'https://example.com', type: 'primary' },
        { label: 'Cancel', action: 'dismiss', type: 'secondary' },
      ],
    });
    render(<ActionCardBlock block={block} />);
    expect(screen.getByText('Confirm')).toBeInTheDocument();
    expect(screen.getByText('Cancel')).toBeInTheDocument();
  });

  it('opens URL in new tab when action button is clicked', () => {
    const mockOpen = vi.spyOn(window, 'open').mockImplementation(() => null);
    const block = makeBlock('b1', 'action_card', {
      title: 'Title',
      body: 'Body',
      actions: [{ label: 'Go', action: 'https://example.com', type: 'primary' }],
    });
    render(<ActionCardBlock block={block} />);
    fireEvent.click(screen.getByText('Go'));
    expect(mockOpen).toHaveBeenCalledWith('https://example.com', '_blank', 'noopener,noreferrer');
  });

  it('does not open URL when action is dismiss', () => {
    const mockOpen = vi.spyOn(window, 'open').mockImplementation(() => null);
    const block = makeBlock('b1', 'action_card', {
      title: 'Title',
      body: 'Body',
      actions: [{ label: 'Dismiss', action: 'dismiss', type: 'secondary' }],
    });
    render(<ActionCardBlock block={block} />);
    fireEvent.click(screen.getByText('Dismiss'));
    expect(mockOpen).not.toHaveBeenCalled();
  });

  it('applies primary styling to primary action buttons', () => {
    const block = makeBlock('b1', 'action_card', {
      title: 'Title',
      actions: [{ label: 'Primary', action: 'https://example.com', type: 'primary' }],
    });
    render(<ActionCardBlock block={block} />);
    const btn = screen.getByText('Primary');
    expect(btn.className).toContain('bg-primary-600');
  });

  it('applies secondary styling to secondary action buttons', () => {
    const block = makeBlock('b1', 'action_card', {
      title: 'Title',
      actions: [{ label: 'Secondary', action: 'dismiss', type: 'secondary' }],
    });
    render(<ActionCardBlock block={block} />);
    const btn = screen.getByText('Secondary');
    expect(btn.className).toContain('bg-secondary-100');
  });

  it('uses default label "Aktion" when action label is empty', () => {
    const block = makeBlock('b1', 'action_card', {
      title: 'Title',
      actions: [{ label: '', action: 'dismiss' }],
    });
    render(<ActionCardBlock block={block} />);
    expect(screen.getByText('Aktion')).toBeInTheDocument();
  });

  it('renders no action buttons when actions array is empty', () => {
    const block = makeBlock('b1', 'action_card', { title: 'Title', body: 'Body', actions: [] });
    render(<ActionCardBlock block={block} />);
    expect(screen.queryByRole('button')).not.toBeInTheDocument();
  });
});

// ─── ContactCardBlock Tests ───

describe('ContactCardBlock', () => {
  it('renders contact name', () => {
    const block = makeBlock('b1', 'contact_card', { contact_id: '123', name: 'Jane Smith' });
    render(<ContactCardBlock block={block} />);
    expect(screen.getByText('Jane Smith')).toBeInTheDocument();
  });

  it('uses default name when name is not provided', () => {
    const block = makeBlock('b1', 'contact_card', { contact_id: '123' });
    render(<ContactCardBlock block={block} />);
    expect(screen.getByText('Unbekannter Kontakt')).toBeInTheDocument();
  });

  it('renders link to contact page with contact_id', () => {
    const block = makeBlock('b1', 'contact_card', { contact_id: 'abc-456', name: 'Test User' });
    render(<ContactCardBlock block={block} />);
    const link = screen.getByText('Test User').closest('a');
    expect(link).toHaveAttribute('href', '/contacts/abc-456');
  });

  it('renders link with href="#" when contact_id is missing', () => {
    const block = makeBlock('b1', 'contact_card', { name: 'No ID User' });
    render(<ContactCardBlock block={block} />);
    const link = screen.getByText('No ID User').closest('a');
    expect(link).toHaveAttribute('href', '#');
  });

  it('generates initials from name', () => {
    const block = makeBlock('b1', 'contact_card', { contact_id: '1', name: 'John Doe' });
    render(<ContactCardBlock block={block} />);
    expect(screen.getByText('JD')).toBeInTheDocument();
  });

  it('generates initials from single name', () => {
    const block = makeBlock('b1', 'contact_card', { contact_id: '1', name: 'Max' });
    render(<ContactCardBlock block={block} />);
    expect(screen.getByText('M')).toBeInTheDocument();
  });

  it('shows "Kontakt anzeigen" subtitle', () => {
    const block = makeBlock('b1', 'contact_card', { contact_id: '1', name: 'Test' });
    render(<ContactCardBlock block={block} />);
    expect(screen.getByText('Kontakt anzeigen')).toBeInTheDocument();
  });
});

// ─── MiniAppBlock Tests ───

describe('MiniAppBlock', () => {
  it('renders app_id in label', () => {
    const block = makeBlock('b1', 'miniapp', { app_id: 'my-mini-app' });
    render(<MiniAppBlock block={block} />);
    expect(screen.getByText(/Mini-App: my-mini-app/)).toBeInTheDocument();
  });

  it('uses default app_id when not provided', () => {
    const block = makeBlock('b1', 'miniapp', {});
    render(<MiniAppBlock block={block} />);
    expect(screen.getByText(/Mini-App: Unbekannt/)).toBeInTheDocument();
  });

  it('renders info message about mini-apps', () => {
    const block = makeBlock('b1', 'miniapp', { app_id: 'test' });
    render(<MiniAppBlock block={block} />);
    expect(screen.getByText(/Mini-Apps werden in Zukunft/)).toBeInTheDocument();
  });

  it('shows config details when config is provided', () => {
    const block = makeBlock('b1', 'miniapp', {
      app_id: 'test',
      config: { key: 'value', nested: { data: 123 } },
    });
    render(<MiniAppBlock block={block} />);
    expect(screen.getByText('Konfiguration')).toBeInTheDocument();
  });

  it('does not show config details when config is empty', () => {
    const block = makeBlock('b1', 'miniapp', { app_id: 'test', config: {} });
    render(<MiniAppBlock block={block} />);
    expect(screen.queryByText('Konfiguration')).not.toBeInTheDocument();
  });

  it('does not show config details when config is not an object', () => {
    const block = makeBlock('b1', 'miniapp', { app_id: 'test', config: 'not-an-object' });
    render(<MiniAppBlock block={block} />);
    expect(screen.queryByText('Konfiguration')).not.toBeInTheDocument();
  });
});
