spec: Add test cases for webRequest
authorCheng Zhao <zcbenz@gmail.com>
Sat, 12 Dec 2015 03:31:19 +0000 (11:31 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Sat, 12 Dec 2015 03:31:19 +0000 (11:31 +0800)
atom/browser/net/atom_network_delegate.cc
docs/api/session.md
spec/api-web-request-spec.coffee [new file with mode: 0644]

index 4b58a8c..1625655 100644 (file)
@@ -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);
+        }
       }
     }
   }
index 87c598e..d1db7e3 100644 (file)
@@ -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 (file)
index 0000000..a10ff3d
--- /dev/null
@@ -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')