Unverified Commit 71383b15 authored by Ryan Lieu's avatar Ryan Lieu Committed by GitHub

Moved PopularTables out into separate component (#183)

* moved PopularTables out into separate component

* added tests

* fixed linting issues

* removed bookmarklist from populartables

* fixed tests

* addressed comments

* move populartables component to common

* removed unecessary boiler plate, improved tests
parent 90bb34a5
......@@ -6,10 +6,6 @@ export const DOCUMENT_TITLE_SUFFIX = ' - Amundsen Search';
export const PAGE_INDEX_ERROR_MESSAGE = 'Page index out of bounds for available matches';
export const POPULAR_TABLES_INFO_TEXT = 'These are some of the most commonly accessed tables within your organization.';
export const POPULAR_TABLES_LABEL = 'Popular Tables';
export const POPULAR_TABLES_SOURCE_NAME = 'popular_tables';
export const SEARCH_INFO_TEXT = `Ordered by the relevance of matches within a resource's metadata, as well as overall usage.`;
export const SEARCH_SOURCE_NAME = 'search_results';
export const SEARCH_ERROR_MESSAGE_INFIX = ' - did not match any ';
......
......@@ -9,6 +9,7 @@ import { RouteComponentProps } from 'react-router';
import SearchBar from './SearchBar';
import SearchList from './SearchList';
import LoadingSpinner from 'components/common/LoadingSpinner';
import PopularTables from 'components/common/PopularTables';
import BookmarkList from 'components/common/Bookmark/BookmarkList'
import InfoButton from 'components/common/InfoButton';
......@@ -25,8 +26,6 @@ import {
TableSearchResults,
UserSearchResults
} from 'ducks/search/types';
import { getPopularTables } from 'ducks/popularTables/reducer';
import { GetPopularTablesRequest } from 'ducks/popularTables/types';
// TODO: Use css-modules instead of 'import'
import './styles.scss';
......@@ -35,9 +34,6 @@ import {
DOCUMENT_TITLE_SUFFIX,
PAGE_INDEX_ERROR_MESSAGE,
PAGINATION_PAGE_RANGE,
POPULAR_TABLES_INFO_TEXT,
POPULAR_TABLES_LABEL,
POPULAR_TABLES_SOURCE_NAME,
RESULTS_PER_PAGE,
SEARCH_ERROR_MESSAGE_INFIX,
SEARCH_ERROR_MESSAGE_PREFIX,
......@@ -50,7 +46,6 @@ import {
export interface StateFromProps {
searchTerm: string;
isLoading: boolean;
popularTables: TableResource[];
tables: TableSearchResults;
dashboards: DashboardSearchResults;
users: UserSearchResults;
......@@ -59,7 +54,6 @@ export interface StateFromProps {
export interface DispatchFromProps {
searchAll: (term: string, options?: SearchAllOptions) => SearchAllRequest;
searchResource: (resource: ResourceType, term: string, pageIndex: number) => SearchResourceRequest;
getPopularTables: () => GetPopularTablesRequest;
}
export type SearchPageProps = StateFromProps & DispatchFromProps & RouteComponentProps<any>;
......@@ -80,7 +74,6 @@ export class SearchPage extends React.Component<SearchPageProps, SearchPageState
}
componentDidMount() {
this.props.getPopularTables();
const params = qs.parse(this.props.location.search);
const { searchTerm, pageIndex, selectedTab } = params;
const { term, index, currentTab } = this.getSanitizedUrlParams(searchTerm, pageIndex, selectedTab);
......@@ -166,20 +159,12 @@ export class SearchPage extends React.Component<SearchPageProps, SearchPageState
};
renderPopularTables = () => {
const searchListParams = {
source: POPULAR_TABLES_SOURCE_NAME,
paginationStartIndex: 0,
};
return (
<div className="search-list-container">
<BookmarkList />
<div className="popular-tables-header">
<label className="title-1">{POPULAR_TABLES_LABEL}</label>
<InfoButton infoText={POPULAR_TABLES_INFO_TEXT}/>
</div>
<SearchList results={ this.props.popularTables } params={ searchListParams }/>
</div>
)
<div className="search-list-container">
<BookmarkList />
<PopularTables />
</div>
)
};
renderSearchResults = () => {
......@@ -294,7 +279,6 @@ export const mapStateToProps = (state: GlobalState) => {
return {
searchTerm: state.search.search_term,
isLoading: state.search.isLoading,
popularTables: state.popularTables,
tables: state.search.tables,
users: state.search.users,
dashboards: state.search.dashboards,
......@@ -302,7 +286,7 @@ export const mapStateToProps = (state: GlobalState) => {
};
export const mapDispatchToProps = (dispatch: any) => {
return bindActionCreators({ searchAll, searchResource, getPopularTables } , dispatch);
return bindActionCreators({ searchAll, searchResource } , dispatch);
};
export default connect<StateFromProps, DispatchFromProps>(mapStateToProps, mapDispatchToProps)(SearchPage);
......@@ -14,14 +14,6 @@
}
}
.popular-tables-header {
display: flex;
flex-direction: row;
margin-bottom: 32px;
}
.tab-content {
.search-list-header {
display: flex;
......
......@@ -10,9 +10,6 @@ import {
DOCUMENT_TITLE_SUFFIX,
PAGINATION_PAGE_RANGE,
PAGE_INDEX_ERROR_MESSAGE,
POPULAR_TABLES_INFO_TEXT,
POPULAR_TABLES_LABEL,
POPULAR_TABLES_SOURCE_NAME,
RESULTS_PER_PAGE,
SEARCH_ERROR_MESSAGE_INFIX,
SEARCH_ERROR_MESSAGE_PREFIX,
......@@ -30,6 +27,8 @@ import SearchList from '../SearchList';
import globalState from 'fixtures/globalState';
import LoadingSpinner from 'components/common/LoadingSpinner';
import BookmarkList from 'components/common/Bookmark/BookmarkList';
import PopularTables from 'components/common/PopularTables';
describe('SearchPage', () => {
const setStateSpy = jest.spyOn(SearchPage.prototype, 'setState');
......@@ -37,13 +36,11 @@ describe('SearchPage', () => {
const props: SearchPageProps = {
searchTerm: globalState.search.search_term,
isLoading: false,
popularTables: globalState.popularTables,
dashboards: globalState.search.dashboards,
tables: globalState.search.tables,
users: globalState.search.users,
searchAll: jest.fn(),
searchResource: jest.fn(),
getPopularTables: jest.fn(),
history: {
length: 2,
action: "POP",
......@@ -116,10 +113,6 @@ describe('SearchPage', () => {
wrapper.instance().componentDidMount();
});
it('calls props.getPopularTables', () => {
expect(props.getPopularTables).toHaveBeenCalled();
});
it('calls setState', () => {
expect(setStateSpy).toHaveBeenCalledWith({ selectedTab: mockSanitizedUrlParams.currentTab });
});
......@@ -642,33 +635,11 @@ describe('SearchPage', () => {
});
describe('renderPopularTables', () => {
let content;
let props;
let wrapper;
beforeAll(() => {
const setupResult = setup({ searchTerm: '' });
props = setupResult.props;
wrapper = setupResult.wrapper;
content = shallow(wrapper.instance().renderPopularTables());
});
it('renders correct label for content', () => {
expect(content.children().at(1).find('label').text()).toEqual(POPULAR_TABLES_LABEL);
});
it('renders InfoButton with correct props', () => {
expect(content.children().at(1).find(InfoButton).props()).toMatchObject({
infoText: POPULAR_TABLES_INFO_TEXT,
});
});
it('renders SearchList with correct props', () => {
expect(content.children().find(SearchList).props()).toMatchObject({
results: props.popularTables,
params: {
source: POPULAR_TABLES_SOURCE_NAME,
paginationStartIndex: 0,
},
});
it('renders bookmark list and popular tables', () => {
const {props, wrapper} = setup();
wrapper.instance().renderPopularTables();
expect(wrapper.contains(<BookmarkList />));
expect(wrapper.contains(<PopularTables />));
});
});
......@@ -746,10 +717,6 @@ describe('mapDispatchToProps', () => {
it('sets searchResource on the props', () => {
expect(result.searchResource).toBeInstanceOf(Function);
});
it('sets getPopularTables on the props', () => {
expect(result.getPopularTables).toBeInstanceOf(Function);
});
});
describe('mapStateToProps', () => {
......@@ -766,10 +733,6 @@ describe('mapStateToProps', () => {
expect(result.isLoading).toEqual(globalState.search.isLoading);
});
it('sets popularTables on the props', () => {
expect(result.popularTables).toEqual(globalState.popularTables);
});
it('sets tables on the props', () => {
expect(result.tables).toEqual(globalState.search.tables);
});
......
// TODO: Hard-coded text strings should be translatable/customizable
export const POPULAR_TABLES_INFO_TEXT = 'These are some of the most commonly accessed tables within your organization.';
export const POPULAR_TABLES_LABEL = 'Popular Tables';
export const POPULAR_TABLES_SOURCE_NAME = 'popular_tables';
import * as React from 'react';
// TODO: Use css-modules instead of 'import'
import './styles.scss';
import { POPULAR_TABLES_LABEL, POPULAR_TABLES_INFO_TEXT, POPULAR_TABLES_SOURCE_NAME } from './constants';
import InfoButton from 'components/common/InfoButton';
import SearchList from 'components/SearchPage/SearchList';
import { getPopularTables } from 'ducks/popularTables/reducer';
import { GetPopularTablesRequest, TableResource } from 'ducks/popularTables/types';
import { GlobalState } from 'ducks/rootReducer';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
export interface StateFromProps {
popularTables: TableResource[];
}
export interface DispatchFromProps {
getPopularTables: () => GetPopularTablesRequest;
}
export type PopularTablesProps = StateFromProps & DispatchFromProps;
export class PopularTables extends React.Component<PopularTablesProps> {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.getPopularTables();
}
render() {
return (
<>
<div className="popular-tables-header">
<label className="title-1">{POPULAR_TABLES_LABEL}</label>
<InfoButton infoText={POPULAR_TABLES_INFO_TEXT} />
</div>
<SearchList
results={this.props.popularTables}
params={{
source: POPULAR_TABLES_SOURCE_NAME,
paginationStartIndex: 0,
}}
/>
</>
);
}
}
export const mapStateToProps = (state: GlobalState) => {
return {
popularTables: state.popularTables,
};
};
export const mapDispatchToProps = (dispatch: any) => {
return bindActionCreators({ getPopularTables }, dispatch);
};
export default connect<StateFromProps, DispatchFromProps>(mapStateToProps, mapDispatchToProps)(PopularTables);
@import 'variables';
.popular-tables-header {
display: flex;
flex-direction: row;
margin-bottom: 32px;
}
import * as React from 'react';
import { shallow } from 'enzyme';
import {
POPULAR_TABLES_INFO_TEXT,
POPULAR_TABLES_LABEL,
POPULAR_TABLES_SOURCE_NAME,
} from '../constants';
import InfoButton from 'components/common/InfoButton';
import SearchList from 'components/SearchPage/SearchList';
import globalState from 'fixtures/globalState';
import { PopularTables, PopularTablesProps, mapStateToProps, mapDispatchToProps } from '..';
describe('PopularTables', () => {
const setup = (propOverrides?: Partial<PopularTablesProps>) => {
const props: PopularTablesProps = {
popularTables: jest.fn() as any,
getPopularTables: jest.fn(),
...propOverrides
};
const wrapper = shallow<PopularTables>(<PopularTables {...props} />)
return { props, wrapper };
};
let wrapper;
let props;
describe('componentDidMount', () => {
let getPopularTablesSpy;
beforeAll(() => {
const setupResult = setup();
wrapper = setupResult.wrapper;
props = setupResult.props;
getPopularTablesSpy = jest.spyOn(props, 'getPopularTables');
});
it('calls getPopularTables', () => {
expect(getPopularTablesSpy).toHaveBeenCalled();
});
});
describe('mapStateToProps', () => {
let result;
beforeAll(() => {
result = mapStateToProps(globalState);
});
it('sets popularTables on the props', () => {
expect(result.popularTables).toEqual(globalState.popularTables);
});
});
describe('mapDispatchToProps', () => {
let result;
beforeAll(() => {
const dispatch = jest.fn(() => Promise.resolve());
result = mapDispatchToProps(dispatch);
});
it('sets getPopularTables on the props', () => {
expect(result.getPopularTables).toBeInstanceOf(Function);
});
});
describe('render', () => {
beforeAll(() => {
const setupResult = setup();
wrapper = setupResult.wrapper;
props = setupResult.props;
});
it('renders correct label for content', () => {
expect(wrapper.children().find('label').text()).toEqual(POPULAR_TABLES_LABEL);
});
it('renders InfoButton with correct props', () => {
expect(wrapper.children().find(InfoButton).props()).toMatchObject({
infoText: POPULAR_TABLES_INFO_TEXT,
});
});
it('renders SearchList with correct props', () => {
expect(wrapper.children().find(SearchList).props()).toMatchObject({
results: props.popularTables,
params: {
source: POPULAR_TABLES_SOURCE_NAME,
paginationStartIndex: 0,
},
});
});
});
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment