go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/generic_libs/components/expandable_entry/expandable_entry.test.tsx (about)

     1  // Copyright 2022 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  import { fireEvent, render, screen } from '@testing-library/react';
    16  
    17  import {
    18    ExpandableEntry,
    19    ExpandableEntryBody,
    20    ExpandableEntryHeader,
    21  } from './expandable_entry';
    22  
    23  describe('ExpandableEntry', () => {
    24    test('collapsed', () => {
    25      render(
    26        <ExpandableEntry expanded={false}>
    27          <ExpandableEntryHeader onToggle={() => {}}>
    28            <span>Header</span>
    29          </ExpandableEntryHeader>
    30          <ExpandableEntryBody>
    31            <span>Content</span>
    32          </ExpandableEntryBody>
    33        </ExpandableEntry>,
    34      );
    35  
    36      expect(screen.findByTestId('ChevronRightIcon')).not.toBeNull();
    37      expect(screen.queryByText('Header')).not.toBeNull();
    38      expect(screen.queryByText('Content')).toBeNull();
    39    });
    40  
    41    test('expanded', () => {
    42      render(
    43        <ExpandableEntry expanded={true}>
    44          <ExpandableEntryHeader onToggle={() => {}}>
    45            <span>Header</span>
    46          </ExpandableEntryHeader>
    47          <ExpandableEntryBody>
    48            <span>Content</span>
    49          </ExpandableEntryBody>
    50        </ExpandableEntry>,
    51      );
    52  
    53      expect(screen.getByTestId('ExpandMoreIcon')).not.toBeNull();
    54      expect(screen.queryByText('Header')).not.toBeNull();
    55      expect(screen.queryByText('Content')).not.toBeNull();
    56    });
    57  
    58    test('onToggle should be fired when the header is clicked', () => {
    59      const onToggleStub = jest.fn();
    60      const { rerender } = render(
    61        <ExpandableEntry expanded={false}>
    62          <ExpandableEntryHeader onToggle={onToggleStub}>
    63            <span>Header</span>
    64          </ExpandableEntryHeader>
    65          <ExpandableEntryBody>
    66            <span>Content</span>
    67          </ExpandableEntryBody>
    68        </ExpandableEntry>,
    69      );
    70  
    71      let headerIconEle = screen.getByTestId('ChevronRightIcon');
    72      const headerContentEle = screen.getByText('Header');
    73  
    74      expect(onToggleStub.mock.calls.length).toStrictEqual(0);
    75      fireEvent.click(headerIconEle);
    76      expect(onToggleStub.mock.calls.length).toStrictEqual(1);
    77      expect(onToggleStub.mock.lastCall).toEqual([true]);
    78  
    79      // Clicking on the header the second time should not change the param passed
    80      // to onToggle.
    81      fireEvent.click(headerIconEle);
    82      expect(onToggleStub.mock.calls.length).toStrictEqual(2);
    83      expect(onToggleStub.mock.lastCall).toEqual([true]);
    84  
    85      // Clicking on the header content should work as well.
    86      fireEvent.click(headerContentEle);
    87      expect(onToggleStub.mock.calls.length).toStrictEqual(3);
    88      expect(onToggleStub.mock.lastCall).toEqual([true]);
    89  
    90      rerender(
    91        <ExpandableEntry expanded={true}>
    92          <ExpandableEntryHeader onToggle={onToggleStub}>
    93            <span>Header</span>
    94          </ExpandableEntryHeader>
    95          <ExpandableEntryBody>
    96            <span>Content</span>
    97          </ExpandableEntryBody>
    98        </ExpandableEntry>,
    99      );
   100  
   101      headerIconEle = screen.getByTestId('ExpandMoreIcon');
   102  
   103      // Updating the expanded prop is updated should change the param passed to
   104      // onToggle.
   105      expect(onToggleStub.mock.calls.length).toStrictEqual(3);
   106      fireEvent.click(headerIconEle);
   107      expect(onToggleStub.mock.calls.length).toStrictEqual(4);
   108      expect(onToggleStub.mock.lastCall).toEqual([false]);
   109    });
   110  });