test http auth-basic handling and implement headers.binaryValue for downloads.download()

BUG=115629

Review URL: http://codereview.chromium.org/9460010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124814 0039d316-1c4b-4281-b951-d872f2087c98
parent 19298036
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/renderer_host/resource_dispatcher_host.h"
#include "content/public/browser/download_item.h" #include "content/public/browser/download_item.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "net/base/load_flags.h"
#include "net/http/http_util.h" #include "net/http/http_util.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
...@@ -89,6 +90,7 @@ const char kFilenameKey[] = "filename"; ...@@ -89,6 +90,7 @@ const char kFilenameKey[] = "filename";
const char kFilenameRegexKey[] = "filenameRegex"; const char kFilenameRegexKey[] = "filenameRegex";
const char kHeaderNameKey[] = "name"; const char kHeaderNameKey[] = "name";
const char kHeaderValueKey[] = "value"; const char kHeaderValueKey[] = "value";
const char kHeaderBinaryValueKey[] = "binaryValue";
const char kHeadersKey[] = "headers"; const char kHeadersKey[] = "headers";
const char kIdKey[] = "id"; const char kIdKey[] = "id";
const char kLimitKey[] = "limit"; const char kLimitKey[] = "limit";
...@@ -404,13 +406,25 @@ bool DownloadsDownloadFunction::ParseArgs() { ...@@ -404,13 +406,25 @@ bool DownloadsDownloadFunction::ParseArgs() {
if (iodata_->extra_headers != NULL) { if (iodata_->extra_headers != NULL) {
for (size_t index = 0; index < iodata_->extra_headers->GetSize(); ++index) { for (size_t index = 0; index < iodata_->extra_headers->GetSize(); ++index) {
base::DictionaryValue* header = NULL; base::DictionaryValue* header = NULL;
std::string name, value; std::string name;
EXTENSION_FUNCTION_VALIDATE(iodata_->extra_headers->GetDictionary( EXTENSION_FUNCTION_VALIDATE(iodata_->extra_headers->GetDictionary(
index, &header)); index, &header));
EXTENSION_FUNCTION_VALIDATE(header->GetString( EXTENSION_FUNCTION_VALIDATE(header->GetString(
kHeaderNameKey, &name)); kHeaderNameKey, &name));
if (header->HasKey(kHeaderBinaryValueKey)) {
base::ListValue* binary_value = NULL;
EXTENSION_FUNCTION_VALIDATE(header->GetList(
kHeaderBinaryValueKey, &binary_value));
for (size_t char_i = 0; char_i < binary_value->GetSize(); ++char_i) {
int char_value = 0;
EXTENSION_FUNCTION_VALIDATE(binary_value->GetInteger(
char_i, &char_value));
}
} else if (header->HasKey(kHeaderValueKey)) {
std::string value;
EXTENSION_FUNCTION_VALIDATE(header->GetString( EXTENSION_FUNCTION_VALIDATE(header->GetString(
kHeaderValueKey, &value)); kHeaderValueKey, &value));
}
if (!net::HttpUtil::IsSafeHeader(name)) { if (!net::HttpUtil::IsSafeHeader(name)) {
error_ = download_extension_errors::kGenericError; error_ = download_extension_errors::kGenericError;
return false; return false;
...@@ -451,8 +465,21 @@ void DownloadsDownloadFunction::BeginDownloadOnIOThread() { ...@@ -451,8 +465,21 @@ void DownloadsDownloadFunction::BeginDownloadOnIOThread() {
base::DictionaryValue* header = NULL; base::DictionaryValue* header = NULL;
std::string name, value; std::string name, value;
CHECK(iodata_->extra_headers->GetDictionary(index, &header)); CHECK(iodata_->extra_headers->GetDictionary(index, &header));
CHECK(header->GetString("name", &name)); CHECK(header->GetString(kHeaderNameKey, &name));
CHECK(header->GetString("value", &value)); if (header->HasKey(kHeaderBinaryValueKey)) {
base::ListValue* binary_value = NULL;
CHECK(header->GetList(kHeaderBinaryValueKey, &binary_value));
for (size_t char_i = 0; char_i < binary_value->GetSize(); ++char_i) {
int char_value = 0;
CHECK(binary_value->GetInteger(char_i, &char_value));
if ((0 <= char_value) &&
(char_value <= 0xff)) {
value.push_back(char_value);
}
}
} else if (header->HasKey(kHeaderValueKey)) {
CHECK(header->GetString(kHeaderValueKey, &value));
}
request->SetExtraRequestHeaderByName(name, value, false/*overwrite*/); request->SetExtraRequestHeaderByName(name, value, false/*overwrite*/);
} }
} }
...@@ -460,6 +487,11 @@ void DownloadsDownloadFunction::BeginDownloadOnIOThread() { ...@@ -460,6 +487,11 @@ void DownloadsDownloadFunction::BeginDownloadOnIOThread() {
request->AppendBytesToUpload(iodata_->post_body.data(), request->AppendBytesToUpload(iodata_->post_body.data(),
iodata_->post_body.size()); iodata_->post_body.size());
} }
// Prevent login prompts for 401/407 responses.
request->set_load_flags(request->load_flags() |
net::LOAD_DO_NOT_PROMPT_FOR_LOGIN);
net::Error error = iodata_->rdh->BeginDownload( net::Error error = iodata_->rdh->BeginDownload(
request.Pass(), request.Pass(),
false, // prefer_cache false, // prefer_cache
......
...@@ -5,6 +5,15 @@ ...@@ -5,6 +5,15 @@
// downloads api test // downloads api test
// browser_tests.exe --gtest_filter=DownloadsApiTest.Downloads // browser_tests.exe --gtest_filter=DownloadsApiTest.Downloads
// Uncomment this when the apitest is re-enabled.
// console.debug = function() {};
function debugObject(obj) {
for (var property in obj) {
console.debug(property + ': ' + obj[property]);
}
}
var downloads = chrome.experimental.downloads; var downloads = chrome.experimental.downloads;
chrome.test.getConfig(function(testConfig) { chrome.test.getConfig(function(testConfig) {
...@@ -55,6 +64,12 @@ chrome.test.getConfig(function(testConfig) { ...@@ -55,6 +64,12 @@ chrome.test.getConfig(function(testConfig) {
var HEADERS_URL = getURL('files/downloads/a_zip_file.zip?' + var HEADERS_URL = getURL('files/downloads/a_zip_file.zip?' +
'expected_headers=Foo:bar&expected_headers=Qx:yo'); 'expected_headers=Foo:bar&expected_headers=Qx:yo');
// A simple handler that requires http auth basic.
var AUTH_BASIC_URL = getURL('auth-basic');
// This is just base64 of 'username:secret'.
var AUTHORIZATION = 'dXNlcm5hbWU6c2VjcmV0';
chrome.test.runTests([ chrome.test.runTests([
// TODO(benjhayden): Test onErased using remove(). // TODO(benjhayden): Test onErased using remove().
...@@ -82,7 +97,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -82,7 +97,7 @@ chrome.test.getConfig(function(testConfig) {
function downloadSimple() { function downloadSimple() {
// Test that we can begin a download. // Test that we can begin a download.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
downloads.download( downloads.download(
{'url': SAFE_FAST_URL}, {'url': SAFE_FAST_URL},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
...@@ -90,28 +105,136 @@ chrome.test.getConfig(function(testConfig) { ...@@ -90,28 +105,136 @@ chrome.test.getConfig(function(testConfig) {
})); }));
}, },
function downloadOnChanged() {
// Test that download completion is detectable by an onChanged event
// listener.
var downloadId = getNextId();
console.debug(downloadId);
var callbackCompleted = chrome.test.callbackAdded();
function myListener(delta) {
console.debug(delta.id);
if ((delta.id != downloadId) ||
!delta.state)
return;
chrome.test.assertEq(downloads.STATE_COMPLETE, delta.state.new);
console.debug(downloadId);
downloads.onChanged.removeListener(myListener);
callbackCompleted();
}
downloads.onChanged.addListener(myListener);
downloads.download(
{"url": SAFE_FAST_URL},
chrome.test.callback(function(id) {
console.debug(downloadId);
chrome.test.assertEq(downloadId, id);
}));
},
function downloadAuthBasicFail() {
var downloadId = getNextId();
console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) {
console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that
// signal any change besides completion.
if ((delta.id != downloadId) ||
!delta.state ||
!delta.error)
return;
console.debug(downloadId);
chrome.test.assertEq(downloads.STATE_INTERRUPTED, delta.state.new);
chrome.test.assertEq(30, delta.error.new);
downloads.onChanged.removeListener(changedListener);
if (changedCompleted) {
changedCompleted();
changedCompleted = null;
}
}
downloads.onChanged.addListener(changedListener);
// Sometimes the DownloadsEventRouter detects the item for the first time
// after the item has already been interrupted. In this case, the
// onChanged event never fires, so run the changedListener manually. If
// the DownloadsEventRouter detects the item before it's interrupted, then
// the onChanged event should fire correctly.
var createdCompleted = chrome.test.callbackAdded();
function createdListener(createdItem) {
console.debug(createdItem.id);
// Ignore events for any download besides our own.
if (createdItem.id != downloadId)
return;
console.debug(downloadId);
downloads.onCreated.removeListener(createdListener);
createdCompleted();
if (createdItem.state == downloads.STATE_INTERRUPTED) {
changedListener({id: downloadId, state: {new: createdItem.state},
error: {new: createdItem.error}});
}
}
downloads.onCreated.addListener(createdListener);
downloads.download(
{'url': AUTH_BASIC_URL,
'filename': downloadId + '.txt'},
chrome.test.callback(function(id) {
console.debug(downloadId);
chrome.test.assertEq(downloadId, id);
}));
},
function downloadAuthBasicSucceed() {
var downloadId = getNextId();
console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) {
console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that
// signal any change besides completion.
if ((delta.id != downloadId) ||
!delta.state)
return;
chrome.test.assertEq(downloads.STATE_COMPLETE, delta.state.new);
console.debug(downloadId);
downloads.onChanged.removeListener(changedListener);
changedCompleted();
}
downloads.onChanged.addListener(changedListener);
downloads.download(
{'url': AUTH_BASIC_URL,
'headers': [{'name': 'Authorization',
'value': 'Basic ' + AUTHORIZATION}],
'filename': downloadId + '.txt'},
chrome.test.callback(function(id) {
console.debug(downloadId);
chrome.test.assertEq(downloadId, id);
}));
},
function downloadPostSuccess() { function downloadPostSuccess() {
// Test the |method| download option. // Test the |method| download option.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded(); var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) { function changedListener(delta) {
console.log(delta.id); console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that // Ignore onChanged events for downloads besides our own, or events that
// signal any change besides completion. // signal any change besides completion.
if ((delta.id != downloadId) || if ((delta.id != downloadId) ||
!delta.state || !delta.state)
(delta.state.new != downloads.STATE_COMPLETE))
return; return;
console.log(downloadId); chrome.test.assertEq(downloads.STATE_COMPLETE, delta.state.new);
console.debug(downloadId);
downloads.search({id: downloadId}, downloads.search({id: downloadId},
chrome.test.callback(function(items) { chrome.test.callback(function(items) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(1, items.length); chrome.test.assertEq(1, items.length);
chrome.test.assertEq(downloadId, items[0].id); chrome.test.assertEq(downloadId, items[0].id);
debugObject(items[0]);
var EXPECTED_SIZE = 164; var EXPECTED_SIZE = 164;
chrome.test.assertEq(EXPECTED_SIZE, items[0].totalBytes);
chrome.test.assertEq(EXPECTED_SIZE, items[0].fileSize);
chrome.test.assertEq(EXPECTED_SIZE, items[0].bytesReceived); chrome.test.assertEq(EXPECTED_SIZE, items[0].bytesReceived);
})); }));
downloads.onChanged.removeListener(changedListener); downloads.onChanged.removeListener(changedListener);
...@@ -125,7 +248,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -125,7 +248,7 @@ chrome.test.getConfig(function(testConfig) {
'filename': downloadId + '.txt', 'filename': downloadId + '.txt',
'body': 'BODY'}, 'body': 'BODY'},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -137,38 +260,55 @@ chrome.test.getConfig(function(testConfig) { ...@@ -137,38 +260,55 @@ chrome.test.getConfig(function(testConfig) {
// it should fail, and this tests how the downloads extension api exposes // it should fail, and this tests how the downloads extension api exposes
// the failure to extensions. // the failure to extensions.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded(); var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) { function changedListener(delta) {
console.log(delta.id); console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that // Ignore onChanged events for downloads besides our own, or events that
// signal any change besides interruption. // signal any change besides interruption.
if ((delta.id != downloadId) || if ((delta.id != downloadId) ||
!delta.state || !delta.state ||
(delta.state.new != downloads.STATE_COMPLETE)) !delta.error)
return; return;
console.log(downloadId); chrome.test.assertEq(downloads.STATE_INTERRUPTED, delta.state.new);
// TODO(benjhayden): Change COMPLETE to INTERRUPTED after chrome.test.assertEq(33, delta.error.new);
// http://crbug.com/112342 console.debug(downloadId);
downloads.search({id: downloadId},
chrome.test.callback(function(items) {
console.log(downloadId);
chrome.test.assertEq(1, items.length);
chrome.test.assertEq(downloadId, items[0].id);
chrome.test.assertEq(0, items[0].totalBytes);
}));
downloads.onChanged.removeListener(changedListener); downloads.onChanged.removeListener(changedListener);
if (changedCompleted) {
changedCompleted(); changedCompleted();
changedCompleted = null;
}
} }
downloads.onChanged.addListener(changedListener); downloads.onChanged.addListener(changedListener);
// Sometimes the DownloadsEventRouter detects the item for the first time
// after the item has already been interrupted. In this case, the
// onChanged event never fires, so run the changedListener manually. If
// the DownloadsEventRouter detects the item before it's interrupted, then
// the onChanged event should fire correctly.
var createdCompleted = chrome.test.callbackAdded();
function createdListener(createdItem) {
console.debug(createdItem.id);
// Ignore events for any download besides our own.
if (createdItem.id != downloadId)
return;
console.debug(downloadId);
downloads.onCreated.removeListener(createdListener);
createdCompleted();
if (createdItem.state == downloads.STATE_INTERRUPTED) {
changedListener({id: downloadId, state: {new: createdItem.state},
error: {new: createdItem.error}});
}
}
downloads.onCreated.addListener(createdListener);
downloads.download( downloads.download(
{'url': POST_URL, {'url': POST_URL,
'filename': downloadId + '.txt', // Prevent 'file' danger. 'filename': downloadId + '.txt', // Prevent 'file' danger.
'body': 'BODY'}, 'body': 'BODY'},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -180,38 +320,56 @@ chrome.test.getConfig(function(testConfig) { ...@@ -180,38 +320,56 @@ chrome.test.getConfig(function(testConfig) {
// does not succeed when it should fail, and this tests how the downloads // does not succeed when it should fail, and this tests how the downloads
// extension api exposes the failure to extensions. // extension api exposes the failure to extensions.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded(); var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) { function changedListener(delta) {
console.log(delta.id); console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that // Ignore onChanged events for downloads besides our own, or events that
// signal any change besides interruption. // signal any change besides interruption.
if ((delta.id != downloadId) || if ((delta.id != downloadId) ||
!delta.state || !delta.state ||
(delta.state.new != downloads.STATE_COMPLETE)) !delta.error)
return; return;
console.log(downloadId); chrome.test.assertEq(downloads.STATE_INTERRUPTED, delta.state.new);
// TODO(benjhayden): Change COMPLETE to INTERRUPTED after chrome.test.assertEq(33, delta.error.new);
// http://crbug.com/112342 if (delta.error) console.debug(delta.error.new);
downloads.search({id: downloadId}, console.debug(downloadId);
chrome.test.callback(function(items) {
console.log(downloadId);
chrome.test.assertEq(1, items.length);
chrome.test.assertEq(downloadId, items[0].id);
chrome.test.assertEq(0, items[0].totalBytes);
}));
downloads.onChanged.removeListener(changedListener); downloads.onChanged.removeListener(changedListener);
if (changedCompleted) {
changedCompleted(); changedCompleted();
changedCompleted = null;
}
} }
downloads.onChanged.addListener(changedListener); downloads.onChanged.addListener(changedListener);
// Sometimes the DownloadsEventRouter detects the item for the first time
// after the item has already been interrupted. In this case, the
// onChanged event never fires, so run the changedListener manually. If
// the DownloadsEventRouter detects the item before it's interrupted, then
// the onChanged event should fire correctly.
var createdCompleted = chrome.test.callbackAdded();
function createdListener(createdItem) {
console.debug(createdItem.id);
// Ignore events for any download besides our own.
if (createdItem.id != downloadId)
return;
console.debug(downloadId);
downloads.onCreated.removeListener(createdListener);
createdCompleted();
if (createdItem.state == downloads.STATE_INTERRUPTED) {
changedListener({id: downloadId, state: {new: createdItem.state},
error: {new: createdItem.error}});
}
}
downloads.onCreated.addListener(createdListener);
downloads.download( downloads.download(
{'url': POST_URL, {'url': POST_URL,
'filename': downloadId + '.txt', // Prevent 'file' danger. 'filename': downloadId + '.txt', // Prevent 'file' danger.
'method': 'POST'}, 'method': 'POST'},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -219,25 +377,24 @@ chrome.test.getConfig(function(testConfig) { ...@@ -219,25 +377,24 @@ chrome.test.getConfig(function(testConfig) {
function downloadHeadersSuccess() { function downloadHeadersSuccess() {
// Test the |header| download option. // Test the |header| download option.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded(); var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) { function changedListener(delta) {
console.log(delta.id); console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that // Ignore onChanged events for downloads besides our own, or events that
// signal any change besides completion. // signal any change besides completion.
if ((delta.id != downloadId) || if ((delta.id != downloadId) ||
!delta.state || !delta.state)
(delta.state.new != downloads.STATE_COMPLETE))
return; return;
console.log(downloadId); chrome.test.assertEq(downloads.STATE_COMPLETE, delta.state.new);
console.debug(downloadId);
downloads.search({id: downloadId}, downloads.search({id: downloadId},
chrome.test.callback(function(items) { chrome.test.callback(function(items) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(1, items.length); chrome.test.assertEq(1, items.length);
chrome.test.assertEq(downloadId, items[0].id); chrome.test.assertEq(downloadId, items[0].id);
debugObject(items[0]);
var EXPECTED_SIZE = 164; var EXPECTED_SIZE = 164;
chrome.test.assertEq(EXPECTED_SIZE, items[0].totalBytes);
chrome.test.assertEq(EXPECTED_SIZE, items[0].fileSize);
chrome.test.assertEq(EXPECTED_SIZE, items[0].bytesReceived); chrome.test.assertEq(EXPECTED_SIZE, items[0].bytesReceived);
})); }));
downloads.onChanged.removeListener(changedListener); downloads.onChanged.removeListener(changedListener);
...@@ -251,7 +408,46 @@ chrome.test.getConfig(function(testConfig) { ...@@ -251,7 +408,46 @@ chrome.test.getConfig(function(testConfig) {
'headers': [{'name': 'Foo', 'value': 'bar'}, 'headers': [{'name': 'Foo', 'value': 'bar'},
{'name': 'Qx', 'value': 'yo'}]}, {'name': 'Qx', 'value': 'yo'}]},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id);
}));
},
function downloadHeadersBinarySuccess() {
// Test the |header| download option.
var downloadId = getNextId();
console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) {
console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that
// signal any change besides completion.
if ((delta.id != downloadId) ||
!delta.state)
return;
chrome.test.assertEq(downloads.STATE_COMPLETE, delta.state.new);
console.debug(downloadId);
downloads.search({id: downloadId},
chrome.test.callback(function(items) {
console.debug(downloadId);
chrome.test.assertEq(1, items.length);
chrome.test.assertEq(downloadId, items[0].id);
debugObject(items[0]);
var EXPECTED_SIZE = 164;
chrome.test.assertEq(EXPECTED_SIZE, items[0].bytesReceived);
}));
downloads.onChanged.removeListener(changedListener);
changedCompleted();
}
downloads.onChanged.addListener(changedListener);
downloads.download(
{'url': HEADERS_URL,
'filename': downloadId + '.txt', // Prevent 'file' danger.
'headers': [{'name': 'Foo', 'binaryValue': [98, 97, 114]},
{'name': 'Qx', 'binaryValue': [121, 111]}]},
chrome.test.callback(function(id) {
console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -263,36 +459,53 @@ chrome.test.getConfig(function(testConfig) { ...@@ -263,36 +459,53 @@ chrome.test.getConfig(function(testConfig) {
// fail as well as how the downloads extension api exposes the // fail as well as how the downloads extension api exposes the
// failure to extensions. // failure to extensions.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var changedCompleted = chrome.test.callbackAdded(); var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) { function changedListener(delta) {
console.log(delta.id); console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that // Ignore onChanged events for downloads besides our own, or events that
// signal any change besides interruption. // signal any change besides interruption.
if ((delta.id != downloadId) || if ((delta.id != downloadId) ||
!delta.state || !delta.state ||
(delta.state.new != downloads.STATE_COMPLETE)) !delta.error)
return; return;
console.log(downloadId); chrome.test.assertEq(downloads.STATE_INTERRUPTED, delta.state.new);
// TODO(benjhayden): Change COMPLETE to INTERRUPTED after chrome.test.assertEq(33, delta.error.new);
// http://crbug.com/112342 console.debug(downloadId);
downloads.search({id: downloadId},
chrome.test.callback(function(items) {
console.log(downloadId);
chrome.test.assertEq(1, items.length);
chrome.test.assertEq(downloadId, items[0].id);
chrome.test.assertEq(0, items[0].totalBytes);
}));
downloads.onChanged.removeListener(changedListener); downloads.onChanged.removeListener(changedListener);
if (changedCompleted) {
changedCompleted(); changedCompleted();
changedCompleted = null;
}
} }
downloads.onChanged.addListener(changedListener); downloads.onChanged.addListener(changedListener);
// Sometimes the DownloadsEventRouter detects the item for the first time
// after the item has already been interrupted. In this case, the
// onChanged event never fires, so run the changedListener manually. If
// the DownloadsEventRouter detects the item before it's interrupted, then
// the onChanged event should fire correctly.
var createdCompleted = chrome.test.callbackAdded();
function createdListener(createdItem) {
console.debug(createdItem.id);
// Ignore events for any download besides our own.
if (createdItem.id != downloadId)
return;
console.debug(downloadId);
downloads.onCreated.removeListener(createdListener);
createdCompleted();
if (createdItem.state == downloads.STATE_INTERRUPTED) {
changedListener({id: downloadId, state: {new: createdItem.state},
error: {new: createdItem.error}});
}
}
downloads.onCreated.addListener(createdListener);
downloads.download( downloads.download(
{'url': HEADERS_URL}, {'url': HEADERS_URL},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -304,20 +517,20 @@ chrome.test.getConfig(function(testConfig) { ...@@ -304,20 +517,20 @@ chrome.test.getConfig(function(testConfig) {
// TODO(benjhayden): Test other sources of interruptions such as server // TODO(benjhayden): Test other sources of interruptions such as server
// death. // death.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var createdCompleted = chrome.test.callbackAdded(); var createdCompleted = chrome.test.callbackAdded();
function createdListener(createdItem) { function createdListener(createdItem) {
console.log(createdItem.id); console.debug(createdItem.id);
// Ignore onCreated events for any download besides our own. // Ignore onCreated events for any download besides our own.
if (createdItem.id != downloadId) if (createdItem.id != downloadId)
return; return;
console.log(downloadId); console.debug(downloadId);
// TODO(benjhayden) Move this cancel() into the download() callback // TODO(benjhayden) Move this cancel() into the download() callback
// after ensuring that DownloadItems are created before that callback // after ensuring that DownloadItems are created before that callback
// is fired. // is fired.
downloads.cancel(downloadId, chrome.test.callback(function() { downloads.cancel(downloadId, chrome.test.callback(function() {
console.log(downloadId); console.debug(downloadId);
})); }));
downloads.onCreated.removeListener(createdListener); downloads.onCreated.removeListener(createdListener);
createdCompleted(); createdCompleted();
...@@ -326,16 +539,16 @@ chrome.test.getConfig(function(testConfig) { ...@@ -326,16 +539,16 @@ chrome.test.getConfig(function(testConfig) {
var changedCompleted = chrome.test.callbackAdded(); var changedCompleted = chrome.test.callbackAdded();
function changedListener(delta) { function changedListener(delta) {
console.log(delta.id); console.debug(delta.id);
// Ignore onChanged events for downloads besides our own, or events that // Ignore onChanged events for downloads besides our own, or events that
// signal any change besides interruption. // signal any change besides interruption.
if ((delta.id != downloadId) || if ((delta.id != downloadId) ||
!delta.state || !delta.state ||
(delta.state.new != downloads.STATE_INTERRUPTED) || !delta.error)
!delta.error ||
(delta.error.new != 40))
return; return;
console.log(downloadId); chrome.test.assertEq(downloads.STATE_INTERRUPTED, delta.state.new);
chrome.test.assertEq(40, delta.error.new);
console.debug(downloadId);
downloads.onChanged.removeListener(changedListener); downloads.onChanged.removeListener(changedListener);
changedCompleted(); changedCompleted();
} }
...@@ -344,32 +557,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -344,32 +557,7 @@ chrome.test.getConfig(function(testConfig) {
downloads.download( downloads.download(
{'url': NEVER_FINISH_URL}, {'url': NEVER_FINISH_URL},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id);
}));
},
function downloadOnChanged() {
// Test that download completion is detectable by an onChanged event
// listener.
var downloadId = getNextId();
console.log(downloadId);
var callbackCompleted = chrome.test.callbackAdded();
function myListener(delta) {
console.log(delta.id);
if ((delta.id != downloadId) ||
!delta.state ||
(delta.state.new != downloads.STATE_COMPLETE))
return;
console.log(downloadId);
downloads.onChanged.removeListener(myListener);
callbackCompleted();
}
downloads.onChanged.addListener(myListener);
downloads.download(
{"url": SAFE_FAST_URL},
chrome.test.callback(function(id) {
console.log(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -379,15 +567,15 @@ chrome.test.getConfig(function(testConfig) { ...@@ -379,15 +567,15 @@ chrome.test.getConfig(function(testConfig) {
// we can detect filename changes with an onChanged event listener. // we can detect filename changes with an onChanged event listener.
var FILENAME = 'owiejtoiwjrfoiwjroiwjroiwjroiwjrfi'; var FILENAME = 'owiejtoiwjrfoiwjroiwjroiwjroiwjrfi';
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var callbackCompleted = chrome.test.callbackAdded(); var callbackCompleted = chrome.test.callbackAdded();
function myListener(delta) { function myListener(delta) {
console.log(delta.id); console.debug(delta.id);
if ((delta.id != downloadId) || if ((delta.id != downloadId) ||
!delta.filename || !delta.filename ||
(delta.filename.new.indexOf(FILENAME) == -1)) (delta.filename.new.indexOf(FILENAME) == -1))
return; return;
console.log(downloadId); console.debug(downloadId);
downloads.onChanged.removeListener(myListener); downloads.onChanged.removeListener(myListener);
callbackCompleted(); callbackCompleted();
} }
...@@ -395,7 +583,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -395,7 +583,7 @@ chrome.test.getConfig(function(testConfig) {
downloads.download( downloads.download(
{'url': SAFE_FAST_URL, 'filename': FILENAME}, {'url': SAFE_FAST_URL, 'filename': FILENAME},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -403,13 +591,13 @@ chrome.test.getConfig(function(testConfig) { ...@@ -403,13 +591,13 @@ chrome.test.getConfig(function(testConfig) {
function downloadOnCreated() { function downloadOnCreated() {
// Test that the onCreated event fires when we start a download. // Test that the onCreated event fires when we start a download.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
var createdCompleted = chrome.test.callbackAdded(); var createdCompleted = chrome.test.callbackAdded();
function createdListener(item) { function createdListener(item) {
console.log(item.id); console.debug(item.id);
if (item.id != downloadId) if (item.id != downloadId)
return; return;
console.log(downloadId); console.debug(downloadId);
createdCompleted(); createdCompleted();
downloads.onCreated.removeListener(createdListener); downloads.onCreated.removeListener(createdListener);
}; };
...@@ -417,7 +605,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -417,7 +605,7 @@ chrome.test.getConfig(function(testConfig) {
downloads.download( downloads.download(
{'url': SAFE_FAST_URL}, {'url': SAFE_FAST_URL},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -506,7 +694,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -506,7 +694,7 @@ chrome.test.getConfig(function(testConfig) {
function downloadAllowFragments() { function downloadAllowFragments() {
// Valid URLs plus fragments are still valid URLs. // Valid URLs plus fragments are still valid URLs.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
downloads.download( downloads.download(
{'url': SAFE_FAST_URL + '#frag'}, {'url': SAFE_FAST_URL + '#frag'},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
...@@ -517,7 +705,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -517,7 +705,7 @@ chrome.test.getConfig(function(testConfig) {
function downloadAllowDataURLs() { function downloadAllowDataURLs() {
// Valid data URLs are valid URLs. // Valid data URLs are valid URLs.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
downloads.download( downloads.download(
{'url': 'data:text/plain,hello'}, {'url': 'data:text/plain,hello'},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
...@@ -528,7 +716,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -528,7 +716,7 @@ chrome.test.getConfig(function(testConfig) {
function downloadAllowFileURLs() { function downloadAllowFileURLs() {
// Valid file URLs are valid URLs. // Valid file URLs are valid URLs.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
downloads.download( downloads.download(
{'url': 'file:///'}, {'url': 'file:///'},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
...@@ -540,7 +728,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -540,7 +728,7 @@ chrome.test.getConfig(function(testConfig) {
// function downloadAllowFTPURLs() { // function downloadAllowFTPURLs() {
// // Valid ftp URLs are valid URLs. // // Valid ftp URLs are valid URLs.
// var downloadId = getNextId(); // var downloadId = getNextId();
// console.log(downloadId); // console.debug(downloadId);
// downloads.download( // downloads.download(
// {'url': 'ftp://localhost:' + testConfig.testServer.port + '/'}, // {'url': 'ftp://localhost:' + testConfig.testServer.port + '/'},
// chrome.test.callback(function(id) { // chrome.test.callback(function(id) {
...@@ -623,7 +811,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -623,7 +811,7 @@ chrome.test.getConfig(function(testConfig) {
function downloadCancelInvalidId() { function downloadCancelInvalidId() {
// Canceling a non-existent download is not considered an error. // Canceling a non-existent download is not considered an error.
downloads.cancel(-42, chrome.test.callback(function() { downloads.cancel(-42, chrome.test.callback(function() {
console.log(''); console.debug('');
})); }));
}, },
...@@ -636,11 +824,11 @@ chrome.test.getConfig(function(testConfig) { ...@@ -636,11 +824,11 @@ chrome.test.getConfig(function(testConfig) {
function downloadNoComplete() { function downloadNoComplete() {
// This is used partly to test cleanUp. // This is used partly to test cleanUp.
var downloadId = getNextId(); var downloadId = getNextId();
console.log(downloadId); console.debug(downloadId);
downloads.download( downloads.download(
{'url': NEVER_FINISH_URL}, {'url': NEVER_FINISH_URL},
chrome.test.callback(function(id) { chrome.test.callback(function(id) {
console.log(downloadId); console.debug(downloadId);
chrome.test.assertEq(downloadId, id); chrome.test.assertEq(downloadId, id);
})); }));
}, },
...@@ -648,10 +836,10 @@ chrome.test.getConfig(function(testConfig) { ...@@ -648,10 +836,10 @@ chrome.test.getConfig(function(testConfig) {
function cleanUp() { function cleanUp() {
// cleanUp must come last. It clears out all in-progress downloads // cleanUp must come last. It clears out all in-progress downloads
// so the browser can shutdown cleanly. // so the browser can shutdown cleanly.
console.log(nextId); console.debug(nextId);
function makeCallback(id) { function makeCallback(id) {
return function() { return function() {
console.log(id); console.debug(id);
} }
} }
for (var id = 0; id < nextId; ++id) { for (var id = 0; id < nextId; ++id) {
...@@ -662,7 +850,7 @@ chrome.test.getConfig(function(testConfig) { ...@@ -662,7 +850,7 @@ chrome.test.getConfig(function(testConfig) {
function callNotifyPass() { function callNotifyPass() {
chrome.test.notifyPass(); chrome.test.notifyPass();
setTimeout(chrome.test.callback(function() { setTimeout(chrome.test.callback(function() {
console.log(''); console.debug('');
}), 0); }), 0);
} }
]); ]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment