Browse Source

Merge branch 'master' into 0.10.0

Ben Hsieh 8 years ago
parent
commit
b22eccf735
10 changed files with 208 additions and 124 deletions
  1. 7
    3
      README.md
  2. 57
    12
      src/README.md
  3. 0
    1
      src/index.js
  4. 1
    1
      src/package.json
  5. 11
    8
      src/polyfill/Blob.js
  6. 29
    17
      src/polyfill/XMLHttpRequest.js
  7. 1
    1
      test-server/server.js
  8. 55
    0
      test/test-0.9.0.js
  9. 32
    4
      test/test-firebase.js
  10. 15
    77
      test/test-init.js

+ 7
- 3
README.md View File

1
-# react-native-fetch-blob [![release](https://img.shields.io/github/release/wkh237/react-native-fetch-blob.svg?style=flat-square)](https://www.npmjs.com/package/react-native-fetch-blob) [![npm](https://img.shields.io/npm/v/react-native-fetch-blob.svg?style=flat-square)](https://www.npmjs.com/package/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg?style=flat-square) [![npm](https://img.shields.io/npm/l/react-native-fetch-blob.svg?maxAge=2592000&style=flat-square)]()
1
+# react-native-fetch-blob [![release](https://img.shields.io/github/release/wkh237/react-native-fetch-blob.svg?style=flat-square)](https://github.com/wkh237/react-native-fetch-blob/releases) [![npm](https://img.shields.io/npm/v/react-native-fetch-blob.svg?style=flat-square)](https://www.npmjs.com/package/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg?style=flat-square) [![npm](https://img.shields.io/npm/l/react-native-fetch-blob.svg?maxAge=2592000&style=flat-square)]()
2
+
2
 
3
 
3
 A project committed to make file acess and data transfer easier, effiecient for React Native developers.
4
 A project committed to make file acess and data transfer easier, effiecient for React Native developers.
4
 
5
 
9
 - File stream support for dealing with large file
10
 - File stream support for dealing with large file
10
 - Blob, File, XMLHttpRequest polyfills that make browser-based library available in RN (experimental)
11
 - Blob, File, XMLHttpRequest polyfills that make browser-based library available in RN (experimental)
11
 
12
 
13
+> The npm package is inside `src` folder, this is development folder
12
 
14
 
13
 ## TOC
15
 ## TOC
14
 * [About](#user-content-about)
16
 * [About](#user-content-about)
15
 * [Installation](#user-content-installation)
17
 * [Installation](#user-content-installation)
16
-* [Recipes](#user-content-recipes)
17
 * [HTTP Data Transfer](#user-content-http-data-transfer)
18
 * [HTTP Data Transfer](#user-content-http-data-transfer)
18
  * [Regular Request](#user-content-regular-request)
19
  * [Regular Request](#user-content-regular-request)
19
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
20
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
119
 
120
 
120
 Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. So adding permissions in `AndroidManifest.xml` won't work in Android 6.0 devices. To grant permissions in runtime, you might use modules like [react-native-android-permissions](https://github.com/lucasferreira/react-native-android-permissions).
121
 Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. So adding permissions in `AndroidManifest.xml` won't work in Android 6.0 devices. To grant permissions in runtime, you might use modules like [react-native-android-permissions](https://github.com/lucasferreira/react-native-android-permissions).
121
 
122
 
122
-## Recipes
123
+## Usage
123
 
124
 
124
 ES6
125
 ES6
125
 
126
 
693
 - Blob
694
 - Blob
694
 - XMLHttpRequest (Use our implementation if you're going to use it with Blob)
695
 - XMLHttpRequest (Use our implementation if you're going to use it with Blob)
695
 
696
 
697
+Here's a [sample app](https://github.com/wkh237/rn-firebase-storage-upload-sample) that uses polyfills to upload files to FireBase.
698
+
696
 ### Performance Tips
699
 ### Performance Tips
697
 
700
 
698
 ---
701
 ---
719
 
722
 
720
 | Version | |
723
 | Version | |
721
 |---|---|
724
 |---|---|
725
+| 0.9.1 | Fix Android Blob constructor asynchronous issue caused by 0.9.0 fs change |
722
 | 0.9.0 | Fix unicode response data format issue #73. Improve Android performance by using thread pool instead of async task. Add Fetch replacement #70. Add Android only API `actionViewIntent` to open file or install APK in app |
726
 | 0.9.0 | Fix unicode response data format issue #73. Improve Android performance by using thread pool instead of async task. Add Fetch replacement #70. Add Android only API `actionViewIntent` to open file or install APK in app |
723
 | 0.8.1 | Remove Web API log and fix ios progress report function. |
727
 | 0.8.1 | Remove Web API log and fix ios progress report function. |
724
 | 0.8.0 | Added Web API polyfills, support regular request, added timeout option. |
728
 | 0.8.0 | Added Web API polyfills, support regular request, added timeout option. |

+ 57
- 12
src/README.md View File

1
-# react-native-fetch-blob [![release](https://img.shields.io/github/release/wkh237/react-native-fetch-blob.svg?maxAge=86400&style=flat-square)](https://www.npmjs.com/package/react-native-fetch-blob) [![npm](https://img.shields.io/npm/v/react-native-fetch-blob.svg?style=flat-square)](https://www.npmjs.com/package/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg?style=flat-square) [![npm](https://img.shields.io/npm/l/react-native-fetch-blob.svg?maxAge=2592000&style=flat-square)]()
2
-
3
-A project committed to make file acess and data transfer easier, effiecient for React Native developers.
1
+# react-native-fetch-blob [![release](https://img.shields.io/github/release/wkh237/react-native-fetch-blob.svg?style=flat-square)](https://github.com/wkh237/react-native-fetch-blob/releases) [![npm](https://img.shields.io/npm/v/react-native-fetch-blob.svg?style=flat-square)](https://www.npmjs.com/package/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg?style=flat-square) [![npm](https://img.shields.io/npm/l/react-native-fetch-blob.svg?maxAge=2592000&style=flat-square)]()
4
 
2
 
5
 # [Visit our Github for latest document](https://github.com/wkh237/react-native-fetch-blob)
3
 # [Visit our Github for latest document](https://github.com/wkh237/react-native-fetch-blob)
6
 
4
 
5
+A project committed to make file acess and data transfer easier, effiecient for React Native developers.
6
+
7
 ## Features
7
 ## Features
8
 - Transfer data directly from/to storage without BASE64 bridging
8
 - Transfer data directly from/to storage without BASE64 bridging
9
 - File API supports normal files, Asset files, and CameraRoll files
9
 - File API supports normal files, Asset files, and CameraRoll files
10
 - Native-to-native file manipulation API, reduce JS bridging performance loss
10
 - Native-to-native file manipulation API, reduce JS bridging performance loss
11
 - File stream support for dealing with large file
11
 - File stream support for dealing with large file
12
-- Blob, File, XMLHttpRequest polyfills that make browser-based library available in RN
12
+- Blob, File, XMLHttpRequest polyfills that make browser-based library available in RN (experimental)
13
+
13
 
14
 
14
 ## TOC
15
 ## TOC
15
 * [About](#user-content-about)
16
 * [About](#user-content-about)
16
 * [Installation](#user-content-installation)
17
 * [Installation](#user-content-installation)
17
-* [Recipes](#user-content-recipes)
18
 * [HTTP Data Transfer](#user-content-http-data-transfer)
18
 * [HTTP Data Transfer](#user-content-http-data-transfer)
19
  * [Regular Request](#user-content-regular-request)
19
  * [Regular Request](#user-content-regular-request)
20
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
20
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
24
  * [Cancel HTTP request](#user-content-cancel-request)
24
  * [Cancel HTTP request](#user-content-cancel-request)
25
  * [Android Media Scanner, and Download Manager Support](#user-content-android-media-scanner-and-download-manager-support)
25
  * [Android Media Scanner, and Download Manager Support](#user-content-android-media-scanner-and-download-manager-support)
26
  * [Self-Signed SSL Server](#user-content-self-signed-ssl-server)
26
  * [Self-Signed SSL Server](#user-content-self-signed-ssl-server)
27
+ * [RNFetchBlob as Fetch](#user-content-rnfetchblob-as-fetch)
27
 * [File System](#user-content-file-system)
28
 * [File System](#user-content-file-system)
28
  * [File access](#user-content-file-access)
29
  * [File access](#user-content-file-access)
29
  * [File stream](#user-content-file-stream)
30
  * [File stream](#user-content-file-stream)
40
 
41
 
41
 In `0.8.0` we introduced experimential Web API polyfills that make it possible to use browser-based libraries in React Native, for example, [FireBase JS SDK](https://github.com/wkh237/rn-firebase-storage-upload-sample)
42
 In `0.8.0` we introduced experimential Web API polyfills that make it possible to use browser-based libraries in React Native, for example, [FireBase JS SDK](https://github.com/wkh237/rn-firebase-storage-upload-sample)
42
 
43
 
44
+
43
 ## Installation
45
 ## Installation
44
 
46
 
45
 Install package from npm
47
 Install package from npm
63
 ```diff
65
 ```diff
64
 include ':app'      
66
 include ':app'      
65
 + include ':react-native-fetch-blob'                                                                                                  
67
 + include ':react-native-fetch-blob'                                                                                                  
66
-+ project(':react-native-fetch-blob').projectDir = new File(rootProject.projectDir,' ../node_modules/react-native-fetch-blob/android')                        
68
++ project(':react-native-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fetch-blob/android')                        
67
 ```
69
 ```
68
 
70
 
69
 Add this line to `MainApplication.java`, so that RNFetchBlob package becomes part of react native package.
71
 Add this line to `MainApplication.java`, so that RNFetchBlob package becomes part of react native package.
118
 
120
 
119
 Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. So adding permissions in `AndroidManifest.xml` won't work in Android 6.0 devices. To grant permissions in runtime, you might use modules like [react-native-android-permissions](https://github.com/lucasferreira/react-native-android-permissions).
121
 Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. So adding permissions in `AndroidManifest.xml` won't work in Android 6.0 devices. To grant permissions in runtime, you might use modules like [react-native-android-permissions](https://github.com/lucasferreira/react-native-android-permissions).
120
 
122
 
121
-## Recipes
123
+## Usage
122
 
124
 
123
 ES6
125
 ES6
124
 
126
 
332
   })
334
   })
333
 ```
335
 ```
334
 
336
 
335
-What if you want to upload a file in some field ? Just like [upload a file from storage](#user-content-upload-a-file-from-storage) example, wrap `data` by `wrap` API (this feature is only available for `version >= v0.5.0`). On version >= `0.6.2`, it is possible to set custom MIME type when appending file to form data.
337
+What if you want to upload a file using form data ? Just like [upload a file from storage](#user-content-upload-a-file-from-storage) example, wrap `data` by `wrap` API (this feature is only available for `version >= v0.5.0`). On version >= `0.6.2`, it is possible to set custom MIME type when appending file to form data.
336
 
338
 
337
 ```js
339
 ```js
338
 
340
 
413
 
415
 
414
 ```
416
 ```
415
 
417
 
416
-#### Android Media Scanner, and Download Manager Support
418
+### RNFetchBlob as Fetch
419
+
420
+0.9.0
421
+
422
+If you have existing code that uses `whatwg-fetch`(the official **fetch**), you don't have to change them after 0.9.0, just use fetch replacement. The difference between Official fetch and fetch replacement is, official fetch uses [whatwg-fetch](https://github.com/github/fetch) js library which wraps XMLHttpRequest polyfill under the hood it's a great library for web developers, however that does not play very well with RN. Our implementation is simply a wrapper of  RNFetchBlob.fetch and fs APIs, so you can access all the features we provide.
423
+
424
+[See document and examples](https://github.com/wkh237/react-native-fetch-blob/wiki/Fetch-API#fetch-replacement)
425
+
426
+### Android Media Scanner, and Download Manager Support
417
 
427
 
418
 If you want to make a file in `External Storage` becomes visible in Picture, Downloads, or other built-in apps, you will have to use `Media Scanner` or `Download Manager`.
428
 If you want to make a file in `External Storage` becomes visible in Picture, Downloads, or other built-in apps, you will have to use `Media Scanner` or `Download Manager`.
419
 
429
 
495
 .then(...)
505
 .then(...)
496
 ```
506
 ```
497
 
507
 
508
+**Open Downloaded File with Intent**
509
+
510
+This is a new feature added in `0.9.0`, if you're going to open a file path using official [Linking](https://facebook.github.io/react-native/docs/linking.html) API that might not work as expected, also, if you're going to install an APK in `Downloads` app, that will not work too. As an alternative, you can try `actionViewIntent` API, which will send an ACTION_VIEW intent for you which uses the given `MIME` type.
511
+
512
+Download and install an APK programatically
513
+
514
+```js
515
+
516
+const android = RNFetchBlob.android
517
+
518
+RNFetchBlob.config({
519
+    addAndroidDownloads : {
520
+      useDownloadManager : true,
521
+      title : 'awesome.apk',
522
+      description : 'An APK that will be installed',
523
+      mime : 'application/vnd.android.package-archive',
524
+      mediaScannable : true,
525
+      notification : true,
526
+    }
527
+  })
528
+  .fetch('GET', `http://www.example.com/awesome.apk`)
529
+  .then((res) => {
530
+      android.actionViewIntent(res.path(), 'application/vnd.android.package-archive')
531
+  })
532
+```
533
+
534
+Or show an image in image viewer
535
+
536
+```js
537
+      android.actionViewIntent(PATH_OF_IMG, 'image/png')
538
+```
539
+
498
 ### File System
540
 ### File System
499
 
541
 
500
 #### File Access
542
 #### File Access
647
 
689
 
648
 ### Web API Polyfills
690
 ### Web API Polyfills
649
 
691
 
650
-After `0.8.0` we've made some [Web API polyfills](https://github.com/wkh237/react-native-fetch-blob/wiki/Web-API-Polyfills-(work-in-progress)) that makes some browser-based library available in RN.
692
+After `0.8.0` we've made some [Web API polyfills](https://github.com/wkh237/react-native-fetch-blob/wiki/Web-API-Polyfills-(experimental)) that makes some browser-based library available in RN.
651
 
693
 
652
 - Blob
694
 - Blob
653
 - XMLHttpRequest (Use our implementation if you're going to use it with Blob)
695
 - XMLHttpRequest (Use our implementation if you're going to use it with Blob)
654
 
696
 
697
+Here's a [sample app](https://github.com/wkh237/rn-firebase-storage-upload-sample) that uses polyfills to upload files to FireBase.
698
+
655
 ### Performance Tips
699
 ### Performance Tips
656
 
700
 
657
 ---
701
 ---
658
 
702
 
659
-**Reduce RCT Bridge Overhead and BASE64 Time**
703
+**Reduce RCT Bridge and BASE64 Overheard**
660
 
704
 
661
 React Native connects JS and Native context by passing JSON through React bridge, therefore there will be an overhead to convert data before they sent. When data is large, this will be quite a performance impact to your app, it's recommended to use file storage instead of BASE64 if possible. The following chart shows how much faster when loading data from storage than BASE64 encoded string on iphone 6.
705
 React Native connects JS and Native context by passing JSON through React bridge, therefore there will be an overhead to convert data before they sent. When data is large, this will be quite a performance impact to your app, it's recommended to use file storage instead of BASE64 if possible. The following chart shows how much faster when loading data from storage than BASE64 encoded string on iphone 6.
662
 
706
 
678
 
722
 
679
 | Version | |
723
 | Version | |
680
 |---|---|
724
 |---|---|
681
-| 0.8.2 | Fix Android RN 0.31 installation issue #78 |
725
+| 0.9.1 | Fix Android Blob constructor asynchronous issue caused by 0.9.0 fs change |
726
+| 0.9.0 | Fix unicode response data format issue #73. Improve Android performance by using thread pool instead of async task. Add Fetch replacement #70. Add Android only API `actionViewIntent` to open file or install APK in app |
682
 | 0.8.1 | Remove Web API log and fix ios progress report function. |
727
 | 0.8.1 | Remove Web API log and fix ios progress report function. |
683
 | 0.8.0 | Added Web API polyfills, support regular request, added timeout option. |
728
 | 0.8.0 | Added Web API polyfills, support regular request, added timeout option. |
684
 | 0.7.5 | Fix installation script that make it compatible to react-native < 0.28 |
729
 | 0.7.5 | Fix installation script that make it compatible to react-native < 0.28 |

+ 0
- 1
src/index.js View File

257
             Blob.build(this.data, { type : cType + ';BASE64' }).then(resolve)
257
             Blob.build(this.data, { type : cType + ';BASE64' }).then(resolve)
258
           break
258
           break
259
           case 'path':
259
           case 'path':
260
-            console.log('##', 'reading path')
261
             polyfill.Blob.build(wrap(this.data), { type : cType }).then(resolve)
260
             polyfill.Blob.build(wrap(this.data), { type : cType }).then(resolve)
262
           break
261
           break
263
           default:
262
           default:

+ 1
- 1
src/package.json View File

1
 {
1
 {
2
   "name": "react-native-fetch-blob",
2
   "name": "react-native-fetch-blob",
3
-  "version": "0.9.0-beta.5",
3
+  "version": "0.9.1",
4
   "description": "A module provides upload, download, and files access API. Supports file stream read/write for process large files.",
4
   "description": "A module provides upload, download, and files access API. Supports file stream read/write for process large files.",
5
   "main": "index.js",
5
   "main": "index.js",
6
   "scripts": {
6
   "scripts": {

+ 11
- 8
src/polyfill/Blob.js View File

172
    * @return {Blob} The Blob object instance itself
172
    * @return {Blob} The Blob object instance itself
173
    */
173
    */
174
   onCreated(fn:() => void):Blob {
174
   onCreated(fn:() => void):Blob {
175
-    log.verbose('register blob onCreated', this._onCreated.length)
175
+    log.verbose('#register blob onCreated', this._blobCreated)
176
     if(!this._blobCreated)
176
     if(!this._blobCreated)
177
       this._onCreated.push(fn)
177
       this._onCreated.push(fn)
178
-    else
178
+    else {
179
       fn(this)
179
       fn(this)
180
+    }
180
     return this
181
     return this
181
   }
182
   }
182
 
183
 
230
   }
231
   }
231
 
232
 
232
   _invokeOnCreateEvent() {
233
   _invokeOnCreateEvent() {
233
-    log.verbose('invoke create event')
234
+    log.verbose('invoke create event', this._onCreated)
234
     this._blobCreated = true
235
     this._blobCreated = true
235
     let fns = this._onCreated
236
     let fns = this._onCreated
236
     for(let i in fns) {
237
     for(let i in fns) {
237
-      if(typeof fns[i] === 'function')
238
+      if(typeof fns[i] === 'function') {
238
         fns[i](this)
239
         fns[i](this)
240
+      }
239
     }
241
     }
240
     delete this._onCreated
242
     delete this._onCreated
241
   }
243
   }
279
   // start write blob data
281
   // start write blob data
280
   // return p.then(() => {
282
   // return p.then(() => {
281
     for(let i in args) {
283
     for(let i in args) {
282
-      p = p.then((written) => {
284
+      p = p.then(function(written){
285
+        let arg = this
283
         if(written)
286
         if(written)
284
           size += written
287
           size += written
285
-        log.verbose('mixed blob write', ...args[i], written)
286
-        return fs.appendFile.call(this, ...args[i])
287
-      })
288
+        log.verbose('mixed blob write', args[i], written)
289
+        return fs.appendFile(...arg)
290
+      }.bind(args[i]))
288
     }
291
     }
289
     return p.then(() => Promise.resolve(size))
292
     return p.then(() => Promise.resolve(size))
290
     // let promises = args.map((p) => {
293
     // let promises = args.map((p) => {

+ 29
- 17
src/polyfill/XMLHttpRequest.js View File

133
 
133
 
134
     if(this._readyState !== XMLHttpRequest.OPENED)
134
     if(this._readyState !== XMLHttpRequest.OPENED)
135
       throw 'InvalidStateError : XMLHttpRequest is not opened yet.'
135
       throw 'InvalidStateError : XMLHttpRequest is not opened yet.'
136
-
136
+    let promise = Promise.resolve()
137
     this._sendFlag = true
137
     this._sendFlag = true
138
     log.verbose('XMLHttpRequest send ', body)
138
     log.verbose('XMLHttpRequest send ', body)
139
     let {_method, _url, _headers } = this
139
     let {_method, _url, _headers } = this
141
     log.verbose(typeof body, body instanceof FormData)
141
     log.verbose(typeof body, body instanceof FormData)
142
 
142
 
143
     if(body instanceof Blob) {
143
     if(body instanceof Blob) {
144
-      body = RNFetchBlob.wrap(body.getRNFetchBlobRef())
144
+      promise = new Promise((resolve, reject) => {
145
+          body.onCreated((blob) => {
146
+            body = RNFetchBlob.wrap(body.getRNFetchBlobRef())
147
+            resolve()
148
+          })
149
+        })
145
     }
150
     }
146
     else if(typeof body === 'object') {
151
     else if(typeof body === 'object') {
147
       body = JSON.stringify(body)
152
       body = JSON.stringify(body)
153
+      promise = Promise.resolve()
148
     }
154
     }
149
-    else
155
+    else {
150
       body = body ? body.toString() : body
156
       body = body ? body.toString() : body
151
-    this._task = RNFetchBlob
152
-                  .config({
153
-                    auto: true,
154
-                    timeout : this._timeout,
155
-                    binaryContentTypes : XMLHttpRequest.binaryContentTypes
156
-                  })
157
-                  .fetch(_method, _url, _headers, body)
158
-    this._task
159
-        .stateChange(this._headerReceived.bind(this))
160
-        .uploadProgress(this._uploadProgressEvent.bind(this))
161
-        .progress(this._progressEvent.bind(this))
162
-        .catch(this._onError.bind(this))
163
-        .then(this._onDone.bind(this))
157
+      promise = Promise.resolve()
158
+    }
159
+
160
+    promise.then(() => {
161
+      this._task = RNFetchBlob
162
+                    .config({
163
+                      auto: true,
164
+                      timeout : this._timeout,
165
+                      binaryContentTypes : XMLHttpRequest.binaryContentTypes
166
+                    })
167
+                    .fetch(_method, _url, _headers, body)
168
+      this._task
169
+          .stateChange(this._headerReceived.bind(this))
170
+          .uploadProgress(this._uploadProgressEvent.bind(this))
171
+          .progress(this._progressEvent.bind(this))
172
+          .catch(this._onError.bind(this))
173
+          .then(this._onDone.bind(this))
174
+    })
164
   }
175
   }
165
 
176
 
166
   overrideMimeType(mime:string) {
177
   overrideMimeType(mime:string) {
306
         case 'blob' :
317
         case 'blob' :
307
           resp.blob().then((b) => {
318
           resp.blob().then((b) => {
308
             this._responseText = resp.text()
319
             this._responseText = resp.text()
309
-            this.response = b
320
+            this._response = b
310
             responseDataReady()
321
             responseDataReady()
311
           })
322
           })
312
         break;
323
         break;
313
         default :
324
         default :
325
+        console.log(resp, resp.text())
314
           this._responseText = resp.text()
326
           this._responseText = resp.text()
315
           this._response = this.responseText
327
           this._response = this.responseText
316
           responseDataReady()
328
           responseDataReady()

+ 1
- 1
test-server/server.js View File

138
 
138
 
139
 app.all('/xhr-header', (req, res) => {
139
 app.all('/xhr-header', (req, res) => {
140
   console.log(req.headers)
140
   console.log(req.headers)
141
-  res.header('Content-Type', 'application/json')
141
+  // res.header('Content-Type', 'application/json')
142
   res.send(req.headers)
142
   res.send(req.headers)
143
 })
143
 })
144
 
144
 

+ 55
- 0
test/test-0.9.0.js View File

32
 
32
 
33
 let prefix = ((Platform.OS === 'android') ? 'file://' : '')
33
 let prefix = ((Platform.OS === 'android') ? 'file://' : '')
34
 
34
 
35
+describe('cache control header and range request test', (report, done) => {
36
+
37
+  let image = RNTest.prop('image')
38
+  let part = [
39
+    `${fs.dirs.DocumentDir}/cache-control-test-part1.png`,
40
+    `${fs.dirs.DocumentDir}/cache-control-test-part2.png`,
41
+    `${fs.dirs.DocumentDir}/cache-control-test-part3.png`
42
+  ]
43
+  let tmp = null
44
+
45
+  RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
46
+    Authorization : `Bearer ${DROPBOX_TOKEN}`,
47
+    'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+FILENAME+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
48
+    'Content-Type' : 'application/octet-stream',
49
+  }, image)
50
+  .then((resp) => {
51
+    resp = resp.json()
52
+    report(
53
+      <Assert key="confirm the file has been uploaded" expect={FILENAME} actual={resp.name}/>
54
+    )
55
+    return RNFetchBlob.config({
56
+      path : part[0],
57
+    })
58
+    .fetch('GET', 'https://content.dropboxapi.com/1/files/auto/rn-upload/' + FILENAME, {
59
+      Authorization : `Bearer ${DROPBOX_TOKEN}`,
60
+      'Cache-Control' : 'no-store',
61
+      'Range' : 'bytes=0-23000'
62
+    })
63
+  })
64
+  .then((res) => {
65
+    let size = Math.floor(res.info().headers['Content-Length'])
66
+    report(<Assert key="part2 content length = 23001" expect={23001} actual={size}/>)
67
+    return RNFetchBlob.config({
68
+      path : part[2]
69
+    })
70
+    .fetch('GET', 'https://content.dropboxapi.com/1/files/auto/rn-upload/' + FILENAME, {
71
+      Authorization : `Bearer ${DROPBOX_TOKEN}`,
72
+      'Range' : 'bytes=23001-23975',
73
+      'Cache-Control' : 'no-store'
74
+    })
75
+  })
76
+  .then((res) => {
77
+    let size = Math.floor(res.info().headers['Content-Length'])
78
+    report(<Assert key="part3 content length = 975" expect={974} actual={size}/>)
79
+    return fs.appendFile(part[0], part[2], 'uri')
80
+  })
81
+  .then((written) => {
82
+    return fs.stat(part[0])
83
+  })
84
+  .then((stat) => {
85
+    report(<Assert key="combined file size check" expect="23975" actual={stat.size}/>)
86
+    done()
87
+  })
88
+})
89
+
35
 describe('#73 unicode response BASE64 content test', (report, done) => {
90
 describe('#73 unicode response BASE64 content test', (report, done) => {
36
 
91
 
37
   fetch(`${TEST_SERVER_URL}/unicode`, {
92
   fetch(`${TEST_SERVER_URL}/unicode`, {

+ 32
- 4
test/test-firebase.js View File

63
 
63
 
64
 describe('upload file to firebase', (report, done) => {
64
 describe('upload file to firebase', (report, done) => {
65
 
65
 
66
-  // create Blob from BASE64 data
67
-  let blob = new Blob(RNTest.prop('image'), { type : 'image/png;BASE64'})
68
   let testImage = `firebase-test-${Platform.OS}-${Date.now()}.png`
66
   let testImage = `firebase-test-${Platform.OS}-${Date.now()}.png`
69
   RNTest.prop('firebase-image', testImage)
67
   RNTest.prop('firebase-image', testImage)
70
-  // start test after Blob created
71
-  blob.onCreated(() => {
68
+
69
+  // create Blob from BASE64 data
70
+  Blob.build(RNTest.prop('image'), { type : 'image/png;BASE64'})
71
+  .then((blob) => {
72
     let storage = firebase.storage().ref('rnfbtest')
72
     let storage = firebase.storage().ref('rnfbtest')
73
     let task = storage
73
     let task = storage
74
       .child(RNTest.prop('firebase-image'))
74
       .child(RNTest.prop('firebase-image'))
147
     done()
147
     done()
148
   })
148
   })
149
 })
149
 })
150
+
151
+describe('upload from storage', (report, done) => {
152
+  try {
153
+  let file = fs.dirs.DocumentDir + '/tempimg.png'
154
+  fs.writeFile(file, RNTest.prop('image'), 'base64')
155
+    .then(() => Blob.build(RNFetchBlob.wrap(file), {type : 'image/png'}))
156
+    .then((blob) => {
157
+      let storage = firebase.storage().ref('rnfbtest')
158
+      let task = storage
159
+        .child(`image-from-storage-${Platform.OS}-${Date.now()}.png`)
160
+        .put(blob, { contentType : 'image/png' })
161
+        .then((snapshot) => {
162
+          console.log(snapshot.metadata)
163
+          report(<Assert key="upload success"
164
+            expect={true}
165
+            actual={true}/>,
166
+          <Info key="uploaded file stat" >
167
+            <Text>{snapshot.totalBytes}</Text>
168
+            <Text>{JSON.stringify(snapshot.metadata)}</Text>
169
+          </Info>)
170
+          done()
171
+        })
172
+    })
173
+  }
174
+  catch(err) {
175
+    console.log(err)
176
+  }
177
+})

+ 15
- 77
test/test-init.js View File

59
 })
59
 })
60
 
60
 
61
 
61
 
62
-describe('Upload octet-stream image to Dropbox', (report, done) => {
63
-  let image = prop('image')
64
-  let tmp = null
65
-  let etag = ''
66
-  // upload a file to dropbox
67
-  RNFetchBlob.fetch('POST', 'https://content.dropboxapi.com/2/files/upload', {
68
-    Authorization : `Bearer ${DROPBOX_TOKEN}`,
69
-    'Dropbox-API-Arg': '{\"path\": \"/rn-upload/'+FILENAME+'\",\"mode\": \"add\",\"autorename\": true,\"mute\": false}',
70
-    'Content-Type' : 'application/octet-stream',
71
-  }, image)
72
-  .then((resp) => {
73
-    resp = resp.json()
74
-    report(
75
-      <Assert key="confirm the file has been uploaded" expect={FILENAME} actual={resp.name}/>
76
-    )
77
-    // detect range request support
78
-    return RNFetchBlob
79
-    .config({
80
-      path : RNFetchBlob.fs.dirs.DocumentDir + '/part1.png'
81
-    })
82
-    .fetch('GET', 'https://content.dropboxapi.com/1/files/auto'+'/rn-upload/'+FILENAME, {
83
-      Authorization : `Bearer ${DROPBOX_TOKEN}`,
84
-      'Cache-Control' : 'no-store',
85
-      'Range' : 'bytes=0-22975'
86
-    })
87
-  })
88
-  .then((res) => {
89
-
90
-    console.log('first chunk', res.info().headers,res.info().headers['Content-Length'])
91
-    // get first range
92
-    return RNFetchBlob
93
-    .config({
94
-      path : RNFetchBlob.fs.dirs.DocumentDir + '/part2.png'
95
-    })
96
-    .fetch('GET', 'https://content.dropboxapi.com/1/files/auto/rn-upload/'+FILENAME, {
97
-      Authorization : `Bearer ${DROPBOX_TOKEN}`,
98
-      'Cache-Control' : 'no-store',
99
-      'Range' : 'bytes=22976-'
100
-    })
101
-  })
102
-  .then((res) => {
103
-    tmp = res
104
-    console.log('second chunk', res.info().headers, res.info().headers['Content-Length'])
105
-    // get second range
106
-    return RNFetchBlob.fs.appendFile(RNFetchBlob.fs.dirs.DocumentDir + '/part1.png', RNFetchBlob.fs.dirs.DocumentDir + '/part2.png', 'uri')
107
-  })
108
-  .then(() => {
109
-    return RNFetchBlob.fs.stat(RNFetchBlob.fs.dirs.DocumentDir + '/part1.png')
110
-  })
111
-  .then((stat) => {
112
-    tmp.flush()
113
-    console.log('combined', stat)
114
-    report(<Info key="combined image">
115
-      <Text>{stat.size}</Text>
116
-      <Image key="combined image" style={styles.image} source={{uri :RNFetchBlob.fs.dirs.DocumentDir + '/part1.png' }}/>
117
-    </Info>)
118
-    done()
119
-  })
120
-
121
-})
122
-
123
-// require('./test-0.1.x-0.4.x')
124
-// require('./test-0.5.1')
125
-// require('./test-0.5.2')
126
-// require('./test-0.6.0')
127
-// require('./test-0.6.2')
128
-// require('./test-0.6.3')
129
-// require('./test-0.7.0')
130
-// require('./test-0.8.0')
131
-// require('./test-0.9.0')
132
-// require('./test-fetch')
133
-// require('./test-fs')
134
-// require('./test-xmlhttp')
135
-// require('./test-blob')
136
-// require('./test-firebase')
137
-// require('./test-android')
138
-// require('./test-readable')
62
+require('./test-0.1.x-0.4.x')
63
+require('./test-0.5.1')
64
+require('./test-0.5.2')
65
+require('./test-0.6.0')
66
+require('./test-0.6.2')
67
+require('./test-0.6.3')
68
+require('./test-0.7.0')
69
+require('./test-0.8.0')
70
+require('./test-0.9.0')
71
+require('./test-fetch')
72
+require('./test-fs')
73
+require('./test-xmlhttp')
74
+require('./test-blob')
75
+require('./test-firebase')
76
+require('./test-android')
139
 // require('./benchmark')
77
 // require('./benchmark')