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