Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
LayerTextFactoryModal.component.test.tsx 4.74 KiB
/* eslint-disable no-magic-numbers */
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { StoreType } from '@/redux/store';
import { getReduxWrapperWithStore } from '@/utils/testing/getReduxWrapperWithStore';
import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
import { GLYPHS_STATE_INITIAL_MOCK } from '@/redux/glyphs/glyphs.mock';
import { apiPath } from '@/redux/apiPath';
import { HttpStatusCode } from 'axios';
import { mockNetworkNewAPIResponse } from '@/utils/mockNetworkResponse';
import {
  LAYER_STATE_DEFAULT_DATA,
  LAYERS_STATE_INITIAL_LAYER_MOCK,
} from '@/redux/layers/layers.mock';
import { MODELS_DATA_MOCK_WITH_MAIN_MAP } from '@/redux/models/models.mock';
import { overlayFixture } from '@/models/fixtures/overlaysFixture';
import { showToast } from '@/utils/showToast';
import {
  TEXT_FONT_SIZES,
  TEXT_HORIZONTAL_ALIGNMENTS,
  TEXT_VERTICAL_ALIGNMENTS,
} from '@/components/FunctionalArea/Modal/LayerTextFactoryModal/LayerTextFactory.constants';
import { layerTextFixture } from '@/models/fixtures/layerTextFixture';
import { LayerTextFactoryModal } from './LayerTextFactoryModal.component';

const mockedAxiosNewClient = mockNetworkNewAPIResponse();

const glyph = { id: 1, file: 23, filename: 'Glyph1.png' };

jest.mock('../../../../utils/showToast');

const renderComponent = (): { store: StoreType } => {
  const { Wrapper, store } = getReduxWrapperWithStore({
    ...INITIAL_STORE_STATE_MOCK,
    glyphs: {
      ...GLYPHS_STATE_INITIAL_MOCK,
      data: [glyph],
    },
    layers: {
      0: {
        ...LAYERS_STATE_INITIAL_LAYER_MOCK,
        data: {
          ...LAYER_STATE_DEFAULT_DATA,
          activeLayer: 1,
        },
      },
    },
    modal: {
      isOpen: true,
      modalTitle: overlayFixture.name,
      modalName: 'edit-overlay',
      editOverlayState: overlayFixture,
      molArtState: {},
      overviewImagesState: {},
      errorReportState: {},
      layerFactoryState: { id: undefined },
      layerImageObjectFactoryState: undefined,
      layerTextFactoryState: {
        x: 1,
        y: 1,
        width: 1,
        height: 1,
      },
    },
    models: {
      ...MODELS_DATA_MOCK_WITH_MAIN_MAP,
    },
  });

  return {
    store,
    ...render(
      <Wrapper>
        <LayerTextFactoryModal />
      </Wrapper>,
    ),
  };
};

describe('LayerTextFactoryModal - component', () => {
  it('should render LayerTextFactoryModal component with initial state', () => {
    renderComponent();

    expect(screen.getByText('Font size:')).toBeInTheDocument();
    expect(screen.getByText('Horizontal alignment:')).toBeInTheDocument();
    expect(screen.getByText('Vertical alignment:')).toBeInTheDocument();
    expect(screen.getByText('Color:')).toBeInTheDocument();
    expect(screen.getByText('Border color:')).toBeInTheDocument();
  });

  it('should display a list of fontSizes in the dropdown', async () => {
    renderComponent();
    const dropdown = screen.getByTestId('font-size-select');
    if (!dropdown.firstChild) {
      throw new Error('Dropdown does not have a firstChild');
    }
    fireEvent.click(dropdown.firstChild);
    await waitFor(() => expect(screen.getByText(TEXT_FONT_SIZES[0])).toBeInTheDocument());
    fireEvent.click(screen.getByText(TEXT_FONT_SIZES[0]));
  });

  it('should display a list of text horizontal alignments in the dropdown', async () => {
    renderComponent();
    const dropdown = screen.getByTestId('horizontal-alignment-select');
    if (!dropdown.firstChild) {
      throw new Error('Dropdown does not have a firstChild');
    }
    fireEvent.click(dropdown.firstChild);
    await waitFor(() => {
      const listItem = screen.getByRole('option', { name: TEXT_HORIZONTAL_ALIGNMENTS[0].name });
      return expect(listItem).toBeInTheDocument();
    });
  });

  it('should display a list of text vertical alignments in the dropdown', async () => {
    renderComponent();
    const dropdown = screen.getByTestId('vertical-alignment-select');
    if (!dropdown.firstChild) {
      throw new Error('Dropdown does not have a firstChild');
    }
    fireEvent.click(dropdown.firstChild);
    await waitFor(() => {
      const listItem = screen.getByRole('option', { name: TEXT_VERTICAL_ALIGNMENTS[0].name });
      return expect(listItem).toBeInTheDocument();
    });
  });

  it('should handle form submission correctly', async () => {
    mockedAxiosNewClient
      .onPost(apiPath.addLayerText(0, 1))
      .reply(HttpStatusCode.Ok, layerTextFixture);
    renderComponent();

    const submitButton = screen.getByText(/Submit/i);

    await act(async () => {
      fireEvent.click(submitButton);
    });

    expect(showToast).toHaveBeenCalledWith({
      message: 'A new text has been successfully added',
      type: 'success',
    });
  });
});