/* * Copyright 2017 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.firebase.database.integration; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; import com.google.firebase.auth.FirebaseCredentials; import com.google.firebase.database.ChildEventListener; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseException; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.MapBuilder; import com.google.firebase.database.TestFailure; import com.google.firebase.database.TestHelpers; import com.google.firebase.database.ValueEventListener; import com.google.firebase.database.future.ReadFuture; import com.google.firebase.tasks.Tasks; import com.google.firebase.testing.IntegrationTestUtils; import com.google.firebase.testing.TestUtils; import java.io.IOException; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class FirebaseDatabaseTestIT { private static FirebaseApp masterApp; @BeforeClass public static void setUpClass() { masterApp = IntegrationTestUtils.ensureDefaultApp(); } @Before public void prepareApp() { TestHelpers.wrapForErrorHandling(masterApp); } @After public void checkAndCleanupApp() { TestHelpers.assertAndUnwrapErrorHandlers(masterApp); } @Test public void testGetDefaultInstance() { FirebaseDatabase db = FirebaseDatabase.getInstance(); assertEquals(FirebaseApp.getInstance().getOptions().getDatabaseUrl(), db.getReference().toString()); } @Test public void testGetInstanceForApp() throws InterruptedException, TestFailure, TimeoutException { FirebaseDatabase db = FirebaseDatabase.getInstance(masterApp); assertEquals(masterApp.getOptions().getDatabaseUrl(), db.getReference().toString()); } @Test public void testNullDatabaseUrl() { FirebaseApp app = appWithDbUrl(null, "nullDbUrl"); try { FirebaseDatabase.getInstance(app); fail("no error thrown for getInstance() with null URL"); } catch (DatabaseException expected) { // ignore } } @Test public void testMalformedDatabaseUrlInOptions() { FirebaseApp app = appWithDbUrl("not-a-url", "malformedDbUrlInOptions"); try { FirebaseDatabase.getInstance(app); fail("no error thrown for getInstance() with malformed URL"); } catch (DatabaseException expected) { // ignore } } @Test public void testMalformedDatabaseUrlInGetInstance() { FirebaseApp app = appWithoutDbUrl("malformedDbUrlInGetInstance"); try { FirebaseDatabase.getInstance(app, "not-a-url"); fail("no error thrown for getInstance() with malformed URL"); } catch (DatabaseException expected) { // ignore } } @Test public void testDatabaseUrlWithPathInOptions() { FirebaseApp app = appWithDbUrl(IntegrationTestUtils.getDatabaseUrl() + "/paths/are/not/allowed", "dbUrlWithPathInOptions"); try { FirebaseDatabase.getInstance(app); fail("no error thrown for DB URL with path"); } catch (DatabaseException expected) { // ignore } } @Test public void testDatabaseUrlWithPathInGetInstance() { FirebaseApp app = appWithoutDbUrl("dbUrlWithPathInGetInstance"); try { FirebaseDatabase.getInstance(app, IntegrationTestUtils.getDatabaseUrl() + "/paths/are/not/allowed"); fail("no error thrown for DB URL with path"); } catch (DatabaseException expected) { // ignore } } @Test public void testGetReference() { FirebaseDatabase db = FirebaseDatabase.getInstance(masterApp); assertEquals(IntegrationTestUtils.getDatabaseUrl() + "/foo", db.getReference("foo").toString()); } @Test public void testGetReferenceFromURLWithoutPath() { String dbUrl = IntegrationTestUtils.getDatabaseUrl(); FirebaseDatabase db = FirebaseDatabase.getInstance(masterApp); DatabaseReference ref = db.getReferenceFromUrl(dbUrl); assertEquals(dbUrl, ref.toString()); } @Test public void testGetReferenceFromURLWithPath() { String dbUrl = IntegrationTestUtils.getDatabaseUrl(); FirebaseDatabase db = FirebaseDatabase.getInstance(masterApp); DatabaseReference ref = db.getReferenceFromUrl(dbUrl + "/foo/bar"); assertEquals(dbUrl + "/foo/bar", ref.toString()); } @Test(expected = DatabaseException.class) public void testGetReferenceThrowsWithBadUrl() { FirebaseDatabase db = FirebaseDatabase.getInstance(); db.getReferenceFromUrl("https://tests2.fake-firebaseio.com:9000"); } @Test public void testSetValue() throws InterruptedException, ExecutionException, TimeoutException, TestFailure { FirebaseDatabase db = FirebaseDatabase.getInstance(masterApp); DatabaseReference ref = db.getReference("testSetValue"); Tasks.await(ref.setValue("foo"), TestUtils.TEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); ReadFuture readFuture = ReadFuture.untilEquals(ref, "foo"); readFuture.timedWait(); } @Test public void testDeleteApp() throws InterruptedException, TestFailure, TimeoutException, ExecutionException { FirebaseApp app = IntegrationTestUtils.initApp("testDeleteApp"); List<DatabaseReference> ref = IntegrationTestUtils.getRandomNode(app, 2); DatabaseReference writer = ref.get(0); DatabaseReference reader = ref.get(1); writer.setValue("test"); TestHelpers.waitForRoundtrip(writer.getRoot()); ReadFuture.untilEquals(reader, "test").timedWait(); app.delete(); try { IntegrationTestUtils.getRandomNode(app); fail("No error thrown for deleted app"); } catch (IllegalStateException expected) { // ignore } try { writer.setValue("foo"); fail("No error thrown for deleted app"); } catch (IllegalStateException expected) { // ignore } try { writer.updateChildren(MapBuilder.of("a", 1)); fail("No error thrown for deleted app"); } catch (IllegalStateException expected) { // ignore } try { writer.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { } @Override public void onCancelled(DatabaseError error) { } }); fail("No error thrown for deleted app"); } catch (IllegalStateException expected) { // ignore } try { writer.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot snapshot, String previousChildName) { } @Override public void onChildChanged(DataSnapshot snapshot, String previousChildName) { } @Override public void onChildRemoved(DataSnapshot snapshot) { } @Override public void onChildMoved(DataSnapshot snapshot, String previousChildName) { } @Override public void onCancelled(DatabaseError error) { } }); fail("No error thrown for deleted app"); } catch (IllegalStateException expected) { // ignore } app = IntegrationTestUtils.initApp("testDeleteApp"); ref = IntegrationTestUtils.getRandomNode(app, 2); writer = ref.get(0); reader = ref.get(1); writer.setValue("test2"); TestHelpers.waitForRoundtrip(writer.getRoot()); ReadFuture.untilEquals(reader, "test2").timedWait(); } private static FirebaseApp appWithDbUrl(String dbUrl, String name) { try { FirebaseOptions options = new FirebaseOptions.Builder() .setDatabaseUrl(dbUrl) .setCredential(FirebaseCredentials.fromCertificate( IntegrationTestUtils.getServiceAccountCertificate())) .build(); return FirebaseApp.initializeApp(options, name); } catch (IOException e) { throw new RuntimeException(e); } } private static FirebaseApp appWithoutDbUrl(String name) { try { FirebaseOptions options = new FirebaseOptions.Builder() .setCredential(FirebaseCredentials.fromCertificate( IntegrationTestUtils.getServiceAccountCertificate())) .build(); return FirebaseApp.initializeApp(options, name); } catch (IOException e) { throw new RuntimeException(e); } } }