├── .gitignore ├── LICENSE.txt ├── README.md ├── bower.json ├── callback.html ├── dropbox.js ├── karma.conf.js └── test └── spec ├── DropboxProviderSpec.coffee └── DropboxSpec.coffee /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | *.swp 4 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Christian Smith, http://anvil.io 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ngDropbox 2 | 3 | ngDropbox is a [Dropbox Core API](https://www.dropbox.com/developers/core/docs) Client for AngularJS adapted from [dropbox-js](https://github.com/dropbox/dropbox-js). It should be familiar to dropbox-js users as well as idiomatic to AngularJS. 4 | 5 | 6 | ## Status 7 | 8 | This module is extracted from an AngularJS application. It mostly satisfies the needs of that project but I'm working (as of 1/4/2014) in my spare time to implement the rest of the API. If you want to use ngDropbox but something is missing or doesn't work as expected, please submit an issue or get in touch to pair program. Thanks in advance! 9 | 10 | 11 | ## Install 12 | 13 | [Bower](http://bower.io/) is the quickest way to include ngDropbox in your project. 14 | 15 | $ bower install git@github.com:christiansmith/ngDropbox.git --save 16 | 17 | 18 | 19 | If you don't use Bower, just download `dropbox.js` into your scripts directory. 20 | 21 | $ curl -O https://raw.github.com/christiansmith/ngDropbox/master/dropbox.js 22 | 23 | 24 | 25 | 26 | ## Usage 27 | 28 | After you create an app in the [Dropbox App Console](https://www.dropbox.com/developers/apps), add an OAuth Redirect URI pointing to `https:///components/ngDropbox/callback.html`. 29 | 30 | In your AngularJS app, load the module. Inform your app of the App key and Redirect URI, then inject the service into your controllers and start making API calls. All methods that communicate with the API return promises. 31 | 32 | // load the module 33 | angular.module('myApp', ['dropbox']) 34 | 35 | .config(function (DropboxProvider) { 36 | DropboxProvider.config(, ); 37 | }) 38 | 39 | // inject the service 40 | .controller('DropboxCtrl', function ($scope, Dropbox) { 41 | 42 | // assign a promise to scope 43 | $scope.accountInfo = Dropbox.accountInfo(); 44 | 45 | // or use callbacks 46 | Dropbox.copy('dir/image1.jpg', 'dir/image2.jpg').then(function (res) { 47 | Dropbox.move('dir/image1.jpg', 'dir/image.jpg').then(function (res) { 48 | $scope.photos = Dropbox.stat('dir'); 49 | }); 50 | }); 51 | 52 | }); 53 | 54 | ### API 55 | 56 | * [**Dropbox.accountInfo()**](https://www.dropbox.com/developers/core/docs#account-info) 57 | * [**Dropbox.userInfo()**](https://www.dropbox.com/developers/core/docs#account-info) (alias Dropbox.accountInfo()) 58 | * [**Dropbox.readFile(path, params)**](https://www.dropbox.com/developers/core/docs#files-GET) 59 | * [**Dropbox.writeFile(path, content, params)**](https://www.dropbox.com/developers/core/docs#files_put) 60 | * [**Dropbox.stat(path, params)**](https://www.dropbox.com/developers/core/docs#metadata) 61 | * [**Dropbox.metadata(path, params)**](https://www.dropbox.com/developers/core/docs#metadata) (alias Dropbox.stat(path, params)) 62 | * [**Dropbox.readdir(path, params)**](https://www.dropbox.com/developers/core/docs#metadata) 63 | * makeUrl 64 | * [**Dropbox.history(path, params)**](https://www.dropbox.com/developers/core/docs#revisions) 65 | * [**Dropbox.revisions(path, params)**](https://www.dropbox.com/developers/core/docs#revisions) (alias Dropbox.history(path, params)) 66 | * [**Dropbox.thumbnailUrl(path, params)**]() 67 | * readThumbnail 68 | * [**Dropbox.revertFile(path, rev)**]() 69 | * [**Dropbox.restore(path, rev)**]() 70 | * [**Dropbox.findByName(path, pattern, params)**]() 71 | * [**Dropbox.search(path, pattern, params)**]() 72 | * makeCopyReference/copyRef 73 | * pullChanges/delta 74 | * [**Dropbox.mkdir(path)**](https://www.dropbox.com/developers/core/docs#fileops-create-folder) 75 | * [**Dropbox.remove(path)**](https://www.dropbox.com/developers/core/docs#fileops-delete) 76 | * [**Dropbox.unlink(path)**](https://www.dropbox.com/developers/core/docs#fileops-delete) (alias Dropbox.remove(path)) 77 | * [**Dropbox.delete(path)**](https://www.dropbox.com/developers/core/docs#fileops-delete) (alias Dropbox.remove(path)) 78 | * [**Dropbox.copy(from, to)**](https://www.dropbox.com/developers/core/docs#fileops-copy) 79 | * [**Dropbox.move(from, to)**](https://www.dropbox.com/developers/core/docs#fileops-move) 80 | 81 | 82 | 83 | 84 | ## TODO 85 | 86 | Methods yet to be implemented (as of 8/1/2013). 87 | 88 | * signOut/signOff 89 | * writeFile 90 | * resumableUpload 91 | * makeUrl 92 | * readThumbnail 93 | * makeCopyReference/copyRef 94 | * pullChanges/delta 95 | 96 | Other 97 | 98 | * Support redirect and other authentication methods in addition to browser popup 99 | * Test in multiple browsers 100 | * Test error cases 101 | 102 | 103 | ## Development 104 | 105 | Installing the Karma test runner with `npm install karma -g`, then run the tests with `karma start`. 106 | 107 | 108 | ## Copyright and License 109 | 110 | The library is Copyright (c) 2013 Christian Smith, and distributed under the MIT License. 111 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngDropbox", 3 | "version": "0.0.0", 4 | "main": "dropbox.js", 5 | "ignore": [ 6 | "**/.*", 7 | "test", 8 | "node_modules", 9 | "components", 10 | "karma.conf.js" 11 | ], 12 | "devDependencies": { 13 | "angular": "~1.2.4", 14 | "angular-mocks": "~1.2.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /callback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 |

Dropbox sign-in successful

17 | 18 |

Please close this window.

19 | 20 | -------------------------------------------------------------------------------- /dropbox.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | angular.module('dropbox', []) 5 | 6 | 7 | .provider('Dropbox', function DropboxProvider () { 8 | 9 | 10 | var clientId, redirectUri; 11 | 12 | 13 | this.config = function (id, uri) { 14 | this.clientId = clientId = id; 15 | this.redirectUri = redirectUri = uri; 16 | }; 17 | 18 | 19 | this.$get = [ 20 | '$q', 21 | '$http', 22 | '$window', 23 | function ($q, $http, $window) { 24 | 25 | 26 | /** 27 | * Credentials 28 | */ 29 | 30 | var oauth = {}; 31 | 32 | 33 | /** 34 | * Dropbox API Servers 35 | */ 36 | 37 | var authServer = 'https://www.dropbox.com' 38 | , apiServer = 'https://api.dropbox.com' 39 | , fileServer = 'https://api-content.dropbox.com'; 40 | 41 | 42 | /** 43 | * API Method URLs 44 | */ 45 | 46 | var urls = { 47 | // Authentication. 48 | authorize: authServer + '/1/oauth2/authorize', 49 | token: apiServer + '/1/oauth2/token', 50 | signOut: apiServer + '/1/unlink_access_token', 51 | 52 | // Accounts. 53 | accountInfo: apiServer + '/1/account/info', 54 | 55 | // Files and metadata. 56 | getFile: fileServer + '/1/files/auto/', 57 | postFile: fileServer + '/1/files/auto/', 58 | putFile: fileServer + '/1/files_put/auto/', 59 | metadata: apiServer + '/1/metadata/auto/', 60 | delta: apiServer + '/1/delta', 61 | revisions: apiServer + '/1/revisions/auto/', 62 | restore: apiServer + '/1/restore/auto/', 63 | search: apiServer + '/1/search/auto/', 64 | shares: apiServer + '/1/shares/auto', 65 | media: apiServer + '/1/media/auto', 66 | copyRef: apiServer + '/1/copy_ref/auto', 67 | thumbnails: fileServer + '/1/thumbnails/auto', 68 | chunkedUpload: fileServer + '/1/chunked_upload', 69 | commitChunkedUpload: fileServer + '/1/commit_chunked_upload/auto', 70 | 71 | // File operations. 72 | fileopsCopy: apiServer + '/1/fileops/copy', 73 | fileopsCreateFolder: apiServer + '/1/fileops/create_folder', 74 | fileopsDelete: apiServer + '/1/fileops/delete', 75 | fileopsMove: apiServer + '/1/fileops/move' 76 | }; 77 | 78 | 79 | /** 80 | * OAuth 2.0 Signatures 81 | */ 82 | 83 | function oauthHeader(options) { 84 | if (!options.headers) { options.headers = {}; } 85 | options.headers['Authorization'] = 'Bearer ' + oauth.access_token; 86 | } 87 | 88 | function oauthParams(options) { 89 | if (!options.params) { options.params = {}; } 90 | options.params.access_token = oauth.access_token; 91 | } 92 | 93 | 94 | /** 95 | * HTTP Request Helper 96 | */ 97 | 98 | function request(config) { 99 | var deferred = $q.defer(); 100 | 101 | oauthHeader(config); 102 | 103 | function success(response) { 104 | console.log(config, response.data); 105 | deferred.resolve(response.data); 106 | } 107 | 108 | function failure(fault) { 109 | console.log(config, fault); 110 | deferred.reject(fault); 111 | } 112 | 113 | $http(config).then(success, failure); 114 | return deferred.promise; 115 | } 116 | 117 | 118 | /** 119 | * HTTP GET Helper 120 | */ 121 | 122 | function GET(url, params) { 123 | var responseType = 'text'; 124 | if (params) { 125 | if (params.arrayBuffer) { 126 | responseType = 'arraybuffer'; 127 | } else if (params.blob) { 128 | responseType = 'blob'; 129 | } else if (params.buffer) { 130 | responseType = 'buffer'; 131 | } else if (params.binary) { 132 | responseType = 'b'; // See the Dropbox.Util.Xhr.setResponseType docs 133 | } 134 | } 135 | 136 | return request({ 137 | responseType: responseType, 138 | method: 'GET', 139 | url: url, 140 | params: params 141 | }); 142 | } 143 | 144 | 145 | /** 146 | * HTTP POST Helper 147 | */ 148 | 149 | function POST(url, data, params) { 150 | return request({ 151 | method: 'POST', 152 | url: url, 153 | data: data, 154 | params: params 155 | }); 156 | } 157 | 158 | 159 | /** 160 | * Configure the authorize popup window 161 | * Adapted from dropbox-js 162 | */ 163 | 164 | function popupSize(popupWidth, popupHeight) { 165 | var x0, y0, width, height, popupLeft, popupTop; 166 | 167 | // Metrics for the current browser window. 168 | x0 = $window.screenX || $window.screenLeft 169 | y0 = $window.screenY || $window.screenTop 170 | width = $window.outerWidth || $document.documentElement.clientWidth 171 | height = $window.outerHeight || $document.documentElement.clientHeight 172 | 173 | // Computed popup window metrics. 174 | popupLeft = Math.round(x0) + (width - popupWidth) / 2 175 | popupTop = Math.round(y0) + (height - popupHeight) / 2.5 176 | if (popupLeft < x0) { popupLeft = x0 } 177 | if (popupTop < y0) { popupTop = y0 } 178 | 179 | return 'width=' + popupWidth + ',height=' + popupHeight + ',' + 180 | 'left=' + popupLeft + ',top=' + popupTop + ',' + 181 | 'dialog=yes,dependent=yes,scrollbars=yes,location=yes'; 182 | } 183 | 184 | 185 | /** 186 | * Parse credentials from Dropbox authorize callback 187 | * Adapted from dropbox-js 188 | */ 189 | 190 | function queryParamsFromUrl(url) { 191 | var match = /^[^?#]+(\?([^\#]*))?(\#(.*))?$/.exec(url); 192 | if (!match) { return {}; } 193 | 194 | var query = match[2] || '' 195 | , fragment = match[4] || '' 196 | , fragmentOffset = fragment.indexOf('?') 197 | , params = {} 198 | ; 199 | 200 | if (fragmentOffset !== -1) { 201 | fragment = fragment.substring(fragmentOffset + 1); 202 | } 203 | 204 | var kvp = query.split('&').concat(fragment.split('&')); 205 | kvp.forEach(function (kv) { 206 | var offset = kv.indexOf('='); 207 | if (offset === -1) { return; } 208 | params[decodeURIComponent(kv.substring(0, offset))] = 209 | decodeURIComponent(kv.substring(offset + 1)); 210 | }); 211 | 212 | return params; 213 | } 214 | 215 | 216 | /** 217 | * Dropbox Service 218 | */ 219 | 220 | return { 221 | 222 | 223 | urls: urls, // exposed for testing 224 | 225 | 226 | credentials: function () { 227 | return oauth; 228 | }, 229 | 230 | 231 | authenticate: function () { 232 | var self = this 233 | , deferred = $q.defer() 234 | , authUrl = urls.authorize 235 | + '?client_id=' + clientId 236 | // + '&state=' + 237 | + '&response_type=token' 238 | + '&redirect_uri=' + redirectUri 239 | 240 | function listener(event) { 241 | var response = queryParamsFromUrl(event.data); 242 | 243 | if (response.access_denied) { 244 | deferred.reject(response); 245 | } 246 | 247 | else if (response.access_token) { 248 | oauth = self.oauth = response; 249 | deferred.resolve(oauth); 250 | } 251 | 252 | $window.removeEventListener('message', listener, false); 253 | } 254 | 255 | $window.addEventListener('message', listener, false); 256 | $window.open(authUrl,'_dropboxOauthSigninWindow', popupSize(700, 500)); 257 | 258 | return deferred.promise; 259 | }, 260 | 261 | 262 | isAuthenticated: function () { 263 | return (oauth.access_token) ? true : false 264 | }, 265 | 266 | 267 | // signOut 268 | 269 | 270 | // signOff 271 | 272 | 273 | accountInfo: function () { 274 | return GET(urls.accountInfo); 275 | }, 276 | 277 | 278 | userInfo: function () { 279 | return this.accountInfo(); 280 | }, 281 | 282 | 283 | readFile: function (path, params) { 284 | return GET(urls.getFile + path, params); 285 | }, 286 | 287 | 288 | writeFile: function (path, content, params) { 289 | return request({ 290 | method: 'POST', 291 | url: urls.putFile + path, 292 | data: content, 293 | headers: { 'Content-Type': undefined }, 294 | transformRequest: angular.identity, 295 | params: params 296 | }); 297 | }, 298 | 299 | 300 | stat: function (path, params) { 301 | return GET(urls.metadata + path, params); 302 | }, 303 | 304 | 305 | readdir: function (path, params) { 306 | var deferred = $q.defer(); 307 | 308 | function success(stat) { 309 | var entries = stat.contents.map(function (entry) { 310 | return entry.path; 311 | }); 312 | 313 | console.log('readdir of ' + path, entries); 314 | deferred.resolve(entries); 315 | } 316 | 317 | function failure(fault) { deferred.reject(fault); } 318 | 319 | this.stat(path, params).then(success, failure); 320 | return deferred.promise; 321 | }, 322 | 323 | 324 | metadata: function (path, params) { 325 | return this.stat(path, params); 326 | }, 327 | 328 | 329 | // makeUrl 330 | 331 | 332 | history: function (path, params) { 333 | return GET(urls.revisions + path, params); 334 | }, 335 | 336 | 337 | revisions: function (path, params) { 338 | return this.history(path, params); 339 | }, 340 | 341 | 342 | thumbnailUrl: function (path, params) { 343 | return urls.thumbnails 344 | + path 345 | + '?format=jpeg&size=m&access_token=' 346 | + oauth.access_token; 347 | }, 348 | 349 | 350 | // readThumbnail 351 | 352 | 353 | revertFile: function (path, rev) { 354 | return POST(urls.restore + path, null, { rev: rev }); 355 | }, 356 | 357 | 358 | restore: function (path, rev) { 359 | return this.revertFile(path, rev); 360 | }, 361 | 362 | 363 | findByName: function (path, pattern, params) { 364 | var params = params || {}; 365 | params.query = pattern; 366 | 367 | return GET(urls.search + path, params); 368 | }, 369 | 370 | 371 | search: function (path, pattern, params) { 372 | return this.findByName(path, pattern, params); 373 | }, 374 | 375 | 376 | // makeCopyReference 377 | 378 | 379 | // copyRef 380 | 381 | 382 | // pullChanges 383 | 384 | 385 | // delta 386 | 387 | 388 | mkdir: function (path) { 389 | return POST(urls.fileopsCreateFolder, null, { 390 | root: 'auto', 391 | path: path 392 | }); 393 | }, 394 | 395 | 396 | remove: function (path) { 397 | return POST(urls.fileopsDelete, null, { 398 | root: 'auto', 399 | path: path 400 | }); 401 | }, 402 | 403 | 404 | unlink: function (path) { 405 | return this.remove(path); 406 | }, 407 | 408 | 409 | delete: function (path) { 410 | return this.remove(path); 411 | }, 412 | 413 | 414 | copy: function (from, to) { 415 | return POST(urls.fileopsCopy, null, { 416 | root: 'auto', 417 | to_path: to, 418 | from_path: from 419 | }); 420 | }, 421 | 422 | 423 | move: function (from, to) { 424 | return POST(urls.fileopsMove, null, { 425 | root: 'auto', 426 | to_path: to, 427 | from_path: from 428 | }); 429 | }, 430 | 431 | 432 | reset: function () { 433 | oauth = {}; 434 | }, 435 | 436 | 437 | setCredentials: function (credentials) { 438 | oauth = credentials; 439 | }, 440 | 441 | 442 | // appHash 443 | 444 | 445 | }; 446 | 447 | 448 | }]; 449 | 450 | 451 | }) 452 | 453 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config) { 2 | config.set({ 3 | // your config 4 | frameworks: ["jasmine"], 5 | 6 | // base path, that will be used to resolve files and exclude 7 | basePath: '', 8 | 9 | 10 | // list of files / patterns to load in the browser 11 | files: [ 12 | 'bower_components/angular/angular.js', 13 | 'bower_components/angular-mocks/angular-mocks.js', 14 | 'dropbox.js', 15 | 'test/**/*Spec.coffee' 16 | ], 17 | 18 | 19 | // list of files to exclude 20 | exclude: [], 21 | 22 | 23 | // test results reporter to use 24 | // possible values: 'dots', 'progress', 'junit' 25 | reporters: ['progress'], 26 | 27 | 28 | // web server port 29 | port: 9876, 30 | 31 | 32 | // cli runner port 33 | runnerPort: 9100, 34 | 35 | 36 | // enable / disable colors in the output (reporters and logs) 37 | colors: true, 38 | 39 | 40 | // level of logging 41 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 42 | logLevel: config.LOG_INFO, 43 | 44 | 45 | // enable / disable watching file and executing tests whenever any file changes 46 | autoWatch: true, 47 | 48 | 49 | // Start these browsers, currently available: 50 | // - Chrome 51 | // - ChromeCanary 52 | // - Firefox 53 | // - Opera 54 | // - Safari (only Mac) 55 | // - PhantomJS 56 | // - IE (only Windows) 57 | browsers: ['Chrome'], 58 | 59 | 60 | // If browser does not capture in given timeout [ms], kill it 61 | captureTimeout: 60000, 62 | 63 | preprocessors: { 64 | '**/*.coffee': 'coffee' 65 | }, 66 | 67 | // Continuous Integration mode 68 | // if true, it capture browsers, run tests and exit 69 | singleRun: false 70 | }); 71 | }; 72 | 73 | 74 | -------------------------------------------------------------------------------- /test/spec/DropboxProviderSpec.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'DropboxProvider', -> 4 | 5 | 6 | {DropboxProvider} = {} 7 | 8 | 9 | beforeEach module 'dropbox' 10 | 11 | 12 | beforeEach module ($injector) -> 13 | DropboxProvider = $injector.get 'DropboxProvider' 14 | DropboxProvider.config 'CLIENT_ID', 'https://HOST/callback.html' 15 | 16 | 17 | beforeEach inject ($injector) -> 18 | Dropbox = $injector.get 'Dropbox' 19 | 20 | 21 | describe 'configure', -> 22 | 23 | it 'should set the client id', -> 24 | expect(DropboxProvider.clientId).toBe 'CLIENT_ID' 25 | 26 | it 'should set the redirect uri', -> 27 | expect(DropboxProvider.redirectUri).toBe 'https://HOST/callback.html' 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/spec/DropboxSpec.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | 4 | describe 'Dropbox', -> 5 | 6 | 7 | {DropboxProvider,Dropbox,$httpBackend,credentials} = {} 8 | 9 | 10 | headers = 11 | 'Accept': 'application/json, text/plain, */*' 12 | 'Authorization': 'Bearer g1bb3r1sh' 13 | 14 | 15 | beforeEach module 'dropbox' 16 | 17 | 18 | beforeEach inject ($injector) -> 19 | Dropbox = $injector.get 'Dropbox' 20 | $httpBackend = $injector.get '$httpBackend' 21 | credentials = access_token: 'g1bb3r1sh' 22 | Dropbox.setCredentials credentials 23 | 24 | 25 | afterEach -> 26 | $httpBackend.verifyNoOutstandingExpectation() 27 | $httpBackend.verifyNoOutstandingRequest() 28 | 29 | 30 | describe 'authorize', -> 31 | # TEST THE MESSAGE EVENT ON WINDOW 32 | 33 | 34 | describe 'credentials', -> 35 | 36 | it 'should return OAuth credentials', -> 37 | expect(Dropbox.credentials()).toEqual(credentials) 38 | 39 | 40 | describe 'authenticate', -> 41 | 42 | it 'should return a promise', -> 43 | expect(typeof Dropbox.authenticate().then).toEqual 'function' 44 | 45 | 46 | describe 'isAuthenticated', -> 47 | 48 | it 'should ...', -> 49 | expect(Dropbox.isAuthenticated()).toEqual true 50 | 51 | 52 | describe 'signOut', -> 53 | 54 | 55 | describe 'signOff', -> 56 | 57 | 58 | describe 'accountInfo', -> 59 | 60 | it 'should get account info', -> 61 | $httpBackend.expectGET("#{Dropbox.urls.accountInfo}").respond(null) 62 | Dropbox.accountInfo() 63 | $httpBackend.flush() 64 | 65 | 66 | describe 'readFile', -> 67 | 68 | it 'should get the contents of a file', -> 69 | url = "#{Dropbox.urls.getFile}directory/name.ext" 70 | $httpBackend.expectGET(url, headers).respond null 71 | Dropbox.readFile 'directory/name.ext' 72 | $httpBackend.flush() 73 | 74 | it 'should get the contents of a file as a blob', -> 75 | url = "#{Dropbox.urls.getFile}directory/name.ext?blob=true" 76 | $httpBackend.expectGET(url, headers).respond null 77 | Dropbox.readFile 'directory/name.ext', 'blob' : true 78 | $httpBackend.flush() 79 | 80 | describe 'writeFile', -> 81 | 82 | it 'should write string data', -> 83 | url = "#{Dropbox.urls.putFile}directory/file.txt" 84 | content = "contents of file" 85 | $httpBackend.expectPOST(url, content, headers).respond null 86 | Dropbox.writeFile 'directory/file.txt', content 87 | $httpBackend.flush() 88 | 89 | it 'should write ArrayBuffer data' 90 | it 'should write ArrayBuffer view data' 91 | it 'should write Blob data' 92 | it 'should write File data' 93 | it 'should write Buffer data' 94 | 95 | 96 | describe 'resumableUploadStep', -> 97 | 98 | 99 | describe 'resumableUploadFinish', -> 100 | 101 | 102 | describe 'stat', -> 103 | 104 | it 'should get the stat for a path', -> 105 | url = "#{Dropbox.urls.metadata}directory/name.ext" 106 | $httpBackend.expectGET(url, headers).respond null 107 | Dropbox.stat 'directory/name.ext' 108 | $httpBackend.flush() 109 | 110 | 111 | describe 'readdir', -> 112 | # HOW TO TEST THIS? 113 | 114 | 115 | describe 'metadata', -> 116 | 117 | it 'should get the metadata for a path', -> 118 | url = "#{Dropbox.urls.metadata}directory/name.ext" 119 | $httpBackend.expectGET(url, headers).respond null 120 | Dropbox.metadata 'directory/name.ext' 121 | $httpBackend.flush() 122 | 123 | 124 | describe 'makeUrl', -> 125 | 126 | 127 | describe 'history', -> 128 | 129 | it 'should get the history for a path', -> 130 | url = "#{Dropbox.urls.revisions}directory/name.ext" 131 | $httpBackend.expectGET(url, headers).respond null 132 | Dropbox.history 'directory/name.ext' 133 | $httpBackend.flush() 134 | 135 | 136 | describe 'revisions', -> 137 | 138 | it 'should get the revisions for a path', -> 139 | url = "#{Dropbox.urls.revisions}directory/name.ext" 140 | $httpBackend.expectGET(url, headers).respond null 141 | Dropbox.revisions 'directory/name.ext' 142 | $httpBackend.flush() 143 | 144 | 145 | describe 'thumbnailUrl', -> 146 | 147 | it 'should make a signed url for a thumbnail', -> 148 | url = "#{Dropbox.urls.thumbnails}directory/image.jpeg?format=jpeg&size=m&access_token=#{credentials.access_token}" 149 | expect(Dropbox.thumbnailUrl('directory/image.jpeg')).toEqual(url) 150 | 151 | 152 | describe 'readThumbnail', -> 153 | 154 | 155 | describe 'revertFile', -> 156 | 157 | 158 | it 'should restore a previous version', -> 159 | url = "#{Dropbox.urls.restore}file1.txt?rev=1234" 160 | $httpBackend.expectPOST(url, undefined).respond null 161 | Dropbox.revertFile 'file1.txt', '1234' 162 | $httpBackend.flush() 163 | 164 | 165 | describe 'restore', -> 166 | 167 | it 'should restore a previous version', -> 168 | url = "#{Dropbox.urls.restore}file1.txt?rev=1234" 169 | $httpBackend.expectPOST(url, undefined).respond null 170 | Dropbox.restore 'file1.txt', '1234' 171 | $httpBackend.flush() 172 | 173 | 174 | describe 'findByName', -> 175 | 176 | it 'should get query a path', -> 177 | url = "#{Dropbox.urls.search}directory/name.ext?query=terms" 178 | $httpBackend.expectGET(url, headers).respond null 179 | Dropbox.findByName 'directory/name.ext', 'terms' 180 | $httpBackend.flush() 181 | 182 | 183 | describe 'search', -> 184 | 185 | it 'should get query a path', -> 186 | url = "#{Dropbox.urls.search}directory/name.ext?query=terms" 187 | $httpBackend.expectGET(url, headers).respond null 188 | Dropbox.search 'directory/name.ext', 'terms' 189 | $httpBackend.flush() 190 | 191 | 192 | describe 'makeCopyReference', -> 193 | 194 | 195 | describe 'copyRef', -> 196 | 197 | 198 | describe 'pullChanges', -> 199 | 200 | 201 | describe 'delta', -> 202 | 203 | 204 | describe 'mkdir', -> 205 | 206 | it 'should create a folder', -> 207 | url = "#{Dropbox.urls.fileopsCreateFolder}?path=folder1&root=auto" 208 | $httpBackend.expectPOST(url, undefined).respond null 209 | Dropbox.mkdir 'folder1' 210 | $httpBackend.flush() 211 | 212 | 213 | describe 'remove', -> 214 | 215 | it 'should remove a file', -> 216 | url = "#{Dropbox.urls.fileopsDelete}?path=dir%2Ffile.ext&root=auto" 217 | $httpBackend.expectPOST(url, undefined).respond null 218 | Dropbox.remove 'dir/file.ext' 219 | $httpBackend.flush() 220 | 221 | 222 | describe 'unlink', -> 223 | 224 | it 'should remove a file', -> 225 | url = "#{Dropbox.urls.fileopsDelete}?path=dir%2Ffile.ext&root=auto" 226 | $httpBackend.expectPOST(url, undefined).respond null 227 | Dropbox.unlink 'dir/file.ext' 228 | $httpBackend.flush() 229 | 230 | 231 | describe 'delete', -> 232 | 233 | it 'should delete a file', -> 234 | url = "#{Dropbox.urls.fileopsDelete}?path=dir%2Ffile.ext&root=auto" 235 | $httpBackend.expectPOST(url, undefined).respond null 236 | Dropbox.delete 'dir/file.ext' 237 | $httpBackend.flush() 238 | 239 | 240 | describe 'copy', -> 241 | 242 | it 'should copy a file from one path to another', -> 243 | url = "#{Dropbox.urls.fileopsCopy}?from_path=dir%2Ffile1.ext&root=auto&to_path=dir%2Ffile2.ext" 244 | $httpBackend.expectPOST(url, undefined).respond null 245 | Dropbox.copy 'dir/file1.ext', 'dir/file2.ext' 246 | $httpBackend.flush() 247 | 248 | 249 | describe 'move', -> 250 | 251 | it 'should move a file', -> 252 | url = "#{Dropbox.urls.fileopsMove}?from_path=dir%2Ffile1.ext&root=auto&to_path=dir%2Ffile2.ext" 253 | $httpBackend.expectPOST(url, undefined).respond null 254 | Dropbox.move 'dir/file1.ext', 'dir/file2.ext' 255 | $httpBackend.flush() 256 | 257 | 258 | describe 'reset', -> 259 | 260 | 261 | describe 'setCredentials', -> 262 | 263 | 264 | describe 'appHash', -> 265 | 266 | --------------------------------------------------------------------------------