Skip to content

Commit

Permalink
Bug 951281 - [Download Manager] Allow downloaded files to be shared
Browse files Browse the repository at this point in the history
  • Loading branch information
crdlc committed Feb 13, 2014
1 parent 3c2e748 commit eeae4d7
Show file tree
Hide file tree
Showing 16 changed files with 492 additions and 104 deletions.
12 changes: 12 additions & 0 deletions apps/setringtone/manifest.webapp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
"disposition": "inline",
"returnValue": true,
"href": "/share.html"
},
"setringtone": {
"filters": {
"type": {
"required": true,
"pattern": "^audio/.*$"
},
"number": 1
},
"disposition": "inline",
"returnValue": true,
"href": "/share.html"
}
},
"icons": {
Expand Down
49 changes: 27 additions & 22 deletions apps/settings/js/downloads/downloads_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@
break;
case 'succeeded':
// launch an app to view the download
_launchDownload(download);
_showDownloadActions(download);
break;
}
}
Expand Down Expand Up @@ -199,28 +199,33 @@
};
};

function _launchDownload(download) {
var req = DownloadHelper.launch(download);

req.onerror = function() {
DownloadHelper.handlerError(req.error, download, function removed(d) {
if (!d) {
return;
}
// If error when opening, we need to delete it!
var downloadId = DownloadItem.getDownloadId(d);
var elementToDelete = _getElementForId(downloadId);
DownloadApiManager.deleteDownloads(
[downloadId],
function onDeleted() {
_removeDownloadsFromUI([elementToDelete]);
_checkEmptyList();
},
function onError() {
console.warn('Download not removed during launching');
function _showDownloadActions(download) {

var actionReq = DownloadUI.showActions(download);

actionReq.onconfirm = function(evt) {
var req = DownloadHelper[actionReq.result.name](download);

req.onerror = function() {
DownloadHelper.handlerError(req.error, download, function removed(d) {
if (!d) {
return;
}
);
});
// If error when opening, we need to delete it!
var downloadId = DownloadItem.getDownloadId(d);
var elementToDelete = _getElementForId(downloadId);
DownloadApiManager.deleteDownloads(
[downloadId],
function onDeleted() {
_removeDownloadsFromUI([elementToDelete]);
_checkEmptyList();
},
function onError() {
console.warn('Download not removed during launching');
}
);
});
};
};
}

Expand Down
8 changes: 4 additions & 4 deletions apps/settings/test/unit/download_helper_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ suite('DownloadHelper', function() {
}
);

var req = DownloadHelper.launch(download);
var req = DownloadHelper.open(download);

req.onsuccess = function() {
assert.ok(false);
Expand All @@ -99,7 +99,7 @@ suite('DownloadHelper', function() {
}

test('Invalid state download', function(done) {
var req = DownloadHelper.launch(download);
var req = DownloadHelper.open(download);

req.onsuccess = function() {
assert.ok(false);
Expand All @@ -120,7 +120,7 @@ suite('DownloadHelper', function() {
return 'xxxxx.xxx';
});

var req = DownloadHelper.launch(download);
var req = DownloadHelper.open(download);

req.onsuccess = function() {
assert.ok(false);
Expand Down Expand Up @@ -161,7 +161,7 @@ suite('DownloadHelper', function() {

test('Success', function(done) {
download.state = 'succeeded';
var req = DownloadHelper.launch(download);
var req = DownloadHelper.open(download);
req.onsuccess = function() {
assert.ok(true);
done();
Expand Down
107 changes: 97 additions & 10 deletions apps/settings/test/unit/download_ui_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
'use strict';

requireApp('settings/test/unit/mock_l10n.js');
requireApp('settings/test/unit/mock_mime_mapper.js');
require('/shared/test/unit/mocks/mock_lazy_loader.js');
require('/shared/test/unit/mocks/mock_download.js');
require('/shared/test/unit/mocks/mock_download_formatter.js');
Expand All @@ -10,12 +11,18 @@ require('/shared/js/download/download_ui.js');

var mocksHelperForDownloadUI = new MocksHelper([
'LazyLoader',
'DownloadFormatter'
'DownloadFormatter',
'MimeMapper'
]).init();

suite('DownloadUI', function() {
var realL10n, download, dialogSelector = '#downloadConfirmUI',
buttonsSelector = '#downloadConfirmUI button';
dialogButtonsSelector = '#downloadConfirmUI button',
actionMenuSelector = '#downloadActionMenuUI',
actionMenuButtonsSelector = '#downloadActionMenuUI button',
actionMenuHeaderSelector = '#downloadActionMenuUI header',
ringtoneButtonSelector = '#RINGTONE',
wallpaperButtonSelector = '#WALLPAPER';

mocksHelperForDownloadUI.attachTestHelpers();

Expand All @@ -38,17 +45,97 @@ suite('DownloadUI', function() {
download = null;
});

test('UI displayed twice ', function(done) {
DownloadUI.show(DownloadUI.TYPE.STOP, download);
this.sinon.clock.tick(0);
function checkDialogUI(type, numberOfButtons, sinon) {
DownloadUI.show(type, download);
sinon.clock.tick(0);

assert.equal(document.querySelectorAll(dialogSelector).length, 1);
assert.equal(document.querySelectorAll(buttonsSelector).length, 2);
assert.equal(document.querySelectorAll(dialogButtonsSelector).length,
numberOfButtons);
var rightButton = document.querySelector(dialogButtonsSelector +
':last-child');
type.classes.forEach(function(clazz) {
assert.isTrue(rightButton.classList.contains(clazz));
});
}

DownloadUI.show(DownloadUI.TYPE.STOP, download);
this.sinon.clock.tick(0);
function checkActionsUI(numberOfButtons, sinon) {
DownloadUI.showActions(download);
sinon.clock.tick(0);

assert.equal(document.querySelectorAll(actionMenuSelector).length, 1);
assert.equal(document.querySelector(actionMenuHeaderSelector).textContent,
DownloadFormatter.getFileName(download));
assert.equal(document.querySelectorAll(actionMenuButtonsSelector).length,
numberOfButtons);
}

test('Dialogs with just one button ', function() {
var types = [DownloadUI.TYPE.FILE_NOT_FOUND, DownloadUI.TYPE.NO_SDCARD,
DownloadUI.TYPE.UNMOUNTED_SDCARD, DownloadUI.TYPE.NO_PROVIDER];

types.forEach((function(type) {
checkDialogUI(type, 1, this.sinon);
}).bind(this));
});

test('Dialogs with two buttons ', function() {
var types = [DownloadUI.TYPE.STOP, DownloadUI.TYPE.STOPPED,
DownloadUI.TYPE.FAILED, DownloadUI.TYPE.DELETE,
DownloadUI.TYPE.UNSUPPORTED_FILE_TYPE,
DownloadUI.TYPE.FILE_OPEN_ERROR];

types.forEach((function(type) {
checkDialogUI(type, 2, this.sinon);
}).bind(this));
});

test('Display actions for a video (three buttons) ', function() {
download.contentType = 'video/mp4';
checkActionsUI(3, this.sinon);
assert.isNull(document.querySelector(ringtoneButtonSelector));
assert.isNull(document.querySelector(wallpaperButtonSelector));
});

test('Display actions for an audio (four buttons)', function() {
download.contentType = 'audio/mp3';
checkActionsUI(4, this.sinon);
assert.ok(document.querySelector(ringtoneButtonSelector));
assert.isNull(document.querySelector(wallpaperButtonSelector));
});

test('Display actions for an image (four buttons)', function() {
download.contentType = 'image/png';
checkActionsUI(4, this.sinon);
assert.ok(document.querySelector(wallpaperButtonSelector));
assert.isNull(document.querySelector(ringtoneButtonSelector));
});

test('Dialog UI will be not displayed twice ', function() {
DownloadUI.show(DownloadUI.TYPE.STOPPED, download);
DownloadUI.show(DownloadUI.TYPE.STOPPED, download);
assert.equal(document.querySelectorAll(dialogSelector).length, 1);
assert.equal(document.querySelectorAll(buttonsSelector).length, 2);
});

done();
test('Hide dialog UI ', function() {
DownloadUI.show(DownloadUI.TYPE.STOPPED, download);
this.sinon.clock.tick(0);
DownloadUI.hide();
assert.equal(document.querySelector(dialogSelector).innerHTML, '');
});

test('Menu actions UI will be not displayed twice ', function() {
DownloadUI.showActions(download);
DownloadUI.showActions(download);
assert.equal(document.querySelectorAll(actionMenuSelector).length, 1);
});

test('Hide menu action UI ', function() {
DownloadUI.showActions(download);
this.sinon.clock.tick(0);
DownloadUI.hide();
assert.equal(document.querySelector(actionMenuSelector).innerHTML, '');
});


});
14 changes: 7 additions & 7 deletions apps/settings/test/unit/downloads_list_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,9 @@ suite('DownloadList', function() {

suite(' > tap actions', function() {
var container;
var launchSpy, downloadUI;
var downloadUI, showActionsSpy;
setup(function(done) {
launchSpy = this.sinon.spy(DownloadHelper, 'launch');
showActionsSpy = this.sinon.spy(DownloadUI, 'showActions');
downloadUI = this.sinon.spy(DownloadUI, 'show');
MockDownloadStore.downloads = [new MockDownload({
state: 'succeeded'
Expand All @@ -259,27 +259,27 @@ suite('DownloadList', function() {
});

teardown(function() {
launchSpy = null;
showActionsSpy = null;
downloadUI = null;
container = null;
MockDownloadStore.downloads = [];
});

test(' > a finalized download, so its in datastore', function() {
container.firstChild.click();
assert.ok(launchSpy.calledOnce);
assert.ok(DownloadUI.showActions.calledOnce);
});

test(' > on downloading download', function() {
container.childNodes[2].click();
assert.isFalse(launchSpy.calledOnce);
assert.isFalse(DownloadUI.showActions.calledOnce);
assert.ok(downloadUI.calledOnce);
assert.equal(downloadUI.args[0][0], DownloadUI.TYPE.STOP);
});

test(' > a stopped download', function() {
container.lastChild.click();
assert.isFalse(launchSpy.calledOnce);
assert.isFalse(DownloadUI.showActions.calledOnce);
assert.ok(downloadUI.calledOnce);
// DownloadUI knows which will be the correct confirm depending on state
// and error attributes
Expand Down Expand Up @@ -322,7 +322,7 @@ suite('DownloadList', function() {
// and then deleting

// Fail on the download;
var launchStub = sinon.stub(DownloadHelper, 'launch', function() {
var launchStub = sinon.stub(DownloadHelper, 'open', function() {
return {
set onsuccess(cb) {},
set onerror(cb) {setTimeout(cb, 50);}
Expand Down
13 changes: 13 additions & 0 deletions apps/settings/test/unit/mock_download_ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ var MockDownloadUI = {
};
},

showActions: function() {
return {
set onconfirm(cb) {cb();},
get onconfirm() {return;},
get result() {
return {
name: 'open'
};
},
set result(value) {}
};
},

TYPE: {
STOP: 'stop',
STOPPED: 'stopped'
Expand Down
8 changes: 8 additions & 0 deletions apps/settings/test/unit/mock_mime_mapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

/* exported MockMimeMapper */
var MockMimeMapper = {
guessTypeFromFileProperties: function(filename, mimetype) {
return mimetype;
}
};
2 changes: 1 addition & 1 deletion apps/system/js/download/download_notification.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ DownloadNotification.prototype = {
case 'succeeded':
// Attempts to open the file
var download = this.download;
var req = DownloadHelper.launch(download);
var req = DownloadHelper.open(download);

req.onerror = function req_onerror() {
DownloadHelper.handlerError(req.error, download);
Expand Down
2 changes: 1 addition & 1 deletion apps/system/test/unit/download_notification_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ suite('system/DownloadNotification >', function() {

test('Finished notification was clicked > Open file', function() {
notification.onClick(function() {});
assert.equal(DownloadHelper.methodCalled, 'launch');
assert.equal(DownloadHelper.methodCalled, 'open');

assert.isNull(notification.id);
assert.isNull(notification.download);
Expand Down
4 changes: 2 additions & 2 deletions apps/system/test/unit/mock_download_helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
'use strict';

var MockDownloadHelper = {
launch: function() {
this.methodCalled = 'launch';
open: function() {
this.methodCalled = 'open';
return {};
},

Expand Down
2 changes: 1 addition & 1 deletion apps/wallpaper/js/share.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
window.onload = function() {
navigator.mozSetMessageHandler('activity', function handler(activityRequest) {
var activityName = activityRequest.source.name;
if (activityName !== 'share')
if (activityName !== 'share' && activityName !== 'setwallpaper')
return;
startShare(activityRequest);
});
Expand Down
9 changes: 9 additions & 0 deletions apps/wallpaper/manifest.webapp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
"disposition": "inline",
"returnValue": true,
"href": "/share.html"
},
"setwallpaper": {
"filters": {
"type": "image/*",
"number": 1
},
"disposition": "inline",
"returnValue": true,
"href": "/share.html"
}
},
"icons": {
Expand Down
Loading

0 comments on commit eeae4d7

Please sign in to comment.