xref: /expo/apps/test-suite/tests/FileSystem.js (revision 51e273e0)
1740b3867SJames Ide'use strict';
2740b3867SJames Ide
3a47a1472SVille Immonenimport { Asset } from 'expo-asset';
48cb96155SEvan Baconimport Constants from 'expo-constants';
519cbf4dcSBartłomiej Bukowskiimport * as FS from 'expo-file-system';
619cbf4dcSBartłomiej Bukowskiimport { Platform } from 'expo-modules-core';
767f55e2bSStanisław Chmiela
867f55e2bSStanisław Chmielaexport const name = 'FileSystem';
9740b3867SJames Ide
108cb96155SEvan Baconexport async function test({ describe, expect, it, ...t }) {
118cb96155SEvan Bacon  describe('FileSystem', () => {
1222d1e005SBartosz Kaszubowski    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      }
198cb96155SEvan Bacon      expect(error).toBeTruthy();
20740b3867SJames Ide    };
21740b3867SJames Ide
228cb96155SEvan Bacon    if (Constants.appOwnership === 'expo') {
238cb96155SEvan Bacon      describe('managed workflow', () => {
248cb96155SEvan Bacon        it('throws out-of-scope exceptions', async () => {
258cb96155SEvan Bacon          const p = FS.documentDirectory;
268cb96155SEvan Bacon
278cb96155SEvan Bacon          await throws(() => FS.readAsStringAsync(p + '../hello/world'));
288cb96155SEvan Bacon          await throws(() => FS.writeAsStringAsync(p + '../hello/world', ''));
298cb96155SEvan Bacon          await throws(() => FS.deleteAsync(p + '../hello/world'));
308cb96155SEvan Bacon          await throws(() => FS.deleteAsync(p));
318cb96155SEvan Bacon          await throws(() => FS.deleteAsync(FS.cacheDirectory));
328cb96155SEvan Bacon          await throws(() => FS.moveAsync({ from: p + '../a/b', to: 'c' }));
338cb96155SEvan Bacon          await throws(() => FS.moveAsync({ from: 'c', to: p + '../a/b' }));
348cb96155SEvan Bacon          await throws(() => FS.copyAsync({ from: p + '../a/b', to: 'c' }));
358cb96155SEvan Bacon          await throws(() => FS.copyAsync({ from: 'c', to: p + '../a/b' }));
368cb96155SEvan Bacon          await throws(() => FS.makeDirectoryAsync(p + '../hello/world'));
378cb96155SEvan Bacon          await throws(() => FS.readDirectoryAsync(p + '../hello/world'));
388cb96155SEvan Bacon          await throws(() => FS.downloadAsync('http://www.google.com', p + '../hello/world'));
398cb96155SEvan Bacon          await throws(() => FS.readDirectoryAsync(p + '../'));
408cb96155SEvan Bacon          await throws(() => FS.downloadAsync('http://www.google.com', p + '../hello/world'));
418cb96155SEvan Bacon        });
428cb96155SEvan Bacon      });
438cb96155SEvan Bacon    }
448cb96155SEvan Bacon
458cb96155SEvan Bacon    if (Platform.OS === 'web') {
468cb96155SEvan Bacon      // Web doesn't support FileSystem
478cb96155SEvan Bacon      return;
488cb96155SEvan Bacon    }
498cb96155SEvan Bacon
5022d1e005SBartosz Kaszubowski    it('delete(idempotent) -> !exists -> download(md5, uri) -> exists -> delete -> !exists', async () => {
51740b3867SJames Ide      const localUri = FS.documentDirectory + 'download1.png';
52740b3867SJames Ide
5322d1e005SBartosz Kaszubowski      const assertExists = async (expectedToExist) => {
5419cbf4dcSBartłomiej Bukowski        const { exists } = await FS.getInfoAsync(localUri);
55740b3867SJames Ide        if (expectedToExist) {
568cb96155SEvan Bacon          expect(exists).toBeTruthy();
57740b3867SJames Ide        } else {
588cb96155SEvan Bacon          expect(exists).not.toBeTruthy();
59740b3867SJames Ide        }
60740b3867SJames Ide      };
61740b3867SJames Ide
62740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
63740b3867SJames Ide      await assertExists(false);
64740b3867SJames Ide
6522d1e005SBartosz Kaszubowski      const { md5, headers } = await FS.downloadAsync(
66740b3867SJames Ide        'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png',
67740b3867SJames Ide        localUri,
68740b3867SJames Ide        { md5: true }
69740b3867SJames Ide      );
708cb96155SEvan Bacon      expect(md5).toBe('1e02045c10b8f1145edc7c8375998f87');
71740b3867SJames Ide      await assertExists(true);
728cb96155SEvan Bacon      expect(headers['Content-Type']).toBe('image/png');
73740b3867SJames Ide
74740b3867SJames Ide      await FS.deleteAsync(localUri);
75740b3867SJames Ide      await assertExists(false);
7622d1e005SBartosz Kaszubowski    }, 9000);
77740b3867SJames Ide
788cb96155SEvan Bacon    it('Can read/write Base64', async () => {
792bd74c95SEvan Bacon      const asset = await Asset.fromModule(require('../assets/icons/app.png'));
802bd74c95SEvan Bacon      await asset.downloadAsync();
812bd74c95SEvan Bacon
8267f55e2bSStanisław Chmiela      for (let startingPosition = 0; startingPosition < 3; startingPosition++) {
832bd74c95SEvan Bacon        const options = {
84fec220cbSSergei Chestakov          encoding: FS.EncodingType.Base64,
8567f55e2bSStanisław Chmiela          position: startingPosition,
8667f55e2bSStanisław Chmiela          length: startingPosition + 1,
872bd74c95SEvan Bacon        };
882bd74c95SEvan Bacon
892bd74c95SEvan Bacon        const b64 = await FS.readAsStringAsync(asset.localUri, options);
908cb96155SEvan Bacon        expect(b64).toBeDefined();
918cb96155SEvan Bacon        expect(typeof b64).toBe('string');
928cb96155SEvan Bacon        expect(b64.length % 4).toBe(0);
932bd74c95SEvan Bacon
942bd74c95SEvan Bacon        const localUri = FS.documentDirectory + 'b64.png';
952bd74c95SEvan Bacon
96fec220cbSSergei Chestakov        await FS.writeAsStringAsync(localUri, b64, { encoding: FS.EncodingType.Base64 });
972bd74c95SEvan Bacon
988cb96155SEvan Bacon        expect(await FS.readAsStringAsync(localUri, { encoding: FS.EncodingType.Base64 })).toBe(
9967f55e2bSStanisław Chmiela          b64
10067f55e2bSStanisław Chmiela        );
1012bd74c95SEvan Bacon      }
1022bd74c95SEvan Bacon    });
1032bd74c95SEvan Bacon
1048cb96155SEvan Bacon    it('delete(idempotent) -> delete[error]', async () => {
105740b3867SJames Ide      const localUri = FS.documentDirectory + 'willDelete.png';
106740b3867SJames Ide
107740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
108740b3867SJames Ide
109740b3867SJames Ide      let error;
110740b3867SJames Ide      try {
111740b3867SJames Ide        await FS.deleteAsync(localUri);
112740b3867SJames Ide      } catch (e) {
113740b3867SJames Ide        error = e;
114740b3867SJames Ide      }
115*51e273e0STomasz Sapeta      expect(error.message).toMatch(/not exist/);
116740b3867SJames Ide    });
117740b3867SJames Ide
1188cb96155SEvan Bacon    it('download(md5, uri) -> read -> delete -> !exists -> read[error]', async () => {
119740b3867SJames Ide      const localUri = FS.documentDirectory + 'download1.txt';
120740b3867SJames Ide
12122d1e005SBartosz Kaszubowski      const { md5 } = await FS.downloadAsync(
122740b3867SJames Ide        'https://s3-us-west-1.amazonaws.com/test-suite-data/text-file.txt',
123740b3867SJames Ide        localUri,
124740b3867SJames Ide        { md5: true }
125740b3867SJames Ide      );
1268cb96155SEvan Bacon      expect(md5).toBe('86d73d2f11e507365f7ea8e7ec3cc4cb');
127740b3867SJames Ide
128740b3867SJames Ide      const string = await FS.readAsStringAsync(localUri);
1298cb96155SEvan Bacon      expect(string).toBe('hello, world\nthis is a test file\n');
130740b3867SJames Ide
131740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
132740b3867SJames Ide
133740b3867SJames Ide      let error;
134740b3867SJames Ide      try {
135740b3867SJames Ide        await FS.readAsStringAsync(localUri);
136740b3867SJames Ide      } catch (e) {
137740b3867SJames Ide        error = e;
138740b3867SJames Ide      }
1398cb96155SEvan Bacon      expect(error).toBeTruthy();
1408cb96155SEvan Bacon    }, 9000);
141740b3867SJames Ide
1428cb96155SEvan Bacon    it('delete(idempotent) -> !exists -> write -> read -> write -> read', async () => {
143740b3867SJames Ide      const localUri = FS.documentDirectory + 'write1.txt';
144740b3867SJames Ide
145740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
146740b3867SJames Ide
147740b3867SJames Ide      const { exists } = await FS.getInfoAsync(localUri);
1488cb96155SEvan Bacon      expect(exists).not.toBeTruthy();
149740b3867SJames Ide
15022d1e005SBartosz Kaszubowski      const writeAndVerify = async (expected) => {
151740b3867SJames Ide        await FS.writeAsStringAsync(localUri, expected);
152740b3867SJames Ide        const string = await FS.readAsStringAsync(localUri);
1538cb96155SEvan Bacon        expect(string).toBe(expected);
154740b3867SJames Ide      };
155740b3867SJames Ide
156740b3867SJames Ide      await writeAndVerify('hello, world');
157740b3867SJames Ide      await writeAndVerify('hello, world!!!!!!');
158740b3867SJames Ide    });
159740b3867SJames Ide
1608cb96155SEvan Bacon    it('delete(new) -> 2 * [write -> move -> !exists(orig) -> read(new)]', async () => {
161740b3867SJames Ide      const from = FS.documentDirectory + 'from.txt';
162740b3867SJames Ide      const to = FS.documentDirectory + 'to.txt';
163740b3867SJames Ide      const contents = ['contents 1', 'contents 2'];
164740b3867SJames Ide
165740b3867SJames Ide      await FS.deleteAsync(to, { idempotent: true });
166740b3867SJames Ide
167740b3867SJames Ide      // Move twice to make sure we can overwrite
168740b3867SJames Ide      for (let i = 0; i < 2; ++i) {
169740b3867SJames Ide        await FS.writeAsStringAsync(from, contents[i]);
170740b3867SJames Ide
171740b3867SJames Ide        await FS.moveAsync({ from, to });
172740b3867SJames Ide
173740b3867SJames Ide        const { exists } = await FS.getInfoAsync(from);
1748cb96155SEvan Bacon        expect(exists).not.toBeTruthy();
175740b3867SJames Ide
1768cb96155SEvan Bacon        expect(await FS.readAsStringAsync(to)).toBe(contents[i]);
177740b3867SJames Ide      }
178740b3867SJames Ide    });
179740b3867SJames Ide
1808cb96155SEvan Bacon    it('delete(new) -> 2 * [write -> copy -> exists(orig) -> read(new)]', async () => {
181740b3867SJames Ide      const from = FS.documentDirectory + 'from.txt';
182740b3867SJames Ide      const to = FS.documentDirectory + 'to.txt';
183740b3867SJames Ide      const contents = ['contents 1', 'contents 2'];
184740b3867SJames Ide
185740b3867SJames Ide      await FS.deleteAsync(to, { idempotent: true });
186740b3867SJames Ide
187740b3867SJames Ide      // Copy twice to make sure we can overwrite
188740b3867SJames Ide      for (let i = 0; i < 2; ++i) {
189740b3867SJames Ide        await FS.writeAsStringAsync(from, contents[i]);
190740b3867SJames Ide
191740b3867SJames Ide        await FS.copyAsync({ from, to });
192740b3867SJames Ide
193740b3867SJames Ide        const { exists } = await FS.getInfoAsync(from);
1948cb96155SEvan Bacon        expect(exists).toBeTruthy();
195740b3867SJames Ide
1968cb96155SEvan Bacon        expect(await FS.readAsStringAsync(to)).toBe(contents[i]);
197740b3867SJames Ide      }
198740b3867SJames Ide    });
199740b3867SJames Ide
2008cb96155SEvan Bacon    it(
201740b3867SJames Ide      'delete(dir) -> write(dir/file)[error] -> mkdir(dir) ->' +
202740b3867SJames Ide        'mkdir(dir)[error] -> write(dir/file) -> read',
203740b3867SJames Ide      async () => {
204740b3867SJames Ide        let error;
205740b3867SJames Ide        const path = FS.documentDirectory + 'dir/file';
206740b3867SJames Ide        const dir = FS.documentDirectory + 'dir';
207740b3867SJames Ide        const contents = 'hello, world';
208740b3867SJames Ide
209740b3867SJames Ide        await FS.deleteAsync(dir, { idempotent: true });
210740b3867SJames Ide
211740b3867SJames Ide        error = null;
212740b3867SJames Ide        try {
213740b3867SJames Ide          await FS.writeAsStringAsync(path, contents);
214740b3867SJames Ide        } catch (e) {
215740b3867SJames Ide          error = e;
216740b3867SJames Ide        }
2178cb96155SEvan Bacon        expect(error).toBeTruthy();
218740b3867SJames Ide
219740b3867SJames Ide        await FS.makeDirectoryAsync(dir);
220740b3867SJames Ide
221740b3867SJames Ide        error = null;
222740b3867SJames Ide        try {
223740b3867SJames Ide          await FS.makeDirectoryAsync(dir);
224740b3867SJames Ide        } catch (e) {
225740b3867SJames Ide          error = e;
226740b3867SJames Ide        }
2278cb96155SEvan Bacon        expect(error).toBeTruthy();
228740b3867SJames Ide
229740b3867SJames Ide        await FS.writeAsStringAsync(path, contents);
230740b3867SJames Ide
2318cb96155SEvan Bacon        expect(await FS.readAsStringAsync(path)).toBe(contents);
232740b3867SJames Ide      }
233740b3867SJames Ide    );
234740b3867SJames Ide
2358cb96155SEvan Bacon    it(
236740b3867SJames Ide      'delete(dir) -> write(dir/dir2/file)[error] -> ' +
237740b3867SJames Ide        'mkdir(dir/dir2, intermediates) -> ' +
238740b3867SJames Ide        'mkdir(dir/dir2, intermediates) -> write(dir/dir2/file) -> read',
239740b3867SJames Ide      async () => {
240740b3867SJames Ide        let error;
241740b3867SJames Ide        const path = FS.documentDirectory + 'dir/dir2/file';
242740b3867SJames Ide        const dir = FS.documentDirectory + 'dir/dir2';
243740b3867SJames Ide        const contents = 'hello, world';
244740b3867SJames Ide
245740b3867SJames Ide        await FS.deleteAsync(dir, { idempotent: true });
246740b3867SJames Ide
247740b3867SJames Ide        error = null;
248740b3867SJames Ide        try {
249740b3867SJames Ide          await FS.writeAsStringAsync(path, contents);
250740b3867SJames Ide        } catch (e) {
251740b3867SJames Ide          error = e;
252740b3867SJames Ide        }
2538cb96155SEvan Bacon        expect(error).toBeTruthy();
254740b3867SJames Ide
255740b3867SJames Ide        await FS.makeDirectoryAsync(dir, {
256740b3867SJames Ide          intermediates: true,
257740b3867SJames Ide        });
258740b3867SJames Ide
259740b3867SJames Ide        error = null;
260740b3867SJames Ide        try {
261740b3867SJames Ide          await FS.makeDirectoryAsync(dir);
262740b3867SJames Ide        } catch (e) {
263740b3867SJames Ide          error = e;
264740b3867SJames Ide        }
2658cb96155SEvan Bacon        expect(error).toBeTruthy();
266740b3867SJames Ide
2676cfa9c5fSSergei Chestakov        error = null;
2686cfa9c5fSSergei Chestakov        try {
2696cfa9c5fSSergei Chestakov          await FS.makeDirectoryAsync(dir, {
2706cfa9c5fSSergei Chestakov            intermediates: true,
2716cfa9c5fSSergei Chestakov          });
2726cfa9c5fSSergei Chestakov        } catch (e) {
2736cfa9c5fSSergei Chestakov          error = e;
2746cfa9c5fSSergei Chestakov        }
2758cb96155SEvan Bacon        expect(error).toBe(null);
2766cfa9c5fSSergei Chestakov
277740b3867SJames Ide        await FS.writeAsStringAsync(path, contents);
278740b3867SJames Ide
2798cb96155SEvan Bacon        expect(await FS.readAsStringAsync(path)).toBe(contents);
280740b3867SJames Ide      }
281740b3867SJames Ide    );
282740b3867SJames Ide
283d12a8680SŁukasz Kosmaty    it('getInfo(dirPath)', async () => {
284d12a8680SŁukasz Kosmaty      const dir = FS.documentDirectory + 'dir';
285d12a8680SŁukasz Kosmaty      const path = FS.documentDirectory + 'dir/file.txt';
286d12a8680SŁukasz Kosmaty
287d12a8680SŁukasz Kosmaty      await FS.deleteAsync(dir, { idempotent: true });
288d12a8680SŁukasz Kosmaty      await FS.makeDirectoryAsync(dir, {
289d12a8680SŁukasz Kosmaty        intermediates: true,
290d12a8680SŁukasz Kosmaty      });
291d12a8680SŁukasz Kosmaty      await FS.writeAsStringAsync(path, 'Expo is awesome ������');
292d12a8680SŁukasz Kosmaty      const info = await FS.getInfoAsync(dir);
293d12a8680SŁukasz Kosmaty
294d12a8680SŁukasz Kosmaty      expect(info).toBeDefined();
295d12a8680SŁukasz Kosmaty      expect(info.exists).toBe(true);
296d12a8680SŁukasz Kosmaty      expect(info.isDirectory).toBe(true);
297d12a8680SŁukasz Kosmaty      expect(info.size).toBe(28);
298d12a8680SŁukasz Kosmaty    });
299d12a8680SŁukasz Kosmaty
300fec220cbSSergei Chestakov    /*
301fec220cbSSergei Chestakov    This test fails in CI because of an exception being thrown by deleteAsync in the nativeModule.
302fec220cbSSergei Chestakov    I traced it down to the FileUtils.forceDelete call here:
303fec220cbSSergei Chestakov    https://github.com/expo/expo/blob/bcd136b096df84e0b0f72a15acbda45491de8201/packages/expo-file-system/android/src/main/java/expo/modules/filesystem/FileSystemModule.java#L294
3048cb96155SEvan Bacon    it(
305740b3867SJames Ide      'delete(dir, idempotent) -> make tree -> check contents ' +
306740b3867SJames Ide        '-> check directory listings' +
307740b3867SJames Ide        '-> move -> check directory listings' +
308740b3867SJames Ide        '-> copy -> check directory listings',
309740b3867SJames Ide      async () => {
310740b3867SJames Ide        let error;
311740b3867SJames Ide        const dir = FS.documentDirectory + 'dir';
312740b3867SJames Ide
313740b3867SJames Ide        await FS.deleteAsync(dir, { idempotent: true });
314740b3867SJames Ide
315740b3867SJames Ide        await FS.makeDirectoryAsync(dir + '/child1', {
316740b3867SJames Ide          intermediates: true,
317740b3867SJames Ide        });
318740b3867SJames Ide        await FS.makeDirectoryAsync(dir + '/child2', {
319740b3867SJames Ide          intermediates: true,
320740b3867SJames Ide        });
321740b3867SJames Ide
322740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/file1', 'contents1');
323740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/file2', 'contents2');
324740b3867SJames Ide
325740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/child1/file3', 'contents3');
326740b3867SJames Ide
327740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/child2/file4', 'contents4');
328740b3867SJames Ide        await FS.writeAsStringAsync(dir + '/child2/file5', 'contents5');
329740b3867SJames Ide
330740b3867SJames Ide        const checkContents = async (path, contents) =>
3318cb96155SEvan Bacon          expect(await FS.readAsStringAsync(path)).toBe(contents);
332740b3867SJames Ide
333740b3867SJames Ide        await checkContents(dir + '/file1', 'contents1');
334740b3867SJames Ide        await checkContents(dir + '/file2', 'contents2');
335740b3867SJames Ide        await checkContents(dir + '/child1/file3', 'contents3');
336740b3867SJames Ide        await checkContents(dir + '/child2/file4', 'contents4');
337740b3867SJames Ide        await checkContents(dir + '/child2/file5', 'contents5');
338740b3867SJames Ide
339740b3867SJames Ide        const checkDirectory = async (path, expected) => {
340740b3867SJames Ide          const list = await FS.readDirectoryAsync(path);
3418cb96155SEvan Bacon          expect(list.sort()).toEqual(expected.sort());
342740b3867SJames Ide        };
343740b3867SJames Ide
344740b3867SJames Ide        const checkRoot = async root => {
345740b3867SJames Ide          await checkDirectory(root, ['file1', 'file2', 'child1', 'child2']);
346740b3867SJames Ide          await checkDirectory(root + '/child1', ['file3']);
347740b3867SJames Ide          await checkDirectory(root + '/child2', ['file4', 'file5']);
348740b3867SJames Ide
349740b3867SJames Ide          error = null;
350740b3867SJames Ide          try {
351740b3867SJames Ide            await checkDirectory(root + '/file1', ['nope']);
352740b3867SJames Ide          } catch (e) {
353740b3867SJames Ide            error = e;
354740b3867SJames Ide          }
3558cb96155SEvan Bacon          expect(error).toBeTruthy();
356740b3867SJames Ide        };
357740b3867SJames Ide
358740b3867SJames Ide        await checkRoot(dir);
359740b3867SJames Ide
360740b3867SJames Ide        await FS.deleteAsync(FS.documentDirectory + 'moved', {
361740b3867SJames Ide          idempotent: true,
362740b3867SJames Ide        });
363740b3867SJames Ide        await FS.moveAsync({ from: dir, to: FS.documentDirectory + 'moved' });
364740b3867SJames Ide        await checkRoot(FS.documentDirectory + 'moved');
365740b3867SJames Ide        await FS.copyAsync({
366740b3867SJames Ide          from: FS.documentDirectory + 'moved',
367740b3867SJames Ide          to: FS.documentDirectory + 'copied',
368740b3867SJames Ide        });
369740b3867SJames Ide        await checkRoot(FS.documentDirectory + 'copied');
370740b3867SJames Ide      }
371740b3867SJames Ide    );
372fec220cbSSergei Chestakov    */
373740b3867SJames Ide
3748cb96155SEvan Bacon    it('delete(idempotent) -> download(md5) -> getInfo(size)', async () => {
375740b3867SJames Ide      const localUri = FS.documentDirectory + 'download1.png';
376740b3867SJames Ide
377740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
378740b3867SJames Ide
37922d1e005SBartosz Kaszubowski      const { md5 } = await FS.downloadAsync(
380740b3867SJames Ide        'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png',
381740b3867SJames Ide        localUri,
382740b3867SJames Ide        { md5: true }
383740b3867SJames Ide      );
3848cb96155SEvan Bacon      expect(md5).toBe('1e02045c10b8f1145edc7c8375998f87');
385740b3867SJames Ide
386740b3867SJames Ide      const { size, modificationTime } = await FS.getInfoAsync(localUri);
3878cb96155SEvan Bacon      expect(size).toBe(3230);
388740b3867SJames Ide      const nowTime = 0.001 * new Date().getTime();
3898cb96155SEvan Bacon      expect(nowTime - modificationTime).toBeLessThan(3600);
390740b3867SJames Ide
391740b3867SJames Ide      await FS.deleteAsync(localUri);
3928cb96155SEvan Bacon    }, 30000);
393740b3867SJames Ide
3948cb96155SEvan Bacon    it('missing parameters', async () => {
395740b3867SJames Ide      const p = FS.documentDirectory + 'test';
396740b3867SJames Ide
397740b3867SJames Ide      await throws(() => FS.moveAsync({ from: p }));
398740b3867SJames Ide      await throws(() => FS.moveAsync({ to: p }));
399740b3867SJames Ide      await throws(() => FS.copyAsync({ from: p }));
400740b3867SJames Ide      await throws(() => FS.copyAsync({ to: p }));
401740b3867SJames Ide    });
402740b3867SJames Ide
4038cb96155SEvan Bacon    it('can read root directories', async () => {
404740b3867SJames Ide      await FS.readDirectoryAsync(FS.documentDirectory);
405740b3867SJames Ide      await FS.readDirectoryAsync(FS.cacheDirectory);
406740b3867SJames Ide    });
407740b3867SJames Ide
4088cb96155SEvan Bacon    it('download(network failure)', async () => {
409740b3867SJames Ide      const localUri = FS.documentDirectory + 'download1.png';
410740b3867SJames Ide
41122d1e005SBartosz Kaszubowski      const assertExists = async (expectedToExist) => {
41219cbf4dcSBartłomiej Bukowski        const { exists } = await FS.getInfoAsync(localUri);
413740b3867SJames Ide        if (expectedToExist) {
4148cb96155SEvan Bacon          expect(exists).toBeTruthy();
415740b3867SJames Ide        } else {
4168cb96155SEvan Bacon          expect(exists).not.toBeTruthy();
417740b3867SJames Ide        }
418740b3867SJames Ide      };
419740b3867SJames Ide
420740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
421740b3867SJames Ide      await assertExists(false);
422740b3867SJames Ide
423740b3867SJames Ide      let error;
424740b3867SJames Ide      try {
4253ba2b94bSŁukasz Kosmaty        await FS.downloadAsync('https://nonexistent-subdomain.expo.io', localUri, {
4263ba2b94bSŁukasz Kosmaty          md5: true,
4273ba2b94bSŁukasz Kosmaty          sessionType: FS.FileSystemSessionType.FOREGROUND,
4283ba2b94bSŁukasz Kosmaty        });
429740b3867SJames Ide      } catch (e) {
430740b3867SJames Ide        error = e;
431740b3867SJames Ide      }
4328cb96155SEvan Bacon      expect(error).toBeTruthy();
433740b3867SJames Ide      await assertExists(false);
434740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
4358cb96155SEvan Bacon    }, 30000);
436740b3867SJames Ide
4378cb96155SEvan Bacon    it('download(404)', async () => {
438740b3867SJames Ide      const localUri = FS.documentDirectory + 'download1.png';
439740b3867SJames Ide
44022d1e005SBartosz Kaszubowski      const assertExists = async (expectedToExist) => {
44119cbf4dcSBartłomiej Bukowski        const { exists } = await FS.getInfoAsync(localUri);
442740b3867SJames Ide        if (expectedToExist) {
4438cb96155SEvan Bacon          expect(exists).toBeTruthy();
444740b3867SJames Ide        } else {
4458cb96155SEvan Bacon          expect(exists).not.toBeTruthy();
446740b3867SJames Ide        }
447740b3867SJames Ide      };
448740b3867SJames Ide
449740b3867SJames Ide      await FS.deleteAsync(localUri, { idempotent: true });
450740b3867SJames Ide      await assertExists(false);
451740b3867SJames Ide
452df3ae3b5Sandy      const { status } = await FS.downloadAsync('https://github.com/omg1231sdfaljs', localUri, {
453740b3867SJames Ide        md5: true,
454740b3867SJames Ide      });
455740b3867SJames Ide      await assertExists(true);
4568cb96155SEvan Bacon      expect(status).toBe(404);
457740b3867SJames Ide
458740b3867SJames Ide      await FS.deleteAsync(localUri);
459740b3867SJames Ide      await assertExists(false);
4608cb96155SEvan Bacon    }, 30000);
461d7aba270SDominik Sokal
4628cb96155SEvan Bacon    it('download(nonexistent local path)', async () => {
463d7aba270SDominik Sokal      try {
464d7aba270SDominik Sokal        const remoteUrl = 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png';
465d7aba270SDominik Sokal        const localUri = FS.documentDirectory + 'doesnt/exists/download1.png';
466d7aba270SDominik Sokal        await FS.downloadAsync(remoteUrl, localUri);
467d7aba270SDominik Sokal      } catch (err) {
468*51e273e0STomasz Sapeta        expect(err.message).toMatch(/Directory '.*' does not exist/);
469d7aba270SDominik Sokal      }
4708cb96155SEvan Bacon    }, 30000);
471d7aba270SDominik Sokal
4728cb96155SEvan Bacon    it('mkdir(multi-level) + download(multi-level local path)', async () => {
473d7aba270SDominik Sokal      const remoteUrl = 'https://s3-us-west-1.amazonaws.com/test-suite-data/avatar2.png';
474d7aba270SDominik Sokal      const localDirUri = FS.documentDirectory + 'foo/bar/baz';
475d7aba270SDominik Sokal      const localFileUri = localDirUri + 'download1.png';
476d7aba270SDominik Sokal
477d7aba270SDominik Sokal      await FS.makeDirectoryAsync(localDirUri, { intermediates: true });
478d7aba270SDominik Sokal
479d7aba270SDominik Sokal      await FS.downloadAsync(remoteUrl, localFileUri);
4808cb96155SEvan Bacon    }, 30000);
4812d9e7c30SGabriel Donadel Dall'Agnol
4822d9e7c30SGabriel Donadel Dall'Agnol    it('create UTF-8 folder and get info', async () => {
4832d9e7c30SGabriel Donadel Dall'Agnol      const folderName = '中文';
4842d9e7c30SGabriel Donadel Dall'Agnol      const folderUri = FS.documentDirectory + folderName;
4852d9e7c30SGabriel Donadel Dall'Agnol
4862d9e7c30SGabriel Donadel Dall'Agnol      const dirInfo = await FS.getInfoAsync(folderUri);
4872d9e7c30SGabriel Donadel Dall'Agnol      if (dirInfo.exists) {
4882d9e7c30SGabriel Donadel Dall'Agnol        await FS.deleteAsync(folderUri);
4892d9e7c30SGabriel Donadel Dall'Agnol      }
4902d9e7c30SGabriel Donadel Dall'Agnol
4912d9e7c30SGabriel Donadel Dall'Agnol      await FS.makeDirectoryAsync(folderUri);
4922d9e7c30SGabriel Donadel Dall'Agnol      const newDirInfo = await FS.getInfoAsync(folderUri);
4932d9e7c30SGabriel Donadel Dall'Agnol
4942d9e7c30SGabriel Donadel Dall'Agnol      expect(newDirInfo.exists).toBeTruthy();
4952d9e7c30SGabriel Donadel Dall'Agnol      expect(newDirInfo.isDirectory).toBeTruthy();
4962d9e7c30SGabriel Donadel Dall'Agnol    }, 30000);
497740b3867SJames Ide  });
498740b3867SJames Ide}
499