Skip to content

Instantly share code, notes, and snippets.

@kumar303
Created August 9, 2016 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kumar303/3cfbefc14acb1c470c859234863261ef to your computer and use it in GitHub Desktop.
Save kumar303/3cfbefc14acb1c470c859234863261ef to your computer and use it in GitHub Desktop.
diff --git a/src/amo/components/AddonDetail.js b/src/amo/components/AddonDetail.js
index 18f0ef9..8ef43ba 100644
--- a/src/amo/components/AddonDetail.js
+++ b/src/amo/components/AddonDetail.js
@@ -1,7 +1,12 @@
import React, { PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { asyncConnect } from 'redux-async-connect';
import translate from 'core/i18n/translate';
+import { fetchAddon } from 'core/api';
+import { loadEntities } from 'core/actions';
+import log from 'core/logger';
import AddonMeta from 'amo/components/AddonMeta';
import InstallButton from 'disco/components/InstallButton';
import LikeButton from 'amo/components/LikeButton';
@@ -14,10 +19,14 @@ import 'amo/css/AddonDetail.scss';
export class AddonDetail extends React.Component {
static propTypes = {
i18n: PropTypes.object,
+ addon: PropTypes.shape({
+ name: PropTypes.string.isRequired,
+ slug: PropTypes.string.isRequired,
+ }),
}
render() {
- const { i18n } = this.props;
+ const { i18n, addon } = this.props;
return (
<div className="AddonDetail">
@@ -28,7 +37,7 @@ export class AddonDetail extends React.Component {
<LikeButton />
</div>
<div className="title">
- <h1>Placeholder Add-on Title
+ <h1>{addon.name}
<span className="author">by <a href="#">AwesomeAddons</a></span></h1>
<InstallButton slug="placeholder" />
</div>
@@ -71,4 +80,39 @@ export class AddonDetail extends React.Component {
}
}
-export default translate({ withRef: true })(AddonDetail);
+function mapStateToProps(state, ownProps) {
+ const { slug } = ownProps.params;
+ log.info(`mapping state to props; slug=${slug}`);
+ return {
+ addon: state.addons[slug],
+ slug,
+ };
+}
+
+export function findAddon(state, slug) {
+ return state.addons[slug];
+}
+
+function loadAddonIfNeeded({
+ store: { getState, dispatch },
+ params: { slug },
+}) {
+ throw new Error('loadAddonIfNeeded: YES');
+ const state = getState();
+ const addon = findAddon(state, slug);
+ if (addon) {
+ log.info(`Found addon ${addon.id} in state`);
+ return Promise.resolve(addon);
+ }
+ log.info(`Fetching addon ${slug} from API`);
+ return fetchAddon({ slug, api: state.api })
+ .then(({ entities }) => dispatch(loadEntities(entities)));
+}
+
+let wrappedAddon = translate({ withRef: true });
+wrappedAddon = wrappedAddon(asyncConnect([{
+ deferred: true,
+ promise: loadAddonIfNeeded,
+}])(connect(mapStateToProps)(AddonDetail)));
+
+export default wrappedAddon;
diff --git a/src/amo/containers/DetailPage.js b/src/amo/containers/DetailPage.js
index 239c349..1728602 100644
--- a/src/amo/containers/DetailPage.js
+++ b/src/amo/containers/DetailPage.js
@@ -6,7 +6,7 @@ export default class DetailPage extends React.Component {
render() {
return (
<div>
- <AddonDetail />
+ <AddonDetail {...this.props} />
</div>
);
}
diff --git a/tests/client/amo/containers/TestDetail.js b/tests/client/amo/containers/TestDetail.js
index 837b931..8a7b295 100644
--- a/tests/client/amo/containers/TestDetail.js
+++ b/tests/client/amo/containers/TestDetail.js
@@ -4,7 +4,9 @@ import {
findRenderedComponentWithType,
renderIntoDocument,
} from 'react-addons-test-utils';
+import { Provider } from 'react-redux';
+import createStore from 'amo/store';
import { getFakeI18nInst } from 'tests/client/helpers';
import DetailPage from 'amo/containers/DetailPage';
import I18nProvider from 'core/i18n/Provider';
@@ -12,10 +14,13 @@ import translate from 'core/i18n/translate';
function renderDetailPage({ ...props }) {
const MyDetailPage = translate({ withRef: true })(DetailPage);
+ const store = createStore();
return findRenderedComponentWithType(renderIntoDocument(
<I18nProvider i18n={getFakeI18nInst()}>
- <MyDetailPage {...props} />
+ <Provider store={store}>
+ <MyDetailPage {...props} />
+ </Provider>
</I18nProvider>
), MyDetailPage).getWrappedInstance();
}
@@ -23,7 +28,7 @@ function renderDetailPage({ ...props }) {
describe('DetailPage', () => {
it('renders a heading', () => {
- const root = renderDetailPage();
+ const root = renderDetailPage({ params: { slug: 'some-addon' }});
const rootNode = findDOMNode(root);
assert.include(rootNode.querySelector('h1').textContent, 'Placeholder Add-on');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment