Skip to content

Commit

Permalink
Step 12.2: Create chat on user pick
Browse files Browse the repository at this point in the history
  • Loading branch information
Urigo committed May 20, 2020
1 parent bbb1203 commit 808313e
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 10 deletions.
53 changes: 47 additions & 6 deletions src/components/ChatCreationScreen/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import gql from 'graphql-tag';
import React from 'react';
import { useCallback } from 'react';
import styled from 'styled-components';
import * as fragments from '../../graphql/fragments';
import UsersList from '../UsersList';
import ChatCreationNavbar from './ChatCreationNavbar';
import { History } from 'history';
import { useAddChatMutation } from '../../graphql/types';

// eslint-disable-next-line
const Container = styled.div`
Expand All @@ -15,15 +19,52 @@ const StyledUsersList = styled(UsersList)`
height: calc(100% - 56px);
`;

gql`
mutation AddChat($recipientId: ID!) {
addChat(recipientId: $recipientId) {
...Chat
}
}
${fragments.chat}
`;

interface ChildComponentProps {
history: History;
}

const ChatCreationScreen: React.FC<ChildComponentProps> = ({ history }) => (
<div>
<ChatCreationNavbar history={history} />
<UsersList />
</div>
);
const ChatCreationScreen: React.FC<ChildComponentProps> = ({ history }) => {
const [addChat] = useAddChatMutation();

const onUserPick = useCallback(
(user) =>
addChat({
optimisticResponse: {
__typename: 'Mutation',
addChat: {
__typename: 'Chat',
id: Math.random().toString(36).substr(2, 9),
name: user.name,
picture: user.picture,
lastMessage: null,
},
},
variables: {
recipientId: user.id,
},
}).then((result) => {
if (result && result.data !== null) {
history.push(`/chats/${result.data!.addChat!.id}`);
}
}),
[addChat, history]
);

return (
<div>
<ChatCreationNavbar history={history} />
<UsersList onUserPick={onUserPick} />
</div>
);
};

export default ChatCreationScreen;
49 changes: 48 additions & 1 deletion src/components/UsersList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import React from 'react';
import { ApolloProvider } from '@apollo/react-hooks';
import { cleanup, render, waitFor, screen } from '@testing-library/react';
import {
cleanup,
render,
fireEvent,
waitFor,
screen,
} from '@testing-library/react';
import { mockApolloClient } from '../test-helpers';
import UsersList, { UsersListQuery } from './UsersList';

Expand Down Expand Up @@ -42,4 +48,45 @@ describe('UsersList', () => {
);
}
});

it('triggers onUserPick() callback on user-item click', async () => {
const client = mockApolloClient([
{
request: { query: UsersListQuery },
result: {
data: {
users: [
{
__typename: 'User',
id: 1,
name: 'Charles Dickhead',
picture: 'https://localhost:4000/dick.jpg',
},
],
},
},
},
]);

const onUserPick = jest.fn(() => {});

{
const { container, getByTestId } = render(
<ApolloProvider client={client}>
<UsersList onUserPick={onUserPick} />
</ApolloProvider>
);

await waitFor(() => screen.getByTestId('user'));

fireEvent.click(getByTestId('user'));

await waitFor(() => expect(onUserPick.mock.calls.length).toBe(1));

expect(onUserPick.mock.calls[0][0].name).toEqual('Charles Dickhead');
expect(onUserPick.mock.calls[0][0].picture).toEqual(
'https://localhost:4000/dick.jpg'
);
}
});
});
16 changes: 13 additions & 3 deletions src/components/UsersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import gql from 'graphql-tag';
import React from 'react';
import styled from 'styled-components';
import * as fragments from '../graphql/fragments';
import { useUsersListQuery } from '../graphql/types';
import { useUsersListQuery, User } from '../graphql/types';

const ActualList = styled(MaterialList)`
padding: 0;
Expand Down Expand Up @@ -38,7 +38,13 @@ export const UsersListQuery = gql`
${fragments.user}
`;

const UsersList: React.FC = () => {
interface ChildComponentProps {
onUserPick: any;
}

const UsersList: React.FC<ChildComponentProps> = ({
onUserPick = (user: User) => {},
}) => {
const { data, loading: loadingUsers } = useUsersListQuery();

if (data === undefined) return null;
Expand All @@ -48,7 +54,11 @@ const UsersList: React.FC = () => {
<ActualList>
{!loadingUsers &&
users.map((user) => (
<UserItem key={user.id} button>
<UserItem
key={user.id}
data-testid="user"
onClick={onUserPick.bind(null, user)}
button>
{user !== null && user.picture !== null && (
<React.Fragment>
<ProfilePicture data-testid="picture" src={user.picture} />
Expand Down

0 comments on commit 808313e

Please sign in to comment.