Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(search): update search to functional component #10072

Merged
merged 20 commits into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,3 @@ describe('ModalHeader', () => {
expect(container.firstChild).toHaveTextContent('Carbon label');
});
});

// TODO: write tests for composed modal
// TODO: write tests for modal body
// TODO: write tests for modal footer
12 changes: 10 additions & 2 deletions packages/react/src/components/Search/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
/**
* Copyright IBM Corp. 2016, 2018
* Copyright IBM Corp. 2016, 2021
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import * as FeatureFlags from '@carbon/feature-flags';
import { default as SearchNext } from './next/Search';
import { default as SearchClassic } from './Search';

const Search = FeatureFlags.enabled('enable-v11-release')
? SearchNext
: SearchClassic;

export * from './Search.Skeleton';
export default from './Search';

export default Search;
281 changes: 281 additions & 0 deletions packages/react/src/components/Search/next/Search-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
/**
* Copyright IBM Corp. 2016, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import React from 'react';
import { Search16, Close16 } from '@carbon/icons-react';
import Search from './Search';
import { mount, shallow } from 'enzyme';
import { settings } from 'carbon-components';

const { prefix } = settings;

describe('Search', () => {
describe('renders as expected', () => {
const wrapper = mount(
<Search
id="test"
className="extra-class"
label="Search Field"
labelText="testlabel"
/>
);

const label = wrapper.find('label');
const textInput = wrapper.find('input');
const container = wrapper.find(`.${prefix}--search`);

describe('container', () => {
it('should add extra classes that are passed via className', () => {
expect(container.hasClass('extra-class')).toEqual(true);
});
});

describe('input', () => {
it('renders as expected', () => {
expect(textInput.length).toBe(1);
});

it('has the expected classes', () => {
expect(textInput.hasClass(`${prefix}--search-input`)).toEqual(true);
});

it('should set type as expected', () => {
expect(textInput.props().type).toEqual('text');
wrapper.setProps({ type: 'email' });
expect(wrapper.find('input').props().type).toEqual('email');
});

it('should set value as expected', () => {
expect(textInput.props().defaultValue).toEqual(undefined);
wrapper.setProps({ defaultValue: 'test' });
expect(wrapper.find('input').props().defaultValue).toEqual('test');
expect(wrapper.find('input').props().value).toEqual(undefined);
});

it('should set placeholder as expected', () => {
expect(textInput.props().placeholder).toEqual('');
wrapper.setProps({ placeholder: 'Enter text' });
expect(wrapper.find('input').props().placeholder).toEqual('Enter text');
});
});

describe('label', () => {
it('renders a label', () => {
expect(label.length).toBe(1);
});

it('has the expected classes', () => {
expect(label.hasClass(`${prefix}--label`)).toEqual(true);
});

it('should set label as expected', () => {
expect(wrapper.props().label).toEqual('Search Field');
wrapper.setProps({ label: 'Email Input' });
expect(wrapper.props().label).toEqual('Email Input');
});
});

describe('Large Search', () => {
const large = mount(
<Search
id="test"
size="lg"
className="extra-class"
label="Search Field"
labelText="testlabel"
/>
);

const largeContainer = large.find(`.${prefix}--search`);

it('renders correct search icon', () => {
const icons = large.find(Search16);
expect(icons.length).toBe(1);
});

it('should have the expected large class', () => {
expect(largeContainer.hasClass(`${prefix}--search--lg`)).toEqual(true);
});

it('should only have 1 button (clear)', () => {
const btn = large.find('button');
expect(btn.length).toEqual(1);
});

it('renders two Icons', () => {
const iconTypes = [Search16, Close16];
const icons = large.findWhere((n) => iconTypes.includes(n.type()));
expect(icons.length).toEqual(2);
});

describe('buttons', () => {
const btns = wrapper.find('button');

it('should be one button', () => {
expect(btns.length).toBe(1);
});

it('should have type="button"', () => {
const type1 = btns.first().instance().getAttribute('type');
const type2 = btns.last().instance().getAttribute('type');
expect(type1).toEqual('button');
expect(type2).toEqual('button');
});
});

describe('icons', () => {
it('renders "search" icon', () => {
const icons = wrapper.find(Search16);
expect(icons.length).toBe(1);
});

it('renders two Icons', () => {
wrapper.setProps({ size: undefined });
const iconTypes = [Search16, Close16];
const icons = wrapper.findWhere((n) => iconTypes.includes(n.type()));
expect(icons.length).toEqual(2);
});
});
});

describe('Small Search', () => {
const small = mount(
<Search
id="test"
size="sm"
className="extra-class"
label="Search Field"
labelText="testlabel"
/>
);

const smallContainer = small.find(`.${prefix}--search`);

it('renders correct search icon', () => {
const icons = small.find(Search16);
expect(icons.length).toBe(1);
});

it('should have the expected small class', () => {
expect(smallContainer.hasClass(`${prefix}--search--sm`)).toEqual(true);
});

it('should only have 1 button (clear)', () => {
const btn = small.find('button');
expect(btn.length).toEqual(1);
});

it('renders two Icons', () => {
const iconTypes = [Search16, Close16];
const icons = wrapper.findWhere((n) => iconTypes.includes(n.type()));
expect(icons.length).toEqual(2);
});
});
});

describe('events', () => {
describe('enabled textinput', () => {
const onClick = jest.fn();
const onChange = jest.fn();
const onClear = jest.fn();

const wrapper = shallow(
<Search
id="test"
labelText="testlabel"
onClick={onClick}
onChange={onChange}
onClear={onClear}
/>
);

const input = wrapper.find('input');
const eventObject = {
target: {
defaultValue: 'test',
},
};

it('should invoke onClick when input is clicked', () => {
input.simulate('click');
expect(onClick).toHaveBeenCalled();
});

it('should invoke onChange when input value is changed', () => {
input.simulate('change', eventObject);
expect(onChange).toHaveBeenCalledWith(eventObject);
});

it('should call onClear when input value is cleared', () => {
const node = document.createElement('div');
document.body.appendChild(node);

const wrapper = mount(
<Search
id="test"
labelText="testlabel"
onClear={onClear}
value="test"
/>,
{
attachTo: node,
}
);

wrapper.find('button').simulate('click', {
target: {
value: 'test',
},
});
expect(onClear).toHaveBeenCalled();
expect(wrapper.find('input').getDOMNode()).toHaveFocus();

document.body.removeChild(node);
});
});
});
});

/**
* Find the <input> element.
* @param {Enzymecontainer} wrapper
* @returns {Enzymecontainer}
*/
const getInput = (wrapper) => {
return wrapper.find(`.${prefix}--search-input`);
};

/**
* Find the value of the <input> element
* @param {EnzymeWrapper} wrapper
* @returns {number}
*/
const getInputValue = (wrapper) => {
return getInput(wrapper).prop('value');
};

describe('Detecting change in value from props', () => {
it('should have empty value', () => {
const search = shallow(
<Search id="test" className="extra-class" labelText="testlabel" />
);
expect(getInputValue(search)).toBe(undefined);
});

it('should set value if value prop is added', () => {
const search = shallow(
<Search
id="test"
className="extra-class"
labelText="testlabel"
value="foo"
/>
);

expect(getInputValue(search)).toBe('foo');
});
});
Loading