Unverified Commit 3eaaf377 authored by Daniel's avatar Daniel Committed by GitHub

TagInfo now fires 'submitSearch' instead of using navigation (#285)

parent 2fc3f8b5
import * as React from 'react'; import * as React from 'react';
import { Link } from 'react-router-dom'; import { bindActionCreators } from 'redux'
import { connect } from 'react-redux';
import { Tag } from 'interfaces'; import { Tag } from 'interfaces';
import { logClick } from 'ducks/utilMethods'; import { logClick } from 'ducks/utilMethods';
import './styles.scss'; import './styles.scss';
import { SubmitSearchRequest } from 'ducks/search/types';
import { submitSearch } from 'ducks/search/reducer';
interface TagInfoProps { interface OwnProps {
data: Tag; data: Tag;
compact?: boolean; compact?: boolean;
} }
class TagInfo extends React.Component<TagInfoProps, {}> { export interface DispatchFromProps {
submitSearch: (searchTerm: string) => SubmitSearchRequest;
}
export type TagInfoProps = OwnProps & DispatchFromProps;
export class TagInfo extends React.Component<TagInfoProps> {
static defaultProps = { static defaultProps = {
compact: true compact: true
}; };
...@@ -20,21 +30,21 @@ class TagInfo extends React.Component<TagInfoProps, {}> { ...@@ -20,21 +30,21 @@ class TagInfo extends React.Component<TagInfoProps, {}> {
} }
onClick = (e) => { onClick = (e) => {
const name = this.props.data.tag_name;
logClick(e, { logClick(e, {
target_type: 'tag', target_type: 'tag',
label: this.props.data.tag_name, label: name,
}); });
this.props.submitSearch(`tag:${name}`);
}; };
render() { render() {
const name = this.props.data.tag_name; const name = this.props.data.tag_name;
const searchUrl = `/search?searchTerm=tag:${name}`;
return ( return (
<Link <button
id={ `tag::${name}` } id={ `tag::${name}` }
role="button" role="button"
to={ searchUrl }
className={ "btn tag-button" + (this.props.compact ? " compact" : "") } className={ "btn tag-button" + (this.props.compact ? " compact" : "") }
onClick={ this.onClick } onClick={ this.onClick }
> >
...@@ -43,9 +53,13 @@ class TagInfo extends React.Component<TagInfoProps, {}> { ...@@ -43,9 +53,13 @@ class TagInfo extends React.Component<TagInfoProps, {}> {
!this.props.compact && !this.props.compact &&
<span className="tag-count">{ this.props.data.tag_count }</span> <span className="tag-count">{ this.props.data.tag_count }</span>
} }
</Link> </button>
); );
} }
} }
export default TagInfo; export const mapDispatchToProps = (dispatch: any) => {
return bindActionCreators({ submitSearch }, dispatch);
};
export default connect<null, DispatchFromProps, OwnProps>(null, mapDispatchToProps)(TagInfo);
import * as React from 'react';
import { shallow } from 'enzyme';
import { mapDispatchToProps, TagInfo, TagInfoProps } from '../';
import * as UtilMethods from 'ducks/utilMethods';
const logClickSpy = jest.spyOn(UtilMethods, 'logClick');
logClickSpy.mockImplementation(() => null);
describe('TagInfo', () => {
const setup = (propOverrides?: Partial<TagInfoProps>) => {
const props = {
data: {
tag_name: 'testTag',
tag_count: 45,
},
compact: false,
submitSearch: jest.fn(),
...propOverrides,
};
const wrapper = shallow<TagInfo>(<TagInfo {...props} />);
return { props, wrapper };
};
describe('onClick', () => {
let props;
let wrapper;
const mockEvent = {};
beforeAll(() => {
const setupResult = setup();
props = setupResult.props;
wrapper = setupResult.wrapper;
});
it('Calls the logClick utility function', () => {
logClickSpy.mockClear();
const expectedData = {
target_type: 'tag',
label: props.data.tag_name,
};
wrapper.instance().onClick(mockEvent);
expect(logClickSpy).toHaveBeenCalledWith(mockEvent, expectedData)
});
it('it calls submitSearch', () => {
wrapper.instance().onClick(mockEvent);
expect(props.submitSearch).toHaveBeenCalledWith(`tag:${props.data.tag_name}`);
});
});
describe('render', () => {
describe('renders a normal sized tag', () => {
let props;
let wrapper;
beforeAll(() => {
const setupResult = setup();
wrapper = setupResult.wrapper;
props = setupResult.props;
});
it('renders a button with correct props', () => {
expect(wrapper.find('button').props()).toMatchObject({
id: `tag::${props.data.tag_name}`,
role: 'button',
onClick: wrapper.instance().onClick,
className: 'btn tag-button'
});
});
it('renders with correct text', () => {
expect(wrapper.text()).toEqual(props.data.tag_name + props.data.tag_count)
});
});
describe('renders a compact sized tag', () => {
let props;
let wrapper;
beforeAll(() => {
const setupResult = setup({ compact: true });
wrapper = setupResult.wrapper;
props = setupResult.props;
});
it('renders with correct text', () => {
expect(wrapper.text()).toEqual(props.data.tag_name)
});
it('renders with the correct classes', () => {
expect(wrapper.find('button').props().className).toEqual('btn tag-button compact')
});
});
});
});
describe('mapDispatchToProps', () => {
let dispatch;
let result;
beforeAll(() => {
dispatch = jest.fn(() => Promise.resolve());
result = mapDispatchToProps(dispatch);
});
it('sets submitSearch on the props', () => {
expect(result.submitSearch).toBeInstanceOf(Function);
});
});
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