Browse Source

Add progres and cancellation support for Fetch replacement

Ben Hsieh 8 years ago
parent
commit
fe9e909938
3 changed files with 62 additions and 19 deletions
  1. 24
    10
      src/polyfill/Fetch.js
  2. 36
    8
      test/test-fetch.js
  3. 2
    1
      test/test-init.js

+ 24
- 10
src/polyfill/Fetch.js View File

@@ -45,17 +45,31 @@ class RNFetchBlobFetchPolyfill {
45 45
       else
46 46
         promise = Promise.resolve(body)
47 47
 
48
-      return promise
49
-          .then((body) => RNFetchBlob.config(config)
50
-          .fetch(options.method, url, options.headers, options.body))
51
-          .then((resp) => {
52
-            log.verbose('response', resp)
53
-            // release blob cache created when sending request
54
-            if(blobCache !== null && blobCache instanceof Blob)
55
-              blobCache.close()
56
-            let info = resp.info()
57
-            return Promise.resolve(new RNFetchBlobFetchRepsonse(resp))
48
+      // task is a progress reportable and cancellable Promise, however,
49
+      // task.then is not, so we have to extend task.then with progress and
50
+      // cancel function
51
+      let task = promise
52
+          .then((body) => {
53
+            return RNFetchBlob.config(config)
54
+            .fetch(options.method, url, options.headers, options.body)
58 55
           })
56
+
57
+      let statefulPromise = task.then((resp) => {
58
+        log.verbose('response', resp)
59
+        // release blob cache created when sending request
60
+        if(blobCache !== null && blobCache instanceof Blob)
61
+          blobCache.close()
62
+        let info = resp.info()
63
+        return Promise.resolve(new RNFetchBlobFetchRepsonse(resp))
64
+      })
65
+
66
+      // extend task.then progress with report and cancelling functions
67
+      statefulPromise.cancel = task.cancel
68
+      statefulPromise.progress = task.progress
69
+      statefulPromise.uploadProgress = task.uploadProgress
70
+
71
+      return statefulPromise
72
+
59 73
     }
60 74
   }
61 75
 

+ 36
- 8
test/test-fetch.js View File

@@ -112,7 +112,7 @@ describe('GET request test : path -> any', (report, done) => {
112 112
 
113 113
 })
114 114
 
115
-describe('POST base64 body auto strategy', (report, done) => {
115
+describe('POST different types of body', (report, done) => {
116 116
 
117 117
   let image = RNTest.prop('image')
118 118
   let tmpPath = dirs.DocumentDir + '/tmp-' + Date.now()
@@ -121,14 +121,12 @@ describe('POST base64 body auto strategy', (report, done) => {
121 121
     let name = `fetch-replacement-${Platform.OS}-${Date.now()}.png`
122 122
     return pBody.then((body) =>
123 123
       fetch('https://content.dropboxapi.com/2/files/upload', {
124
-        method : method,
124
+        method : 'post',
125 125
         headers : {
126 126
           Authorization : `Bearer ${DROPBOX_TOKEN}`,
127 127
           'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+name+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
128 128
           'Content-Type' : 'application/octet-stream'
129
-        },
130
-        body : body
131
-      })
129
+        }, body })
132 130
     )
133 131
     .then((res) => {
134 132
       return res.json()
@@ -139,12 +137,42 @@ describe('POST base64 body auto strategy', (report, done) => {
139 137
   }
140 138
 
141 139
   let tests = [
142
-    upload('upload base64 encoded body', 'post', Promise.resolve(image)),
143
-    upload('upload Blob body', 'post', Blob.build(image, 'image/png;BASE64')),
144
-    upload('upload file path body', 'post', fs.writeFile(tmpPath, image, 'base64').then(() => Promise.resolve(RNFetchBlob.wrap(tmpPath))))
140
+    upload('upload base64 encoded body', Promise.resolve(image)),
141
+    upload('upload Blob body', Blob.build(image, 'image/png;BASE64')),
142
+    upload('upload file path body', fs.writeFile(tmpPath, image, 'base64').then(() => Promise.resolve(RNFetchBlob.wrap(tmpPath))))
145 143
   ]
146 144
 
147 145
   Promise.all(tests).then(() => done())
148 146
 
147
+})
148
+
149
+describe('check HTTP body correctness', (report, done) => {
150
+
151
+  let tmpPath = dirs.DocumentDir + '/tmp-' + Date.now()
152
+
153
+  function upload(pBody) {
154
+    return pBody.then((body) =>
155
+      fetch('https://content.dropboxapi.com/2/files/upload', {
156
+        method : 'POST',
157
+        headers : {
158
+          Authorization : `Bearer ${DROPBOX_TOKEN}`,
159
+          'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+name+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
160
+          'Content-Type' : 'application/octet-stream'
161
+        }, body })
162
+      .then((res) => res.json())
163
+      .then((info) => {
164
+        
165
+      })
166
+    )
167
+  }
168
+
169
+
170
+  let pUnicodeBody = fetch(`${TEST_SERVER_URL}/public/utf8-dummy`, { method : 'GET' })
171
+    .then((res) => res.text())
172
+
173
+  let tests = [
174
+    upload(pUnicodeBody)
175
+  ]
176
+
149 177
 
150 178
 })

+ 2
- 1
test/test-init.js View File

@@ -67,8 +67,9 @@ describe('GET image from server', (report, done) => {
67 67
 // require('./test-0.7.0')
68 68
 // require('./test-0.8.0')
69 69
 // require('./test-0.8.2')
70
+require('./test-fetch')
70 71
 // require('./test-fs')
71
-require('./test-xmlhttp')
72
+// require('./test-xmlhttp')
72 73
 // require('./test-blob')
73 74
 // require('./test-firebase')
74 75
 // require('./test-android')