1import * as FileSystem from 'expo-file-system';
2import firebase from 'firebase/compat';
3import 'firebase/compat/auth';
4import 'firebase/compat/database';
5import 'firebase/compat/firestore';
6import 'firebase/compat/functions';
7import 'firebase/compat/storage';
8
9// The modules below require browser features and are not compatible within the react-native context.
10// import "firebase/compat/analytics";
11// import "firebase/compat/remote-config";
12// import "firebase/compat/messaging";
13// import "firebase/compat/performance";
14// import "firebase/compat/installations";
15
16import { expectMethodToThrowAsync } from '../TestUtils';
17
18export const name = 'FirebaseJSSDK (Compat)';
19
20const FIREBASE_CONFIG = {
21  apiKey: 'AIzaSyD2gZuX5utrLBAdJoMrAdrMW7Sv9xQ5uBE',
22  authDomain: 'expo-payments.firebaseapp.com',
23  databaseURL: 'https://expo-payments.firebaseio.com',
24  projectId: 'expo-payments',
25  storageBucket: 'expo-payments.appspot.com',
26  messagingSenderId: '482324271988',
27  appId: '1:482324271988:web:9597460d096749b3f8d221',
28  measurementId: 'G-498KQSTM5G',
29};
30
31export async function test({ describe, it, expect, beforeAll }) {
32  beforeAll(() => {
33    try {
34      firebase.initializeApp(FIREBASE_CONFIG);
35    } catch {
36      // nop
37    }
38  });
39
40  describe('FirebaseJSSDK', async () => {
41    describe('auth', async () => {
42      it(`calls auth() succesfully`, () => {
43        firebase.auth();
44      });
45      it(`returns correct sign-in error`, async () => {
46        const error = await expectMethodToThrowAsync(() =>
47          firebase.auth().signInWithEmailAndPassword('[email protected]', '0')
48        );
49        expect(error.code).toBe('auth/operation-not-allowed');
50      });
51    });
52
53    describe('database', async () => {
54      it(`calls database() succesfully`, () => {
55        const db = firebase.database();
56        expect(db).not.toBeNull();
57      });
58      it(`reads data once`, async () => {
59        let error = null;
60        try {
61          const snapshot = await firebase.database().ref('/test1').once('value');
62          expect(snapshot.val()).toBe('foobar');
63        } catch (e) {
64          error = e;
65        }
66        expect(error).toBeNull();
67      });
68    });
69
70    describe('firestore', async () => {
71      it(`calls firestore() succesfully`, () => {
72        const db = firebase.firestore();
73        expect(db).not.toBeNull();
74      });
75      it(`gets a collection`, async () => {
76        let error = null;
77        try {
78          const { docs } = await firebase.firestore().collection('tests').get();
79          expect(docs.length).toBeGreaterThan(0);
80        } catch (e) {
81          error = e;
82        }
83        expect(error).toBeNull();
84      });
85      it(`gets a document`, async () => {
86        let error = null;
87        try {
88          const snapshot = await firebase.firestore().doc('tests/doc1').get();
89          expect(snapshot).not.toBeNull();
90        } catch (e) {
91          error = e;
92        }
93        expect(error).toBeNull();
94      });
95    });
96
97    describe('functions', async () => {
98      it(`calls functions() succesfully`, () => {
99        const functions = firebase.functions();
100        expect(functions).not.toBeNull();
101      });
102      it(`calls the echo function`, async () => {
103        let error = null;
104        try {
105          const message = "I'm a unit test";
106          const echoMessage = firebase.functions().httpsCallable('echoMessage');
107          const response = await echoMessage({ message });
108          const responseMessage = response.data.message;
109          expect(responseMessage).toBe(`Hi ��, you said: ${message}`);
110        } catch (e) {
111          error = e;
112        }
113        expect(error).toBeNull();
114      });
115    });
116
117    describe('storage', () => {
118      it(`calls storage() succesfully`, () => {
119        const storage = firebase.storage();
120        expect(storage).not.toBeNull();
121      });
122      it(`lists all files`, async () => {
123        let error = null;
124        try {
125          const files = await firebase.storage().ref('public').listAll();
126          expect(files.items.length).toBeGreaterThan(0);
127        } catch (e) {
128          error = e;
129        }
130        expect(error).toBeNull();
131      });
132      it(`downloads a file`, async () => {
133        let error = null;
134        try {
135          const files = await firebase.storage().ref('public').listAll();
136          expect(files.items.length).toBeGreaterThan(0);
137          const file = files.items[0];
138          const downloadUrl = await file.getDownloadURL();
139          expect(typeof downloadUrl).toBe('string');
140          const startUrl = 'https://firebasestorage.googleapis.com';
141          expect(downloadUrl.substring(0, startUrl.length)).toBe(startUrl);
142          const { uri } = await FileSystem.downloadAsync(
143            downloadUrl,
144            FileSystem.documentDirectory + file.name
145          );
146          expect(typeof uri).toBe('string');
147          expect(uri).not.toBeNull();
148        } catch (e) {
149          error = e;
150        }
151        expect(error).toBeNull();
152      });
153      /* it(`upload a file`, async () => {
154        let error = null;
155        try {
156          // REQUIRES AUTH
157          const currentUser = firebase.auth ? firebase.auth().currentUser : undefined;
158          // const suffix = new Date().toISOString().replace(/\D/g, '');
159          const fileContent = new ArrayBuffer(1000);
160          const ref = firebase
161            .storage()
162            .ref(`users/${currentUser.uid}`)
163            .child(`unittest`);
164          // @ts-ignore
165          const uploadTask = ref.put(fileContent);
166          await new Promise((resolve, reject) => {
167            uploadTask.on(
168              firebase.storage.TaskEvent.STATE_CHANGED,
169              snapshot => {},
170              reject,
171              resolve
172            );
173          });
174        } catch (e) {
175          error = e;
176        }
177        expect(error).toBeNull();
178      });*/
179    });
180  });
181}
182