Skip to content

Commit

Permalink
Tests and storybook updates
Browse files Browse the repository at this point in the history
  • Loading branch information
TowhidKashem committed Jul 3, 2020
1 parent d65ea78 commit b537703
Show file tree
Hide file tree
Showing 23 changed files with 248 additions and 95 deletions.
3 changes: 1 addition & 2 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ module.exports = {
stories: ['../src/**/*.stories.js'],
addons: [
'@storybook/preset-create-react-app',
// '@storybook/addon-actions',
'@storybook/addon-links',
'@storybook/addon-actions',
'@storybook/addon-knobs/register'
]
};
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
"devDependencies": {
"@storybook/addon-actions": "^5.3.19",
"@storybook/addon-knobs": "^5.3.19",
"@storybook/addon-links": "^5.3.19",
"@storybook/addons": "^5.3.19",
"@storybook/preset-create-react-app": "^3.1.1",
"@storybook/react": "^5.3.19",
Expand Down
2 changes: 1 addition & 1 deletion public/api/session.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": 123,
"username": "Towhid",
"avatar": "https://pngimage.net/wp-content/uploads/2019/05/bitmoji-png-1.png",
"avatar": "./images/bitmoji-self-head.png",
"gender": "male",
"age": 31,
"fullName": "Towhid Kashem"
Expand Down
File renamed without changes
Binary file added public/images/bitmoji-self-head.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions src/AppShell/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface Props {
hideDrawer: HideDrawer;
footerType: FooterType;
setFooterType: SetFooterType;
avatar: string;
getSession: () => void;
getFriends: () => void;
getPhotos: () => void;
Expand All @@ -33,6 +34,7 @@ const AppShell: React.FC<Props> = ({
hideDrawer,
footerType,
setFooterType,
avatar,
getSession,
getFriends,
getPhotos,
Expand All @@ -48,7 +50,7 @@ const AppShell: React.FC<Props> = ({
return (
<>
<Toolbar drawers={drawers} />
<Header showDrawer={showDrawer} />
<Header avatar={avatar} showDrawer={showDrawer} />
<section className="view">{children}</section>
{drawers && <Drawer drawers={drawers} />}
<Footer
Expand All @@ -62,11 +64,12 @@ const AppShell: React.FC<Props> = ({
);
};

const mapStateToProps = ({ app, users, media }) => ({
const mapStateToProps = ({ app, user, users, media }) => ({
users,
media,
drawers: app.drawers,
footerType: app.footerType
footerType: app.footerType,
avatar: user.session.avatar
});

const mapDispatchToProps = (dispatch) => ({
Expand Down
17 changes: 0 additions & 17 deletions src/common/Avatar/index.test.js

This file was deleted.

25 changes: 25 additions & 0 deletions src/common/Avatar/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { shallow } from 'enzyme';
import Avatar, { sizeType, sizeMap } from './index';

const defaultProps = { src: '' };

describe('<Avatar />', () => {
it('renders without crashing', () => {
const component = shallow(<Avatar {...defaultProps} />);
expect(component.length).toBe(1);
});

it('loads img tag with the url as src', () => {
const src = '/path/to/img.png';
const component = shallow(<Avatar src={src} />);
expect(component.find('img').prop('src')).toEqual(src);
});

it('can pass different sizes', () => {
Object.keys(sizeMap).forEach((size) => {
const component = shallow(<Avatar {...defaultProps} size={size as sizeType} />);
expect(component.find('img').prop('width')).toEqual(sizeMap[size]);
});
});
});
4 changes: 3 additions & 1 deletion src/common/Avatar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import './index.scss';

export type sizeType = 'sm' | 'md' | 'lg';

interface Props {
src: string;
size?: 'sm' | 'md' | 'lg';
size?: sizeType;
}

export const sizeMap = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ describe('<Button />', () => {
});

it('image button', () => {
const image = '/dev/null/img.png';
const image = '/path/to/img.png';
const component = shallow(<Button image={image} />);
expect(component.find('img').prop('src')).toEqual(image);
});

it('single icon button', () => {
const icon = 'faCamera';
const component = shallow(<Button icon={icon} />);
expect(component.find(Icon)).toHaveLength(1);
expect(component.find(Icon).prop('icon')).toEqual(icon);
});

it('multiple icons button', () => {
const icons = ['faCamera', 'faCompass'];
const component = shallow(<Button icons={icons} />);
Expand All @@ -30,10 +37,18 @@ describe('<Button />', () => {
});
});

it('single icon button', () => {
const icon = 'faCamera';
const component = shallow(<Button icon={icon} />);
expect(component.find(Icon)).toHaveLength(1);
expect(component.find(Icon).prop('icon')).toEqual(icon);
it('`purple`, `round` and `plain` buttons', () => {
['purple', 'round', 'plain'].forEach((type) => {
const prop = { [type]: true };
const component = shallow(<Button {...prop} />);
expect(component.find('button').hasClass(type)).toBe(true);
});
});

it('supports click handler', () => {
const callback = jest.fn();
const component = shallow(<Button onclick={callback} />);
component.simulate('click');
expect(callback).toHaveBeenCalledTimes(1);
});
});
8 changes: 7 additions & 1 deletion src/common/Header/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@
margin-top: $toolbar-height;

.btn-user {
font-size: 28px;
.icon {
font-size: 30px;
}

img {
width: 30px;
}
}

.input {
Expand Down
6 changes: 5 additions & 1 deletion src/common/Header/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ export default {
component: Header
};

export const Default = () => <Header showDrawe={() => {}} />;
export const withAvatar = () => (
<Header avatar="https://i.imgur.com/EbafXMb.png" showDrawer={() => {}} />
);

export const withIcon = () => <Header showDrawer={() => {}} />;
47 changes: 47 additions & 0 deletions src/common/Header/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { shallow, mount } from 'enzyme';
import Button from 'common/Button';
import Input from 'common/Input';
import Icon from 'common/Icon';
import Header from './index';

const defaultProps = { showDrawer: jest.fn() };

describe('<Header />', () => {
it('renders without crashing', () => {
const component = shallow(<Header {...defaultProps} />);
expect(component.length).toBe(1);
});

it('contains avatar/user icons and input field', () => {
const component = shallow(<Header {...defaultProps} />);
expect(component.find(Button).first().prop('buttonClass')).toEqual('btn-user');
expect(component.find(Button).last().prop('buttonClass')).toEqual('btn-flip-camera');
expect(component.find(Input)).toHaveLength(1);
});

it('contains avatar image', () => {
const image = '/path/to/img.png';
const component = mount(<Header {...defaultProps} avatar={image} />);
expect(component.find('img').prop('src')).toEqual(image);
});

it("contains user icon if avatar prop isn't passed", () => {
const component = mount(<Header {...defaultProps} />);
expect(component.find(Icon).first().prop('icon')).toEqual('faUserCircle');
});

it('clicking avatar opens account drawer', () => {
const component = mount(<Header {...defaultProps} />);
component.find(Button).first().simulate('click');
expect(defaultProps.showDrawer).toHaveBeenCalledWith({ component: 'account' });
});

it('clicking input field opens search drawer', () => {
const component = mount(<Header {...defaultProps} />);
component.find(Input).simulate('click');
expect(defaultProps.showDrawer).toHaveBeenCalledWith(
expect.objectContaining({ component: 'search' })
);
});
});
52 changes: 28 additions & 24 deletions src/common/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,36 @@ import Input from 'common/Input';
import './index.scss';

interface Props {
avatar?: string;
showDrawer: ShowDrawer;
}

const Header: React.FC<Props> = ({ showDrawer }) => (
<header className="header">
<Button
icon="faUserCircle"
onclick={() => showDrawer({ component: 'account' })}
buttonClass="btn-user"
/>
<Input
placeholder="Search"
leftIcon="faSearch"
rightIcon="faUserPlus"
onClick={() =>
showDrawer({
component: 'search',
animationIn: 'fadeIn',
animationOut: 'fadeOut',
animationInDuration: 200,
animationOutDuration: 200
})
}
/>
<Button icon="faRetweet" buttonClass="btn-flip-camera" />
</header>
);
const Header: React.FC<Props> = ({ avatar, showDrawer }) => {
const iconImage = avatar ? { image: avatar } : { icon: 'faUserCircle' };
return (
<header className="header">
<Button
{...iconImage}
onclick={() => showDrawer({ component: 'account' })}
buttonClass="btn-user"
/>
<Input
placeholder="Search"
leftIcon="faSearch"
rightIcon="faUserPlus"
onClick={() =>
showDrawer({
component: 'search',
animationIn: 'fadeIn',
animationOut: 'fadeOut',
animationInDuration: 200,
animationOutDuration: 200
})
}
/>
<Button icon="faRetweet" buttonClass="btn-flip-camera" />
</header>
);
};

export default Header;
27 changes: 27 additions & 0 deletions src/common/Icon/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { shallow } from 'enzyme';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Icon, { iconMap } from './index';

const defaultProps = { icon: 'faSnapchatSquare' };

describe('<Icon />', () => {
it('renders without crashing', () => {
const component = shallow(<Icon {...defaultProps} />);
expect(component.length).toBe(1);
});

it('loads fontawesome icon', () => {
const component = shallow(<Icon {...defaultProps} />);
expect(component.find(FontAwesomeIcon).prop('icon')).toEqual(
iconMap[defaultProps.icon]
);
});

it('supports click handler', () => {
const callback = jest.fn();
const component = shallow(<Icon {...defaultProps} onClick={callback} />);
component.simulate('click');
expect(callback).toHaveBeenCalledTimes(1);
});
});
2 changes: 1 addition & 1 deletion src/common/Icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import {
} from '@fortawesome/free-solid-svg-icons';
import './index.scss';

const iconMap = {
export const iconMap = {
// free-brands-svg-icons
faSnapchatSquare,
faGithub,
Expand Down
47 changes: 47 additions & 0 deletions src/common/Input/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { shallow } from 'enzyme';
import Input from 'common/Input';

const defaultProps = { placeholder: '' };

describe('<Input />', () => {
it('renders without crashing', () => {
const component = shallow(<Input {...defaultProps} />);
expect(component.length).toBe(1);
});

describe('event handlers', () => {
it('supports `onClick` handler', () => {
const callback = jest.fn();
const component = shallow(<Input {...defaultProps} onClick={callback} />);
component.simulate('click');
expect(callback).toHaveBeenCalledTimes(1);
});

it('supports `onEnter` handler', () => {
const callback = jest.fn();
const component = shallow(<Input {...defaultProps} onEnter={callback} />);
component.find('input[type="text"]').simulate('keypress', { key: 'Enter' });
expect(callback).toHaveBeenCalledTimes(1);
});

it('supports `onFocus`, `onBlur` and `onChange` handlers', () => {
const handlers = {
onFocus: jest.fn(),
onBlur: jest.fn(),
onChange: jest.fn()
};
const events = {
onFocus: 'focus',
onBlur: 'blur',
onChange: 'change'
};
for (let i in handlers) {
const prop = { [i]: handlers[i] };
const component = shallow(<Input {...defaultProps} {...prop} />);
component.find('input[type="text"]').simulate(events[i]);
expect(handlers[i]).toHaveBeenCalledTimes(1);
}
});
});
});
2 changes: 1 addition & 1 deletion src/features/Account/Map/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
cursor: pointer;

.self-marker {
background-image: url(/images/bitmoji-self.png);
background-image: url(/images/bitmoji-self-body.png);
background-size: cover;
width: 55px;
height: 55px;
Expand Down
Loading

0 comments on commit b537703

Please sign in to comment.