Skip to content
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
8 changes: 6 additions & 2 deletions src/disco/addonManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ export function install(url, eventCallback,
log.info(`[install] Adding listener for ${event}`);
installObj.addEventListener(event, callback);
}
log.info('Events to handle the installation initialized.');
return installObj.install();
return new Promise((resolve, reject) => {
installObj.addEventListener('onInstallEnded', () => resolve());
installObj.addEventListener('onInstallFailed', () => reject());
log.info('Events to handle the installation initialized.');
installObj.install();
});
});
}

Expand Down
29 changes: 24 additions & 5 deletions src/disco/components/Addon.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ export function makeProgressHandler(dispatch, guid) {
}

export function mapDispatchToProps(dispatch, { _tracking = tracking,
_addonManager = addonManager } = {}) {
_addonManager = addonManager,
...ownProps } = {}) {
if (config.get('server')) {
return {};
}
Expand All @@ -272,10 +273,28 @@ export function mapDispatchToProps(dispatch, { _tracking = tracking,
});
},

install({ guid, installURL, name }) {
install() {
const { guid, i18n, iconUrl, installURL, name } = ownProps;
dispatch({ type: START_DOWNLOAD, payload: { guid } });
_tracking.sendEvent({ action: 'addon', category: INSTALL_CATEGORY, label: name });
return _addonManager.install(installURL, makeProgressHandler(dispatch, guid));
return _addonManager.install(installURL, makeProgressHandler(dispatch, guid))
.then(() => {
document.dispatchEvent(new CustomEvent('mozUITour', {
bubbles: true,
detail: {
action: 'showInfo',
data: {
target: 'appMenu',
icon: iconUrl,
title: i18n.gettext('Installed and added to toolbar'),
text: i18n.sprintf(
i18n.gettext('Click here to access %(name)s any time.'),
{ name }),
buttons: [{ label: i18n.gettext('Ok'), callbackID: 'add-on-installed' }],
},
},
}));
});
},

uninstall({ guid, name, type }) {
Expand All @@ -289,6 +308,6 @@ export function mapDispatchToProps(dispatch, { _tracking = tracking,
};
}

export default connect(
export default translate({ withRef: true })(connect(
mapStateToProps, mapDispatchToProps, undefined, { withRef: true }
)(translate({ withRef: true })(Addon));
)(Addon));
2 changes: 1 addition & 1 deletion src/disco/components/InstallButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class InstallButton extends React.Component {
if (type === THEME_TYPE && status === UNINSTALLED) {
installTheme(this.refs.themeData, guid, name);
} else if (status === UNINSTALLED) {
install({ guid, installURL, name });
install();
} else if (status === INSTALLED) {
uninstall({ guid, installURL, name, type });
}
Expand Down
48 changes: 33 additions & 15 deletions tests/client/disco/TestAddonManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@ describe('addonManager', () => {
uninstall: sinon.stub(),
};
fakeInstallObj = {
addEventListener: sinon.stub(),
install: sinon.stub(),
addEventListener: sinon.spy(function addEventListener(eventName, cb) {
this[`${eventName}Listener`] = cb;
}),
install: sinon.spy(function install() {
this.onInstallEndedListener();
}),
};
fakeMozAddonManager = {
createInstall: sinon.stub(),
createInstall: sinon.stub().returns(Promise.resolve(fakeInstallObj)),
getAddonByID: sinon.stub(),
addEventListener: sinon.stub(),
};
fakeMozAddonManager.createInstall.returns(Promise.resolve(fakeInstallObj));
});

describe('getAddon()', () => {
Expand All @@ -49,31 +52,46 @@ describe('addonManager', () => {
});

describe('install()', () => {
it('should call mozAddonManager.createInstall() with url', () => {
addonManager.install(fakeInstallUrl, fakeCallback, { _mozAddonManager: fakeMozAddonManager });
assert.ok(fakeMozAddonManager.createInstall.calledWith({ url: fakeInstallUrl }));
});

it('should call installObj.addEventListener to setup events', () => addonManager.install(
fakeInstallUrl, fakeCallback, { _mozAddonManager: fakeMozAddonManager })
it(
'should call mozAddonManager.createInstall() with url',
() => addonManager.install(
fakeInstallUrl, fakeCallback, { _mozAddonManager: fakeMozAddonManager })
.then(() => {
assert.equal(fakeInstallObj.addEventListener.callCount, installEventList.length);
assert.ok(fakeMozAddonManager.createInstall.calledWith({ url: fakeInstallUrl }));
}));

it(
'should call installObj.addEventListener to setup events',
() => addonManager.install(
fakeInstallUrl, fakeCallback, { _mozAddonManager: fakeMozAddonManager })
.then(() => {
// It registers an extra onInstallFailed and onInstallEnded listener.
assert.equal(fakeInstallObj.addEventListener.callCount, installEventList.length + 2);
}));

it('should call installObj.install()', () => addonManager.install(
fakeInstallUrl, fakeCallback, { _mozAddonManager: fakeMozAddonManager })
.then(() => {
assert.ok(fakeInstallObj.install.called);
}));

it('rejects if the install fails', () => {
fakeInstallObj.install = sinon.spy(function install() {
this.onInstallFailedListener();
});
return addonManager.install(
fakeInstallUrl, fakeCallback, { _mozAddonManager: fakeMozAddonManager })
.then(
unexpectedSuccess,
() => assert.ok(fakeInstallObj.install.called));
});

it('passes the installObj, the event and the id to the callback', () => {
const fakeEvent = { type: 'fakeEvent' };
let callback;
fakeInstallObj.addEventListener = (event, cb) => { callback = cb; };
return addonManager.install(
fakeInstallUrl, fakeCallback, { _mozAddonManager: fakeMozAddonManager })
.then(() => {
callback(fakeEvent);
fakeInstallObj.onDownloadProgressListener(fakeEvent);
assert.ok(fakeCallback.calledWith(fakeInstallObj, fakeEvent));
});
});
Expand Down
17 changes: 12 additions & 5 deletions tests/client/disco/components/TestAddon.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,10 @@ describe('<Addon />', () => {
it('calls addonManager.install()', () => {
const fakeAddonManager = getFakeAddonManagerWrapper();
const dispatch = sinon.spy();
const { install } = mapDispatchToProps(dispatch, { _addonManager: fakeAddonManager });
const i18n = getFakeI18nInst();
const { install } = mapDispatchToProps(
dispatch,
{ _addonManager: fakeAddonManager, i18n, installURL });
return install({ guid, installURL })
.then(() => {
assert(fakeAddonManager.install.calledWith(installURL, sinon.match.func));
Expand All @@ -456,12 +459,14 @@ describe('<Addon />', () => {
const fakeAddonManager = getFakeAddonManagerWrapper();
const name = 'hai-addon';
const type = 'extension';
const i18n = getFakeI18nInst();
const dispatch = sinon.spy();
const fakeTracking = {
sendEvent: sinon.spy(),
};
const { install } = mapDispatchToProps(dispatch,
{ _tracking: fakeTracking, _addonManager: fakeAddonManager });
const { install } = mapDispatchToProps(
dispatch,
{ _tracking: fakeTracking, _addonManager: fakeAddonManager, i18n, name });
return install({ guid, installURL, name, type })
.then(() => {
assert(fakeTracking.sendEvent.calledWith({
Expand All @@ -472,11 +477,13 @@ describe('<Addon />', () => {
});
});


it('should dispatch START_DOWNLOAD', () => {
const fakeAddonManager = getFakeAddonManagerWrapper();
const i18n = getFakeI18nInst();
const dispatch = sinon.spy();
const { install } = mapDispatchToProps(dispatch, { _addonManager: fakeAddonManager });
const { install } = mapDispatchToProps(
dispatch,
{ _addonManager: fakeAddonManager, guid, i18n });
return install({ guid, installURL })
.then(() => assert(dispatch.calledWith({
type: START_DOWNLOAD,
Expand Down
2 changes: 1 addition & 1 deletion tests/client/disco/components/TestInstallButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ describe('<InstallButton />', () => {
const button = renderButton({ guid, i18n, install, installURL, name, status: UNINSTALLED });
const root = findDOMNode(button);
Simulate.click(root);
assert(install.calledWith({ guid, installURL, name }));
assert(install.calledWith());
});

it('should call uninstall function on click when installed', () => {
Expand Down
1 change: 1 addition & 0 deletions tests/client/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function getFakeI18nInst() {
dpgettext: sinon.stub(),
npgettext: sinon.stub(),
dnpgettext: sinon.stub(),
sprintf: sinon.stub(),
};
}

Expand Down