1'use strict';
2
3import React from 'react';
4import { Platform } from 'react-native';
5import { Asset, BarCodeScanner, Permissions } from 'expo';
6import * as TestUtils from '../TestUtils';
7
8import { mountAndWaitFor as originalMountAndWaitFor } from './helpers';
9
10export const name = 'BarCodeScanner';
11const style = { width: 200, height: 200 };
12
13export async function test(t, { setPortalChild, cleanupPortal }) {
14  const shouldSkipTestsRequiringPermissions = await TestUtils.shouldSkipTestsRequiringPermissionsAsync();
15  const describeWithPermissions = shouldSkipTestsRequiringPermissions ? t.xdescribe : t.describe;
16
17  describeWithPermissions('BarCodeScanner', () => {
18    const mountAndWaitFor = (child, propName = 'ref') =>
19      new Promise(resolve => {
20        const response = originalMountAndWaitFor(child, propName, setPortalChild);
21        setTimeout(() => resolve(response), 1500);
22      });
23
24    t.beforeAll(async () => {
25      await TestUtils.acceptPermissionsAndRunCommandAsync(() => {
26        return Permissions.askAsync(Permissions.CAMERA);
27      });
28    });
29
30    t.beforeEach(async () => {
31      const { status } = await Permissions.getAsync(Permissions.CAMERA);
32      t.expect(status).toEqual('granted');
33    });
34
35    t.afterEach(async () => {
36      await cleanupPortal();
37    });
38
39    t.describe('when created', () => {
40      t.it('displays the view', async () => {
41        await mountAndWaitFor(<BarCodeScanner style={style} />);
42      });
43    });
44
45    t.describe('scanFromURLAsync', () => {
46      t.it('returns empty result when there is no barcode', async () => {
47        const asset = await Asset.fromModule(require('../assets/black-128x256.png'));
48        const result = await BarCodeScanner.scanFromURLAsync(asset.uri);
49
50        t.expect(result).toBeDefined();
51        t.expect(result.length).toEqual(0);
52      });
53
54      t.it('scans a QR code from asset', async () => {
55        const asset = await Asset.fromModule(require('../assets/qrcode_expo.jpg'));
56        const result = await BarCodeScanner.scanFromURLAsync(asset.uri);
57
58        t.expect(result).toBeDefined();
59        t.expect(result.length).toEqual(1);
60        t.expect(result[0]).toBeDefined();
61        t.expect(result[0].type).toEqual(BarCodeScanner.Constants.BarCodeType.qr);
62        t.expect(result[0].data).toEqual('https://expo.io/');
63      });
64
65      t.it('scans a QR code from photo asset', async () => {
66        // Public domain photo from https://commons.wikimedia.org/wiki/File:QR_Code_Damaged.jpg
67        const asset = await Asset.fromModule(require('../assets/qrcode_photo_wikipedia.jpg'));
68        const result = await BarCodeScanner.scanFromURLAsync(asset.uri);
69
70        t.expect(result).toBeDefined();
71        t.expect(result.length).toEqual(1);
72        t.expect(result[0]).toBeDefined();
73        t.expect(result[0].type).toEqual(BarCodeScanner.Constants.BarCodeType.qr);
74        t.expect(result[0].data).toEqual('http://en.m.wikipedia.org');
75      });
76
77      t.it('scans a QR code from base64 URL', async () => {
78        const url =
79          'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAQMAAAAk8RryAAAABlBMVEX/' +
80          '//8AAABVwtN+AAAAcElEQVQY04XFMQrAMAgFUCGr4FUCXQO9uuAq/KsEugq2m2bqWx79kQRn1EzGyu' +
81          '1whx/Pc+gxKSnXku4ZNdFQolq2m3jN9/SrD0Ws9l4Ysx5uj9QftqstqQatmey2ftjW6GPI7PvD2iYE' +
82          'uJbEmlT/eAEXiXvHFX7hfQAAAABJRU5ErkJggg==';
83        const result = await BarCodeScanner.scanFromURLAsync(url);
84
85        t.expect(result).toBeDefined();
86        t.expect(result.length).toEqual(1);
87        t.expect(result[0]).toBeDefined();
88        t.expect(result[0].type).toEqual(BarCodeScanner.Constants.BarCodeType.qr);
89        t.expect(result[0].data).toEqual('test');
90      });
91
92      if (Platform.OS === 'android') {
93        t.it('scans a Data Matrix code from asset', async () => {
94          const asset = await Asset.fromModule(require('../assets/datamatrix_expo.png'));
95          const result = await BarCodeScanner.scanFromURLAsync(asset.uri);
96
97          t.expect(result).toBeDefined();
98          t.expect(result.length).toEqual(1);
99          t.expect(result[0]).toBeDefined();
100          t.expect(result[0].type).toEqual(BarCodeScanner.Constants.BarCodeType.datamatrix);
101          t.expect(result[0].data).toEqual('https://expo.io/');
102        });
103      }
104
105      t.it('respects barCodeTypes parameter', async () => {
106        const asset = await Asset.fromModule(require('../assets/datamatrix_expo.png'));
107        const result = await BarCodeScanner.scanFromURLAsync(asset.uri, [
108          BarCodeScanner.Constants.BarCodeType.qr,
109        ]);
110
111        t.expect(result).toBeDefined();
112        t.expect(result.length).toEqual(0);
113      });
114
115      t.it('works with multiple codes', async () => {
116        const asset = await Asset.fromModule(require('../assets/multiple_codes.png'));
117        const result = await BarCodeScanner.scanFromURLAsync(asset.uri);
118
119        t.expect(result).toBeDefined();
120        t.expect(result.length > 0).toBe(true);
121      });
122    });
123  });
124}
125