Skip to content

Commit

Permalink
feat: Add link to stats for add-on developer
Browse files Browse the repository at this point in the history
fixes #2751
  • Loading branch information
tofumatt committed Sep 22, 2017
1 parent d84f570 commit 29d0606
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 21 deletions.
36 changes: 28 additions & 8 deletions src/amo/components/AddonMeta.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { compose } from 'redux';

import Link from 'amo/components/Link';
import translate from 'core/i18n/translate';
import { isAddonAuthor } from 'core/utils';
import type { AddonType } from 'core/types/addons';
import LoadingText from 'ui/components/LoadingText';
import Rating from 'ui/components/Rating';

import 'amo/css/AddonMeta.scss';


type PropTypes = {
addon: AddonType | null,
i18n: Object,
userId: number | null,
}

export class AddonMetaBase extends React.Component {
static propTypes = {
addon: PropTypes.object.isRequired,
i18n: PropTypes.object.isRequired,
}
props: PropTypes;

render() {
const { addon, i18n } = this.props;
const { addon, clientApp, i18n, lang, userId } = this.props;
const averageRating = addon ? addon.ratings.average : null;
const addonRatingCount = addon ? addon.ratings.count : null;

Expand Down Expand Up @@ -49,7 +55,14 @@ export class AddonMetaBase extends React.Component {
<div className="AddonMeta-item AddonMeta-users">
<h3 className="visually-hidden">{i18n.gettext('Used by')}</h3>
<p className="AddonMeta-text AddonMeta-user-count">
{userCount}
{addon && isAddonAuthor({ addon, userId }) ? (
<Link
href={`/addon/${addon.slug}/statistics/`}
title={i18n.gettext('Click to view statistics')}
>
{userCount}
</Link>
) : userCount}
</p>
<p className="AddonMeta-text AddonMeta-review-count">
{reviewCount}
Expand All @@ -66,6 +79,13 @@ export class AddonMetaBase extends React.Component {
}
}

export const mapStateToProps = (state) => {
return {
userId: state.user ? state.user.id : null,
};
};

export default compose(
translate({ withRef: true }),
connect(mapStateToProps),
translate(),
)(AddonMetaBase);
10 changes: 10 additions & 0 deletions src/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,16 @@ export function loadAddonIfNeeded(
return _refreshAddon({ addonSlug: slug, apiState: state.api, dispatch });
}

export function isAddonAuthor({ addon, userId }) {
if (!addon || !addon.authors || !addon.authors.length || !userId) {
return false;
}

return addon.authors.some((author) => {
return author.id === userId;
});
}

export function isAllowedOrigin(urlString, {
allowedOrigins = [config.get('amoCDN')],
} = {}) {
Expand Down
61 changes: 49 additions & 12 deletions tests/unit/amo/components/TestAddonMeta.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import { shallow } from 'enzyme';
import React from 'react';

import { AddonMetaBase } from 'amo/components/AddonMeta';
import { fakeAddon } from 'tests/unit/amo/helpers';
import { getFakeI18nInst } from 'tests/unit/helpers';
import AddonMeta, { AddonMetaBase } from 'amo/components/AddonMeta';
import Link from 'amo/components/Link';
import {
dispatchSignInActions,
dispatchClientMetadata,
fakeAddon,
} from 'tests/unit/amo/helpers';
import { getFakeI18nInst, shallowUntilTarget } from 'tests/unit/helpers';
import LoadingText from 'ui/components/LoadingText';
import Rating from 'ui/components/Rating';

function render({ ...customProps } = {}) {
const props = {
addon: fakeAddon,
i18n: getFakeI18nInst(),
...customProps,
};
return shallow(<AddonMetaBase {...props} />);
}

describe('<AddonMeta>', () => {
function render({
addon = fakeAddon,
store = dispatchClientMetadata().store,
...props
} = {}) {
return shallowUntilTarget(
<AddonMeta
addon={addon}
i18n={getFakeI18nInst()}
store={store}
{...props}
/>,
AddonMetaBase
);
}

it('can render without an addon', () => {
const root = render({ addon: null });
expect(root.find('.AddonMeta-user-count').find(LoadingText))
Expand Down Expand Up @@ -53,6 +65,31 @@ describe('<AddonMeta>', () => {
});
expect(getUserCount(root)).toMatch(/^1\.000/);
});

it('links to stats if add-on author is viewing the page', () => {
const addon = {
...fakeAddon,
slug: 'coolio',
authors: [
{
id: 11,
name: 'tofumatt',
picture_url: 'http://cdn.a.m.o/myphoto.jpg',
url: 'http://a.m.o/en-GB/firefox/user/tofumatt/',
username: 'tofumatt',
},
],
};
const root = render({
addon,
store: dispatchSignInActions({ userId: 11 }).store,
});

const statsLink = root.find('.AddonMeta-user-count').find(Link);
expect(statsLink).toHaveLength(1);
expect(statsLink).toHaveProp('title', 'Click to view statistics');
expect(statsLink).toHaveProp('href', '/addon/coolio/statistics/');
});
});

describe('ratings', () => {
Expand Down
44 changes: 43 additions & 1 deletion tests/unit/core/test_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
getClientCompatibility,
getClientConfig,
getCompatibleVersions,
isAddonAuthor,
isAllowedOrigin,
isCompatibleWithUserAgent,
isValidClientApp,
Expand Down Expand Up @@ -150,7 +151,6 @@ describe('convertBoolean', () => {
});
});


describe('getClientApp', () => {
it('should return firefox by default with no args', () => {
expect(getClientApp()).toEqual(CLIENT_APP_FIREFOX);
Expand Down Expand Up @@ -209,6 +209,48 @@ describe('getClientApp', () => {
});
});

describe('isAddonAuthor', () => {
const addon = {
...fakeAddon,
authors: [
{
id: 5838591,
name: 'tofumatt',
picture_url: 'http://cdn.a.m.o/myphoto.jpg',
url: 'http://a.m.o/en-GB/firefox/user/tofumatt/',
username: 'tofumatt',
},
],
};

it('returns true when userId is in add-on author object', () => {
expect(isAddonAuthor({ addon, userId: 5838591 })).toEqual(true);
});

it('returns true when userId is not in add-on author object', () => {
expect(isAddonAuthor({ addon, userId: 5838592 })).toEqual(false);
});

it('returns false when addon is not set', () => {
expect(isAddonAuthor({ addon: null, userId: 5838591 })).toEqual(false);
});

it('returns false when addon.authors is not set', () => {
expect(isAddonAuthor({ addon: {}, userId: 5838591 })).toEqual(false);
});

it('returns false when userId is not set', () => {
expect(isAddonAuthor({ addon, userId: null })).toEqual(false);
});

it('returns false if add-on has no authors', () => {
const partialAddon = { ...addon, authors: [] };

expect(isAddonAuthor({ addon: partialAddon, userId: null }))
.toEqual(false);
});
});

describe('isCompatibleWithUserAgent', () => {
it('should throw if no userAgentInfo supplied', () => {
expect(() => {
Expand Down

0 comments on commit 29d0606

Please sign in to comment.