Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Get author info tooltips working again #2104

Merged
merged 5 commits into from
Apr 30, 2019
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 18 additions & 8 deletions lib/containers/user-mention-tooltip-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import PropTypes from 'prop-types';

import Octicon from '../atom/octicon';

class UserMentionTooltip extends React.Component {
export class BareUserMentionTooltipContainer extends React.Component {
static propTypes = {
repositoryOwner: PropTypes.shape({
login: PropTypes.string.isRequired,
Expand All @@ -17,15 +17,15 @@ class UserMentionTooltip extends React.Component {
company: PropTypes.string,

// Organizations
members: PropTypes.shape({
membersWithRole: PropTypes.shape({
totalCount: PropTypes.number.isRequired,
}),
}).isRequired,
}

render() {
const owner = this.props.repositoryOwner;
const {login, company, repositories, members} = owner;
const {login, company, repositories, membersWithRole} = owner;
return (
<div className="github-UserMentionTooltip">
<div className="github-UserMentionTooltip-avatar">
Expand All @@ -36,7 +36,9 @@ class UserMentionTooltip extends React.Component {
<Octicon icon="mention" /><strong>{login}</strong>
</div>
{company && <div><Octicon icon="briefcase" /><span>{company}</span></div>}
{members && <div><Octicon icon="organization" /><span>{members.totalCount} members</span></div>}
{membersWithRole && (
<div><Octicon icon="organization" /><span>{membersWithRole.totalCount} members</span></div>
)}
<div><Octicon icon="repo" /><span>{repositories.totalCount} repositories</span></div>
</div>
<div style={{clear: 'both'}} />
Expand All @@ -45,12 +47,20 @@ class UserMentionTooltip extends React.Component {
}
}

export default createFragmentContainer(UserMentionTooltip, {
export default createFragmentContainer(BareUserMentionTooltipContainer, {
repositoryOwner: graphql`
fragment userMentionTooltipContainer_repositoryOwner on RepositoryOwner {
login avatarUrl repositories { totalCount }
... on User { company }
... on Organization { members { totalCount } }
login
avatarUrl
repositories { totalCount }
... on User {
company
}
... on Organization {
membersWithRole {
totalCount
}
}
}
`,
});
10 changes: 5 additions & 5 deletions lib/items/__generated__/userMentionTooltipItemQuery.graphql.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions test/builder/graphql/base/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class FragmentSpec extends Spec {
);
throw new Error(`Unrecognized node kind ${node.kind}`);
} else {
return fn(node);
return fn({...node});
}
});

Expand All @@ -62,7 +62,6 @@ export class FragmentSpec extends Spec {
for (let i = selections.length - 1; i >= 0; i--) {
if (selections[i].kind === 'InlineFragment') {
// Replace inline fragments in-place with their selected fields *if* the GraphQL type name matches.

if (!typeNameSet.has(selections[i].type)) {
continue;
}
Expand All @@ -77,6 +76,7 @@ export class FragmentSpec extends Spec {
};

for (const node of this.nodes) {
node.selections = node.selections.slice();
flattenFragments(node.selections);
}
}
Expand Down
33 changes: 32 additions & 1 deletion test/builder/graphql/user.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {createSpecBuilderClass} from './base';
import {createSpecBuilderClass, createConnectionBuilderClass, createUnionBuilderClass, defer} from './base';
import {nextID} from '../id-sequence';

const RepositoryBuilder = defer('../repository', 'RepositoryBuilder');

export const RepositoryConnectionBuilder = createConnectionBuilderClass('Repository', RepositoryBuilder);

export const UserBuilder = createSpecBuilderClass('User', {
__typename: {default: 'User'},
id: {default: nextID},
Expand All @@ -10,8 +14,35 @@ export const UserBuilder = createSpecBuilderClass('User', {
const login = f.login || 'login';
return `https://github.com/${login}`;
}},
company: {default: 'GitHub'},
repositories: {linked: RepositoryConnectionBuilder},
},
'Node & Actor & RegistryPackageOwner & RegistryPackageSearch & ProjectOwner ' +
'& RepositoryOwner & UniformResourceLocatable',
);

export const OrganizationMemberConnectionBuilder = createConnectionBuilderClass('OrganizationMember', UserBuilder);

export const OrganizationBuilder = createSpecBuilderClass('Organization', {
login: {default: 'someone'},
avatarUrl: {default: 'https://avatars3.githubusercontent.com/u/17565?s=32&v=4'},
repositories: {linked: RepositoryConnectionBuilder},
membersWithRole: {linked: OrganizationMemberConnectionBuilder},
},
'Node & Actor & RegistryPackageOwner & RegistryPackageSearch & ProjectOwner ' +
'& RepositoryOwner & UniformResourceLocatable & MemberStatusable',
);

export const RepositoryOwnerBuilder = createUnionBuilderClass('RepositoryOwner', {
beUser: UserBuilder,
beOrganization: OrganizationBuilder,
default: 'beUser',
});

export function userBuilder(...nodes) {
return UserBuilder.onFragmentQuery(nodes);
}

export function organizationBuilder(...nodes) {
return OrganizationBuilder.onFragmentQuery(nodes);
}
47 changes: 47 additions & 0 deletions test/containers/user-mention-tooltip-container.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import {shallow} from 'enzyme';

import {BareUserMentionTooltipContainer} from '../../lib/containers/user-mention-tooltip-container';
import {userBuilder, organizationBuilder} from '../builder/graphql/user';

import ownerQuery from '../../lib/containers/__generated__/userMentionTooltipContainer_repositoryOwner.graphql';

describe('UserMentionTooltipContainer', function() {
function buildApp(override = {}) {
const props = {
...override,
};

return <BareUserMentionTooltipContainer {...props} />;
}

it('renders information about a User', function() {
const wrapper = shallow(buildApp({
repositoryOwner: userBuilder(ownerQuery)
.login('someone')
.avatarUrl('https://i.redd.it/03xcogvbr6v21.jpg')
.company('Infinity, Ltd.')
.repositories(conn => conn.totalCount(5))
.build(),
}));

assert.strictEqual(wrapper.find('img').prop('src'), 'https://i.redd.it/03xcogvbr6v21.jpg');
assert.isTrue(wrapper.find('span').someWhere(s => s.text() === 'Infinity, Ltd.'));
assert.isTrue(wrapper.find('span').someWhere(s => s.text() === '5 repositories'));
});

it('renders information about an Organization', function() {
const wrapper = shallow(buildApp({
repositoryOwner: organizationBuilder(ownerQuery)
.login('acme')
.avatarUrl('https://i.redd.it/eekf8onik0v21.jpg')
.membersWithRole(conn => conn.totalCount(10))
.repositories(conn => conn.totalCount(5))
.build(),
}));

assert.strictEqual(wrapper.find('img').prop('src'), 'https://i.redd.it/eekf8onik0v21.jpg');
assert.isTrue(wrapper.find('span').someWhere(s => s.text() === '10 members'));
assert.isTrue(wrapper.find('span').someWhere(s => s.text() === '5 repositories'));
});
});