1740b3867SJames Ide'use strict'; 2740b3867SJames Ide 3a47a1472SVille Immonenimport { Asset } from 'expo-asset'; 4a47a1472SVille Immonenimport * as FS from 'expo-file-system'; 5*8cb96155SEvan Baconimport Constants from 'expo-constants'; 6*8cb96155SEvan Baconimport { Platform } from '@unimodules/core'; 767f55e2bSStanisław Chmiela 867f55e2bSStanisław Chmielaexport const name = 'FileSystem'; 9740b3867SJames Ide 10*8cb96155SEvan Baconexport async function test({ describe, expect, it, ...t }) { 11*8cb96155SEvan Bacon describe('FileSystem', () => { 12740b3867SJames Ide const throws = async run => { 13740b3867SJames Ide let error = null; 14740b3867SJames Ide try { 15740b3867SJames Ide await run(); 16740b3867SJames Ide } catch (e) { 17740b3867SJames Ide error = e; 18740b3867SJames Ide } 19*8cb96155SEvan Bacon expect(error).toBeTruthy(); 20740b3867SJames Ide }; 21740b3867SJames Ide 22*8cb96155SEvan Bacon if (Constants.appOwnership === 'expo') { 23*8cb96155SEvan Bacon describe('managed workflow', () => { 24*8cb96155SEvan Bacon it('throws out-of-scope exceptions', async () => { 25*8cb96155SEvan Bacon const p = FS.documentDirectory; 26*8cb96155SEvan Bacon 27*8cb96155SEvan Bacon await throws(() => FS.getInfoAsync(p + '../hello/world')); 28*8cb96155SEvan Bacon await throws(() => FS.readAsStringAsync(p + '../hello/world')); 29*8cb96155SEvan Bacon await throws(() => FS.writeAsStringAsync(p + '../hello/world', '')); 30*8cb96155SEvan Bacon await throws(() => FS.deleteAsync(p + '../hello/world')); 31*8cb96155SEvan Bacon await throws(() => FS.deleteAsync(p)); 32*8cb96155SEvan Bacon await throws(() => FS.deleteAsync(FS.cacheDirectory)); 33*8cb96155SEvan Bacon await throws(() => FS.moveAsync({ from: p + '../a/b', to: 'c' })); 34*8cb96155SEvan Bacon await throws(() => FS.moveAsync({ from: 'c', to: p + '../a/b' })); 35*8cb96155SEvan Bacon await throws(() => FS.copyAsync({ from: p + '../a/b', to: 'c' })); 36*8cb96155SEvan Bacon await throws(() => FS.copyAsync({ from: 'c', to: p + '../a/b' })); 37*8cb96155SEvan Bacon await throws(() => FS.makeDirectoryAsync(p + '../hello/world')); 38*8cb96155SEvan Bacon await throws(() => FS.readDirectoryAsync(p + '../hello/world')); 39*8cb96155SEvan Bacon await throws(() => FS.downloadAsync('http://www.google.com', p + '../hello/world')); 40*8cb96155SEvan Bacon await throws(() => FS.readDirectoryAsync(p + '../')); 41*8cb96155SEvan Bacon await throws(() => FS.downloadAsync('http://www.google.com', p + '../hello/world')); 42*8cb96155SEvan Bacon }); 43*8cb96155SEvan Bacon }); 44*8cb96155SEvan Bacon } 45*8cb96155SEvan Bacon 46*8cb96155SEvan Bacon if (Platform.OS === 'web') { 47*8cb96155SEvan Bacon // Web doesn't support FileSystem 48*8cb96155SEvan Bacon return; 49*8cb96155SEvan Bacon } 50*8cb96155SEvan Bacon 51*8cb96155SEvan Bacon it( 52740b3867SJames Ide 'delete(idempotent) -> !exists -> download(md5, uri) -> exists ' + '-> delete -> !exists', 53740b3867SJames Ide async () => { 54740b3867SJames Ide const localUri = FS.documentDirectory + 'download1.png'; 55740b3867SJames Ide 56740b3867SJames Ide const assertExists = async expectedToExist => { 57740b3867SJames Ide let { exists } = await FS.getInfoAsync(localUri); 58740b3867SJames Ide if (expectedToExist) { 59*8cb96155SEvan Bacon expect(exists).toBeTruthy(); 60740b3867SJames Ide } else { 61*8cb96155SEvan Bacon expect(exists).not.toBeTruthy(); 62740b3867SJames Ide } 63740b3867SJames Ide }; 64740b3867SJames Ide 65740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 66740b3867SJames Ide await assertExists(false); 67740b3867SJames Ide 68fec220cbSSergei Chestakov const { md5, headers } = await FS.downloadAsync( 69740b3867SJames Ide 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png', 70740b3867SJames Ide localUri, 71740b3867SJames Ide { md5: true } 72740b3867SJames Ide ); 73*8cb96155SEvan Bacon expect(md5).toBe('1e02045c10b8f1145edc7c8375998f87'); 74740b3867SJames Ide await assertExists(true); 75*8cb96155SEvan Bacon expect(headers['Content-Type']).toBe('image/png'); 76740b3867SJames Ide 77740b3867SJames Ide await FS.deleteAsync(localUri); 78740b3867SJames Ide await assertExists(false); 79740b3867SJames Ide }, 80740b3867SJames Ide 9000 81fec220cbSSergei Chestakov ); 82740b3867SJames Ide 83*8cb96155SEvan Bacon it('Can read/write Base64', async () => { 842bd74c95SEvan Bacon const asset = await Asset.fromModule(require('../assets/icons/app.png')); 852bd74c95SEvan Bacon await asset.downloadAsync(); 862bd74c95SEvan Bacon 8767f55e2bSStanisław Chmiela for (let startingPosition = 0; startingPosition < 3; startingPosition++) { 882bd74c95SEvan Bacon const options = { 89fec220cbSSergei Chestakov encoding: FS.EncodingType.Base64, 9067f55e2bSStanisław Chmiela position: startingPosition, 9167f55e2bSStanisław Chmiela length: startingPosition + 1, 922bd74c95SEvan Bacon }; 932bd74c95SEvan Bacon 942bd74c95SEvan Bacon const b64 = await FS.readAsStringAsync(asset.localUri, options); 95*8cb96155SEvan Bacon expect(b64).toBeDefined(); 96*8cb96155SEvan Bacon expect(typeof b64).toBe('string'); 97*8cb96155SEvan Bacon expect(b64.length % 4).toBe(0); 982bd74c95SEvan Bacon 992bd74c95SEvan Bacon const localUri = FS.documentDirectory + 'b64.png'; 1002bd74c95SEvan Bacon 101fec220cbSSergei Chestakov await FS.writeAsStringAsync(localUri, b64, { encoding: FS.EncodingType.Base64 }); 1022bd74c95SEvan Bacon 103*8cb96155SEvan Bacon expect(await FS.readAsStringAsync(localUri, { encoding: FS.EncodingType.Base64 })).toBe( 10467f55e2bSStanisław Chmiela b64 10567f55e2bSStanisław Chmiela ); 1062bd74c95SEvan Bacon } 1072bd74c95SEvan Bacon }); 1082bd74c95SEvan Bacon 109*8cb96155SEvan Bacon it('delete(idempotent) -> delete[error]', async () => { 110740b3867SJames Ide const localUri = FS.documentDirectory + 'willDelete.png'; 111740b3867SJames Ide 112740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 113740b3867SJames Ide 114740b3867SJames Ide let error; 115740b3867SJames Ide try { 116740b3867SJames Ide await FS.deleteAsync(localUri); 117740b3867SJames Ide } catch (e) { 118740b3867SJames Ide error = e; 119740b3867SJames Ide } 120*8cb96155SEvan Bacon expect(error.message).toMatch(/not.*found/); 121740b3867SJames Ide }); 122740b3867SJames Ide 123*8cb96155SEvan Bacon it('download(md5, uri) -> read -> delete -> !exists -> read[error]', async () => { 124740b3867SJames Ide const localUri = FS.documentDirectory + 'download1.txt'; 125740b3867SJames Ide 126fec220cbSSergei Chestakov const { md5 } = await FS.downloadAsync( 127740b3867SJames Ide 'https://s3-us-west-1.amazonaws.com/test-suite-data/text-file.txt', 128740b3867SJames Ide localUri, 129740b3867SJames Ide { md5: true } 130740b3867SJames Ide ); 131*8cb96155SEvan Bacon expect(md5).toBe('86d73d2f11e507365f7ea8e7ec3cc4cb'); 132740b3867SJames Ide 133740b3867SJames Ide const string = await FS.readAsStringAsync(localUri); 134*8cb96155SEvan Bacon expect(string).toBe('hello, world\nthis is a test file\n'); 135740b3867SJames Ide 136740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 137740b3867SJames Ide 138740b3867SJames Ide let error; 139740b3867SJames Ide try { 140740b3867SJames Ide await FS.readAsStringAsync(localUri); 141740b3867SJames Ide } catch (e) { 142740b3867SJames Ide error = e; 143740b3867SJames Ide } 144*8cb96155SEvan Bacon expect(error).toBeTruthy(); 145*8cb96155SEvan Bacon }, 9000); 146740b3867SJames Ide 147*8cb96155SEvan Bacon it('delete(idempotent) -> !exists -> write -> read -> write -> read', async () => { 148740b3867SJames Ide const localUri = FS.documentDirectory + 'write1.txt'; 149740b3867SJames Ide 150740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 151740b3867SJames Ide 152740b3867SJames Ide const { exists } = await FS.getInfoAsync(localUri); 153*8cb96155SEvan Bacon expect(exists).not.toBeTruthy(); 154740b3867SJames Ide 155740b3867SJames Ide const writeAndVerify = async expected => { 156740b3867SJames Ide await FS.writeAsStringAsync(localUri, expected); 157740b3867SJames Ide const string = await FS.readAsStringAsync(localUri); 158*8cb96155SEvan Bacon expect(string).toBe(expected); 159740b3867SJames Ide }; 160740b3867SJames Ide 161740b3867SJames Ide await writeAndVerify('hello, world'); 162740b3867SJames Ide await writeAndVerify('hello, world!!!!!!'); 163740b3867SJames Ide }); 164740b3867SJames Ide 165*8cb96155SEvan Bacon it('delete(new) -> 2 * [write -> move -> !exists(orig) -> read(new)]', async () => { 166740b3867SJames Ide const from = FS.documentDirectory + 'from.txt'; 167740b3867SJames Ide const to = FS.documentDirectory + 'to.txt'; 168740b3867SJames Ide const contents = ['contents 1', 'contents 2']; 169740b3867SJames Ide 170740b3867SJames Ide await FS.deleteAsync(to, { idempotent: true }); 171740b3867SJames Ide 172740b3867SJames Ide // Move twice to make sure we can overwrite 173740b3867SJames Ide for (let i = 0; i < 2; ++i) { 174740b3867SJames Ide await FS.writeAsStringAsync(from, contents[i]); 175740b3867SJames Ide 176740b3867SJames Ide await FS.moveAsync({ from, to }); 177740b3867SJames Ide 178740b3867SJames Ide const { exists } = await FS.getInfoAsync(from); 179*8cb96155SEvan Bacon expect(exists).not.toBeTruthy(); 180740b3867SJames Ide 181*8cb96155SEvan Bacon expect(await FS.readAsStringAsync(to)).toBe(contents[i]); 182740b3867SJames Ide } 183740b3867SJames Ide }); 184740b3867SJames Ide 185*8cb96155SEvan Bacon it('delete(new) -> 2 * [write -> copy -> exists(orig) -> read(new)]', async () => { 186740b3867SJames Ide const from = FS.documentDirectory + 'from.txt'; 187740b3867SJames Ide const to = FS.documentDirectory + 'to.txt'; 188740b3867SJames Ide const contents = ['contents 1', 'contents 2']; 189740b3867SJames Ide 190740b3867SJames Ide await FS.deleteAsync(to, { idempotent: true }); 191740b3867SJames Ide 192740b3867SJames Ide // Copy twice to make sure we can overwrite 193740b3867SJames Ide for (let i = 0; i < 2; ++i) { 194740b3867SJames Ide await FS.writeAsStringAsync(from, contents[i]); 195740b3867SJames Ide 196740b3867SJames Ide await FS.copyAsync({ from, to }); 197740b3867SJames Ide 198740b3867SJames Ide const { exists } = await FS.getInfoAsync(from); 199*8cb96155SEvan Bacon expect(exists).toBeTruthy(); 200740b3867SJames Ide 201*8cb96155SEvan Bacon expect(await FS.readAsStringAsync(to)).toBe(contents[i]); 202740b3867SJames Ide } 203740b3867SJames Ide }); 204740b3867SJames Ide 205*8cb96155SEvan Bacon it( 206740b3867SJames Ide 'delete(dir) -> write(dir/file)[error] -> mkdir(dir) ->' + 207740b3867SJames Ide 'mkdir(dir)[error] -> write(dir/file) -> read', 208740b3867SJames Ide async () => { 209740b3867SJames Ide let error; 210740b3867SJames Ide const path = FS.documentDirectory + 'dir/file'; 211740b3867SJames Ide const dir = FS.documentDirectory + 'dir'; 212740b3867SJames Ide const contents = 'hello, world'; 213740b3867SJames Ide 214740b3867SJames Ide await FS.deleteAsync(dir, { idempotent: true }); 215740b3867SJames Ide 216740b3867SJames Ide error = null; 217740b3867SJames Ide try { 218740b3867SJames Ide await FS.writeAsStringAsync(path, contents); 219740b3867SJames Ide } catch (e) { 220740b3867SJames Ide error = e; 221740b3867SJames Ide } 222*8cb96155SEvan Bacon expect(error).toBeTruthy(); 223740b3867SJames Ide 224740b3867SJames Ide await FS.makeDirectoryAsync(dir); 225740b3867SJames Ide 226740b3867SJames Ide error = null; 227740b3867SJames Ide try { 228740b3867SJames Ide await FS.makeDirectoryAsync(dir); 229740b3867SJames Ide } catch (e) { 230740b3867SJames Ide error = e; 231740b3867SJames Ide } 232*8cb96155SEvan Bacon expect(error).toBeTruthy(); 233740b3867SJames Ide 234740b3867SJames Ide await FS.writeAsStringAsync(path, contents); 235740b3867SJames Ide 236*8cb96155SEvan Bacon expect(await FS.readAsStringAsync(path)).toBe(contents); 237740b3867SJames Ide } 238740b3867SJames Ide ); 239740b3867SJames Ide 240*8cb96155SEvan Bacon it( 241740b3867SJames Ide 'delete(dir) -> write(dir/dir2/file)[error] -> ' + 242740b3867SJames Ide 'mkdir(dir/dir2, intermediates) -> ' + 243740b3867SJames Ide 'mkdir(dir/dir2, intermediates) -> write(dir/dir2/file) -> read', 244740b3867SJames Ide async () => { 245740b3867SJames Ide let error; 246740b3867SJames Ide const path = FS.documentDirectory + 'dir/dir2/file'; 247740b3867SJames Ide const dir = FS.documentDirectory + 'dir/dir2'; 248740b3867SJames Ide const contents = 'hello, world'; 249740b3867SJames Ide 250740b3867SJames Ide await FS.deleteAsync(dir, { idempotent: true }); 251740b3867SJames Ide 252740b3867SJames Ide error = null; 253740b3867SJames Ide try { 254740b3867SJames Ide await FS.writeAsStringAsync(path, contents); 255740b3867SJames Ide } catch (e) { 256740b3867SJames Ide error = e; 257740b3867SJames Ide } 258*8cb96155SEvan Bacon expect(error).toBeTruthy(); 259740b3867SJames Ide 260740b3867SJames Ide await FS.makeDirectoryAsync(dir, { 261740b3867SJames Ide intermediates: true, 262740b3867SJames Ide }); 263740b3867SJames Ide 264740b3867SJames Ide error = null; 265740b3867SJames Ide try { 266740b3867SJames Ide await FS.makeDirectoryAsync(dir); 267740b3867SJames Ide } catch (e) { 268740b3867SJames Ide error = e; 269740b3867SJames Ide } 270*8cb96155SEvan Bacon expect(error).toBeTruthy(); 271740b3867SJames Ide 2726cfa9c5fSSergei Chestakov error = null; 2736cfa9c5fSSergei Chestakov try { 2746cfa9c5fSSergei Chestakov await FS.makeDirectoryAsync(dir, { 2756cfa9c5fSSergei Chestakov intermediates: true, 2766cfa9c5fSSergei Chestakov }); 2776cfa9c5fSSergei Chestakov } catch (e) { 2786cfa9c5fSSergei Chestakov error = e; 2796cfa9c5fSSergei Chestakov } 280*8cb96155SEvan Bacon expect(error).toBe(null); 2816cfa9c5fSSergei Chestakov 282740b3867SJames Ide await FS.writeAsStringAsync(path, contents); 283740b3867SJames Ide 284*8cb96155SEvan Bacon expect(await FS.readAsStringAsync(path)).toBe(contents); 285740b3867SJames Ide } 286740b3867SJames Ide ); 287740b3867SJames Ide 288fec220cbSSergei Chestakov /* 289fec220cbSSergei Chestakov This test fails in CI because of an exception being thrown by deleteAsync in the nativeModule. 290fec220cbSSergei Chestakov I traced it down to the FileUtils.forceDelete call here: 291fec220cbSSergei Chestakov https://github.com/expo/expo/blob/bcd136b096df84e0b0f72a15acbda45491de8201/packages/expo-file-system/android/src/main/java/expo/modules/filesystem/FileSystemModule.java#L294 292*8cb96155SEvan Bacon it( 293740b3867SJames Ide 'delete(dir, idempotent) -> make tree -> check contents ' + 294740b3867SJames Ide '-> check directory listings' + 295740b3867SJames Ide '-> move -> check directory listings' + 296740b3867SJames Ide '-> copy -> check directory listings', 297740b3867SJames Ide async () => { 298740b3867SJames Ide let error; 299740b3867SJames Ide const dir = FS.documentDirectory + 'dir'; 300740b3867SJames Ide 301740b3867SJames Ide await FS.deleteAsync(dir, { idempotent: true }); 302740b3867SJames Ide 303740b3867SJames Ide await FS.makeDirectoryAsync(dir + '/child1', { 304740b3867SJames Ide intermediates: true, 305740b3867SJames Ide }); 306740b3867SJames Ide await FS.makeDirectoryAsync(dir + '/child2', { 307740b3867SJames Ide intermediates: true, 308740b3867SJames Ide }); 309740b3867SJames Ide 310740b3867SJames Ide await FS.writeAsStringAsync(dir + '/file1', 'contents1'); 311740b3867SJames Ide await FS.writeAsStringAsync(dir + '/file2', 'contents2'); 312740b3867SJames Ide 313740b3867SJames Ide await FS.writeAsStringAsync(dir + '/child1/file3', 'contents3'); 314740b3867SJames Ide 315740b3867SJames Ide await FS.writeAsStringAsync(dir + '/child2/file4', 'contents4'); 316740b3867SJames Ide await FS.writeAsStringAsync(dir + '/child2/file5', 'contents5'); 317740b3867SJames Ide 318740b3867SJames Ide const checkContents = async (path, contents) => 319*8cb96155SEvan Bacon expect(await FS.readAsStringAsync(path)).toBe(contents); 320740b3867SJames Ide 321740b3867SJames Ide await checkContents(dir + '/file1', 'contents1'); 322740b3867SJames Ide await checkContents(dir + '/file2', 'contents2'); 323740b3867SJames Ide await checkContents(dir + '/child1/file3', 'contents3'); 324740b3867SJames Ide await checkContents(dir + '/child2/file4', 'contents4'); 325740b3867SJames Ide await checkContents(dir + '/child2/file5', 'contents5'); 326740b3867SJames Ide 327740b3867SJames Ide const checkDirectory = async (path, expected) => { 328740b3867SJames Ide const list = await FS.readDirectoryAsync(path); 329*8cb96155SEvan Bacon expect(list.sort()).toEqual(expected.sort()); 330740b3867SJames Ide }; 331740b3867SJames Ide 332740b3867SJames Ide const checkRoot = async root => { 333740b3867SJames Ide await checkDirectory(root, ['file1', 'file2', 'child1', 'child2']); 334740b3867SJames Ide await checkDirectory(root + '/child1', ['file3']); 335740b3867SJames Ide await checkDirectory(root + '/child2', ['file4', 'file5']); 336740b3867SJames Ide 337740b3867SJames Ide error = null; 338740b3867SJames Ide try { 339740b3867SJames Ide await checkDirectory(root + '/file1', ['nope']); 340740b3867SJames Ide } catch (e) { 341740b3867SJames Ide error = e; 342740b3867SJames Ide } 343*8cb96155SEvan Bacon expect(error).toBeTruthy(); 344740b3867SJames Ide }; 345740b3867SJames Ide 346740b3867SJames Ide await checkRoot(dir); 347740b3867SJames Ide 348740b3867SJames Ide await FS.deleteAsync(FS.documentDirectory + 'moved', { 349740b3867SJames Ide idempotent: true, 350740b3867SJames Ide }); 351740b3867SJames Ide await FS.moveAsync({ from: dir, to: FS.documentDirectory + 'moved' }); 352740b3867SJames Ide await checkRoot(FS.documentDirectory + 'moved'); 353740b3867SJames Ide await FS.copyAsync({ 354740b3867SJames Ide from: FS.documentDirectory + 'moved', 355740b3867SJames Ide to: FS.documentDirectory + 'copied', 356740b3867SJames Ide }); 357740b3867SJames Ide await checkRoot(FS.documentDirectory + 'copied'); 358740b3867SJames Ide } 359740b3867SJames Ide ); 360fec220cbSSergei Chestakov */ 361740b3867SJames Ide 362*8cb96155SEvan Bacon it('delete(idempotent) -> download(md5) -> getInfo(size)', async () => { 363740b3867SJames Ide const localUri = FS.documentDirectory + 'download1.png'; 364740b3867SJames Ide 365740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 366740b3867SJames Ide 36767f55e2bSStanisław Chmiela const { md5 } = await FS.downloadAsync( 368740b3867SJames Ide 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png', 369740b3867SJames Ide localUri, 370740b3867SJames Ide { md5: true } 371740b3867SJames Ide ); 372*8cb96155SEvan Bacon expect(md5).toBe('1e02045c10b8f1145edc7c8375998f87'); 373740b3867SJames Ide 374740b3867SJames Ide const { size, modificationTime } = await FS.getInfoAsync(localUri); 375*8cb96155SEvan Bacon expect(size).toBe(3230); 376740b3867SJames Ide const nowTime = 0.001 * new Date().getTime(); 377*8cb96155SEvan Bacon expect(nowTime - modificationTime).toBeLessThan(3600); 378740b3867SJames Ide 379740b3867SJames Ide await FS.deleteAsync(localUri); 380*8cb96155SEvan Bacon }, 30000); 381740b3867SJames Ide 382*8cb96155SEvan Bacon it('missing parameters', async () => { 383740b3867SJames Ide const p = FS.documentDirectory + 'test'; 384740b3867SJames Ide 385740b3867SJames Ide await throws(() => FS.moveAsync({ from: p })); 386740b3867SJames Ide await throws(() => FS.moveAsync({ to: p })); 387740b3867SJames Ide await throws(() => FS.copyAsync({ from: p })); 388740b3867SJames Ide await throws(() => FS.copyAsync({ to: p })); 389740b3867SJames Ide }); 390740b3867SJames Ide 391*8cb96155SEvan Bacon it('can read root directories', async () => { 392740b3867SJames Ide await FS.readDirectoryAsync(FS.documentDirectory); 393740b3867SJames Ide await FS.readDirectoryAsync(FS.cacheDirectory); 394740b3867SJames Ide }); 395740b3867SJames Ide 396*8cb96155SEvan Bacon it('download(network failure)', async () => { 397740b3867SJames Ide const localUri = FS.documentDirectory + 'download1.png'; 398740b3867SJames Ide 399740b3867SJames Ide const assertExists = async expectedToExist => { 400740b3867SJames Ide let { exists } = await FS.getInfoAsync(localUri); 401740b3867SJames Ide if (expectedToExist) { 402*8cb96155SEvan Bacon expect(exists).toBeTruthy(); 403740b3867SJames Ide } else { 404*8cb96155SEvan Bacon expect(exists).not.toBeTruthy(); 405740b3867SJames Ide } 406740b3867SJames Ide }; 407740b3867SJames Ide 408740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 409740b3867SJames Ide await assertExists(false); 410740b3867SJames Ide 411740b3867SJames Ide let error; 412740b3867SJames Ide try { 413fec220cbSSergei Chestakov await FS.downloadAsync('https://nonexistent-subdomain.expo.io', localUri, { md5: true }); 414740b3867SJames Ide } catch (e) { 415740b3867SJames Ide error = e; 416740b3867SJames Ide } 417*8cb96155SEvan Bacon expect(error).toBeTruthy(); 418740b3867SJames Ide await assertExists(false); 419740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 420*8cb96155SEvan Bacon }, 30000); 421740b3867SJames Ide 422*8cb96155SEvan Bacon it('download(404)', async () => { 423740b3867SJames Ide const localUri = FS.documentDirectory + 'download1.png'; 424740b3867SJames Ide 425740b3867SJames Ide const assertExists = async expectedToExist => { 426740b3867SJames Ide let { exists } = await FS.getInfoAsync(localUri); 427740b3867SJames Ide if (expectedToExist) { 428*8cb96155SEvan Bacon expect(exists).toBeTruthy(); 429740b3867SJames Ide } else { 430*8cb96155SEvan Bacon expect(exists).not.toBeTruthy(); 431740b3867SJames Ide } 432740b3867SJames Ide }; 433740b3867SJames Ide 434740b3867SJames Ide await FS.deleteAsync(localUri, { idempotent: true }); 435740b3867SJames Ide await assertExists(false); 436740b3867SJames Ide 437fec220cbSSergei Chestakov const { status } = await FS.downloadAsync('https://expo.io/404', localUri, { 438740b3867SJames Ide md5: true, 439740b3867SJames Ide }); 440740b3867SJames Ide await assertExists(true); 441*8cb96155SEvan Bacon expect(status).toBe(404); 442740b3867SJames Ide 443740b3867SJames Ide await FS.deleteAsync(localUri); 444740b3867SJames Ide await assertExists(false); 445*8cb96155SEvan Bacon }, 30000); 446d7aba270SDominik Sokal 447*8cb96155SEvan Bacon it('download(nonexistent local path)', async () => { 448d7aba270SDominik Sokal try { 449d7aba270SDominik Sokal const remoteUrl = 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png'; 450d7aba270SDominik Sokal const localUri = FS.documentDirectory + 'doesnt/exists/download1.png'; 451d7aba270SDominik Sokal await FS.downloadAsync(remoteUrl, localUri); 452d7aba270SDominik Sokal } catch (err) { 453*8cb96155SEvan Bacon expect(err.message).toMatch(/Directory for .* doesn't exist/); 454d7aba270SDominik Sokal } 455*8cb96155SEvan Bacon }, 30000); 456d7aba270SDominik Sokal 457*8cb96155SEvan Bacon it('mkdir(multi-level) + download(multi-level local path)', async () => { 458d7aba270SDominik Sokal const remoteUrl = 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png'; 459d7aba270SDominik Sokal const localDirUri = FS.documentDirectory + 'foo/bar/baz'; 460d7aba270SDominik Sokal const localFileUri = localDirUri + 'download1.png'; 461d7aba270SDominik Sokal 462d7aba270SDominik Sokal await FS.makeDirectoryAsync(localDirUri, { intermediates: true }); 463d7aba270SDominik Sokal 464d7aba270SDominik Sokal await FS.downloadAsync(remoteUrl, localFileUri); 465*8cb96155SEvan Bacon }, 30000); 466740b3867SJames Ide }); 467740b3867SJames Ide} 468