<commit_before>import algoliasearchHelper, {
  SearchResults,
  SearchParameters,
} from 'algoliasearch-helper';
import { warning } from '../../../lib/utils';
import connectBreadcrumb from '../connectBreadcrumb';
import { createSearchClient } from '../../../../test/mock/createSearchClient';
import { createSingleSearchResponse } from '../../../../test/mock/createAPIResponse';
import {
  createInitOptions,
  createRenderOptions,
} from '../../../../test/mock/createWidget';

describe('connectBreadcrumb', () => {
  describe('Usage', () => {
    it('throws without render function', () => {
      expect(() => {
        // @ts-ignore
        connectBreadcrumb()({});
      }).toThrowErrorMatchingInlineSnapshot(`
"The render function is not valid (received type Undefined).

See documentation: https://www.algolia.com/doc/api-reference/widgets/breadcrumb/js/#connector"
`);
    });

    it('throws with undefined `attributes`', () => {
      expect(() => {
        connectBreadcrumb(() => {})({
          // @ts-ignore
          attributes: undefined,
        });
      }).toThrowErrorMatchingInlineSnapshot(`
"The \`attributes\` option expects an array of strings.

See documentation: https://www.algolia.com/doc/api-reference/widgets/breadcrumb/js/#connector"
`);
    });

    it('throws with empty `attributes`', () => {
      expect(() => {
        connectBreadcrumb(() => {})({
          attributes: [],
        });
      }).toThrowErrorMatchingInlineSnapshot(`
"The \`attributes\` option expects an array of strings.

See documentation: https://www.algolia.com/doc/api-reference/widgets/breadcrumb/js/#connector"
`);
    });
  });

  it('is a widget', () => {
    const render = jest.fn();
    const unmount = jest.fn();

    const customBreadcrumb = connectBreadcrumb(render, unmount);
    const widget = customBreadcrumb({ attributes: ['category'] });

    expect(widget).toEqual(
      expect.objectContaining({
        $$type: 'ais.breadcrumb',
        init: expect.any(Function),
        render: expect.any(Function),
        dispose: expect.any(Function),
      })
    );
  });

  describe('getRenderState', () => {
    test('returns the render state', () => {
      const renderFn = jest.fn();
      const unmountFn = jest.fn();
      const createBreadcrumb = connectBreadcrumb(renderFn, unmountFn);
      const breadcrumb = createBreadcrumb({
        attributes: ['category', 'subCategory'],
      });
      const helper = algoliasearchHelper(
        createSearchClient(),
        'indexName',
        breadcrumb.getWidgetSearchParameters!(new SearchParameters(), {
          uiState: {},
        })
      );

      helper.toggleRefinement('category', 'Decoration');

      const renderState1 = breadcrumb.getRenderState(
        {
          breadcrumb: {
            anotherCategory: {
              canRefine: false,
              createURL: () => '',
              items: [],
              refine: () => {},
              widgetParams: { attributes: ['anotherCategory'] },
            },
          },
        },
        createInitOptions({ helper })
      );

      expect(renderState1.breadcrumb).toEqual({
        anotherCategory: {
          canRefine: false,
          createURL: expect.any(Function),
          items: [],
          refine: expect.any(Function),
          widgetParams: { attributes: ['anotherCategory'] },
        },
        category: {
          canRefine: false,
          createURL: undefined,
          items: [],
          refine: undefined,
          widgetParams: { attributes: ['category', 'subCategory'] },
        },
      });

      breadcrumb.init!(createInitOptions({ helper }));

      const renderState2 = breadcrumb.getRenderState(
        {
          breadcrumb: {
            anotherCategory: {
              canRefine: false,
              createURL: () => '',
              items: [],
              refine: () => {},
              widgetParams: { attributes: ['anotherCategory'] },
            },
          },
        },
        createRenderOptions({
          helper,
          state: helper.state,
          results: new SearchResults(helper.state, [
            createSingleSearchResponse({
              hits: [],
              facets: {
                category: {
                  Decoration: 880,
                },
                subCategory: {
                  'Decoration > Candle holders & candles': 193,
                  'Decoration > Frames & pictures': 173,
                },
              },
            }),
            createSingleSearchResponse({
              facets: {
                category: {
                  Decoration: 880,
                  Outdoor: 47,
                },
              },
            }),
          ]),
        })
      );

      expect(renderState2.breadcrumb).toEqual({
        anotherCategory: {
          canRefine: false,
          createURL: expect.any(Function),
          items: [],
          refine: expect.any(Function),
          widgetParams: { attributes: ['anotherCategory'] },
        },
        category: {
          canRefine: true,
          createURL: expect.any(Function),
          items: [{ label: 'Decoration', value: null }],
          refine: expect.any(Function),
          widgetParams: { attributes: ['category', 'subCategory'] },
        },
      });
    });
  });

  describe('getWidgetSearchParameters', () => {
    beforeEach(() => {
      warning.cache = {};
    });

    it('returns the `SearchParameters` with default value', () => {
      const render = () => {};
      const makeWidget = connectBreadcrumb(render);
      const helper = algoliasearchHelper(createSearchClient(), '');
      const widget = makeWidget({<commit_msg>test(renderState): add tests for getWidgetRenderState at connectBreadcrumb (#4562)<commit_after>import algoliasearchHelper, {
  SearchResults,
  SearchParameters,
} from 'algoliasearch-helper';
import { warning } from '../../../lib/utils';
import connectBreadcrumb from '../connectBreadcrumb';
import { createSearchClient } from '../../../../test/mock/createSearchClient';
import { createSingleSearchResponse } from '../../../../test/mock/createAPIResponse';
import {
  createInitOptions,
  createRenderOptions,
} from '../../../../test/mock/createWidget';

describe('connectBreadcrumb', () => {
  describe('Usage', () => {
    it('throws without render function', () => {
      expect(() => {
        // @ts-ignore
        connectBreadcrumb()({});
      }).toThrowErrorMatchingInlineSnapshot(`
"The render function is not valid (received type Undefined).

See documentation: https://www.algolia.com/doc/api-reference/widgets/breadcrumb/js/#connector"
`);
    });

    it('throws with undefined `attributes`', () => {
      expect(() => {
        connectBreadcrumb(() => {})({
          // @ts-ignore
          attributes: undefined,
        });
      }).toThrowErrorMatchingInlineSnapshot(`
"The \`attributes\` option expects an array of strings.

See documentation: https://www.algolia.com/doc/api-reference/widgets/breadcrumb/js/#connector"
`);
    });

    it('throws with empty `attributes`', () => {
      expect(() => {
        connectBreadcrumb(() => {})({
          attributes: [],
        });
      }).toThrowErrorMatchingInlineSnapshot(`
"The \`attributes\` option expects an array of strings.

See documentation: https://www.algolia.com/doc/api-reference/widgets/breadcrumb/js/#connector"
`);
    });
  });

  it('is a widget', () => {
    const render = jest.fn();
    const unmount = jest.fn();

    const customBreadcrumb = connectBreadcrumb(render, unmount);
    const widget = customBreadcrumb({ attributes: ['category'] });

    expect(widget).toEqual(
      expect.objectContaining({
        $$type: 'ais.breadcrumb',
        init: expect.any(Function),
        render: expect.any(Function),
        dispose: expect.any(Function),
      })
    );
  });

  describe('getRenderState', () => {
    test('returns the render state', () => {
      const renderFn = jest.fn();
      const unmountFn = jest.fn();
      const createBreadcrumb = connectBreadcrumb(renderFn, unmountFn);
      const breadcrumb = createBreadcrumb({
        attributes: ['category', 'subCategory'],
      });
      const helper = algoliasearchHelper(
        createSearchClient(),
        'indexName',
        breadcrumb.getWidgetSearchParameters!(new SearchParameters(), {
          uiState: {},
        })
      );

      helper.toggleRefinement('category', 'Decoration');

      const renderState1 = breadcrumb.getRenderState(
        {
          breadcrumb: {
            anotherCategory: {
              canRefine: false,
              createURL: () => '',
              items: [],
              refine: () => {},
              widgetParams: { attributes: ['anotherCategory'] },
            },
          },
        },
        createInitOptions({ helper })
      );

      expect(renderState1.breadcrumb).toEqual({
        anotherCategory: {
          canRefine: false,
          createURL: expect.any(Function),
          items: [],
          refine: expect.any(Function),
          widgetParams: { attributes: ['anotherCategory'] },
        },
        category: {
          canRefine: false,
          createURL: undefined,
          items: [],
          refine: undefined,
          widgetParams: { attributes: ['category', 'subCategory'] },
        },
      });

      breadcrumb.init!(createInitOptions({ helper }));

      const renderState2 = breadcrumb.getRenderState(
        {
          breadcrumb: {
            anotherCategory: {
              canRefine: false,
              createURL: () => '',
              items: [],
              refine: () => {},
              widgetParams: { attributes: ['anotherCategory'] },
            },
          },
        },
        createRenderOptions({
          helper,
          state: helper.state,
          results: new SearchResults(helper.state, [
            createSingleSearchResponse({
              hits: [],
              facets: {
                category: {
                  Decoration: 880,
                },
                subCategory: {
                  'Decoration > Candle holders & candles': 193,
                  'Decoration > Frames & pictures': 173,
                },
              },
            }),
            createSingleSearchResponse({
              facets: {
                category: {
                  Decoration: 880,
                  Outdoor: 47,
                },
              },
            }),
          ]),
        })
      );

      expect(renderState2.breadcrumb).toEqual({
        anotherCategory: {
          canRefine: false,
          createURL: expect.any(Function),
          items: [],
          refine: expect.any(Function),
          widgetParams: { attributes: ['anotherCategory'] },
        },
        category: {
          canRefine: true,
          createURL: expect.any(Function),
          items: [{ label: 'Decoration', value: null }],
          refine: expect.any(Function),
          widgetParams: { attributes: ['category', 'subCategory'] },
        },
      });
    });
  });

  describe('getWidgetRenderState', () => {
    test('returns the widget render state', () => {
      const renderFn = jest.fn();
      const unmountFn = jest.fn();
      const createBreadcrumb = connectBreadcrumb(renderFn, unmountFn);
      const breadcrumb = createBreadcrumb({
        attributes: ['category', 'subCategory'],
      });
      const helper = algoliasearchHelper(
        createSearchClient(),
        'indexName',
        breadcrumb.getWidgetSearchParameters!(new SearchParameters(), {
          uiState: {},
        })
      );

      helper.toggleRefinement('category', 'Decoration');

      const renderState1 = breadcrumb.getWidgetRenderState(
        createInitOptions({ helper })
      );

      expect(renderState1).toEqual({
        canRefine: false,
        createURL: undefined,
        items: [],
        refine: undefined,
        widgetParams: { attributes: ['category', 'subCategory'] },
      });

      breadcrumb.init!(createInitOptions({ helper }));

      const renderState2 = breadcrumb.getWidgetRenderState(
        createRenderOptions({
          helper,
          state: helper.state,
          results: new SearchResults(helper.state, [
            createSingleSearchResponse({
              hits: [],
              facets: {
                category: {
                  Decoration: 880,
                },
                subCategory: {
                  'Decoration > Candle holders & candles': 193,
                  'Decoration > Frames & pictures': 173,
                },
              },
            }),
            createSingleSearchResponse({
              facets: {
                category: {
                  Decoration: 880,
                  Outdoor: 47,
                },
              },
            }),
          ]),
        })
      );

      expect(renderState2).toEqual({
        canRefine: true,
        createURL: expect.any(Function),
        items: [{ label: 'Decoration', value: null }],
        refine: expect.any(Function),
        widgetParams: { attributes: ['category', 'subCategory'] },
      });
    });
  });

  describe('getWidgetSearchParameters', () => {
    beforeEach(() => {
      warning.cache = {};
    });

    it('returns the `SearchParameters` with default value', () => {
      const render = () => {};
      const makeWidget = connectBreadcrumb(render);
      const helper = algoliasearchHelper(createSearchClient(), '');
      const widget = makeWidget({
{'fraction_non_alphanumeric': 0.1424341131181522, 'fraction_numerical': 0.004293751850755108, 'mean_word_length': 1.9082884822389665, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 53, 'https://': 6, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3401111', 'n_tokens_mistral': 3596, 'n_tokens_neox': 3498, 'n_words': 666}