Bläddra i källkod

Merge branch 'master' into 0.10.0

Ben Hsieh 8 år sedan
förälder
incheckning
b22eccf735
10 ändrade filer med 208 tillägg och 124 borttagningar
  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 Visa fil

@@ -1,4 +1,5 @@
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 4
 A project committed to make file acess and data transfer easier, effiecient for React Native developers.
4 5
 
@@ -9,11 +10,11 @@ A project committed to make file acess and data transfer easier, effiecient for
9 10
 - File stream support for dealing with large file
10 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 15
 ## TOC
14 16
 * [About](#user-content-about)
15 17
 * [Installation](#user-content-installation)
16
-* [Recipes](#user-content-recipes)
17 18
 * [HTTP Data Transfer](#user-content-http-data-transfer)
18 19
  * [Regular Request](#user-content-regular-request)
19 20
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
@@ -119,7 +120,7 @@ Also, if you're going to use `Android Download Manager` you have to add this to
119 120
 
120 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 125
 ES6
125 126
 
@@ -693,6 +694,8 @@ After `0.8.0` we've made some [Web API polyfills](https://github.com/wkh237/reac
693 694
 - Blob
694 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 699
 ### Performance Tips
697 700
 
698 701
 ---
@@ -719,6 +722,7 @@ If you're going to concatenate files, you don't have to read the data to JS cont
719 722
 
720 723
 | Version | |
721 724
 |---|---|
725
+| 0.9.1 | Fix Android Blob constructor asynchronous issue caused by 0.9.0 fs change |
722 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 727
 | 0.8.1 | Remove Web API log and fix ios progress report function. |
724 728
 | 0.8.0 | Added Web API polyfills, support regular request, added timeout option. |

+ 57
- 12
src/README.md Visa fil

@@ -1,20 +1,20 @@
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 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 7
 ## Features
8 8
 - Transfer data directly from/to storage without BASE64 bridging
9 9
 - File API supports normal files, Asset files, and CameraRoll files
10 10
 - Native-to-native file manipulation API, reduce JS bridging performance loss
11 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 15
 ## TOC
15 16
 * [About](#user-content-about)
16 17
 * [Installation](#user-content-installation)
17
-* [Recipes](#user-content-recipes)
18 18
 * [HTTP Data Transfer](#user-content-http-data-transfer)
19 19
  * [Regular Request](#user-content-regular-request)
20 20
  * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
@@ -24,6 +24,7 @@ A project committed to make file acess and data transfer easier, effiecient for
24 24
  * [Cancel HTTP request](#user-content-cancel-request)
25 25
  * [Android Media Scanner, and Download Manager Support](#user-content-android-media-scanner-and-download-manager-support)
26 26
  * [Self-Signed SSL Server](#user-content-self-signed-ssl-server)
27
+ * [RNFetchBlob as Fetch](#user-content-rnfetchblob-as-fetch)
27 28
 * [File System](#user-content-file-system)
28 29
  * [File access](#user-content-file-access)
29 30
  * [File stream](#user-content-file-stream)
@@ -40,6 +41,7 @@ This project was initially for solving the issue [facebook/react-native#854](htt
40 41
 
41 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 45
 ## Installation
44 46
 
45 47
 Install package from npm
@@ -63,7 +65,7 @@ Open `android/settings.gradle`, and add these lines which will app RNFetchBlob A
63 65
 ```diff
64 66
 include ':app'      
65 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 71
 Add this line to `MainApplication.java`, so that RNFetchBlob package becomes part of react native package.
@@ -118,7 +120,7 @@ Also, if you're going to use `Android Download Manager` you have to add this to
118 120
 
119 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 125
 ES6
124 126
 
@@ -332,7 +334,7 @@ Elements have property `filename` will be transformed into binary format, otherw
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 339
 ```js
338 340
 
@@ -413,7 +415,15 @@ task.cancel((err) => { ... })
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 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,6 +505,38 @@ RNFetchBlob.config({
495 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 540
 ### File System
499 541
 
500 542
 #### File Access
@@ -647,16 +689,18 @@ RNFetchBlob.config({
647 689
 
648 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 694
 - Blob
653 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 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 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,7 +722,8 @@ If you're going to concatenate files, you don't have to read the data to JS cont
678 722
 
679 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 727
 | 0.8.1 | Remove Web API log and fix ios progress report function. |
683 728
 | 0.8.0 | Added Web API polyfills, support regular request, added timeout option. |
684 729
 | 0.7.5 | Fix installation script that make it compatible to react-native < 0.28 |

+ 0
- 1
src/index.js Visa fil

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

+ 1
- 1
src/package.json Visa fil

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

+ 11
- 8
src/polyfill/Blob.js Visa fil

@@ -172,11 +172,12 @@ export default class Blob extends EventTarget {
172 172
    * @return {Blob} The Blob object instance itself
173 173
    */
174 174
   onCreated(fn:() => void):Blob {
175
-    log.verbose('register blob onCreated', this._onCreated.length)
175
+    log.verbose('#register blob onCreated', this._blobCreated)
176 176
     if(!this._blobCreated)
177 177
       this._onCreated.push(fn)
178
-    else
178
+    else {
179 179
       fn(this)
180
+    }
180 181
     return this
181 182
   }
182 183
 
@@ -230,12 +231,13 @@ export default class Blob extends EventTarget {
230 231
   }
231 232
 
232 233
   _invokeOnCreateEvent() {
233
-    log.verbose('invoke create event')
234
+    log.verbose('invoke create event', this._onCreated)
234 235
     this._blobCreated = true
235 236
     let fns = this._onCreated
236 237
     for(let i in fns) {
237
-      if(typeof fns[i] === 'function')
238
+      if(typeof fns[i] === 'function') {
238 239
         fns[i](this)
240
+      }
239 241
     }
240 242
     delete this._onCreated
241 243
   }
@@ -279,12 +281,13 @@ function createMixedBlobData(ref, dataArray) {
279 281
   // start write blob data
280 282
   // return p.then(() => {
281 283
     for(let i in args) {
282
-      p = p.then((written) => {
284
+      p = p.then(function(written){
285
+        let arg = this
283 286
         if(written)
284 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 292
     return p.then(() => Promise.resolve(size))
290 293
     // let promises = args.map((p) => {

+ 29
- 17
src/polyfill/XMLHttpRequest.js Visa fil

@@ -133,7 +133,7 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
133 133
 
134 134
     if(this._readyState !== XMLHttpRequest.OPENED)
135 135
       throw 'InvalidStateError : XMLHttpRequest is not opened yet.'
136
-
136
+    let promise = Promise.resolve()
137 137
     this._sendFlag = true
138 138
     log.verbose('XMLHttpRequest send ', body)
139 139
     let {_method, _url, _headers } = this
@@ -141,26 +141,37 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
141 141
     log.verbose(typeof body, body instanceof FormData)
142 142
 
143 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 151
     else if(typeof body === 'object') {
147 152
       body = JSON.stringify(body)
153
+      promise = Promise.resolve()
148 154
     }
149
-    else
155
+    else {
150 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 177
   overrideMimeType(mime:string) {
@@ -306,11 +317,12 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget{
306 317
         case 'blob' :
307 318
           resp.blob().then((b) => {
308 319
             this._responseText = resp.text()
309
-            this.response = b
320
+            this._response = b
310 321
             responseDataReady()
311 322
           })
312 323
         break;
313 324
         default :
325
+        console.log(resp, resp.text())
314 326
           this._responseText = resp.text()
315 327
           this._response = this.responseText
316 328
           responseDataReady()

+ 1
- 1
test-server/server.js Visa fil

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

+ 55
- 0
test/test-0.9.0.js Visa fil

@@ -32,6 +32,61 @@ const dirs = RNFetchBlob.fs.dirs
32 32
 
33 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 90
 describe('#73 unicode response BASE64 content test', (report, done) => {
36 91
 
37 92
   fetch(`${TEST_SERVER_URL}/unicode`, {

+ 32
- 4
test/test-firebase.js Visa fil

@@ -63,12 +63,12 @@ describe('firebase login', (report, done) => {
63 63
 
64 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 66
   let testImage = `firebase-test-${Platform.OS}-${Date.now()}.png`
69 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 72
     let storage = firebase.storage().ref('rnfbtest')
73 73
     let task = storage
74 74
       .child(RNTest.prop('firebase-image'))
@@ -147,3 +147,31 @@ describe('download to base64', (report, done) => {
147 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 Visa fil

@@ -59,81 +59,19 @@ describe('GET image from server', (report, done) => {
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 77
 // require('./benchmark')