From d3e723557e6158ce1d6216a19f2945ac924cd896 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 12 Dec 2015 11:31:19 +0800 Subject: [PATCH] spec: Add test cases for webRequest --- atom/browser/net/atom_network_delegate.cc | 13 +- docs/api/session.md | 20 +-- spec/api-web-request-spec.coffee | 232 ++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+), 15 deletions(-) create mode 100644 spec/api-web-request-spec.coffee diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index 4b58a8c..1625655 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -88,7 +88,7 @@ void FillDetailsObject(base::DictionaryValue* details, } void FillDetailsObject(base::DictionaryValue* details, - net::HttpResponseHeaders* headers) { + const net::HttpResponseHeaders* headers) { if (!headers) return; @@ -97,7 +97,6 @@ void FillDetailsObject(base::DictionaryValue* details, std::string key; std::string value; while (headers->EnumerateHeaderLines(&iter, &key, &value)) { - key = base::ToLowerASCII(key); if (dict->HasKey(key)) { base::ListValue* values = nullptr; if (dict->GetList(key, &values)) @@ -162,10 +161,14 @@ void ReadFromResponseObject(const base::DictionaryValue& response, for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { - std::string value; - if (it.value().GetAsString(&value)) { + const base::ListValue* list; + if (it.value().GetAsList(&list)) { (*headers)->RemoveHeader(it.key()); - (*headers)->AddHeader(it.key() + " : " + value); + for (size_t i = 0; i < list->GetSize(); ++i) { + std::string value; + if (list->GetString(i, &value)) + (*headers)->AddHeader(it.key() + " : " + value); + } } } } diff --git a/docs/api/session.md b/docs/api/session.md index 87c598e..d1db7e3 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -326,7 +326,7 @@ The `listener` will be called with `listener(details)` when a request is about to occur. * `details` Object - * `id` String - Request ID. + * `id` Integer * `url` String * `method` String * `resourceType` String @@ -335,7 +335,7 @@ to occur. The `listener` has to return an `response` object: * `response` Object - * `cancel` Boolean + * `cancel` Boolean __optional__ * `redirectURL` String __optional__ - The original request is prevented from being sent or completed, and is instead redirected to the given URL. @@ -349,7 +349,7 @@ request, once the request headers are available. This may occur after a TCP connection is made to the server, but before any http data is sent. * `details` Object - * `id` String - Request ID. + * `id` Integer * `url` String * `method` String * `resourceType` String @@ -359,7 +359,7 @@ connection is made to the server, but before any http data is sent. The `listener` has to return an `response` object: * `response` Object - * `cancel` Boolean + * `cancel` Boolean __optional__ * `requestHeaders` Object __optional__ - When provided, request will be made with these headers. @@ -373,7 +373,7 @@ going to be sent to the server, modifications of previous `onBeforeSendHeaders` response are visible by the time this listener is fired. * `details` Object - * `id` String - Request ID. + * `id` Integer * `url` String * `method` String * `resourceType` String @@ -389,7 +389,7 @@ The `listener` will be called with `listener(details)` when HTTP response headers of a request have been received. * `details` Object - * `id` String - Request ID. + * `id` String * `url` String * `method` String * `resourceType` String @@ -415,7 +415,7 @@ response body is received. For HTTP requests, this means that the status line and response headers are available. * `details` Object - * `id` String - Request ID. + * `id` Integer * `url` String * `method` String * `resourceType` String @@ -435,7 +435,7 @@ The `listener` will be called with `listener(details)` when a server initiated redirect is about to occur. * `details` Object - * `id` String - Request ID. + * `id` String * `url` String * `method` String * `resourceType` String @@ -456,7 +456,7 @@ The `listener` will be called with `listener(details)` when a request is completed. * `details` Object - * `id` String - Request ID. + * `id` Integer * `url` String * `method` String * `resourceType` String @@ -474,7 +474,7 @@ completed. The `listener` will be called with `listener(details)` when an error occurs. * `details` Object - * `id` String - Request ID. + * `id` Integer * `url` String * `method` String * `resourceType` String diff --git a/spec/api-web-request-spec.coffee b/spec/api-web-request-spec.coffee new file mode 100644 index 0000000..a10ff3d --- /dev/null +++ b/spec/api-web-request-spec.coffee @@ -0,0 +1,232 @@ +assert = require 'assert' +http = require 'http' + +{remote} = require 'electron' +{session} = remote + +describe 'webRequest module', -> + ses = session.defaultSession + server = http.createServer (req, res) -> + res.setHeader('Custom', ['Header']) + content = req.url + if req.headers.accept is '*/*;test/header' + content += 'header/received' + res.end content + defaultURL = null + + before (done) -> + server.listen 0, '127.0.0.1', -> + {port} = server.address() + defaultURL = "http://127.0.0.1:#{port}/" + done() + after -> + server.close() + + describe 'webRequest.onBeforeRequest', -> + afterEach -> + ses.webRequest.onBeforeRequest null + + it 'can cancel the request', (done) -> + ses.webRequest.onBeforeRequest (details, callback) -> + callback(cancel: true) + $.ajax + url: defaultURL + success: (data) -> done('unexpected success') + error: (xhr, errorType, error) -> done() + + it 'can filter URLs', (done) -> + filter = urls: ["#{defaultURL}filter/*"] + ses.webRequest.onBeforeRequest filter, (details, callback) -> + callback(cancel: true) + $.ajax + url: "#{defaultURL}nofilter/test" + success: (data) -> + assert.equal data, '/nofilter/test' + $.ajax + url: "#{defaultURL}filter/test" + success: (data) -> done('unexpected success') + error: (xhr, errorType, error) -> done() + error: (xhr, errorType, error) -> done(errorType) + + it 'receives details object', (done) -> + ses.webRequest.onBeforeRequest (details, callback) -> + assert.equal typeof details.id, 'number' + assert.equal typeof details.timestamp, 'number' + assert.equal details.url, defaultURL + assert.equal details.method, 'GET' + assert.equal details.resourceType, 'xhr' + callback({}) + $.ajax + url: defaultURL + success: (data) -> + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + it 'can redirect the request', (done) -> + ses.webRequest.onBeforeRequest (details, callback) -> + if details.url is defaultURL + callback(redirectURL: "#{defaultURL}redirect") + else + callback({}) + $.ajax + url: defaultURL + success: (data) -> + assert.equal data, '/redirect' + done() + error: (xhr, errorType, error) -> done(errorType) + + describe 'webRequest.onBeforeSendHeaders', -> + afterEach -> + ses.webRequest.onBeforeSendHeaders null + + it 'receives details object', (done) -> + ses.webRequest.onBeforeSendHeaders (details, callback) -> + assert.equal typeof details.requestHeaders, 'object' + callback({}) + $.ajax + url: defaultURL + success: (data) -> + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + it 'can change the request headers', (done) -> + ses.webRequest.onBeforeSendHeaders (details, callback) -> + {requestHeaders} = details + requestHeaders.Accept = '*/*;test/header' + callback({requestHeaders}) + $.ajax + url: defaultURL + success: (data, textStatus, request) -> + assert.equal data, '/header/received' + done() + error: (xhr, errorType, error) -> done(errorType) + + describe 'webRequest.onSendHeaders', -> + afterEach -> + ses.webRequest.onSendHeaders null + + it 'receives details object', (done) -> + ses.webRequest.onSendHeaders (details, callback) -> + assert.equal typeof details.requestHeaders, 'object' + $.ajax + url: defaultURL + success: (data) -> + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + describe 'webRequest.onHeadersReceived', -> + afterEach -> + ses.webRequest.onHeadersReceived null + + it 'receives details object', (done) -> + ses.webRequest.onHeadersReceived (details, callback) -> + assert.equal details.statusLine, 'HTTP/1.1 200 OK' + assert.equal details.statusCode, 200 + assert.equal details.responseHeaders['Custom'], 'Header' + callback({}) + $.ajax + url: defaultURL + success: (data) -> + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + it 'can change the response header', (done) -> + ses.webRequest.onHeadersReceived (details, callback) -> + {responseHeaders} = details + responseHeaders['Custom'] = ['Changed'] + callback({responseHeaders}) + $.ajax + url: defaultURL + success: (data, status, xhr) -> + assert.equal xhr.getResponseHeader('Custom'), 'Changed' + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + it 'does not change header by default', (done) -> + ses.webRequest.onHeadersReceived (details, callback) -> + callback({}) + $.ajax + url: defaultURL + success: (data, status, xhr) -> + assert.equal xhr.getResponseHeader('Custom'), 'Header' + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + describe 'webRequest.onResponseStarted', -> + afterEach -> + ses.webRequest.onResponseStarted null + + it 'receives details object', (done) -> + ses.webRequest.onResponseStarted (details) -> + assert.equal typeof details.fromCache, 'boolean' + assert.equal details.statusLine, 'HTTP/1.1 200 OK' + assert.equal details.statusCode, 200 + assert.equal details.responseHeaders['Custom'], 'Header' + $.ajax + url: defaultURL + success: (data, status, xhr) -> + assert.equal xhr.getResponseHeader('Custom'), 'Header' + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + describe 'webRequest.onBeforeRedirect', -> + afterEach -> + ses.webRequest.onBeforeRedirect null + ses.webRequest.onBeforeRequest null + + it 'receives details object', (done) -> + redirectURL = "#{defaultURL}redirect" + ses.webRequest.onBeforeRequest (details, callback) -> + if details.url is defaultURL + callback({redirectURL}) + else + callback({}) + ses.webRequest.onBeforeRedirect (details) -> + assert.equal typeof details.fromCache, 'boolean' + assert.equal details.statusLine, 'HTTP/1.1 307 Internal Redirect' + assert.equal details.statusCode, 307 + assert.equal details.redirectURL, redirectURL + $.ajax + url: defaultURL + success: (data, status, xhr) -> + assert.equal data, '/redirect' + done() + error: (xhr, errorType, error) -> done(errorType) + + describe 'webRequest.onCompleted', -> + afterEach -> + ses.webRequest.onCompleted null + + it 'receives details object', (done) -> + ses.webRequest.onCompleted (details) -> + assert.equal typeof details.fromCache, 'boolean' + assert.equal details.statusLine, 'HTTP/1.1 200 OK' + assert.equal details.statusCode, 200 + $.ajax + url: defaultURL + success: (data, status, xhr) -> + assert.equal data, '/' + done() + error: (xhr, errorType, error) -> done(errorType) + + describe 'webRequest.onErrorOccurred', -> + afterEach -> + ses.webRequest.onErrorOccurred null + ses.webRequest.onBeforeRequest null + + it 'receives details object', (done) -> + ses.webRequest.onBeforeRequest (details, callback) -> + callback(cancel: true) + ses.webRequest.onErrorOccurred (details) -> + assert.equal details.error, 'net::ERR_BLOCKED_BY_CLIENT' + done() + $.ajax + url: defaultURL + success: (data) -> done('unexpected success') -- 2.7.4