xref: /expo/apps/test-suite/tests/FileSystem.js (revision a47a1472)
1740b3867SJames Ide'use strict';
2740b3867SJames Ide
3*a47a1472SVille Immonenimport { Asset } from 'expo-asset';
4*a47a1472SVille Immonenimport * as FS from 'expo-file-system';
567f55e2bSStanisław Chmiela
667f55e2bSStanisław Chmielaexport const name = 'FileSystem';
7740b3867SJames Ide
8fec220cbSSergei Chestakovexport async function test(t) {
9740b3867SJames Ide  t.describe('FileSystem', () => {
10740b3867SJames Ide    const throws = async run => {
11740b3867SJames Ide      let error = null;
12740b3867SJames Ide      try {
13740b3867SJames Ide        await run();
14740b3867SJames Ide      } catch (e) {
15740b3867SJames Ide        error = e;
16740b3867SJames Ide      }
17740b3867SJames Ide      t.expect(error).toBeTruthy();
18740b3867SJames Ide    };
19740b3867SJames Ide
20fec220cbSSergei Chestakov    t.it(
21740b3867SJames Ide      'delete(idempotent) -> !exists -> download(md5, uri) -> exists ' + '-> delete -> !exists',
22740b3867SJames Ide      async () => {
23740b3867SJames Ide        const localUri = FS.documentDirectory + 'download1.png';
24740b3867SJames Ide
25740b3867SJames Ide        const assertExists = async expectedToExist => {
26740b3867SJames Ide          let { exists } = await FS.getInfoAsync(localUri);
27740b3867SJames Ide          if (expectedToExist) {
28740b3867SJames Ide            t.expect(exists).toBeTruthy();
29740b3867SJames Ide          } else {
30740b3867SJames Ide            t.expect(exists).not.toBeTruthy();
31740b3867SJames Ide          }
32740b3867SJames Ide        };
33740b3867SJames Ide
34740b3867SJames Ide        await FS.deleteAsync(localUri, { idempotent: true });
35740b3867SJames Ide        await assertExists(false);
36740b3867SJames Ide
37fec220cbSSergei Chestakov        const { md5, headers } = await FS.downloadAsync(
38740b3867SJames Ide          'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png',
39740b3867SJames Ide          localUri,
40740b3867SJames Ide          { md5: true }
41740b3867SJames Ide        );
42740b3867SJames Ide        t.expect(md5).toBe('1e02045c10b8f1145edc7c8375998f87');
43740b3867SJames Ide        await assertExists(true);
44740b3867SJames Ide        t.expect(headers['Content-Type']).toBe('image/png');
45740b3867SJames Ide
46740b3867SJames Ide        await FS.deleteAsync(localUri);
47740b3867SJames Ide        await assertExists(false);
48740b3867SJames Ide      },
49740b3867SJames Ide      9000
50fec220cbSSergei Chestakov    );
51740b3867SJames Ide
522bd74c95SEvan Bacon    t.it('Can read/write Base64', async () => {
532bd74c95SEvan Bacon      const asset = await Asset.fromModule(require('../assets/icons/app.png'));
542bd74c95SEvan Bacon      await asset.downloadAsync();
552bd74c95SEvan Bacon
5667f55e2bSStanisław Chmiela      for (let startingPosition = 0; startingPosition < 3; startingPosition++) {
572bd74c95SEvan Bacon        const options = {
58fec220cbSSergei Chestakov          encoding: FS.EncodingType.Base64,
5967f55e2bSStanisław Chmiela          position: startingPosition,
6067f55e2bSStanisław Chmiela          length: startingPosition + 1,
612bd74c95SEvan Bacon        };
622bd74c95SEvan Bacon
632bd74c95SEvan Bacon        const b64 = await FS.readAsStringAsync(asset.localUri, options);
642bd74c95SEvan Bacon        t.expect(b64).toBeDefined();
652bd74c95SEvan Bacon        t.expect(typeof b64).toBe('string');
6667f55e2bSStanisław Chmiela        t.expect(b64.length % 4).toBe(0);
672bd74c95SEvan Bacon
682bd74c95SEvan Bacon        const localUri = FS.documentDirectory + 'b64.png';
692bd74c95SEvan Bacon
70fec220cbSSergei Chestakov        await FS.writeAsStringAsync(localUri, b64, { encoding: FS.EncodingType.Base64 });
712bd74c95SEvan Bacon
72fec220cbSSergei Chestakov        t.expect(await FS.readAsStringAsync(localUri, { encoding: FS.EncodingType.Base64 })).toBe(
7367f55e2bSStanisław Chmiela          b64
7467f55e2bSStanisław Chmiela        );
752bd74c95SEvan Bacon      }
762bd74c95SEvan Bacon    });
772bd74c95SEvan Bacon
78740b3867SJames Ide    t.it('delete(idempotent) -> delete[error]', async () => {
79740b3867SJames Ide      const localUri = FS.documentDirectory + 'willDelete.png';
80740b3867SJames Ide
81740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
82740b3867SJames Ide
83740b3867SJames Ide      let error;
84740b3867SJames Ide      try {
85740b3867SJames Ide        await FS.deleteAsync(localUri);
86740b3867SJames Ide      } catch (e) {
87740b3867SJames Ide        error = e;
88740b3867SJames Ide      }
89740b3867SJames Ide      t.expect(error.message).toMatch(/not.*found/);
90740b3867SJames Ide    });
91740b3867SJames Ide
92fec220cbSSergei Chestakov    t.it(
93740b3867SJames Ide      'download(md5, uri) -> read -> delete -> !exists -> read[error]',
94740b3867SJames Ide      async () => {
95740b3867SJames Ide        const localUri = FS.documentDirectory + 'download1.txt';
96740b3867SJames Ide
97fec220cbSSergei Chestakov        const { md5 } = await FS.downloadAsync(
98740b3867SJames Ide          'https://s3-us-west-1.amazonaws.com/test-suite-data/text-file.txt',
99740b3867SJames Ide          localUri,
100740b3867SJames Ide          { md5: true }
101740b3867SJames Ide        );
102740b3867SJames Ide        t.expect(md5).toBe('86d73d2f11e507365f7ea8e7ec3cc4cb');
103740b3867SJames Ide
104740b3867SJames Ide        const string = await FS.readAsStringAsync(localUri);
105740b3867SJames Ide        t.expect(string).toBe('hello, world\nthis is a test file\n');
106740b3867SJames Ide
107740b3867SJames Ide        await FS.deleteAsync(localUri, { idempotent: true });
108740b3867SJames Ide
109740b3867SJames Ide        let error;
110740b3867SJames Ide        try {
111740b3867SJames Ide          await FS.readAsStringAsync(localUri);
112740b3867SJames Ide        } catch (e) {
113740b3867SJames Ide          error = e;
114740b3867SJames Ide        }
115740b3867SJames Ide        t.expect(error).toBeTruthy();
116740b3867SJames Ide      },
117740b3867SJames Ide      9000
118fec220cbSSergei Chestakov    );
119740b3867SJames Ide
120740b3867SJames Ide    t.it('delete(idempotent) -> !exists -> write -> read -> write -> read', async () => {
121740b3867SJames Ide      const localUri = FS.documentDirectory + 'write1.txt';
122740b3867SJames Ide
123740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
124740b3867SJames Ide
125740b3867SJames Ide      const { exists } = await FS.getInfoAsync(localUri);
126740b3867SJames Ide      t.expect(exists).not.toBeTruthy();
127740b3867SJames Ide
128740b3867SJames Ide      const writeAndVerify = async expected => {
129740b3867SJames Ide        await FS.writeAsStringAsync(localUri, expected);
130740b3867SJames Ide        const string = await FS.readAsStringAsync(localUri);
131740b3867SJames Ide        t.expect(string).toBe(expected);
132740b3867SJames Ide      };
133740b3867SJames Ide
134740b3867SJames Ide      await writeAndVerify('hello, world');
135740b3867SJames Ide      await writeAndVerify('hello, world!!!!!!');
136740b3867SJames Ide    });
137740b3867SJames Ide
138740b3867SJames Ide    t.it('delete(new) -> 2 * [write -> move -> !exists(orig) -> read(new)]', async () => {
139740b3867SJames Ide      const from = FS.documentDirectory + 'from.txt';
140740b3867SJames Ide      const to = FS.documentDirectory + 'to.txt';
141740b3867SJames Ide      const contents = ['contents 1', 'contents 2'];
142740b3867SJames Ide
143740b3867SJames Ide      await FS.deleteAsync(to, { idempotent: true });
144740b3867SJames Ide
145740b3867SJames Ide      // Move twice to make sure we can overwrite
146740b3867SJames Ide      for (let i = 0; i < 2; ++i) {
147740b3867SJames Ide        await FS.writeAsStringAsync(from, contents[i]);
148740b3867SJames Ide
149740b3867SJames Ide        await FS.moveAsync({ from, to });
150740b3867SJames Ide
151740b3867SJames Ide        const { exists } = await FS.getInfoAsync(from);
152740b3867SJames Ide        t.expect(exists).not.toBeTruthy();
153740b3867SJames Ide
154740b3867SJames Ide        t.expect(await FS.readAsStringAsync(to)).toBe(contents[i]);
155740b3867SJames Ide      }
156740b3867SJames Ide    });
157740b3867SJames Ide
158740b3867SJames Ide    t.it('delete(new) -> 2 * [write -> copy -> exists(orig) -> read(new)]', async () => {
159740b3867SJames Ide      const from = FS.documentDirectory + 'from.txt';
160740b3867SJames Ide      const to = FS.documentDirectory + 'to.txt';
161740b3867SJames Ide      const contents = ['contents 1', 'contents 2'];
162740b3867SJames Ide
163740b3867SJames Ide      await FS.deleteAsync(to, { idempotent: true });
164740b3867SJames Ide
165740b3867SJames Ide      // Copy twice to make sure we can overwrite
166740b3867SJames Ide      for (let i = 0; i < 2; ++i) {
167740b3867SJames Ide        await FS.writeAsStringAsync(from, contents[i]);
168740b3867SJames Ide
169740b3867SJames Ide        await FS.copyAsync({ from, to });
170740b3867SJames Ide
171740b3867SJames Ide        const { exists } = await FS.getInfoAsync(from);
172740b3867SJames Ide        t.expect(exists).toBeTruthy();
173740b3867SJames Ide
174740b3867SJames Ide        t.expect(await FS.readAsStringAsync(to)).toBe(contents[i]);
175740b3867SJames Ide      }
176740b3867SJames Ide    });
177740b3867SJames Ide
178740b3867SJames Ide    t.it(
179740b3867SJames Ide      'delete(dir) -> write(dir/file)[error] -> mkdir(dir) ->' +
180740b3867SJames Ide        'mkdir(dir)[error] -> write(dir/file) -> read',
181740b3867SJames Ide      async () => {
182740b3867SJames Ide        let error;
183740b3867SJames Ide        const path = FS.documentDirectory + 'dir/file';
184740b3867SJames Ide        const dir = FS.documentDirectory + 'dir';
185740b3867SJames Ide        const contents = 'hello, world';
186740b3867SJames Ide
187740b3867SJames Ide        await FS.deleteAsync(dir, { idempotent: true });
188740b3867SJames Ide
189740b3867SJames Ide        error = null;
190740b3867SJames Ide        try {
191740b3867SJames Ide          await FS.writeAsStringAsync(path, contents);
192740b3867SJames Ide        } catch (e) {
193740b3867SJames Ide          error = e;
194740b3867SJames Ide        }
195740b3867SJames Ide        t.expect(error).toBeTruthy();
196740b3867SJames Ide
197740b3867SJames Ide        await FS.makeDirectoryAsync(dir);
198740b3867SJames Ide
199740b3867SJames Ide        error = null;
200740b3867SJames Ide        try {
201740b3867SJames Ide          await FS.makeDirectoryAsync(dir);
202740b3867SJames Ide        } catch (e) {
203740b3867SJames Ide          error = e;
204740b3867SJames Ide        }
205740b3867SJames Ide        t.expect(error).toBeTruthy();
206740b3867SJames Ide
207740b3867SJames Ide        await FS.writeAsStringAsync(path, contents);
208740b3867SJames Ide
209740b3867SJames Ide        t.expect(await FS.readAsStringAsync(path)).toBe(contents);
210740b3867SJames Ide      }
211740b3867SJames Ide    );
212740b3867SJames Ide
213740b3867SJames Ide    t.it(
214740b3867SJames Ide      'delete(dir) -> write(dir/dir2/file)[error] -> ' +
215740b3867SJames Ide        'mkdir(dir/dir2, intermediates) -> ' +
216740b3867SJames Ide        'mkdir(dir/dir2, intermediates) -> write(dir/dir2/file) -> read',
217740b3867SJames Ide      async () => {
218740b3867SJames Ide        let error;
219740b3867SJames Ide        const path = FS.documentDirectory + 'dir/dir2/file';
220740b3867SJames Ide        const dir = FS.documentDirectory + 'dir/dir2';
221740b3867SJames Ide        const contents = 'hello, world';
222740b3867SJames Ide
223740b3867SJames Ide        await FS.deleteAsync(dir, { idempotent: true });
224740b3867SJames Ide
225740b3867SJames Ide        error = null;
226740b3867SJames Ide        try {
227740b3867SJames Ide          await FS.writeAsStringAsync(path, contents);
228740b3867SJames Ide        } catch (e) {
229740b3867SJames Ide          error = e;
230740b3867SJames Ide        }
231740b3867SJames Ide        t.expect(error).toBeTruthy();
232740b3867SJames Ide
233740b3867SJames Ide        await FS.makeDirectoryAsync(dir, {
234740b3867SJames Ide          intermediates: true,
235740b3867SJames Ide        });
236740b3867SJames Ide
237740b3867SJames Ide        error = null;
238740b3867SJames Ide        try {
239740b3867SJames Ide          await FS.makeDirectoryAsync(dir);
240740b3867SJames Ide        } catch (e) {
241740b3867SJames Ide          error = e;
242740b3867SJames Ide        }
243740b3867SJames Ide        t.expect(error).toBeTruthy();
244740b3867SJames Ide
2456cfa9c5fSSergei Chestakov        error = null;
2466cfa9c5fSSergei Chestakov        try {
2476cfa9c5fSSergei Chestakov          await FS.makeDirectoryAsync(dir, {
2486cfa9c5fSSergei Chestakov            intermediates: true,
2496cfa9c5fSSergei Chestakov          });
2506cfa9c5fSSergei Chestakov        } catch (e) {
2516cfa9c5fSSergei Chestakov          error = e;
2526cfa9c5fSSergei Chestakov        }
2536cfa9c5fSSergei Chestakov        t.expect(error).toBe(null);
2546cfa9c5fSSergei Chestakov
255740b3867SJames Ide        await FS.writeAsStringAsync(path, contents);
256740b3867SJames Ide
257740b3867SJames Ide        t.expect(await FS.readAsStringAsync(path)).toBe(contents);
258740b3867SJames Ide      }
259740b3867SJames Ide    );
260740b3867SJames Ide
261fec220cbSSergei Chestakov    /*
262fec220cbSSergei Chestakov    This test fails in CI because of an exception being thrown by deleteAsync in the nativeModule.
263fec220cbSSergei Chestakov    I traced it down to the FileUtils.forceDelete call here:
264fec220cbSSergei Chestakov    https://github.com/expo/expo/blob/bcd136b096df84e0b0f72a15acbda45491de8201/packages/expo-file-system/android/src/main/java/expo/modules/filesystem/FileSystemModule.java#L294
265740b3867SJames Ide    t.it(
266740b3867SJames Ide      'delete(dir, idempotent) -> make tree -> check contents ' +
267740b3867SJames Ide        '-> check directory listings' +
268740b3867SJames Ide        '-> move -> check directory listings' +
269740b3867SJames Ide        '-> copy -> check directory listings',
270740b3867SJames Ide      async () => {
271740b3867SJames Ide        let error;
272740b3867SJames Ide        const dir = FS.documentDirectory + 'dir';
273740b3867SJames Ide
274740b3867SJames Ide        await FS.deleteAsync(dir, { idempotent: true });
275740b3867SJames Ide
276740b3867SJames Ide        await FS.makeDirectoryAsync(dir + '/child1', {
277740b3867SJames Ide          intermediates: true,
278740b3867SJames Ide        });
279740b3867SJames Ide        await FS.makeDirectoryAsync(dir + '/child2', {
280740b3867SJames Ide          intermediates: true,
281740b3867SJames Ide        });
282740b3867SJames Ide
283740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/file1', 'contents1');
284740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/file2', 'contents2');
285740b3867SJames Ide
286740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/child1/file3', 'contents3');
287740b3867SJames Ide
288740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/child2/file4', 'contents4');
289740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/child2/file5', 'contents5');
290740b3867SJames Ide
291740b3867SJames Ide        const checkContents = async (path, contents) =>
292740b3867SJames Ide          t.expect(await FS.readAsStringAsync(path)).toBe(contents);
293740b3867SJames Ide
294740b3867SJames Ide        await checkContents(dir + '/file1', 'contents1');
295740b3867SJames Ide        await checkContents(dir + '/file2', 'contents2');
296740b3867SJames Ide        await checkContents(dir + '/child1/file3', 'contents3');
297740b3867SJames Ide        await checkContents(dir + '/child2/file4', 'contents4');
298740b3867SJames Ide        await checkContents(dir + '/child2/file5', 'contents5');
299740b3867SJames Ide
300740b3867SJames Ide        const checkDirectory = async (path, expected) => {
301740b3867SJames Ide          const list = await FS.readDirectoryAsync(path);
302740b3867SJames Ide          t.expect(list.sort()).toEqual(expected.sort());
303740b3867SJames Ide        };
304740b3867SJames Ide
305740b3867SJames Ide        const checkRoot = async root => {
306740b3867SJames Ide          await checkDirectory(root, ['file1', 'file2', 'child1', 'child2']);
307740b3867SJames Ide          await checkDirectory(root + '/child1', ['file3']);
308740b3867SJames Ide          await checkDirectory(root + '/child2', ['file4', 'file5']);
309740b3867SJames Ide
310740b3867SJames Ide          error = null;
311740b3867SJames Ide          try {
312740b3867SJames Ide            await checkDirectory(root + '/file1', ['nope']);
313740b3867SJames Ide          } catch (e) {
314740b3867SJames Ide            error = e;
315740b3867SJames Ide          }
316740b3867SJames Ide          t.expect(error).toBeTruthy();
317740b3867SJames Ide        };
318740b3867SJames Ide
319740b3867SJames Ide        await checkRoot(dir);
320740b3867SJames Ide
321740b3867SJames Ide        await FS.deleteAsync(FS.documentDirectory + 'moved', {
322740b3867SJames Ide          idempotent: true,
323740b3867SJames Ide        });
324740b3867SJames Ide        await FS.moveAsync({ from: dir, to: FS.documentDirectory + 'moved' });
325740b3867SJames Ide        await checkRoot(FS.documentDirectory + 'moved');
326740b3867SJames Ide        await FS.copyAsync({
327740b3867SJames Ide          from: FS.documentDirectory + 'moved',
328740b3867SJames Ide          to: FS.documentDirectory + 'copied',
329740b3867SJames Ide        });
330740b3867SJames Ide        await checkRoot(FS.documentDirectory + 'copied');
331740b3867SJames Ide      }
332740b3867SJames Ide    );
333fec220cbSSergei Chestakov    */
334740b3867SJames Ide
335740b3867SJames Ide    t.it(
336740b3867SJames Ide      'delete(idempotent) -> download(md5) -> getInfo(size)',
337740b3867SJames Ide      async () => {
338740b3867SJames Ide        const localUri = FS.documentDirectory + 'download1.png';
339740b3867SJames Ide
340740b3867SJames Ide        await FS.deleteAsync(localUri, { idempotent: true });
341740b3867SJames Ide
34267f55e2bSStanisław Chmiela        const { md5 } = await FS.downloadAsync(
343740b3867SJames Ide          'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png',
344740b3867SJames Ide          localUri,
345740b3867SJames Ide          { md5: true }
346740b3867SJames Ide        );
347740b3867SJames Ide        t.expect(md5).toBe('1e02045c10b8f1145edc7c8375998f87');
348740b3867SJames Ide
349740b3867SJames Ide        const { size, modificationTime } = await FS.getInfoAsync(localUri);
350740b3867SJames Ide        t.expect(size).toBe(3230);
351740b3867SJames Ide        const nowTime = 0.001 * new Date().getTime();
352740b3867SJames Ide        t.expect(nowTime - modificationTime).toBeLessThan(3600);
353740b3867SJames Ide
354740b3867SJames Ide        await FS.deleteAsync(localUri);
355740b3867SJames Ide      },
35667f55e2bSStanisław Chmiela      30000
357740b3867SJames Ide    );
358740b3867SJames Ide
359740b3867SJames Ide    t.it('throws out-of-scope exceptions', async () => {
360740b3867SJames Ide      const p = FS.documentDirectory;
361740b3867SJames Ide
362740b3867SJames Ide      await throws(() => FS.getInfoAsync(p + '../hello/world'));
363740b3867SJames Ide      await throws(() => FS.readAsStringAsync(p + '../hello/world'));
364740b3867SJames Ide      await throws(() => FS.writeAsStringAsync(p + '../hello/world', ''));
365740b3867SJames Ide      await throws(() => FS.deleteAsync(p + '../hello/world'));
366740b3867SJames Ide      await throws(() => FS.deleteAsync(p));
367740b3867SJames Ide      await throws(() => FS.deleteAsync(FS.cacheDirectory));
368740b3867SJames Ide      await throws(() => FS.moveAsync({ from: p + '../a/b', to: 'c' }));
369740b3867SJames Ide      await throws(() => FS.moveAsync({ from: 'c', to: p + '../a/b' }));
370740b3867SJames Ide      await throws(() => FS.copyAsync({ from: p + '../a/b', to: 'c' }));
371740b3867SJames Ide      await throws(() => FS.copyAsync({ from: 'c', to: p + '../a/b' }));
372740b3867SJames Ide      await throws(() => FS.makeDirectoryAsync(p + '../hello/world'));
373740b3867SJames Ide      await throws(() => FS.readDirectoryAsync(p + '../hello/world'));
374740b3867SJames Ide      await throws(() => FS.downloadAsync('http://www.google.com', p + '../hello/world'));
375740b3867SJames Ide      await throws(() => FS.readDirectoryAsync(p + '../'));
376740b3867SJames Ide      await throws(() => FS.downloadAsync('http://www.google.com', p + '../hello/world'));
377740b3867SJames Ide    });
378740b3867SJames Ide
379740b3867SJames Ide    t.it('missing parameters', async () => {
380740b3867SJames Ide      const p = FS.documentDirectory + 'test';
381740b3867SJames Ide
382740b3867SJames Ide      await throws(() => FS.moveAsync({ from: p }));
383740b3867SJames Ide      await throws(() => FS.moveAsync({ to: p }));
384740b3867SJames Ide      await throws(() => FS.copyAsync({ from: p }));
385740b3867SJames Ide      await throws(() => FS.copyAsync({ to: p }));
386740b3867SJames Ide    });
387740b3867SJames Ide
388740b3867SJames Ide    t.it('can read root directories', async () => {
389740b3867SJames Ide      await FS.readDirectoryAsync(FS.documentDirectory);
390740b3867SJames Ide      await FS.readDirectoryAsync(FS.cacheDirectory);
391740b3867SJames Ide    });
392740b3867SJames Ide
393740b3867SJames Ide    t.it(
394740b3867SJames Ide      'download(network failure)',
395740b3867SJames Ide      async () => {
396740b3867SJames Ide        const localUri = FS.documentDirectory + 'download1.png';
397740b3867SJames Ide
398740b3867SJames Ide        const assertExists = async expectedToExist => {
399740b3867SJames Ide          let { exists } = await FS.getInfoAsync(localUri);
400740b3867SJames Ide          if (expectedToExist) {
401740b3867SJames Ide            t.expect(exists).toBeTruthy();
402740b3867SJames Ide          } else {
403740b3867SJames Ide            t.expect(exists).not.toBeTruthy();
404740b3867SJames Ide          }
405740b3867SJames Ide        };
406740b3867SJames Ide
407740b3867SJames Ide        await FS.deleteAsync(localUri, { idempotent: true });
408740b3867SJames Ide        await assertExists(false);
409740b3867SJames Ide
410740b3867SJames Ide        let error;
411740b3867SJames Ide        try {
412fec220cbSSergei Chestakov          await FS.downloadAsync('https://nonexistent-subdomain.expo.io', localUri, { md5: true });
413740b3867SJames Ide        } catch (e) {
414740b3867SJames Ide          error = e;
415740b3867SJames Ide        }
416740b3867SJames Ide        t.expect(error).toBeTruthy();
417740b3867SJames Ide        await assertExists(false);
418740b3867SJames Ide        await FS.deleteAsync(localUri, { idempotent: true });
419740b3867SJames Ide      },
42067f55e2bSStanisław Chmiela      30000
421740b3867SJames Ide    );
422740b3867SJames Ide
423740b3867SJames Ide    t.it(
424740b3867SJames Ide      'download(404)',
425740b3867SJames Ide      async () => {
426740b3867SJames Ide        const localUri = FS.documentDirectory + 'download1.png';
427740b3867SJames Ide
428740b3867SJames Ide        const assertExists = async expectedToExist => {
429740b3867SJames Ide          let { exists } = await FS.getInfoAsync(localUri);
430740b3867SJames Ide          if (expectedToExist) {
431740b3867SJames Ide            t.expect(exists).toBeTruthy();
432740b3867SJames Ide          } else {
433740b3867SJames Ide            t.expect(exists).not.toBeTruthy();
434740b3867SJames Ide          }
435740b3867SJames Ide        };
436740b3867SJames Ide
437740b3867SJames Ide        await FS.deleteAsync(localUri, { idempotent: true });
438740b3867SJames Ide        await assertExists(false);
439740b3867SJames Ide
440fec220cbSSergei Chestakov        const { status } = await FS.downloadAsync('https://expo.io/404', localUri, {
441740b3867SJames Ide          md5: true,
442740b3867SJames Ide        });
443740b3867SJames Ide        await assertExists(true);
444740b3867SJames Ide        t.expect(status).toBe(404);
445740b3867SJames Ide
446740b3867SJames Ide        await FS.deleteAsync(localUri);
447740b3867SJames Ide        await assertExists(false);
448740b3867SJames Ide      },
44967f55e2bSStanisław Chmiela      30000
450740b3867SJames Ide    );
451d7aba270SDominik Sokal
452d7aba270SDominik Sokal    t.it(
453d7aba270SDominik Sokal      'download(nonexistent local path)',
454d7aba270SDominik Sokal      async () => {
455d7aba270SDominik Sokal        try {
456d7aba270SDominik Sokal          const remoteUrl = 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png';
457d7aba270SDominik Sokal          const localUri = FS.documentDirectory + 'doesnt/exists/download1.png';
458d7aba270SDominik Sokal          await FS.downloadAsync(remoteUrl, localUri);
459d7aba270SDominik Sokal        } catch (err) {
460d7aba270SDominik Sokal          t.expect(err.message).toMatch(/Directory for .* doesn't exist/);
461d7aba270SDominik Sokal        }
462d7aba270SDominik Sokal      },
463d7aba270SDominik Sokal      30000
464d7aba270SDominik Sokal    );
465d7aba270SDominik Sokal
466d7aba270SDominik Sokal    t.it(
467d7aba270SDominik Sokal      'mkdir(multi-level) + download(multi-level local path)',
468d7aba270SDominik Sokal      async () => {
469d7aba270SDominik Sokal        const remoteUrl = 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png';
470d7aba270SDominik Sokal        const localDirUri = FS.documentDirectory + 'foo/bar/baz';
471d7aba270SDominik Sokal        const localFileUri = localDirUri + 'download1.png';
472d7aba270SDominik Sokal
473d7aba270SDominik Sokal        await FS.makeDirectoryAsync(localDirUri, { intermediates: true });
474d7aba270SDominik Sokal
475d7aba270SDominik Sokal        await FS.downloadAsync(remoteUrl, localFileUri);
476d7aba270SDominik Sokal      },
477d7aba270SDominik Sokal      30000
478d7aba270SDominik Sokal    );
479740b3867SJames Ide  });
480740b3867SJames Ide}
481