blob: e8e173283e61bd685e9cc95e399432f25b021e41 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.webapk.lib.client;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.ServiceConnection;
import org.chromium.base.Callback;
import org.chromium.base.ContextUtils;
import org.chromium.testing.local.CustomShadowAsyncTask;
import org.chromium.testing.local.LocalRobolectricTestRunner;
import org.chromium.webapk.lib.runtime_library.IWebApkApi;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
/**
* Unit tests for {@link org.chromium.libs.client.WebApkServiceConnectionManager}.
*/
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE, shadows = {CustomShadowAsyncTask.class})
public class WebApkServiceConnectionManagerTest {
private static final String WEB_APK_PACKAGE = "com.webapk.package";
private ShadowApplication mShadowApplication;
private WebApkServiceConnectionManager mConnectionManager;
private class TestCallback implements Callback<IWebApkApi> {
public boolean mGotResult = false;
@Override
public void onResult(IWebApkApi api) {
mGotResult = true;
}
}
@Before
public void setUp() {
ContextUtils.initApplicationContextForTests(Robolectric.application);
mShadowApplication = Robolectric.shadowOf(Robolectric.application);
mConnectionManager = new WebApkServiceConnectionManager();
}
/**
* Test that a connection request to a WebAPK's service does not create a new connection if one
* already exists.
*/
@Test
public void testAfterConnectionEstablished() throws Exception {
TestCallback callback1 = new TestCallback();
TestCallback callback2 = new TestCallback();
mConnectionManager.connect(WEB_APK_PACKAGE, callback1);
mConnectionManager.connect(WEB_APK_PACKAGE, callback2);
// Only one connection should have been created.
Assert.assertEquals(WEB_APK_PACKAGE, getNextStartedServicePackage());
Assert.assertEquals(null, getNextStartedServicePackage());
// Both callbacks should have been called.
Assert.assertTrue(callback1.mGotResult);
Assert.assertTrue(callback2.mGotResult);
}
/**
* Test connecting to a WebAPK when Chrome is in the process of establishing a connection to the
* WebAPK but has not established a connection yet.
*/
@Test
public void testConnectWhileConnectionBeingEstablished() throws Exception {
// Context for testing {@link Context#bindService()} occurring asynchronously.
class AsyncBindContext extends ContextWrapper {
private ServiceConnection mConnection;
public AsyncBindContext() {
super(null);
}
// Establish pending connection created in {@link #bindService}.
public void establishServiceConnection() {
if (mConnection != null) {
mConnection.onServiceConnected(null, null);
}
}
@Override
public Context getApplicationContext() {
// Need to return real context so that ContextUtils#fetchAppSharedPreferences() does
// not crash.
return Robolectric.application;
}
// Create pending connection.
@Override
public boolean bindService(Intent service, ServiceConnection connection, int flags) {
mConnection = connection;
return true;
}
}
AsyncBindContext asyncBindContext = new AsyncBindContext();
ContextUtils.initApplicationContextForTests(asyncBindContext);
TestCallback callback1 = new TestCallback();
TestCallback callback2 = new TestCallback();
mConnectionManager.connect(WEB_APK_PACKAGE, callback1);
mConnectionManager.connect(WEB_APK_PACKAGE, callback2);
// The connection has not been established yet. Neither of the callbacks should have been
// called.
Assert.assertFalse(callback1.mGotResult);
Assert.assertFalse(callback2.mGotResult);
// Establishing the connection should cause both callbacks to be called.
asyncBindContext.establishServiceConnection();
Assert.assertTrue(callback1.mGotResult);
Assert.assertTrue(callback2.mGotResult);
}
/**
* Test reconnecting to a WebAPK's service.
*/
@Test
public void testDisconnectConnect() throws Exception {
mConnectionManager.connect(WEB_APK_PACKAGE, new TestCallback());
Assert.assertEquals(WEB_APK_PACKAGE, getNextStartedServicePackage());
Assert.assertEquals(null, getNextStartedServicePackage());
mConnectionManager.disconnect(WEB_APK_PACKAGE);
mConnectionManager.connect(WEB_APK_PACKAGE, new TestCallback());
Assert.assertEquals(WEB_APK_PACKAGE, getNextStartedServicePackage());
Assert.assertEquals(null, getNextStartedServicePackage());
}
/**
* Returns the package name of the most recently started service.
*/
public String getNextStartedServicePackage() {
Intent intent = mShadowApplication.getNextStartedService();
return (intent == null) ? null : intent.getPackage();
}
}