Загрузка данных


import { render } from '@testing-library/react';
import React from 'react';

import { InstrumentSearch } from '@components/InstrumentSearch';

import { SymbolSearchModal } from '../components/MoexChart/components/SymbolSearchModal';

import type { Contract } from '@modules/contracts';

jest.mock('@components/InstrumentSearch', () => ({
  InstrumentSearch: jest.fn(() => null),
}));

interface InstrumentSearchMockProps {
  widgetId: number;
  variant: string;
  isOpen: boolean;
  setOpen: (isOpen: boolean) => void;
  addInstruments: (instruments: Contract[]) => void;
}

describe('SymbolSearchModal', () => {
  const mockInstrumentSearch = InstrumentSearch as jest.Mock;

  const mockSetOpen = jest.fn();
  const mockOnSymbolChange = jest.fn();

  const renderComponent = (): InstrumentSearchMockProps => {
    render(
      <SymbolSearchModal
        widgetId={42}
        isOpen
        setOpen={mockSetOpen}
        onSymbolChange={mockOnSymbolChange}
      />,
    );

    return mockInstrumentSearch.mock.calls[0]?.[0] as InstrumentSearchMockProps;
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('should pass modal properties to instrument search', () => {
    // Arrange & Act
    const instrumentSearchProps = renderComponent();

    // Assert
    expect(instrumentSearchProps.widgetId).toBe(42);
    expect(instrumentSearchProps.variant).toBe('single');
    expect(instrumentSearchProps.isOpen).toBe(true);
    expect(instrumentSearchProps.setOpen).toBe(mockSetOpen);
    expect(instrumentSearchProps.addInstruments).toEqual(
      expect.any(Function),
    );
  });

  it('should pass selected instrument after instrument selection', () => {
    // Arrange
    const instrumentSearchProps = renderComponent();

    const instrument = {
      issKey: 'MOEX:SBER',
      displayName: 'Сбербанк',
    } as Contract;

    // Act
    instrumentSearchProps.addInstruments([instrument]);

    // Assert
    expect(mockOnSymbolChange).toHaveBeenCalledTimes(1);
    expect(mockOnSymbolChange).toHaveBeenCalledWith(instrument);
  });

  it('should close modal after instrument selection', () => {
    // Arrange
    const instrumentSearchProps = renderComponent();

    const instrument = {
      issKey: 'MOEX:SBER',
      displayName: 'Сбербанк',
    } as Contract;

    // Act
    instrumentSearchProps.addInstruments([instrument]);

    // Assert
    expect(mockSetOpen).toHaveBeenCalledTimes(1);
    expect(mockSetOpen).toHaveBeenCalledWith(false);
  });

  it('should not change instrument when instruments list is empty', () => {
    // Arrange
    const instrumentSearchProps = renderComponent();

    // Act
    instrumentSearchProps.addInstruments([]);

    // Assert
    expect(mockOnSymbolChange).not.toHaveBeenCalled();
    expect(mockSetOpen).not.toHaveBeenCalled();
  });

  it('should not change instrument when selected instrument has no issKey', () => {
    // Arrange
    const instrumentSearchProps = renderComponent();

    // Act
    instrumentSearchProps.addInstruments([{} as Contract]);

    // Assert
    expect(mockOnSymbolChange).not.toHaveBeenCalled();
    expect(mockSetOpen).not.toHaveBeenCalled();
  });

  it('should not change instrument when selected instrument has empty issKey', () => {
    // Arrange
    const instrumentSearchProps = renderComponent();

    const instrument = {
      issKey: '',
      displayName: 'Сбербанк',
    } as Contract;

    // Act
    instrumentSearchProps.addInstruments([instrument]);

    // Assert
    expect(mockOnSymbolChange).not.toHaveBeenCalled();
    expect(mockSetOpen).not.toHaveBeenCalled();
  });
});