TrackPanelListItem.test.tsx 6.02 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/**
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

17
import React from 'react';
18
import configureMockStore from 'redux-mock-store';
19 20
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
21
import faker from 'faker';
22 23 24 25
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import { getType } from 'typesafe-actions';
import set from 'lodash/fp/set';
26 27 28 29 30 31 32 33

import {
  TrackPanelListItem,
  TrackPanelListItemProps
} from './TrackPanelListItem';

import { createMainTrackInfo } from 'tests/fixtures/track-panel';
import { Status } from 'src/shared/types/status';
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
import { DrawerView } from 'src/content/app/browser/drawer/drawerState';

import * as drawerActions from '../../drawer/drawerActions';
import * as browserActions from 'src/content/app/browser/browserActions';
import * as trackPanelActions from 'src/content/app/browser/track-panel/trackPanelActions';

jest.mock('src/content/app/browser/browser-storage-service.ts'); // don't want to pollute localStorage

const fakeGenomeId = 'human';

const mockState = {
  drawer: {
    isDrawerOpened: { [fakeGenomeId]: false },
    drawerView: { [fakeGenomeId]: DrawerView.BOOKMARKS },
    activeDrawerTrackIds: {}
  },
  browser: {
    browserEntity: {
      activeGenomeId: fakeGenomeId,
      activeEnsObjectIds: {
        [fakeGenomeId]: faker.lorem.words()
      }
    },
    trackPanel: {
      [fakeGenomeId]: {
        highlightedTrackId: faker.lorem.words(),
        collapsedTrackIds: []
      }
    }
  }
};

const mockStore = configureMockStore([thunk]);
let store: ReturnType<typeof mockStore>;

const defaultProps: TrackPanelListItemProps = {
  categoryName: faker.lorem.words(),
  trackStatus: Status.SELECTED,
  defaultTrackStatus: Status.SELECTED,
  track: createMainTrackInfo()
};

const wrapInRedux = (state: typeof mockState = mockState) => {
  store = mockStore(state);
  return render(
    <Provider store={store}>
      <TrackPanelListItem {...defaultProps} />
    </Provider>
  );
};
84 85

describe('<TrackPanelListItem />', () => {
86
  beforeEach(() => {
87 88 89 90
    jest.resetAllMocks();
  });

  describe('rendering', () => {
91
    it('renders the track buttons', () => {
92 93
      const { container } = wrapInRedux();

94 95
      expect(container.querySelector('.ellipsisHolder')).toBeTruthy();
      expect(container.querySelector('.eyeHolder')).toBeTruthy();
96 97 98 99
    });
  });

  describe('behaviour', () => {
100
    describe('when clicked', () => {
101 102 103
      it('updates the active track id if the drawer is opened', () => {
        const { container } = wrapInRedux(
          set(`drawer.isDrawerOpened.${fakeGenomeId}`, true, mockState)
104
        );
105

106 107 108
        const track = container.querySelector('.track') as HTMLElement;

        userEvent.click(track);
109 110 111 112 113 114 115 116 117 118

        const drawerAction = store
          .getActions()
          .find(
            (action) =>
              action.type === getType(drawerActions.setActiveDrawerTrackId)
          );
        expect(drawerAction.payload).toEqual({
          [fakeGenomeId]: defaultProps.track.track_id
        });
119 120
      });

121 122
      it('does not update the active track id if the drawer is closed', () => {
        const { container } = wrapInRedux();
123 124 125
        const track = container.querySelector('.track') as HTMLElement;

        userEvent.click(track);
126 127 128 129 130 131 132 133

        const drawerAction = store
          .getActions()
          .find(
            (action) =>
              action.type === getType(drawerActions.setActiveDrawerTrackId)
          );
        expect(drawerAction).toBeFalsy();
134 135 136
      });
    });

137 138
    it('toggles the expanded/collapsed state of the track when clicked on the expand button', async () => {
      const { container } = wrapInRedux();
Andrey Azov's avatar
Andrey Azov committed
139
      const expandButton = container.querySelector('.chevron') as HTMLElement;
140 141

      userEvent.click(expandButton);
142 143 144 145 146 147 148 149 150 151 152

      const collapseTrackAction = store
        .getActions()
        .find(
          (action) =>
            action.type === getType(trackPanelActions.updateTrackPanelForGenome)
        );
      expect(collapseTrackAction.payload.activeGenomeId).toBe(fakeGenomeId);
      expect(collapseTrackAction.payload.data.collapsedTrackIds).toEqual([
        defaultProps.track.track_id
      ]);
153 154
    });

155
    it('opens/updates drawer view when clicked on the open track button', () => {
156
      const { container } = wrapInRedux();
157 158 159 160 161
      const ellipsisButton = container.querySelector(
        '.ellipsisHolder button'
      ) as HTMLElement;

      userEvent.click(ellipsisButton);
162 163 164 165 166 167 168 169 170
      const drawerToggleAction = store
        .getActions()
        .find(
          (action) =>
            action.type === getType(drawerActions.changeDrawerViewForGenome)
        );
      expect(drawerToggleAction.payload).toEqual({
        [fakeGenomeId]: DrawerView.TRACK_DETAILS
      });
171 172
    });

173
    it('toggles the track when clicked on the toggle track button', () => {
174
      const { container } = wrapInRedux();
175 176 177 178 179
      const eyeButton = container.querySelector(
        '.eyeHolder button'
      ) as HTMLElement;

      userEvent.click(eyeButton);
180 181 182 183 184 185 186 187

      const updateTracksAction = store
        .getActions()
        .find(
          (action) => action.type === getType(browserActions.updateTrackStates)
        );
      const expectedPayload = {
        [fakeGenomeId]: {
188 189 190 191 192 193
          commonTracks: {
            [defaultProps.categoryName]: {
              [defaultProps.track.track_id]: Status.UNSELECTED
            }
          }
        }
194 195 196
      };

      expect(updateTracksAction.payload).toEqual(expectedPayload);
197 198 199
    });
  });
});