Skip to content

Commit 5e35eec

Browse files
committed
feat(avatar): implement the component
1 parent 82d9731 commit 5e35eec

File tree

5 files changed

+416
-15
lines changed

5 files changed

+416
-15
lines changed
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1-
Webex Avatar Component!
1+
# Webex Avatar Component
2+
3+
Webex avatar component displays the avatar of a _Webex Teams_ user with a given `personID` and `adapter` object.
4+
5+
## How to use
6+
7+
```js
8+
<WebexAvatar personID="PersonID" adapter={peopleJSONAdapter} />
9+
```
Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,34 @@
1-
import React from 'react';
1+
import React, {PureComponent} from 'react';
2+
import PropTypes from 'prop-types';
23
import {Avatar} from '@momentum-ui/react';
34

4-
export default function WebexAvatar(props) {
5-
return <Avatar {...props} />;
5+
const propTypes = {
6+
personID: PropTypes.string.isRequired,
7+
adapter: PropTypes.object.isRequired,
8+
};
9+
10+
export default class WebexAvatar extends PureComponent {
11+
constructor(props) {
12+
super(props);
13+
this.props = props;
14+
this.state = {
15+
person: {},
16+
};
17+
}
18+
19+
componentDidMount() {
20+
const onNext = (person) => this.setState({person});
21+
// eslint-disable-next-line no-console
22+
const onError = (error) => console.error(error.message);
23+
24+
this.props.adapter.getPerson(this.props.personID).subscribe(onNext, onError);
25+
}
26+
27+
render() {
28+
const {avatar, displayName, status} = this.state.person;
29+
30+
return <Avatar src={avatar} title={displayName} type={status} alt={displayName} />;
31+
}
632
}
33+
34+
WebexAvatar.propTypes = propTypes;
Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,78 @@
11
import React from 'react';
22
import {storiesOf} from '@storybook/react';
33

4+
import PeopleJSONAdapter from '../../adapters/PeopleJSONAdapter';
5+
import {PersonStatus} from '../../adapters/PeopleAdapter';
6+
import person from '../../data/people';
7+
48
import WebexAvatar from './WebexAvatar';
59

6-
storiesOf('Webex Avatar', module).add('Avatar with title', () => <WebexAvatar title="Tom Smith" />);
10+
// Setup for the stories
11+
const [personID] = Object.keys(person);
12+
const peopleJSONAdapter = new PeopleJSONAdapter(person);
13+
const stories = storiesOf('Webex Avatar', module);
14+
15+
// Stories
16+
stories.add('no status', () => <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />);
17+
18+
stories.add(`${PersonStatus.ACTIVE}`, () => {
19+
peopleJSONAdapter.datasource[personID].status = PersonStatus.ACTIVE;
20+
21+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
22+
});
23+
24+
stories.add(PersonStatus.BOT, () => {
25+
peopleJSONAdapter.datasource[personID].status = PersonStatus.BOT;
26+
27+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
28+
});
29+
30+
stories.add(PersonStatus.CALL, () => {
31+
peopleJSONAdapter.datasource[personID].status = PersonStatus.CALL;
32+
33+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
34+
});
35+
36+
stories.add(PersonStatus.DO_NOT_DISTURB, () => {
37+
peopleJSONAdapter.datasource[personID].status = PersonStatus.DO_NOT_DISTURB;
38+
39+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
40+
});
41+
42+
stories.add(PersonStatus.INACTIVE, () => {
43+
peopleJSONAdapter.datasource[personID].status = PersonStatus.INACTIVE;
44+
45+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
46+
});
47+
48+
stories.add(PersonStatus.MEETING, () => {
49+
peopleJSONAdapter.datasource[personID].status = PersonStatus.MEETING;
50+
51+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
52+
});
53+
54+
stories.add(PersonStatus.OUT_OF_OFFICE, () => {
55+
peopleJSONAdapter.datasource[personID].status = PersonStatus.OUT_OF_OFFICE;
56+
57+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
58+
});
59+
60+
stories.add(PersonStatus.PRESENTING, () => {
61+
peopleJSONAdapter.datasource[personID].status = PersonStatus.PRESENTING;
62+
63+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
64+
});
65+
66+
stories.add(PersonStatus.SELF, () => {
67+
peopleJSONAdapter.datasource[personID].status = PersonStatus.SELF;
68+
69+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
70+
});
71+
72+
stories.add(PersonStatus.TYPING, () => {
73+
peopleJSONAdapter.datasource[personID].status = PersonStatus.TYPING;
74+
75+
return <WebexAvatar personID={personID} adapter={peopleJSONAdapter} />;
76+
});
77+
78+
stories.add('wrong PersonID', () => <WebexAvatar personID="Wrong personID" adapter={peopleJSONAdapter} />);
Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,92 @@
11
import React from 'react';
22

3+
import PeopleJSONAdapter from '../../adapters/PeopleJSONAdapter';
4+
import {PersonStatus} from '../../adapters/PeopleAdapter';
5+
import person from '../../data/people';
6+
37
import WebexAvatar from './WebexAvatar';
48

5-
describe('Webex Avatar component:', () => {
6-
let wrapper;
9+
describe('Webex Avatar component', () => {
10+
let personID, peopleJSONAdapter;
711

812
beforeEach(() => {
9-
wrapper = shallow(<WebexAvatar />);
13+
[personID] = Object.keys(person);
14+
peopleJSONAdapter = new PeopleJSONAdapter(person);
15+
global.console.error = jest.fn();
16+
});
17+
18+
test('matches snapshot with "default" status', () => {
19+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
20+
});
21+
22+
test(`matches snapshot with "${PersonStatus.ACTIVE}" person status`, () => {
23+
peopleJSONAdapter.datasource[personID].status = PersonStatus.ACTIVE;
24+
25+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
26+
});
27+
28+
test(`matches snapshot with "${PersonStatus.BOT}" person status`, () => {
29+
peopleJSONAdapter.datasource[personID].status = PersonStatus.BOT;
30+
31+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
32+
});
33+
test(`matches snapshot with "${PersonStatus.CALL}" person status`, () => {
34+
peopleJSONAdapter.datasource[personID].status = PersonStatus.CALL;
35+
36+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
37+
});
38+
39+
test(`matches snapshot with "${PersonStatus.DO_NOT_DISTURB}" person status`, () => {
40+
peopleJSONAdapter.datasource[personID].status = PersonStatus.DO_NOT_DISTURB;
41+
42+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
43+
});
44+
45+
test(`matches snapshot with "${PersonStatus.INACTIVE}" person status`, () => {
46+
peopleJSONAdapter.datasource[personID].status = PersonStatus.INACTIVE;
47+
48+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
1049
});
1150

12-
test('exists', () => {
13-
expect(wrapper).toMatchSnapshot();
51+
test(`matches snapshot with "${PersonStatus.MEETING}" person status`, () => {
52+
peopleJSONAdapter.datasource[personID].status = PersonStatus.MEETING;
53+
54+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
55+
});
56+
57+
test(`matches snapshot with "${PersonStatus.OUT_OF_OFFICE}" person status`, () => {
58+
peopleJSONAdapter.datasource[personID].status = PersonStatus.OUT_OF_OFFICE;
59+
60+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
61+
});
62+
63+
test(`matches snapshot with "${PersonStatus.PRESENTING}" person status`, () => {
64+
peopleJSONAdapter.datasource[personID].status = PersonStatus.PRESENTING;
65+
66+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
67+
});
68+
69+
test(`matches snapshot with "${PersonStatus.SELF}" person status`, () => {
70+
peopleJSONAdapter.datasource[personID].status = PersonStatus.SELF;
71+
72+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
73+
});
74+
75+
test(`matches snapshot with "${PersonStatus.TYPING}" person status`, () => {
76+
peopleJSONAdapter.datasource[personID].status = PersonStatus.TYPING;
77+
78+
expect(shallow(<WebexAvatar personID={personID} adapter={peopleJSONAdapter} />)).toMatchSnapshot();
79+
});
80+
81+
test('throws error with inappropriate personID', () => {
82+
shallow(<WebexAvatar personID="Wrong PersonID" adapter={peopleJSONAdapter} />);
83+
84+
expect(global.console.error).toHaveBeenCalledWith('Could not find person with ID "Wrong PersonID"');
1485
});
1586

1687
afterEach(() => {
17-
wrapper = null;
88+
personID = null;
89+
peopleJSONAdapter = null;
90+
global.console.error = null;
1891
});
1992
});

0 commit comments

Comments
 (0)