Messaging: Remove tests
Nobody runs them anyway Change-Id: I2b07847509269af31430abc6cb0fb190f08d45f9
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
Copyright (C) 2024 The LineageOS Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -297,15 +298,6 @@
|
||||
android:value="com.android.messaging.ui.conversation.ConversationActivity" />
|
||||
</activity>
|
||||
|
||||
<!-- Test activity that we use to host fragments/views. Unfortunately, apparently necessary
|
||||
because Android framework test cases want activity to be in the instrumented package.
|
||||
See http://developer.android.com/reference/android/test/ActivityInstrumentationTestCase2.html
|
||||
-->
|
||||
<activity
|
||||
android:name=".ui.TestActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ui.debug.DebugMmsConfigActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
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.
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/test_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/test_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -44,7 +45,6 @@ import com.android.messaging.util.LogUtil;
|
||||
import com.android.messaging.util.OsUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
import com.android.messaging.util.Trace;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
@@ -56,32 +56,13 @@ public class BugleApplication extends Application implements UncaughtExceptionHa
|
||||
private static final String TAG = LogUtil.BUGLE_TAG;
|
||||
|
||||
private UncaughtExceptionHandler sSystemUncaughtExceptionHandler;
|
||||
private static boolean sRunningTests = false;
|
||||
|
||||
@VisibleForTesting
|
||||
protected static void setTestsRunning() {
|
||||
sRunningTests = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if we're running unit tests.
|
||||
*/
|
||||
public static boolean isRunningTests() {
|
||||
return sRunningTests;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Trace.beginSection("app.onCreate");
|
||||
super.onCreate();
|
||||
|
||||
// Note onCreate is called in both test and real application environments
|
||||
if (!sRunningTests) {
|
||||
// Only create the factory if not running tests
|
||||
FactoryImpl.register(getApplicationContext(), this);
|
||||
} else {
|
||||
LogUtil.e(TAG, "BugleApplication.onCreate: FactoryImpl.register skipped for test run");
|
||||
}
|
||||
FactoryImpl.register(getApplicationContext(), this);
|
||||
|
||||
sSystemUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,7 +24,6 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
import com.android.messaging.BugleApplication;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.data.ConversationListItemData;
|
||||
import com.android.messaging.datamodel.data.MessageData;
|
||||
@@ -31,7 +31,6 @@ import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.Assert.DoesNotRunOnMainThread;
|
||||
import com.android.messaging.util.LogUtil;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* TODO: Open Issues:
|
||||
@@ -586,18 +585,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
mApplicationContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method that always instantiates a new DatabaseHelper instance. This should
|
||||
* be used ONLY by the tests and never by the real application.
|
||||
* @param context Test context.
|
||||
* @return Brand new DatabaseHelper instance.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static DatabaseHelper getNewInstanceForTest(final Context context) {
|
||||
Assert.isTrue(BugleApplication.isRunningTests());
|
||||
return new DatabaseHelper(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the (singleton) instance of @{link DatabaseWrapper}.
|
||||
* <p>The database is always opened as a writeable database.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +27,6 @@ import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.messaging.BugleApplication;
|
||||
import com.android.messaging.Factory;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ConversationColumns;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ConversationParticipantsColumns;
|
||||
@@ -35,7 +35,6 @@ import com.android.messaging.datamodel.data.ConversationListItemData;
|
||||
import com.android.messaging.datamodel.data.ConversationMessageData;
|
||||
import com.android.messaging.datamodel.data.MessageData;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.LogUtil;
|
||||
import com.android.messaging.util.OsUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
@@ -244,12 +243,6 @@ public class MessagingContentProvider extends ContentProvider {
|
||||
super();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setDatabaseForTest(final DatabaseWrapper db) {
|
||||
Assert.isTrue(BugleApplication.isRunningTests());
|
||||
mDatabaseWrapper = db;
|
||||
}
|
||||
|
||||
private DatabaseWrapper getDatabaseWrapper() {
|
||||
if (mDatabaseWrapper == null) {
|
||||
mDatabaseWrapper = mDatabaseHelper.getDatabase();
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.util.LogUtil;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* An empty activity that can be used to host a fragment or view for unit testing purposes. Lives in
|
||||
* app code vs test code due to requirement of ActivityInstrumentationTestCase2.
|
||||
*/
|
||||
public class TestActivity extends FragmentActivity {
|
||||
private FragmentEventListener mFragmentEventListener;
|
||||
|
||||
public interface FragmentEventListener {
|
||||
public void onAttachFragment(Fragment fragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(final Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
||||
if (bundle != null) {
|
||||
// The test case may have configured the fragment, and recreating the activity will
|
||||
// lose that configuration. The real activity is the only activity that would know
|
||||
// how to reapply that configuration.
|
||||
throw new IllegalStateException("TestActivity cannot get recreated");
|
||||
}
|
||||
|
||||
// There is a race condition, but this often makes it possible for tests to run with the
|
||||
// key guard up
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
|
||||
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
|
||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.test_activity);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setFragment(final Fragment fragment) {
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "TestActivity.setFragment");
|
||||
getFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(R.id.test_content, fragment)
|
||||
.commit();
|
||||
getFragmentManager().executePendingTransactions();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setView(final View view) {
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "TestActivity.setView");
|
||||
((FrameLayout) findViewById(R.id.test_content)).addView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachFragment(final Fragment fragment) {
|
||||
if (mFragmentEventListener != null) {
|
||||
mFragmentEventListener.onAttachFragment(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFragmentEventListener(final FragmentEventListener fragmentEventListener) {
|
||||
mFragmentEventListener = fragmentEventListener;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright (C) 2015 The Android Open Source Project
|
||||
//
|
||||
// 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 {
|
||||
default_team: "trendy_team_messages",
|
||||
// See: http://go/android-license-faq
|
||||
default_applicable_licenses: [
|
||||
"Android-Apache-2.0",
|
||||
],
|
||||
}
|
||||
|
||||
android_test {
|
||||
name: "messagingtests",
|
||||
srcs: ["src/**/*.java"],
|
||||
instrumentation_for: "messaging",
|
||||
optimize: {
|
||||
enabled: false,
|
||||
},
|
||||
sdk_version: "current",
|
||||
test_suites: ["general-tests"],
|
||||
certificate: "platform",
|
||||
static_libs: [
|
||||
"mockito-target",
|
||||
"androidx.test.rules",
|
||||
],
|
||||
libs: [
|
||||
"android.test.mock.stubs",
|
||||
"android.test.runner.stubs",
|
||||
"android.test.base.stubs",
|
||||
],
|
||||
data: [
|
||||
":messaging",
|
||||
],
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 The Android Open Source Project
|
||||
|
||||
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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.messaging.test" >
|
||||
|
||||
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="29"/>
|
||||
|
||||
<application android:label="Messaging Tests" >
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
|
||||
<instrumentation
|
||||
android:label="Messaging Tests"
|
||||
android:name="android.test.InstrumentationTestRunner"
|
||||
android:targetPackage="com.android.messaging"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize" />
|
||||
</manifest>
|
||||
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2019 The Android Open Source Project
|
||||
|
||||
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.
|
||||
-->
|
||||
<configuration description="Runs Messaging Tests.">
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-instrumentation" />
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
<option name="cleanup-apks" value="true" />
|
||||
<option name="test-file-name" value="messagingtests.apk" />
|
||||
<option name="test-file-name" value="messaging.apk" />
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
|
||||
<option name="package" value="com.android.messaging.test" />
|
||||
<option name="runner" value="android.test.InstrumentationTestRunner" />
|
||||
</test>
|
||||
</configuration>
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging;
|
||||
|
||||
import android.content.Context;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/*
|
||||
* Base class for service tests that takes care of housekeeping that is common amongst basic test
|
||||
* cases.
|
||||
*/
|
||||
public abstract class BugleTestCase extends AndroidTestCase {
|
||||
|
||||
static {
|
||||
// Set flag during loading of test cases to prevent application initialization starting
|
||||
setTestsRunning();
|
||||
}
|
||||
|
||||
public static void setTestsRunning() {
|
||||
BugleApplication.setTestsRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
TestUtil.testSetup(super.getContext(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
TestUtil.testTeardown(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getContext() {
|
||||
// This doesn't really get the "application context" - just the fake context
|
||||
// that the factory has been initialized with for each test case.
|
||||
return Factory.get().getApplicationContext();
|
||||
}
|
||||
|
||||
public Context getTestContext() {
|
||||
return super.getContext();
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import androidx.collection.SimpleArrayMap;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
import com.android.messaging.util.LogUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FakeContentProvider extends ContentProvider {
|
||||
|
||||
private static class ContentOverride {
|
||||
private final String uri;
|
||||
private final String where;
|
||||
private final String args;
|
||||
private final String[] columns;
|
||||
private final Object[][] data;
|
||||
|
||||
ContentOverride(final String uri, final String where, final String args,
|
||||
final String[] columns, final Object[][] data) {
|
||||
this.uri = uri;
|
||||
this.where = where;
|
||||
this.args = args;
|
||||
this.columns = columns;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
boolean match(final String uri, final String where, final String[] args) {
|
||||
if (!this.uri.equals(uri) || !TextUtils.equals(this.where, where)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.args == null || args == null) {
|
||||
return this.args == null && args == null;
|
||||
}
|
||||
|
||||
return this.args.equals(TextUtils.join(";", args));
|
||||
}
|
||||
}
|
||||
|
||||
private final Context mGlobalContext;
|
||||
private final ArrayList<ContentOverride> mOverrides = new ArrayList<ContentOverride>();
|
||||
private final SimpleArrayMap<String, String> mTypes = new SimpleArrayMap<String, String>();
|
||||
private final ContentProviderClient mProvider;
|
||||
private final Uri mUri;
|
||||
|
||||
public FakeContentProvider(final Context context, final Uri uri, final boolean canDelegate) {
|
||||
mGlobalContext = context;
|
||||
mUri = uri;
|
||||
if (canDelegate) {
|
||||
mProvider = mGlobalContext.getContentResolver().acquireContentProviderClient(mUri);
|
||||
} else {
|
||||
mProvider = null;
|
||||
}
|
||||
|
||||
ProviderInfo providerInfo = new ProviderInfo();
|
||||
providerInfo.authority = uri.getAuthority();
|
||||
|
||||
this.attachInfo(mGlobalContext, providerInfo);
|
||||
}
|
||||
|
||||
public void addOverrideData(final Uri uri, final String where, final String args,
|
||||
final String[] columns, final Object[][] data) {
|
||||
mOverrides.add(new ContentOverride(uri.toString(), where, args, columns, data));
|
||||
}
|
||||
|
||||
public void addOverrideType(final Uri uri, final String type) {
|
||||
mTypes.put(uri.toString(), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
if (mProvider != null) {
|
||||
mProvider.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(final Uri uri, final String[] projection, final String selection,
|
||||
final String[] selectionArgs, final String sortOrder) {
|
||||
LogUtil.w(LogUtil.BUGLE_TAG, "FakeContentProvider: query " + uri.toString()
|
||||
+ " for " + (projection == null ? null : TextUtils.join(",", projection))
|
||||
+ " where " + selection
|
||||
+ " with " + (selectionArgs == null ? null : TextUtils.join(";", selectionArgs)));
|
||||
|
||||
for(final ContentOverride content : mOverrides) {
|
||||
if (content.match(uri.toString(), selection, selectionArgs)) {
|
||||
return new FakeCursor(projection, content.columns, content.data);
|
||||
}
|
||||
}
|
||||
if (mProvider != null) {
|
||||
try {
|
||||
LogUtil.w(LogUtil.BUGLE_TAG, "FakeContentProvider: delgating");
|
||||
|
||||
final Cursor cursor = mProvider.query(uri, projection, selection, selectionArgs,
|
||||
sortOrder);
|
||||
|
||||
LogUtil.w(LogUtil.BUGLE_TAG, "FakeContentProvider: response size "
|
||||
+ cursor.getCount() + " contains " + TextUtils.join(",",
|
||||
cursor.getColumnNames()) + " type(0) " + cursor.getType(0));
|
||||
|
||||
return cursor;
|
||||
} catch (final RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(final Uri uri) {
|
||||
String type = mTypes.get(uri.toString());
|
||||
if (type == null) {
|
||||
try {
|
||||
type = mProvider.getType(uri);
|
||||
} catch (final RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(final Uri uri, final ContentValues values) {
|
||||
// TODO: Add code to track insert operations and return correct status
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(final Uri uri, final String selection, final String[] selectionArgs) {
|
||||
// TODO: Add code to track delete operations and return correct status
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(final Uri uri, final ContentValues values, final String selection,
|
||||
final String[] selectionArgs) {
|
||||
// TODO: Add code to track update operations and return correct status
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Bundle call(final String callingPkg, final String method, final String arg,
|
||||
final Bundle extras) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
import android.test.mock.MockContentResolver;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class FakeContext extends RenamingDelegatingContext {
|
||||
private static final String TAG = "FakeContext";
|
||||
|
||||
public interface FakeContextHost {
|
||||
public String getServiceClassName();
|
||||
public void startServiceForStub(Intent intent);
|
||||
public void onStartCommandForStub(Intent intent, int flags, int startid);
|
||||
}
|
||||
|
||||
ArrayList<Intent> mStartedIntents;
|
||||
boolean mServiceStarted = false;
|
||||
private final FakeContextHost mService;
|
||||
private final MockContentResolver mContentResolver;
|
||||
|
||||
|
||||
public FakeContext(final Context context, final FakeContextHost service) {
|
||||
super(context, "test_");
|
||||
mService = service;
|
||||
mStartedIntents = new ArrayList<Intent>();
|
||||
mContentResolver = new MockContentResolver();
|
||||
}
|
||||
|
||||
public FakeContext(final Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public ArrayList<Intent> extractIntents() {
|
||||
final ArrayList<Intent> intents = mStartedIntents;
|
||||
mStartedIntents = new ArrayList<Intent>();
|
||||
return intents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentName startService(final Intent intent) {
|
||||
// Record that a startService occurred with the intent that was passed.
|
||||
Log.d(TAG, "MockContext receiving startService. intent=" + intent.toString());
|
||||
mStartedIntents.add(intent);
|
||||
if (mService == null) {
|
||||
return super.startService(intent);
|
||||
} else if (intent.getComponent() != null &&
|
||||
intent.getComponent().getClassName().equals(mService.getServiceClassName())) {
|
||||
if (!mServiceStarted) {
|
||||
Log.d(TAG, "MockContext first start service.");
|
||||
mService.startServiceForStub(intent);
|
||||
} else {
|
||||
Log.d(TAG, "MockContext not first start service. Calling onStartCommand.");
|
||||
mService.onStartCommandForStub(intent, 0, 0);
|
||||
}
|
||||
mServiceStarted = true;
|
||||
return new ComponentName(this, intent.getComponent().getClassName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentResolver getContentResolver() {
|
||||
// If you want to use a content provider in your test, then you need to add it
|
||||
// explicitly.
|
||||
return mContentResolver;
|
||||
}
|
||||
|
||||
public void addContentProvider(final String name, final ContentProvider provider) {
|
||||
mContentResolver.addProvider(name, provider);
|
||||
}
|
||||
|
||||
public void addDefaultProvider(final Context context, final Uri uri) {
|
||||
final FakeContentProvider provider = new FakeContentProvider(context, uri, true);
|
||||
mContentResolver.addProvider(uri.getAuthority(), provider);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.MemoryCacheManager;
|
||||
import com.android.messaging.datamodel.ParticipantRefresh.ContactContentObserver;
|
||||
import com.android.messaging.datamodel.media.MediaCacheManager;
|
||||
import com.android.messaging.datamodel.media.MediaResourceManager;
|
||||
import com.android.messaging.sms.ApnDatabase;
|
||||
import com.android.messaging.sms.BugleCarrierConfigValuesLoader;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.BugleGservices;
|
||||
import com.android.messaging.util.BuglePrefs;
|
||||
import com.android.messaging.util.FakeBugleGservices;
|
||||
import com.android.messaging.util.FakeBuglePrefs;
|
||||
import com.android.messaging.util.MediaUtil;
|
||||
import com.android.messaging.util.OsUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FakeFactory extends Factory {
|
||||
private Context mContext;
|
||||
private FakeContext mFakeContext;
|
||||
private BugleGservices mBugleGservices;
|
||||
private BuglePrefs mBuglePrefs;
|
||||
private DataModel mDataModel;
|
||||
private UIIntents mUIIntents;
|
||||
private MemoryCacheManager mMemoryCacheManager;
|
||||
private MediaResourceManager mMediaResourceManager;
|
||||
private MediaCacheManager mMediaCacheManager;
|
||||
@Mock protected PhoneUtils mPhoneUtils;
|
||||
private MediaUtil mMediaUtil;
|
||||
private BugleCarrierConfigValuesLoader mCarrierConfigValuesLoader;
|
||||
|
||||
private FakeFactory() {
|
||||
}
|
||||
|
||||
public static FakeFactory registerWithFakeContext(final Context context,
|
||||
final FakeContext fake) {
|
||||
// In tests we currently NEVER run the application/factory initialization
|
||||
Assert.isTrue(!sRegistered);
|
||||
Assert.isTrue(!sInitialized);
|
||||
|
||||
final FakeFactory factory = new FakeFactory();
|
||||
Factory.setInstance(factory);
|
||||
|
||||
// At this point Factory is published. Services can now get initialized and depend on
|
||||
// Factory.get().
|
||||
factory.mContext = context;
|
||||
factory.mFakeContext = fake;
|
||||
factory.mMediaResourceManager = Mockito.mock(MediaResourceManager.class);
|
||||
factory.mBugleGservices = new FakeBugleGservices();
|
||||
factory.mBuglePrefs = new FakeBuglePrefs();
|
||||
factory.mPhoneUtils = Mockito.mock(PhoneUtils.class);
|
||||
|
||||
ApnDatabase.initializeAppContext(context);
|
||||
|
||||
Mockito.when(factory.mPhoneUtils.getCanonicalBySystemLocale(Matchers.anyString()))
|
||||
.thenAnswer(new Answer<String>() {
|
||||
@Override
|
||||
public String answer(final InvocationOnMock invocation) throws Throwable {
|
||||
final Object[] args = invocation.getArguments();
|
||||
return (String) args[0];
|
||||
}
|
||||
}
|
||||
);
|
||||
Mockito.when(factory.mPhoneUtils.getCanonicalBySimLocale(Matchers.anyString())).thenAnswer(
|
||||
new Answer<String>() {
|
||||
@Override
|
||||
public String answer(final InvocationOnMock invocation) throws Throwable {
|
||||
final Object[] args = invocation.getArguments();
|
||||
return (String) args[0];
|
||||
}
|
||||
}
|
||||
);
|
||||
Mockito.when(factory.mPhoneUtils.formatForDisplay(Matchers.anyString())).thenAnswer(
|
||||
new Answer<String>() {
|
||||
@Override
|
||||
public String answer(final InvocationOnMock invocation) throws Throwable {
|
||||
return (String) invocation.getArguments()[0];
|
||||
}
|
||||
}
|
||||
);
|
||||
if (OsUtil.isAtLeastL_MR1()) {
|
||||
Mockito.when(factory.mPhoneUtils.toLMr1()).thenReturn(
|
||||
new PhoneUtils.LMr1() {
|
||||
@Override
|
||||
public SubscriptionInfo getActiveSubscriptionInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SubscriptionInfo> getActiveSubscriptionInfoList() {
|
||||
// Return empty list
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerOnSubscriptionsChangedListener(
|
||||
final SubscriptionManager.OnSubscriptionsChangedListener listener) {
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
// By default only allow reading of system settings (that we provide) - can delegate
|
||||
// to real provider if required.
|
||||
final FakeContentProvider settings = new FakeContentProvider(context,
|
||||
Settings.System.CONTENT_URI, false);
|
||||
settings.addOverrideData(Settings.System.CONTENT_URI, "name=?", "time_12_24",
|
||||
new String[] { "value" }, new Object[][] { { "12" } });
|
||||
settings.addOverrideData(Settings.System.CONTENT_URI, "name=?", "sound_effects_enabled",
|
||||
new String[] { "value" }, new Object[][] { { 1 } });
|
||||
|
||||
factory.withProvider(Settings.System.CONTENT_URI, settings);
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
public static FakeFactory register(final Context applicationContext) {
|
||||
final FakeContext context = new FakeContext(applicationContext);
|
||||
return registerWithFakeContext(applicationContext, context);
|
||||
}
|
||||
|
||||
public static FakeFactory registerWithoutFakeContext(final Context applicationContext) {
|
||||
return registerWithFakeContext(applicationContext, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequiredPermissionsAcquired() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context getApplicationContext() {
|
||||
return ((mFakeContext != null) ? mFakeContext : mContext );
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataModel getDataModel() {
|
||||
return mDataModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BugleGservices getBugleGservices() {
|
||||
return mBugleGservices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuglePrefs getApplicationPrefs() {
|
||||
return mBuglePrefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuglePrefs getWidgetPrefs() {
|
||||
return mBuglePrefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuglePrefs getSubscriptionPrefs(final int subId) {
|
||||
return mBuglePrefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UIIntents getUIIntents() {
|
||||
return mUIIntents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryCacheManager getMemoryCacheManager() {
|
||||
return mMemoryCacheManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaResourceManager getMediaResourceManager() {
|
||||
return mMediaResourceManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaCacheManager getMediaCacheManager() {
|
||||
return mMediaCacheManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhoneUtils getPhoneUtils(final int subId) {
|
||||
return mPhoneUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaUtil getMediaUtil() {
|
||||
return mMediaUtil;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BugleCarrierConfigValuesLoader getCarrierConfigValuesLoader() {
|
||||
return mCarrierConfigValuesLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactContentObserver getContactContentObserver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reclaimMemory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResume() {
|
||||
}
|
||||
|
||||
public FakeFactory withDataModel(final DataModel dataModel) {
|
||||
this.mDataModel = dataModel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withUIIntents(final UIIntents uiIntents) {
|
||||
this.mUIIntents = uiIntents;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withMemoryCacheManager(final MemoryCacheManager memoryCacheManager) {
|
||||
this.mMemoryCacheManager = memoryCacheManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withBugleGservices(final BugleGservices bugleGservices) {
|
||||
this.mBugleGservices = bugleGservices;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withMediaCacheManager(final MediaCacheManager mediaCacheManager) {
|
||||
this.mMediaCacheManager = mediaCacheManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withProvider(final Uri uri, final ContentProvider provider) {
|
||||
if (mFakeContext != null) {
|
||||
mFakeContext.addContentProvider(uri.getAuthority(), provider);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withDefaultProvider(final Uri uri) {
|
||||
if (mFakeContext != null) {
|
||||
mFakeContext.addDefaultProvider(this.mContext, uri);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withMediaUtil(final MediaUtil mediaUtil) {
|
||||
this.mMediaUtil = mediaUtil;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeFactory withCarrierConfigValuesLoader(
|
||||
final BugleCarrierConfigValuesLoader carrierConfigValuesLoader) {
|
||||
this.mCarrierConfigValuesLoader = carrierConfigValuesLoader;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
import android.test.InstrumentationTestCase;
|
||||
|
||||
import com.android.messaging.util.LogUtil;
|
||||
import com.android.messaging.widget.BugleWidgetProvider;
|
||||
import com.android.messaging.widget.WidgetConversationProvider;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* Helpers that can be called from all test base classes to 'reset' state and prevent as much as
|
||||
* possible having side effects leak from one test to another.
|
||||
*/
|
||||
public class TestUtil {
|
||||
public static void testSetup(final Context context, final TestCase testCase) {
|
||||
haltIfTestsAreNotAbleToRun(context);
|
||||
|
||||
// Workaround to get mockito to work.
|
||||
// See https://code.google.com/p/dexmaker/issues/detail?id=2. TODO: Apparently
|
||||
// solvable by using a different runner.
|
||||
System.setProperty("dexmaker.dexcache",
|
||||
context.getCacheDir().getPath());
|
||||
|
||||
// Initialize @Mock objects.
|
||||
MockitoAnnotations.initMocks(testCase);
|
||||
|
||||
// Tests have to explicitly override this
|
||||
Factory.setInstance(null);
|
||||
}
|
||||
|
||||
public static void testTeardown(final TestCase testCase) {
|
||||
if (testCase instanceof InstrumentationTestCase) {
|
||||
// Make sure the test case is finished running or we'll get NPEs when accessing
|
||||
// Fragment.get()
|
||||
((InstrumentationTestCase) testCase).getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
Factory.setInstance(null);
|
||||
}
|
||||
|
||||
private static void haltIfTestsAreNotAbleToRun(final Context context) {
|
||||
final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
if (!pm.isScreenOn()) {
|
||||
// Ideally we could turn it on for you using the WindowManager, but we currently run
|
||||
// the tests independently of the activity life cycle.
|
||||
LogUtil.wtf(LogUtil.BUGLE_TAG, "You need to turn on your screen to run tests!");
|
||||
}
|
||||
|
||||
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||
int [] conversationWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context,
|
||||
WidgetConversationProvider.class));
|
||||
int [] conversationListWidgetIds = appWidgetManager.getAppWidgetIds(new
|
||||
ComponentName(context, BugleWidgetProvider.class));
|
||||
|
||||
if ((conversationWidgetIds.length > 0) || (conversationListWidgetIds.length > 0)) {
|
||||
// Currently widgets asynchronously access our content providers and singletons which
|
||||
// interacts badly with our test setup and tear down.
|
||||
LogUtil.wtf(LogUtil.BUGLE_TAG, "You currently can't reliably run unit tests" +
|
||||
" with a Messaging widget on your desktop!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.datamodel.binding.BindableData;
|
||||
import com.android.messaging.datamodel.binding.Binding;
|
||||
import com.android.messaging.datamodel.binding.BindingBase;
|
||||
import com.android.messaging.datamodel.binding.ImmutableBindingRef;
|
||||
|
||||
/**
|
||||
* Test binding
|
||||
*/
|
||||
@SmallTest
|
||||
public class BindingTest extends BugleTestCase {
|
||||
private static final Object TEST_DATA_ID = "myDataId";
|
||||
private static final Object YOUR_DATA_ID = "yourDataId";
|
||||
|
||||
public void testBindingStartsUnbound() {
|
||||
final Binding<TestBindableData> binding = BindingBase.createBinding(this);
|
||||
assertNull(binding.getBindingId());
|
||||
}
|
||||
|
||||
public void testDataStartsUnbound() {
|
||||
final TestBindableData data = new TestBindableData(TEST_DATA_ID);
|
||||
assertFalse(data.isBound());
|
||||
}
|
||||
|
||||
public void testBindingUpdatesDataAndBindee() {
|
||||
final Binding<TestBindableData> binding = BindingBase.createBinding(this);
|
||||
final TestBindableData data = new TestBindableData(TEST_DATA_ID);
|
||||
binding.bind(data);
|
||||
assertTrue(binding.isBound());
|
||||
assertEquals(binding.getData(), data);
|
||||
assertTrue(data.isBound(binding.getBindingId()));
|
||||
assertFalse(data.isBound("SomeRandomString"));
|
||||
assertNotNull(binding.getBindingId());
|
||||
assertFalse(data.mListenersUnregistered);
|
||||
}
|
||||
|
||||
public void testRebindingFails() {
|
||||
final Binding<TestBindableData> binding = BindingBase.createBinding(this);
|
||||
final TestBindableData yours = new TestBindableData(YOUR_DATA_ID);
|
||||
binding.bind(yours);
|
||||
assertEquals(binding.getData(), yours);
|
||||
assertTrue(yours.isBound(binding.getBindingId()));
|
||||
final TestBindableData data = new TestBindableData(TEST_DATA_ID);
|
||||
try {
|
||||
binding.bind(data);
|
||||
fail();
|
||||
} catch (final IllegalStateException e) {
|
||||
}
|
||||
assertTrue(binding.isBound());
|
||||
assertEquals(binding.getData(), yours);
|
||||
assertTrue(yours.isBound(binding.getBindingId()));
|
||||
}
|
||||
|
||||
public void testUnbindingClearsDataAndBindee() {
|
||||
final Binding<TestBindableData> binding = BindingBase.createBinding(this);
|
||||
final TestBindableData data = new TestBindableData(TEST_DATA_ID);
|
||||
binding.bind(data);
|
||||
assertTrue(data.isBound(binding.getBindingId()));
|
||||
assertTrue(binding.isBound());
|
||||
binding.unbind();
|
||||
try {
|
||||
final TestBindableData other = binding.getData();
|
||||
fail();
|
||||
} catch (final IllegalStateException e) {
|
||||
}
|
||||
assertFalse(data.isBound());
|
||||
assertNull(binding.getBindingId());
|
||||
assertTrue(data.mListenersUnregistered);
|
||||
}
|
||||
|
||||
public void testUnbindingAndRebinding() {
|
||||
final Binding<TestBindableData> binding = BindingBase.createBinding(this);
|
||||
final TestBindableData yours = new TestBindableData(YOUR_DATA_ID);
|
||||
binding.bind(yours);
|
||||
assertEquals(binding.getData(), yours);
|
||||
assertTrue(yours.isBound(binding.getBindingId()));
|
||||
binding.unbind();
|
||||
assertFalse(yours.isBound());
|
||||
assertNull(binding.getBindingId());
|
||||
|
||||
final TestBindableData data = new TestBindableData(TEST_DATA_ID);
|
||||
binding.bind(data);
|
||||
assertEquals(binding.getData(), data);
|
||||
assertTrue(data.isBound(binding.getBindingId()));
|
||||
assertFalse(data.isBound("SomeRandomString"));
|
||||
assertTrue(binding.isBound());
|
||||
assertNotNull(binding.getBindingId());
|
||||
}
|
||||
|
||||
public void testBindingReference() {
|
||||
final Binding<TestBindableData> binding = BindingBase.createBinding(this);
|
||||
final TestBindableData data = new TestBindableData(TEST_DATA_ID);
|
||||
binding.bind(data);
|
||||
assertEquals(binding.getData(), data);
|
||||
assertTrue(data.isBound(binding.getBindingId()));
|
||||
|
||||
final ImmutableBindingRef<TestBindableData> bindingRef =
|
||||
BindingBase.createBindingReference(binding);
|
||||
assertEquals(bindingRef.getData(), data);
|
||||
assertTrue(data.isBound(bindingRef.getBindingId()));
|
||||
|
||||
binding.unbind();
|
||||
assertFalse(binding.isBound());
|
||||
assertNull(binding.getBindingId());
|
||||
assertFalse(bindingRef.isBound());
|
||||
assertNull(bindingRef.getBindingId());
|
||||
}
|
||||
|
||||
static class TestBindableData extends BindableData {
|
||||
private final Object mDataId;
|
||||
public boolean mListenersUnregistered;
|
||||
|
||||
public TestBindableData(final Object dataId) {
|
||||
mDataId = dataId;
|
||||
mListenersUnregistered = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterListeners() {
|
||||
mListenersUnregistered = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBound() {
|
||||
return super.isBound();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@SmallTest
|
||||
public class BitmapPoolTest extends BugleTestCase {
|
||||
private static final int POOL_SIZE = 5;
|
||||
private static final int IMAGE_DIM = 1;
|
||||
private static final String NAME = "BitmapPoolTest";
|
||||
|
||||
@Mock private MemoryCacheManager mockMemoryCacheManager;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getTestContext())
|
||||
.withMemoryCacheManager(mockMemoryCacheManager);
|
||||
}
|
||||
|
||||
private Set<Bitmap> fillPoolAndGetPoolContents(final BitmapPool pool, final int width,
|
||||
final int height) {
|
||||
final Set<Bitmap> returnedBitmaps = new HashSet<Bitmap>();
|
||||
for (int i = 0; i < POOL_SIZE; i++) {
|
||||
final Bitmap temp = pool.createOrReuseBitmap(width, height);
|
||||
assertFalse(returnedBitmaps.contains(temp));
|
||||
returnedBitmaps.add(temp);
|
||||
}
|
||||
for (final Bitmap b : returnedBitmaps) {
|
||||
pool.reclaimBitmap(b);
|
||||
}
|
||||
assertTrue(pool.isFull(width, height));
|
||||
return returnedBitmaps;
|
||||
}
|
||||
|
||||
public void testCreateAndPutBackInPoolTest() {
|
||||
final BitmapPool pool = new BitmapPool(POOL_SIZE, NAME);
|
||||
final Bitmap bitmap = pool.createOrReuseBitmap(IMAGE_DIM, IMAGE_DIM);
|
||||
assertFalse(bitmap.isRecycled());
|
||||
assertFalse(pool.isFull(IMAGE_DIM, IMAGE_DIM));
|
||||
pool.reclaimBitmap(bitmap);
|
||||
|
||||
// Don't recycle because the pool isn't full yet.
|
||||
assertFalse(bitmap.isRecycled());
|
||||
}
|
||||
|
||||
public void testCreateBeyondFullAndCheckReuseTest() {
|
||||
final BitmapPool pool = new BitmapPool(POOL_SIZE, NAME);
|
||||
final Set<Bitmap> returnedBitmaps =
|
||||
fillPoolAndGetPoolContents(pool, IMAGE_DIM, IMAGE_DIM);
|
||||
final Bitmap overflowBitmap = pool.createOrReuseBitmap(IMAGE_DIM, IMAGE_DIM);
|
||||
assertFalse(overflowBitmap.isRecycled());
|
||||
assertTrue(returnedBitmaps.contains(overflowBitmap));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that we have the correct options to create mutable for bitmap pool reuse.
|
||||
*/
|
||||
public void testAssertBitmapOptionsAreMutable() {
|
||||
final BitmapFactory.Options options =
|
||||
BitmapPool.getBitmapOptionsForPool(false, IMAGE_DIM, IMAGE_DIM);
|
||||
assertTrue(options.inMutable);
|
||||
}
|
||||
|
||||
public void testDecodeFromResourceBitmap() {
|
||||
final BitmapPool pool = new BitmapPool(POOL_SIZE, NAME);
|
||||
final BitmapFactory.Options options =
|
||||
BitmapPool.getBitmapOptionsForPool(true, IMAGE_DIM, IMAGE_DIM);
|
||||
final Resources resources = getContext().getResources();
|
||||
final Bitmap resourceBitmap = pool.decodeSampledBitmapFromResource(
|
||||
R.drawable.msg_bubble_incoming, resources, options, IMAGE_DIM, IMAGE_DIM);
|
||||
assertNotNull(resourceBitmap);
|
||||
assertTrue(resourceBitmap.getByteCount() > 0);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import android.app.Service;
|
||||
import android.test.ServiceTestCase;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.TestUtil;
|
||||
|
||||
|
||||
/*
|
||||
* Base class for service tests that takes care of housekeeping that is commong amongst our service
|
||||
* test case.
|
||||
*/
|
||||
public abstract class BugleServiceTestCase<T extends Service> extends ServiceTestCase<T> {
|
||||
|
||||
static {
|
||||
// Set flag during loading of test cases to prevent application initialization starting
|
||||
BugleTestCase.setTestsRunning();
|
||||
}
|
||||
|
||||
public BugleServiceTestCase(final Class<T> serviceClass) {
|
||||
super(serviceClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
TestUtil.testSetup(getContext(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
TestUtil.testTeardown(this);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
|
||||
@SmallTest
|
||||
public class ConversationListTest extends BugleTestCase {
|
||||
public void testTesting() {
|
||||
assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.data.ConversationData;
|
||||
import com.android.messaging.datamodel.data.ConversationData.ConversationDataListener;
|
||||
import com.android.messaging.datamodel.data.ConversationListData;
|
||||
import com.android.messaging.datamodel.data.ConversationListData.ConversationListDataListener;
|
||||
|
||||
import org.mockito.Mock;
|
||||
|
||||
public class DataModelTest extends BugleTestCase {
|
||||
|
||||
DataModel dataModel;
|
||||
@Mock protected ConversationDataListener mockConversationDataListener;
|
||||
@Mock protected ConversationListDataListener mockConversationListDataListener;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory factory = FakeFactory.register(mContext);
|
||||
dataModel = new DataModelImpl(getTestContext());
|
||||
factory.withDataModel(dataModel);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testCreateConversationList() {
|
||||
final ConversationListData list = dataModel.createConversationListData(getContext(),
|
||||
mockConversationListDataListener, true);
|
||||
assertTrue(list instanceof ConversationListData);
|
||||
final ConversationData conv = dataModel.createConversationData(getContext(),
|
||||
mockConversationDataListener, "testConversation");
|
||||
assertTrue(conv instanceof ConversationData);
|
||||
}
|
||||
|
||||
private static final String FOCUSED_CONV_ID = "focused_conv_id";
|
||||
|
||||
@SmallTest
|
||||
public void testFocusedConversationIsObservable() {
|
||||
dataModel.setFocusedConversation(FOCUSED_CONV_ID);
|
||||
assertTrue(dataModel.isNewMessageObservable(FOCUSED_CONV_ID));
|
||||
dataModel.setFocusedConversation(null);
|
||||
assertFalse(dataModel.isNewMessageObservable(FOCUSED_CONV_ID));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testConversationIsObservableInList() {
|
||||
dataModel.setConversationListScrolledToNewestConversation(true);
|
||||
assertTrue(dataModel.isNewMessageObservable(FOCUSED_CONV_ID));
|
||||
dataModel.setConversationListScrolledToNewestConversation(false);
|
||||
assertFalse(dataModel.isNewMessageObservable(FOCUSED_CONV_ID));
|
||||
}
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.test.mock.MockCursor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A simple in memory fake cursor that can be used for UI tests.
|
||||
*/
|
||||
public class FakeCursor extends MockCursor {
|
||||
private final ArrayList<Integer> mProjection;
|
||||
private final String[] mColumnNamesOfData;
|
||||
private final Object[][] mData;
|
||||
private int mIndex;
|
||||
|
||||
public FakeCursor(final String[] projection, final String[] columnNames,
|
||||
final Object[][] data) {
|
||||
mColumnNamesOfData = columnNames;
|
||||
mData = data;
|
||||
mIndex = -1;
|
||||
mProjection = new ArrayList<Integer>(projection.length);
|
||||
for (final String column : projection) {
|
||||
mProjection.add(getColumnIndex(column));
|
||||
}
|
||||
}
|
||||
|
||||
public Object getAt(final String columnName, final int row) {
|
||||
final int dataIdx = getColumnIndex(columnName);
|
||||
return (dataIdx < 0 || row < 0 || row >= mData.length) ? 0 : mData[row][dataIdx];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mData.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFirst() {
|
||||
return mIndex == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLast() {
|
||||
return mIndex == mData.length - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToFirst() {
|
||||
if (mData.length == 0) {
|
||||
return false;
|
||||
}
|
||||
mIndex = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPosition(final int position) {
|
||||
if (position < 0 || position >= mData.length) {
|
||||
return false;
|
||||
}
|
||||
mIndex = position;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPosition() {
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPrevious() {
|
||||
if (mIndex <= 0) {
|
||||
return false;
|
||||
}
|
||||
mIndex--;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToNext() {
|
||||
if (mIndex == mData.length - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mIndex++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return mColumnNamesOfData.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnIndex(final String columnName) {
|
||||
for (int i = 0 ; i < mColumnNamesOfData.length ; i++) {
|
||||
if (mColumnNamesOfData[i].equals(columnName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnIndexOrThrow(final String columnName) {
|
||||
final int result = getColumnIndex(columnName);
|
||||
if (result == -1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(final int columnIndex) {
|
||||
final int dataIdx = mProjection.get(columnIndex);
|
||||
final Object obj = (dataIdx < 0 ? null : mData[mIndex][dataIdx]);
|
||||
return (obj == null ? null : obj.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final int columnIndex) {
|
||||
final int dataIdx = mProjection.get(columnIndex);
|
||||
return (dataIdx < 0 ? 0 : (Integer) mData[mIndex][dataIdx]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(final int columnIndex) {
|
||||
final int dataIdx = mProjection.get(columnIndex);
|
||||
return (dataIdx < 0 ? 0 : (Long) mData[mIndex][dataIdx]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getExtras() { return null; }
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.test.RenamingDelegatingContext;
|
||||
|
||||
import com.android.messaging.datamodel.action.ActionService;
|
||||
import com.android.messaging.datamodel.action.BackgroundWorker;
|
||||
import com.android.messaging.datamodel.data.BlockedParticipantsData;
|
||||
import com.android.messaging.datamodel.data.BlockedParticipantsData.BlockedParticipantsDataListener;
|
||||
import com.android.messaging.datamodel.data.ContactListItemData;
|
||||
import com.android.messaging.datamodel.data.ContactPickerData;
|
||||
import com.android.messaging.datamodel.data.ContactPickerData.ContactPickerDataListener;
|
||||
import com.android.messaging.datamodel.data.ConversationData;
|
||||
import com.android.messaging.datamodel.data.ConversationData.ConversationDataListener;
|
||||
import com.android.messaging.datamodel.data.ConversationListData;
|
||||
import com.android.messaging.datamodel.data.ConversationListData.ConversationListDataListener;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData;
|
||||
import com.android.messaging.datamodel.data.GalleryGridItemData;
|
||||
import com.android.messaging.datamodel.data.LaunchConversationData;
|
||||
import com.android.messaging.datamodel.data.LaunchConversationData.LaunchConversationDataListener;
|
||||
import com.android.messaging.datamodel.data.MediaPickerData;
|
||||
import com.android.messaging.datamodel.data.MessagePartData;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.datamodel.data.ParticipantListItemData;
|
||||
import com.android.messaging.datamodel.data.PeopleAndOptionsData;
|
||||
import com.android.messaging.datamodel.data.PeopleAndOptionsData.PeopleAndOptionsDataListener;
|
||||
import com.android.messaging.datamodel.data.PeopleOptionsItemData;
|
||||
import com.android.messaging.datamodel.data.SettingsData;
|
||||
import com.android.messaging.datamodel.data.SettingsData.SettingsDataListener;
|
||||
import com.android.messaging.datamodel.data.SubscriptionListData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.datamodel.data.VCardContactItemData;
|
||||
|
||||
public class FakeDataModel extends DataModel {
|
||||
private BackgroundWorker mWorker;
|
||||
private ActionService mActionService;
|
||||
private final DatabaseHelper mDatabaseHelper;
|
||||
private ConversationListData mConversationListData;
|
||||
private ContactPickerData mContactPickerData;
|
||||
private MediaPickerData mMediaPickerData;
|
||||
private PeopleAndOptionsData mPeopleAndOptionsData;
|
||||
private SyncManager mSyncManager;
|
||||
private SettingsData mSettingsData;
|
||||
private DraftMessageData mDraftMessageData;
|
||||
|
||||
public FakeDataModel(final Context context) {
|
||||
super();
|
||||
if (context instanceof RenamingDelegatingContext) {
|
||||
mDatabaseHelper = DatabaseHelper.getNewInstanceForTest(context);
|
||||
} else {
|
||||
mDatabaseHelper = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackgroundWorker getBackgroundWorkerForActionService() {
|
||||
return mWorker;
|
||||
}
|
||||
|
||||
public FakeDataModel withBackgroundWorkerForActionService(final BackgroundWorker worker) {
|
||||
mWorker = worker;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withActionService(final ActionService ActionService) {
|
||||
mActionService = ActionService;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withConversationListData(final ConversationListData conversationListData) {
|
||||
mConversationListData = conversationListData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withContactPickerData(final ContactPickerData contactPickerData) {
|
||||
mContactPickerData = contactPickerData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withMediaPickerData(final MediaPickerData mediaPickerData) {
|
||||
mMediaPickerData = mediaPickerData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withSyncManager(final SyncManager syncManager) {
|
||||
mSyncManager = syncManager;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withPeopleAndOptionsData(final PeopleAndOptionsData peopleAndOptionsData) {
|
||||
mPeopleAndOptionsData = peopleAndOptionsData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withSettingsData(final SettingsData settingsData) {
|
||||
mSettingsData = settingsData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FakeDataModel withDraftMessageData(final DraftMessageData draftMessageData) {
|
||||
mDraftMessageData = draftMessageData;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationListData createConversationListData(final Context context,
|
||||
final ConversationListDataListener listener, final boolean archivedMode) {
|
||||
return mConversationListData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversationData createConversationData(final Context context,
|
||||
final ConversationDataListener listener, final String conversationId) {
|
||||
throw new IllegalStateException("Add withXXX or mock this method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactListItemData createContactListItemData() {
|
||||
// This is a lightweight data holder object for each individual list item for which
|
||||
// we don't perform any data request, so we can directly return a new instance.
|
||||
return new ContactListItemData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContactPickerData createContactPickerData(final Context context,
|
||||
final ContactPickerDataListener listener) {
|
||||
return mContactPickerData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaPickerData createMediaPickerData(final Context context) {
|
||||
return mMediaPickerData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GalleryGridItemData createGalleryGridItemData() {
|
||||
// This is a lightweight data holder object for each individual grid item for which
|
||||
// we don't perform any data request, so we can directly return a new instance.
|
||||
return new GalleryGridItemData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LaunchConversationData createLaunchConversationData(
|
||||
final LaunchConversationDataListener listener) {
|
||||
return new LaunchConversationData(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeopleOptionsItemData createPeopleOptionsItemData(final Context context) {
|
||||
return new PeopleOptionsItemData(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeopleAndOptionsData createPeopleAndOptionsData(final String conversationId,
|
||||
final Context context, final PeopleAndOptionsDataListener listener) {
|
||||
return mPeopleAndOptionsData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VCardContactItemData createVCardContactItemData(final Context context,
|
||||
final MessagePartData data) {
|
||||
return new VCardContactItemData(context, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VCardContactItemData createVCardContactItemData(final Context context,
|
||||
final Uri vCardUri) {
|
||||
return new VCardContactItemData(context, vCardUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParticipantListItemData createParticipantListItemData(
|
||||
final ParticipantData participant) {
|
||||
return new ParticipantListItemData(participant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubscriptionListData createSubscriptonListData(Context context) {
|
||||
return new SubscriptionListData(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SettingsData createSettingsData(Context context, SettingsDataListener listener) {
|
||||
return mSettingsData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DraftMessageData createDraftMessageData(String conversationId) {
|
||||
return mDraftMessageData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionService getActionService() {
|
||||
return mActionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SyncManager getSyncManager() {
|
||||
return mSyncManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseWrapper getDatabase() {
|
||||
// Note this will crash unless the application context is redirected...
|
||||
// This is by design so that tests do not inadvertently use the real database
|
||||
return mDatabaseHelper.getDatabase();
|
||||
}
|
||||
|
||||
@Override
|
||||
void onCreateTables(final SQLiteDatabase db) {
|
||||
TestDataFactory.createTestData(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResume() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationCreated() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockedParticipantsData createBlockedParticipantsData(Context context,
|
||||
BlockedParticipantsDataListener listener) {
|
||||
return new BlockedParticipantsData(context, listener);
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.util.ContactUtil;
|
||||
|
||||
@SmallTest
|
||||
public class FrequentContactsCursorBuilderTest extends BugleTestCase {
|
||||
|
||||
private void verifyBuiltCursor(final Cursor expected, final Cursor actual) {
|
||||
final int rowCount = expected.getCount();
|
||||
final int columnCount = expected.getColumnCount();
|
||||
assertEquals(rowCount, actual.getCount());
|
||||
assertEquals(columnCount, actual.getColumnCount());
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
expected.moveToPosition(i);
|
||||
actual.moveToPosition(i);
|
||||
assertEquals(expected.getLong(ContactUtil.INDEX_DATA_ID),
|
||||
actual.getLong(ContactUtil.INDEX_DATA_ID));
|
||||
assertEquals(expected.getLong(ContactUtil.INDEX_CONTACT_ID),
|
||||
actual.getLong(ContactUtil.INDEX_CONTACT_ID));
|
||||
assertEquals(expected.getString(ContactUtil.INDEX_LOOKUP_KEY),
|
||||
actual.getString(ContactUtil.INDEX_LOOKUP_KEY));
|
||||
assertEquals(expected.getString(ContactUtil.INDEX_DISPLAY_NAME),
|
||||
actual.getString(ContactUtil.INDEX_DISPLAY_NAME));
|
||||
assertEquals(expected.getString(ContactUtil.INDEX_PHOTO_URI),
|
||||
actual.getString(ContactUtil.INDEX_PHOTO_URI));
|
||||
assertEquals(expected.getString(ContactUtil.INDEX_PHONE_EMAIL),
|
||||
actual.getString(ContactUtil.INDEX_PHONE_EMAIL));
|
||||
assertEquals(expected.getInt(ContactUtil.INDEX_PHONE_EMAIL_TYPE),
|
||||
actual.getInt(ContactUtil.INDEX_PHONE_EMAIL_TYPE));
|
||||
assertEquals(expected.getString(ContactUtil.INDEX_PHONE_EMAIL_LABEL),
|
||||
actual.getString(ContactUtil.INDEX_PHONE_EMAIL_LABEL));
|
||||
}
|
||||
}
|
||||
|
||||
public void testIncompleteBuild() {
|
||||
final FrequentContactsCursorBuilder builder = new FrequentContactsCursorBuilder();
|
||||
assertNull(builder.build());
|
||||
assertNull(builder.setFrequents(TestDataFactory.getStrequentContactsCursor()).build());
|
||||
builder.resetBuilder();
|
||||
assertNull(builder.build());
|
||||
assertNull(builder.setAllContacts(TestDataFactory.getAllContactListCursor()).build());
|
||||
}
|
||||
|
||||
public void testBuildOnce() {
|
||||
final Cursor cursor = new FrequentContactsCursorBuilder()
|
||||
.setAllContacts(TestDataFactory.getAllContactListCursor())
|
||||
.setFrequents(TestDataFactory.getStrequentContactsCursor())
|
||||
.build();
|
||||
assertNotNull(cursor);
|
||||
verifyBuiltCursor(TestDataFactory.getFrequentContactListCursor(), cursor);
|
||||
}
|
||||
|
||||
public void testBuildTwice() {
|
||||
final FrequentContactsCursorBuilder builder = new FrequentContactsCursorBuilder();
|
||||
final Cursor firstCursor = builder
|
||||
.setAllContacts(TestDataFactory.getAllContactListCursor())
|
||||
.setFrequents(TestDataFactory.getStrequentContactsCursor())
|
||||
.build();
|
||||
assertNotNull(firstCursor);
|
||||
builder.resetBuilder();
|
||||
assertNull(builder.build());
|
||||
|
||||
final Cursor secondCursor = builder
|
||||
.setAllContacts(TestDataFactory.getAllContactListCursor())
|
||||
.setFrequents(TestDataFactory.getStrequentContactsCursor())
|
||||
.build();
|
||||
assertNotNull(firstCursor);
|
||||
verifyBuiltCursor(TestDataFactory.getFrequentContactListCursor(), secondCursor);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.datamodel.MemoryCacheManager.MemoryCache;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@SmallTest
|
||||
public class MemoryCacheManagerTest extends AndroidTestCase {
|
||||
|
||||
public void testRegisterCachesGetReclaimed() {
|
||||
final MemoryCache mockMemoryCache = Mockito.mock(MemoryCache.class);
|
||||
final MemoryCache otherMockMemoryCache = Mockito.mock(MemoryCache.class);
|
||||
final MemoryCacheManager memoryCacheManager = new MemoryCacheManager();
|
||||
|
||||
memoryCacheManager.registerMemoryCache(mockMemoryCache);
|
||||
memoryCacheManager.registerMemoryCache(otherMockMemoryCache);
|
||||
memoryCacheManager.reclaimMemory();
|
||||
memoryCacheManager.unregisterMemoryCache(otherMockMemoryCache);
|
||||
memoryCacheManager.reclaimMemory();
|
||||
|
||||
Mockito.verify(mockMemoryCache, Mockito.times(2)).reclaim();
|
||||
Mockito.verify(otherMockMemoryCache, Mockito.times(1)).reclaim();
|
||||
}
|
||||
}
|
||||
@@ -1,285 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeContentProvider;
|
||||
import com.android.messaging.FakeContext;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ParticipantColumns;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.datamodel.data.ParticipantData.ParticipantsQuery;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.ContactUtil;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.mockito.Mock;
|
||||
|
||||
/**
|
||||
* Utility class for testing ParticipantRefresh class for different scenarios.
|
||||
*/
|
||||
@SmallTest
|
||||
public class ParticipantRefreshTest extends BugleTestCase {
|
||||
private FakeContext mContext;
|
||||
FakeFactory mFakeFactory;
|
||||
@Mock protected UIIntents mMockUIIntents;
|
||||
protected FakeDataModel mFakeDataModel;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mContext = new FakeContext(getTestContext());
|
||||
|
||||
final ContentProvider provider = new MessagingContentProvider();
|
||||
provider.attachInfo(mContext, null);
|
||||
mContext.addContentProvider(MessagingContentProvider.AUTHORITY, provider);
|
||||
|
||||
mFakeDataModel = new FakeDataModel(mContext);
|
||||
mFakeFactory = FakeFactory.registerWithFakeContext(getTestContext(), mContext)
|
||||
.withDataModel(mFakeDataModel)
|
||||
.withUIIntents(mMockUIIntents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some phonelookup result into take PhoneLookup content provider. This will be
|
||||
* used for doing phone lookup during participant refresh.
|
||||
*/
|
||||
private void addPhoneLookup(final String phone, final Object[][] lookupResult) {
|
||||
final Uri uri = ContactUtil.lookupPhone(mContext, phone).getUri();
|
||||
final FakeContentProvider phoneLookup = new FakeContentProvider(mContext,
|
||||
uri, false);
|
||||
phoneLookup.addOverrideData(uri, null, null, ContactUtil.PhoneLookupQuery.PROJECTION,
|
||||
lookupResult);
|
||||
mFakeFactory.withProvider(uri, phoneLookup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add some participant to test database.
|
||||
*/
|
||||
private void addParticipant(final String normalizedDestination, final long contactId,
|
||||
final String name, final String photoUrl) {
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
final ContentValues values = new ContentValues();
|
||||
|
||||
values.put(ParticipantColumns.NORMALIZED_DESTINATION, normalizedDestination);
|
||||
values.put(ParticipantColumns.CONTACT_ID, contactId);
|
||||
values.put(ParticipantColumns.FULL_NAME, name);
|
||||
values.put(ParticipantColumns.PROFILE_PHOTO_URI, photoUrl);
|
||||
|
||||
db.beginTransaction();
|
||||
try {
|
||||
db.insert(DatabaseHelper.PARTICIPANTS_TABLE, null, values);
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that participant in the database has expected contacdtId, name and photoUrl fields.
|
||||
*/
|
||||
private void verifyParticipant(final String normalizedDestination, final long contactId,
|
||||
final String name, final String photoUrl) {
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final String selection = ParticipantColumns.NORMALIZED_DESTINATION + "=?";
|
||||
final String[] selectionArgs = new String[] { normalizedDestination };
|
||||
|
||||
final Cursor cursor = db.query(DatabaseHelper.PARTICIPANTS_TABLE,
|
||||
ParticipantsQuery.PROJECTION, selection, selectionArgs, null, null, null);
|
||||
|
||||
if (cursor == null || cursor.getCount() != 1) {
|
||||
Assert.fail("Should have participants for:" + normalizedDestination);
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.moveToFirst();
|
||||
final int currentContactId = cursor.getInt(ParticipantsQuery.INDEX_CONTACT_ID);
|
||||
final String currentName = cursor.getString(ParticipantsQuery.INDEX_FULL_NAME);
|
||||
final String currentPhotoUrl =
|
||||
cursor.getString(ParticipantsQuery.INDEX_PROFILE_PHOTO_URI);
|
||||
if (currentContactId != contactId) {
|
||||
Assert.fail("Contact Id doesn't match. normalizedNumber=" + normalizedDestination +
|
||||
" expected=" + contactId + " actual=" + currentContactId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextUtils.equals(currentName, name)) {
|
||||
Assert.fail("Name doesn't match. normalizedNumber=" + normalizedDestination +
|
||||
" expected=" + name + " actual=" + currentName);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TextUtils.equals(currentPhotoUrl, photoUrl)) {
|
||||
Assert.fail("Contact Id doesn't match. normalizedNumber=" + normalizedDestination +
|
||||
" expected=" + photoUrl + " actual=" + currentPhotoUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that incremental refresh will resolve previously not resolved participants.
|
||||
*/
|
||||
public void testIncrementalRefreshNotResolvedSingleMatch() {
|
||||
addParticipant("650-123-1233", ParticipantData.PARTICIPANT_CONTACT_ID_NOT_RESOLVED,
|
||||
null, null);
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_INCREMENTAL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that incremental refresh will resolve previously not resolved participants.
|
||||
*/
|
||||
public void testIncrementalRefreshNotResolvedMultiMatch() {
|
||||
addParticipant("650-123-1233", ParticipantData.PARTICIPANT_CONTACT_ID_NOT_RESOLVED,
|
||||
null, null);
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null },
|
||||
{ 2L, "Joe", "content://photo/joe", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_INCREMENTAL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that incremental refresh will not touch already-resolved participants.
|
||||
*/
|
||||
public void testIncrementalRefreshResolvedSingleMatch() {
|
||||
addParticipant("650-123-1233", 1, "Joh", "content://photo/joh");
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_INCREMENTAL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that full refresh will correct already-resolved participants if needed
|
||||
*/
|
||||
public void testFullRefreshResolvedSingleMatch() {
|
||||
addParticipant("650-123-1233", 1, "Joh", "content://photo/joh");
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_FULL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that incremental refresh will not touch participant that is marked as not found.
|
||||
*/
|
||||
public void testIncrementalRefreshNotFound() {
|
||||
addParticipant("650-123-1233", ParticipantData.PARTICIPANT_CONTACT_ID_NOT_FOUND,
|
||||
null, null);
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_INCREMENTAL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that full refresh will resolve participant that is marked as not found.
|
||||
*/
|
||||
public void testFullRefreshNotFound() {
|
||||
addParticipant("650-123-1233", ParticipantData.PARTICIPANT_CONTACT_ID_NOT_FOUND,
|
||||
null, null);
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_FULL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that refresh take consideration of current contact_id when having multiple matches.
|
||||
*/
|
||||
public void testFullRefreshResolvedMultiMatch1() {
|
||||
addParticipant("650-123-1233", 1, "Joh", "content://photo/joh");
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null },
|
||||
{ 2L, "Joe", "content://photo/joe", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_FULL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that refresh take consideration of current contact_id when having multiple matches.
|
||||
*/
|
||||
public void testFullRefreshResolvedMultiMatch2() {
|
||||
addParticipant("650-123-1233", 2, "Joh", "content://photo/joh");
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null },
|
||||
{ 2L, "Joe", "content://photo/joe", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_FULL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that refresh take first contact in case current contact_id no longer matches.
|
||||
*/
|
||||
public void testFullRefreshResolvedMultiMatch3() {
|
||||
addParticipant("650-123-1233", 3, "Joh", "content://photo/joh");
|
||||
addPhoneLookup("650-123-1233", new Object[][] {
|
||||
{ 1L, "John", "content://photo/john", "650-123-1233", null, null, null },
|
||||
{ 2L, "Joe", "content://photo/joe", "650-123-1233", null, null, null }
|
||||
});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_FULL);
|
||||
verifyParticipant("650-123-1233", 1, "John", "content://photo/john");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that refresh take first contact in case current contact_id no longer matches.
|
||||
*/
|
||||
public void testFullRefreshResolvedBeforeButNotFoundNow() {
|
||||
addParticipant("650-123-1233", 1, "Joh", "content://photo/joh");
|
||||
addPhoneLookup("650-123-1233", new Object[][] {});
|
||||
|
||||
ParticipantRefresh.refreshParticipants(ParticipantRefresh.REFRESH_MODE_FULL);
|
||||
verifyParticipant("650-123-1233", ParticipantData.PARTICIPANT_CONTACT_ID_NOT_FOUND,
|
||||
null, null);
|
||||
}
|
||||
}
|
||||
@@ -1,429 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.action;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.Factory;
|
||||
import com.android.messaging.FakeContext;
|
||||
import com.android.messaging.FakeContext.FakeContextHost;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.BugleServiceTestCase;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.action.ActionMonitor.ActionCompletedListener;
|
||||
import com.android.messaging.datamodel.action.ActionMonitor.ActionExecutedListener;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.ResultTracker;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubBackgroundWorker;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubLoader;
|
||||
|
||||
@MediumTest
|
||||
public class ActionServiceSystemTest extends BugleServiceTestCase<ActionServiceImpl>
|
||||
implements ActionCompletedListener, ActionExecutedListener, FakeContextHost {
|
||||
private static final String TAG = "ActionServiceSystemTest";
|
||||
|
||||
static {
|
||||
// Set flag during loading of test cases to prevent application initialization starting
|
||||
BugleTestCase.setTestsRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionSucceeded(final ActionMonitor monitor,
|
||||
final Action action, final Object data, final Object result) {
|
||||
final TestChatAction test = (TestChatAction) action;
|
||||
assertEquals("Expect correct action parameter", parameter, test.parameter);
|
||||
final ResultTracker tracker = (ResultTracker) data;
|
||||
tracker.completionResult = result;
|
||||
synchronized(tracker) {
|
||||
tracker.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionFailed(final ActionMonitor monitor, final Action action,
|
||||
final Object data, final Object result) {
|
||||
final TestChatAction test = (TestChatAction) action;
|
||||
assertEquals("Expect correct action parameter", parameter, test.parameter);
|
||||
final ResultTracker tracker = (ResultTracker) data;
|
||||
tracker.completionResult = result;
|
||||
synchronized(tracker) {
|
||||
tracker.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionExecuted(final ActionMonitor monitor, final Action action,
|
||||
final Object data, final Object result) {
|
||||
final TestChatAction test = (TestChatAction) action;
|
||||
assertEquals("Expect correct action parameter", parameter, test.parameter);
|
||||
final ResultTracker tracker = (ResultTracker) data;
|
||||
tracker.executionResult = result;
|
||||
}
|
||||
|
||||
public ActionServiceSystemTest() {
|
||||
super(ActionServiceImpl.class);
|
||||
}
|
||||
|
||||
public void testChatActionSucceeds() {
|
||||
final ResultTracker tracker = new ResultTracker();
|
||||
|
||||
final ActionService service = DataModel.get().getActionService();
|
||||
final TestChatActionMonitor monitor = new TestChatActionMonitor(null, tracker, this, this);
|
||||
final TestChatAction initial = new TestChatAction(monitor.getActionKey(), parameter);
|
||||
|
||||
assertNull("Expect completion result to start null", tracker.completionResult);
|
||||
assertNull("Expect execution result to start null", tracker.executionResult);
|
||||
|
||||
final Parcel parcel = Parcel.obtain();
|
||||
parcel.writeParcelable(initial, 0);
|
||||
parcel.setDataPosition(0);
|
||||
final TestChatAction action = parcel.readParcelable(mContext.getClassLoader());
|
||||
|
||||
synchronized(mWorker) {
|
||||
try {
|
||||
action.start(monitor);
|
||||
// Wait for callback across threads
|
||||
mWorker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for execution", false);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals("Expect to see 1 server request queued", 1,
|
||||
mWorker.getRequestsMade().size());
|
||||
final Action request = mWorker.getRequestsMade().get(0);
|
||||
assertTrue("Expect Test type", request instanceof TestChatAction);
|
||||
|
||||
final Bundle response = new Bundle();
|
||||
response.putString(TestChatAction.RESPONSE_TEST, processResponseResult);
|
||||
synchronized(tracker) {
|
||||
try {
|
||||
request.markBackgroundWorkStarting();
|
||||
request.markBackgroundWorkQueued();
|
||||
|
||||
request.markBackgroundWorkStarting();
|
||||
request.markBackgroundCompletionQueued();
|
||||
service.handleResponseFromBackgroundWorker(request, response);
|
||||
// Wait for callback across threads
|
||||
tracker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for response processing", false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
//assertEquals("Expect execution result set", executeActionResult, tracker.executionResult);
|
||||
assertEquals("Expect completion result set", processResponseResult,
|
||||
tracker.completionResult);
|
||||
}
|
||||
|
||||
public void testChatActionFails() {
|
||||
final ResultTracker tracker = new ResultTracker();
|
||||
|
||||
final ActionService service = DataModel.get().getActionService();
|
||||
final TestChatActionMonitor monitor = new TestChatActionMonitor(null, tracker, this, this);
|
||||
final TestChatAction action = new TestChatAction(monitor.getActionKey(), parameter);
|
||||
|
||||
assertNull("Expect completion result to start null", tracker.completionResult);
|
||||
assertNull("Expect execution result to start null", tracker.executionResult);
|
||||
|
||||
synchronized(mWorker) {
|
||||
try {
|
||||
action.start(monitor);
|
||||
// Wait for callback across threads
|
||||
mWorker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for requests", false);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals("Expect to see 1 server request queued", 1,
|
||||
mWorker.getRequestsMade().size());
|
||||
final Action request = mWorker.getRequestsMade().get(0);
|
||||
assertTrue("Expect Test type", request instanceof TestChatAction);
|
||||
|
||||
synchronized(tracker) {
|
||||
try {
|
||||
request.markBackgroundWorkStarting();
|
||||
request.markBackgroundWorkQueued();
|
||||
|
||||
request.markBackgroundWorkStarting();
|
||||
request.markBackgroundCompletionQueued();
|
||||
service.handleFailureFromBackgroundWorker(request, new Exception("It went wrong"));
|
||||
// Wait for callback across threads
|
||||
tracker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for response processing", false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
//assertEquals("Expect execution result set", executeActionResult, tracker.executionResult);
|
||||
assertEquals("Expect completion result set", processFailureResult,
|
||||
tracker.completionResult);
|
||||
}
|
||||
|
||||
public void testChatActionNoMonitor() {
|
||||
final ActionService service = DataModel.get().getActionService();
|
||||
final TestChatAction action =
|
||||
new TestChatAction(Action.generateUniqueActionKey(null), parameter);
|
||||
|
||||
synchronized(mWorker) {
|
||||
try {
|
||||
action.start();
|
||||
// Wait for callback across threads
|
||||
mWorker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for execution", false);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals("Expect to see 1 server request queued", 1,
|
||||
mWorker.getRequestsMade().size());
|
||||
Action request = mWorker.getRequestsMade().get(0);
|
||||
assertTrue("Expect Test type", request instanceof TestChatAction);
|
||||
|
||||
final Bundle response = new Bundle();
|
||||
response.putString(TestChatAction.RESPONSE_TEST, processResponseResult);
|
||||
synchronized(mWorker) {
|
||||
try {
|
||||
service.handleResponseFromBackgroundWorker(request, response);
|
||||
// Wait for callback across threads
|
||||
mWorker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for response processing", false);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals("Expect to see second server request queued",
|
||||
2, mWorker.getRequestsMade().size());
|
||||
request = mWorker.getRequestsMade().get(1);
|
||||
assertTrue("Expect other type",
|
||||
request instanceof TestChatActionOther);
|
||||
}
|
||||
|
||||
public void testChatActionUnregisterListener() {
|
||||
final ResultTracker tracker = new ResultTracker();
|
||||
|
||||
final ActionService service = DataModel.get().getActionService();
|
||||
final TestChatActionMonitor monitor = new TestChatActionMonitor(null, tracker, this, this);
|
||||
final TestChatAction action = new TestChatAction(monitor.getActionKey(), parameter);
|
||||
|
||||
assertNull("Expect completion result to start null", tracker.completionResult);
|
||||
assertNull("Expect execution result to start null", tracker.executionResult);
|
||||
|
||||
synchronized(mWorker) {
|
||||
try {
|
||||
action.start(monitor);
|
||||
// Wait for callback across threads
|
||||
mWorker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for execution", false);
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals("Expect to see 1 server request queued", 1,
|
||||
mWorker.getRequestsMade().size());
|
||||
final Action request = mWorker.getRequestsMade().get(0);
|
||||
assertTrue("Expect Test type", request instanceof TestChatAction);
|
||||
|
||||
monitor.unregister();
|
||||
|
||||
final Bundle response = new Bundle();
|
||||
synchronized(mWorker) {
|
||||
try {
|
||||
request.markBackgroundWorkStarting();
|
||||
request.markBackgroundWorkQueued();
|
||||
|
||||
request.markBackgroundWorkStarting();
|
||||
request.markBackgroundCompletionQueued();
|
||||
service.handleResponseFromBackgroundWorker(request, response);
|
||||
// Wait for callback across threads
|
||||
mWorker.wait(2000);
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for response processing", false);
|
||||
}
|
||||
}
|
||||
|
||||
//assertEquals("Expect execution result set", executeActionResult, tracker.executionResult);
|
||||
assertEquals("Expect completion never called", null, tracker.completionResult);
|
||||
}
|
||||
|
||||
StubBackgroundWorker mWorker;
|
||||
FakeContext mContext;
|
||||
StubLoader mLoader;
|
||||
|
||||
private static final String parameter = "parameter";
|
||||
private static final Object executeActionResult = "executeActionResult";
|
||||
private static final String processResponseResult = "processResponseResult";
|
||||
private static final Object processFailureResult = "processFailureResult";
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Log.d(TAG, "ChatActionTest setUp");
|
||||
|
||||
mContext = new FakeContext(getContext(), this);
|
||||
mWorker = new StubBackgroundWorker();
|
||||
FakeFactory.registerWithFakeContext(getContext(), mContext)
|
||||
.withDataModel(new FakeDataModel(mContext)
|
||||
.withBackgroundWorkerForActionService(mWorker)
|
||||
.withActionService(new ActionService()));
|
||||
|
||||
mLoader = new StubLoader();
|
||||
setContext(Factory.get().getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceClassName() {
|
||||
return ActionServiceImpl.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startServiceForStub(final Intent intent) {
|
||||
this.startService(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartCommandForStub(final Intent intent, final int flags, final int startId) {
|
||||
this.getService().onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
public static class TestChatAction extends Action implements Parcelable {
|
||||
public static String RESPONSE_TEST = "response_test";
|
||||
public static String KEY_PARAMETER = "parameter";
|
||||
|
||||
protected TestChatAction(final String key, final String parameter) {
|
||||
super(key);
|
||||
this.actionParameters.putString(KEY_PARAMETER, parameter);
|
||||
// Cache parameter as a member variable
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
// An example parameter
|
||||
public final String parameter;
|
||||
|
||||
/**
|
||||
* Process the action locally - runs on datamodel service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object executeAction() {
|
||||
requestBackgroundWork();
|
||||
return executeActionResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the response from the server - runs on datamodel service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object processBackgroundResponse(final Bundle response) {
|
||||
requestBackgroundWork(new TestChatActionOther(null, parameter));
|
||||
return response.get(RESPONSE_TEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in case of failures when sending requests - runs on datamodel service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object processBackgroundFailure() {
|
||||
return processFailureResult;
|
||||
}
|
||||
|
||||
private TestChatAction(final Parcel in) {
|
||||
super(in);
|
||||
// Cache parameter as a member variable
|
||||
parameter = actionParameters.getString(KEY_PARAMETER);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TestChatAction> CREATOR
|
||||
= new Parcelable.Creator<TestChatAction>() {
|
||||
@Override
|
||||
public TestChatAction createFromParcel(final Parcel in) {
|
||||
return new TestChatAction(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestChatAction[] newArray(final int size) {
|
||||
return new TestChatAction[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int flags) {
|
||||
writeActionToParcel(parcel, flags);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestChatActionOther extends Action implements Parcelable {
|
||||
protected TestChatActionOther(final String key, final String parameter) {
|
||||
super(generateUniqueActionKey(key));
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
public final String parameter;
|
||||
|
||||
private TestChatActionOther(final Parcel in) {
|
||||
super(in);
|
||||
parameter = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TestChatActionOther> CREATOR
|
||||
= new Parcelable.Creator<TestChatActionOther>() {
|
||||
@Override
|
||||
public TestChatActionOther createFromParcel(final Parcel in) {
|
||||
return new TestChatActionOther(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestChatActionOther[] newArray(final int size) {
|
||||
return new TestChatActionOther[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int flags) {
|
||||
writeActionToParcel(parcel, flags);
|
||||
parcel.writeString(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation that notifies a listener upon completion
|
||||
*/
|
||||
public static class TestChatActionMonitor extends ActionMonitor {
|
||||
/**
|
||||
* Create action state wrapping an BlockUserAction instance
|
||||
* @param account - account in which to block the user
|
||||
* @param baseKey - suggested action key from BlockUserAction
|
||||
* @param data - optional action specific data that is handed back to listener
|
||||
* @param listener - action completed listener
|
||||
*/
|
||||
public TestChatActionMonitor(final String baseKey, final Object data,
|
||||
final ActionCompletedListener completed, final ActionExecutedListener executed) {
|
||||
super(STATE_CREATED, Action.generateUniqueActionKey(baseKey), data);
|
||||
setCompletedListener(completed);
|
||||
setExecutedListener(executed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.action;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
import com.android.messaging.Factory;
|
||||
import com.android.messaging.FakeContext;
|
||||
import com.android.messaging.FakeContext.FakeContextHost;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.BugleServiceTestCase;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.action.ActionMonitor.ActionCompletedListener;
|
||||
import com.android.messaging.datamodel.action.ActionMonitor.ActionStateChangedListener;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.ResultTracker;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubBackgroundWorker;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubLoader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@MediumTest
|
||||
public class ActionServiceTest extends BugleServiceTestCase<ActionServiceImpl>
|
||||
implements FakeContextHost, ActionStateChangedListener, ActionCompletedListener {
|
||||
private static final String TAG = "ActionServiceTest";
|
||||
|
||||
@Override
|
||||
public void onActionStateChanged(final Action action, final int state) {
|
||||
mStates.add(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionSucceeded(final ActionMonitor monitor,
|
||||
final Action action, final Object data, final Object result) {
|
||||
final TestChatAction test = (TestChatAction) action;
|
||||
assertNotSame(test.dontRelyOnMe, dontRelyOnMe);
|
||||
// This will be true - but only briefly
|
||||
assertEquals(test.dontRelyOnMe, becauseIChange);
|
||||
|
||||
final ResultTracker tracker = (ResultTracker) data;
|
||||
tracker.completionResult = result;
|
||||
synchronized(tracker) {
|
||||
tracker.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionFailed(final ActionMonitor monitor, final Action action,
|
||||
final Object data, final Object result) {
|
||||
final TestChatAction test = (TestChatAction) action;
|
||||
assertNotSame(test.dontRelyOnMe, dontRelyOnMe);
|
||||
// This will be true - but only briefly
|
||||
assertEquals(test.dontRelyOnMe, becauseIChange);
|
||||
|
||||
final ResultTracker tracker = (ResultTracker) data;
|
||||
tracker.completionResult = result;
|
||||
synchronized(tracker) {
|
||||
tracker.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For a chat action verify that the service intent is constructed and queued correctly and
|
||||
* that when that intent is processed it actually executes the action.
|
||||
*/
|
||||
public void testChatServiceCreatesIntentAndExecutesAction() {
|
||||
final ResultTracker tracker = new ResultTracker();
|
||||
|
||||
final TestChatActionMonitor monitor = new TestChatActionMonitor(null, tracker, this, this);
|
||||
final TestChatAction action = new TestChatAction(monitor.getActionKey(), parameter);
|
||||
|
||||
action.dontRelyOnMe = dontRelyOnMe;
|
||||
assertFalse("Expect service initially stopped", mServiceStarted);
|
||||
|
||||
synchronized(mWorker) {
|
||||
try {
|
||||
action.start(monitor);
|
||||
// Wait for callback across threads
|
||||
mWorker.wait(2000);
|
||||
mServiceStarted = true;
|
||||
} catch (final InterruptedException e) {
|
||||
assertTrue("Interrupted waiting for execution", false);
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Expect service started", mServiceStarted);
|
||||
|
||||
assertEquals("Expect three states ", mStates.size(), 3);
|
||||
assertEquals("State-0 should be STATE_QUEUED", (int)mStates.get(0),
|
||||
ActionMonitor.STATE_QUEUED);
|
||||
assertEquals("State-1 should be STATE_EXECUTING", (int)mStates.get(1),
|
||||
ActionMonitor.STATE_EXECUTING);
|
||||
assertEquals("State-2 should be STATE_COMPLETE", (int)mStates.get(2),
|
||||
ActionMonitor.STATE_COMPLETE);
|
||||
}
|
||||
|
||||
StubBackgroundWorker mWorker;
|
||||
FakeContext mContext;
|
||||
StubLoader mLoader;
|
||||
ActionService mService;
|
||||
|
||||
ArrayList<Integer> mStates;
|
||||
|
||||
private static final String parameter = "parameter";
|
||||
private static final Object dontRelyOnMe = "dontRelyOnMe";
|
||||
private static final Object becauseIChange = "becauseIChange";
|
||||
private static final Object executeActionResult = "executeActionResult";
|
||||
private static final Object processResponseResult = "processResponseResult";
|
||||
private static final Object processFailureResult = "processFailureResult";
|
||||
|
||||
public ActionServiceTest() {
|
||||
super(ActionServiceImpl.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Log.d(TAG, "ChatActionTest setUp");
|
||||
|
||||
sLooper = Looper.myLooper();
|
||||
|
||||
mWorker = new StubBackgroundWorker();
|
||||
mContext = new FakeContext(getContext(), this);
|
||||
FakeFactory.registerWithFakeContext(getContext(),mContext)
|
||||
.withDataModel(new FakeDataModel(mContext)
|
||||
.withBackgroundWorkerForActionService(mWorker)
|
||||
.withActionService(new ActionService()));
|
||||
|
||||
mStates = new ArrayList<Integer>();
|
||||
setContext(Factory.get().getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceClassName() {
|
||||
return ActionServiceImpl.class.getName();
|
||||
}
|
||||
|
||||
boolean mServiceStarted = false;
|
||||
|
||||
@Override
|
||||
public void startServiceForStub(final Intent intent) {
|
||||
// Do nothing until later
|
||||
assertFalse(mServiceStarted);
|
||||
mServiceStarted = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartCommandForStub(final Intent intent, final int flags, final int startId) {
|
||||
assertTrue(mServiceStarted);
|
||||
}
|
||||
|
||||
private static Looper sLooper;
|
||||
public static void assertRunsOnOtherThread() {
|
||||
assertTrue (Looper.myLooper() != Looper.getMainLooper());
|
||||
assertTrue (Looper.myLooper() != sLooper);
|
||||
}
|
||||
|
||||
public static class TestChatAction extends Action implements Parcelable {
|
||||
public static String RESPONSE_TEST = "response_test";
|
||||
public static String KEY_PARAMETER = "parameter";
|
||||
|
||||
protected TestChatAction(final String key, final String parameter) {
|
||||
super(key);
|
||||
this.actionParameters.putString(KEY_PARAMETER, parameter);
|
||||
}
|
||||
|
||||
transient Object dontRelyOnMe;
|
||||
|
||||
/**
|
||||
* Process the action locally - runs on service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object executeAction() {
|
||||
this.dontRelyOnMe = becauseIChange;
|
||||
assertRunsOnOtherThread();
|
||||
return executeActionResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the response from the server - runs on service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object processBackgroundResponse(final Bundle response) {
|
||||
assertRunsOnOtherThread();
|
||||
return processResponseResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in case of failures when sending requests - runs on service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object processBackgroundFailure() {
|
||||
assertRunsOnOtherThread();
|
||||
return processFailureResult;
|
||||
}
|
||||
|
||||
private TestChatAction(final Parcel in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TestChatAction> CREATOR
|
||||
= new Parcelable.Creator<TestChatAction>() {
|
||||
@Override
|
||||
public TestChatAction createFromParcel(final Parcel in) {
|
||||
return new TestChatAction(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestChatAction[] newArray(final int size) {
|
||||
return new TestChatAction[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int flags) {
|
||||
writeActionToParcel(parcel, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation that notifies a listener upon state changes, execution and completion
|
||||
*/
|
||||
public static class TestChatActionMonitor extends ActionMonitor {
|
||||
public TestChatActionMonitor(final String baseKey, final Object data,
|
||||
final ActionStateChangedListener listener, final ActionCompletedListener executed) {
|
||||
super(STATE_CREATED, Action.generateUniqueActionKey(baseKey), data);
|
||||
setStateChangedListener(listener);
|
||||
setCompletedListener(executed);
|
||||
assertEquals("Initial state should be STATE_CREATED", mState, STATE_CREATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,325 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.action;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.DataModelImpl;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubChatActionMonitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@MediumTest
|
||||
public class ActionTest extends BugleTestCase {
|
||||
private static final String parameter = "parameter";
|
||||
private static final Object executeActionResult = "executeActionResult";
|
||||
private static final Object processResponseResult = "processResponseResult";
|
||||
private static final Object processFailureResult = "processFailureResult";
|
||||
|
||||
private static final String mActionKey = "TheActionKey";
|
||||
private static final Object mData = "PrivateData";
|
||||
private StubChatActionMonitor mMonitor;
|
||||
private TestChatAction mAction;
|
||||
|
||||
private ArrayList<StubChatActionMonitor.StateTransition> mTransitions;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getTestContext())
|
||||
.withDataModel(new DataModelImpl(getContext()));
|
||||
|
||||
mMonitor = new StubChatActionMonitor(ActionMonitor.STATE_CREATED, mActionKey,
|
||||
mData);
|
||||
mAction = new TestChatAction(mActionKey, parameter);
|
||||
mTransitions = mMonitor.getTransitions();
|
||||
}
|
||||
|
||||
private void verifyState(final int count, final int from, final int to) {
|
||||
assertEquals(to, mMonitor.getState());
|
||||
assertEquals(mTransitions.size(), count);
|
||||
verifyTransition(count-1, from , to);
|
||||
}
|
||||
|
||||
private void verifyTransition(final int index, final int from, final int to) {
|
||||
assertTrue(mTransitions.size() > index);
|
||||
assertEquals(mAction, mTransitions.get(index).action);
|
||||
assertEquals(from, mTransitions.get(index).from);
|
||||
assertEquals(to, mTransitions.get(index).to);
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testActionStartTransitionsCorrectly() {
|
||||
mMonitor.setState(ActionMonitor.STATE_CREATED);
|
||||
|
||||
ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor);
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
mAction.markStart();
|
||||
assertEquals("After start state: STATE_QUEUED", ActionMonitor.STATE_QUEUED,
|
||||
mMonitor.getState());
|
||||
verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED);
|
||||
|
||||
ActionMonitor.unregisterActionMonitor(mAction.actionKey, mMonitor);
|
||||
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testActionStartAssertsFromIncorrectState() {
|
||||
mMonitor.setState(ActionMonitor.STATE_UNDEFINED);
|
||||
|
||||
ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor);
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
try {
|
||||
mAction.markStart();
|
||||
fail("Expect assertion when starting from STATE_UNDEFINED");
|
||||
} catch (final IllegalStateException ex){
|
||||
}
|
||||
ActionMonitor.unregisterActionMonitor(mAction.actionKey, mMonitor);
|
||||
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
}
|
||||
|
||||
public void testActionTransitionsEndToEndWithRequests() {
|
||||
assertEquals("Start state: STATE_CREATED", ActionMonitor.STATE_CREATED,
|
||||
mMonitor.getState());
|
||||
|
||||
ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor);
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
mAction.markStart();
|
||||
|
||||
verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED);
|
||||
|
||||
mAction.markBeginExecute();
|
||||
|
||||
verifyState(2, ActionMonitor.STATE_QUEUED, ActionMonitor.STATE_EXECUTING);
|
||||
|
||||
final Object result = mAction.executeAction();
|
||||
mAction.requestBackgroundWork();
|
||||
|
||||
assertEquals("Check executeAction result", result, executeActionResult);
|
||||
|
||||
mAction.markEndExecute(result);
|
||||
|
||||
verifyState(3, ActionMonitor.STATE_EXECUTING,
|
||||
ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED);
|
||||
|
||||
mAction.markBackgroundWorkStarting();
|
||||
|
||||
verifyState(4, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED,
|
||||
ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION);
|
||||
|
||||
mAction.markBackgroundWorkQueued();
|
||||
|
||||
verifyState(5, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION,
|
||||
ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED);
|
||||
|
||||
mAction.markBackgroundWorkStarting();
|
||||
|
||||
verifyState(6, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED,
|
||||
ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION);
|
||||
|
||||
final Bundle response = null;
|
||||
|
||||
mAction.markBackgroundCompletionQueued();
|
||||
|
||||
verifyState(7, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION,
|
||||
ActionMonitor.STATE_BACKGROUND_COMPLETION_QUEUED);
|
||||
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
mAction.processBackgroundWorkResponse(response);
|
||||
|
||||
verifyTransition(7, ActionMonitor.STATE_BACKGROUND_COMPLETION_QUEUED,
|
||||
ActionMonitor.STATE_PROCESSING_BACKGROUND_RESPONSE);
|
||||
|
||||
verifyState(9, ActionMonitor.STATE_PROCESSING_BACKGROUND_RESPONSE,
|
||||
ActionMonitor.STATE_COMPLETE);
|
||||
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
}
|
||||
|
||||
public void testActionTransitionsEndToEndFailsRequests() {
|
||||
assertEquals("Start state: STATE_CREATED", ActionMonitor.STATE_CREATED,
|
||||
mMonitor.getState());
|
||||
|
||||
ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor);
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
mAction.markStart();
|
||||
|
||||
verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED);
|
||||
|
||||
mAction.markBeginExecute();
|
||||
|
||||
verifyState(2, ActionMonitor.STATE_QUEUED, ActionMonitor.STATE_EXECUTING);
|
||||
|
||||
final Object result = mAction.executeAction();
|
||||
mAction.requestBackgroundWork();
|
||||
|
||||
assertEquals("Check executeAction result", result, executeActionResult);
|
||||
|
||||
mAction.markEndExecute(result);
|
||||
|
||||
verifyState(3, ActionMonitor.STATE_EXECUTING,
|
||||
ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED);
|
||||
|
||||
mAction.markBackgroundWorkStarting();
|
||||
|
||||
verifyState(4, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED,
|
||||
ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION);
|
||||
|
||||
mAction.markBackgroundWorkQueued();
|
||||
|
||||
verifyState(5, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION,
|
||||
ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED);
|
||||
|
||||
mAction.markBackgroundWorkStarting();
|
||||
|
||||
verifyState(6, ActionMonitor.STATE_BACKGROUND_ACTIONS_QUEUED,
|
||||
ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION);
|
||||
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
mAction.processBackgroundWorkFailure();
|
||||
|
||||
verifyState(7, ActionMonitor.STATE_EXECUTING_BACKGROUND_ACTION,
|
||||
ActionMonitor.STATE_COMPLETE);
|
||||
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
}
|
||||
|
||||
public void testActionTransitionsEndToEndNoRequests() {
|
||||
assertEquals("Start state: STATE_CREATED", ActionMonitor.STATE_CREATED,
|
||||
mMonitor.getState());
|
||||
|
||||
ActionMonitor.registerActionMonitor(mAction.actionKey, mMonitor);
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
mAction.markStart();
|
||||
|
||||
verifyState(1, ActionMonitor.STATE_CREATED, ActionMonitor.STATE_QUEUED);
|
||||
|
||||
mAction.markBeginExecute();
|
||||
|
||||
verifyState(2, ActionMonitor.STATE_QUEUED, ActionMonitor.STATE_EXECUTING);
|
||||
|
||||
final Object result = mAction.executeAction();
|
||||
|
||||
assertEquals("Check executeAction result", result, executeActionResult);
|
||||
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertTrue(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
assertEquals(ActionMonitor.sActionMonitors.get(mAction.actionKey), mMonitor);
|
||||
|
||||
mAction.markEndExecute(result);
|
||||
|
||||
verifyState(3, ActionMonitor.STATE_EXECUTING,
|
||||
ActionMonitor.STATE_COMPLETE);
|
||||
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsKey(mAction.actionKey));
|
||||
assertFalse(ActionMonitor.sActionMonitors.containsValue(mMonitor));
|
||||
}
|
||||
|
||||
public static class TestChatAction extends Action implements Parcelable {
|
||||
protected TestChatAction(final String key, final String parameter) {
|
||||
super(key);
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
public final String parameter;
|
||||
|
||||
/**
|
||||
* Process the action locally - runs on service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object executeAction() {
|
||||
assertEquals("Check parameter", parameter, ActionTest.parameter);
|
||||
return executeActionResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the response from the server - runs on service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object processBackgroundResponse(final Bundle response) {
|
||||
assertEquals("Check parameter", parameter, ActionTest.parameter);
|
||||
return processResponseResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in case of failures when sending requests - runs on service thread
|
||||
*/
|
||||
@Override
|
||||
protected Object processBackgroundFailure() {
|
||||
assertEquals("Check parameter", parameter, ActionTest.parameter);
|
||||
return processFailureResult;
|
||||
}
|
||||
|
||||
private TestChatAction(final Parcel in) {
|
||||
super(in);
|
||||
parameter = in.readString();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<TestChatAction> CREATOR
|
||||
= new Parcelable.Creator<TestChatAction>() {
|
||||
@Override
|
||||
public TestChatAction createFromParcel(final Parcel in) {
|
||||
return new TestChatAction(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestChatAction[] newArray(final int size) {
|
||||
return new TestChatAction[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int flags) {
|
||||
writeActionToParcel(parcel, flags);
|
||||
parcel.writeString(parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.action;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ActionTestHelpers {
|
||||
private static final String TAG = "DataModelTestHelpers";
|
||||
|
||||
static class StubLoader extends ContentObserver {
|
||||
ArrayList<Uri> mUriList = new ArrayList<Uri>();
|
||||
|
||||
StubLoader() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mUriList.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(final boolean selfChange) {
|
||||
// Handle change.
|
||||
mUriList.add(null);
|
||||
}
|
||||
|
||||
// Implement the onChange(boolean, Uri) method to take advantage of the new Uri argument.
|
||||
// Only supported on platform 16 and above...
|
||||
@Override
|
||||
public void onChange(final boolean selfChange, final Uri uri) {
|
||||
// Handle change.
|
||||
mUriList.add(uri);
|
||||
}
|
||||
}
|
||||
|
||||
static class StubBackgroundWorker extends BackgroundWorker {
|
||||
public StubBackgroundWorker() {
|
||||
super();
|
||||
mActions = new ArrayList<Action>();
|
||||
}
|
||||
|
||||
ArrayList<Action> mActions;
|
||||
public ArrayList<Action> getRequestsMade() {
|
||||
return mActions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void queueBackgroundWork(final List<Action> actions) {
|
||||
mActions.addAll(actions);
|
||||
|
||||
synchronized(this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class ResultTracker {
|
||||
public Object executionResult;
|
||||
public Object completionResult;
|
||||
}
|
||||
|
||||
static class StubChatActionMonitor extends ActionMonitor {
|
||||
static public class StateTransition {
|
||||
Action action;
|
||||
int from;
|
||||
int to;
|
||||
public StateTransition(final Action action, final int from, final int to) {
|
||||
this.action = action;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayList<StateTransition> mTransitions;
|
||||
public ArrayList<StateTransition> getTransitions() {
|
||||
return mTransitions;
|
||||
}
|
||||
|
||||
protected StubChatActionMonitor(final int initialState, final String actionKey,
|
||||
final Object data) {
|
||||
super(initialState, actionKey, data);
|
||||
mTransitions = new ArrayList<StateTransition>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateState(final Action action, final int expectedState,
|
||||
final int state) {
|
||||
mTransitions.add(new StateTransition(action, mState, state));
|
||||
super.updateState(action, expectedState, state);
|
||||
}
|
||||
|
||||
public void setState(final int state) {
|
||||
mState = state;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return mState;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StubActionService extends ActionService {
|
||||
public static class StubActionServiceCallLog {
|
||||
public final Action action;
|
||||
public final Action request;
|
||||
public final Bundle response;
|
||||
public final Exception exception;
|
||||
public final Action update;
|
||||
|
||||
public StubActionServiceCallLog(final Action action,
|
||||
final Action request,
|
||||
final Bundle response,
|
||||
final Exception exception,
|
||||
final Action update) {
|
||||
this.action = action;
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.exception = exception;
|
||||
this.update = update;
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayList<StubActionServiceCallLog> mServiceCalls =
|
||||
new ArrayList<StubActionServiceCallLog>();
|
||||
|
||||
public ArrayList<StubActionServiceCallLog> getCalls() {
|
||||
return mServiceCalls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startAction(final Action action) {
|
||||
mServiceCalls.add(new StubActionServiceCallLog(action, null, null, null, null));
|
||||
synchronized(this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleResponseFromBackgroundWorker(final Action request,
|
||||
final Bundle response) {
|
||||
mServiceCalls.add(new StubActionServiceCallLog(null, request, response, null, null));
|
||||
synchronized(this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleFailureFromBackgroundWorker(final Action request,
|
||||
final Exception exception) {
|
||||
mServiceCalls.add(new StubActionServiceCallLog(null, request, null, exception, null));
|
||||
synchronized(this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.action;
|
||||
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.test.mock.MockContentProvider;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeContext;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.BugleDatabaseOperations;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.DatabaseWrapper;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.MessagingContentProvider;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService.StubActionServiceCallLog;
|
||||
import com.android.messaging.datamodel.action.GetOrCreateConversationAction.GetOrCreateConversationActionListener;
|
||||
import com.android.messaging.datamodel.action.GetOrCreateConversationAction.GetOrCreateConversationActionMonitor;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.sms.MmsUtils;
|
||||
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SmallTest
|
||||
public class GetOrCreateConversationActionTest extends BugleTestCase {
|
||||
|
||||
@Mock GetOrCreateConversationActionListener mockListener;
|
||||
|
||||
public void testGetOrCreateConversation() {
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
|
||||
final ArrayList<String> recipients = new ArrayList<String>();
|
||||
recipients.add("5551234567");
|
||||
recipients.add("5551234568");
|
||||
|
||||
// Generate a list of partially formed participants
|
||||
final ArrayList<ParticipantData> participants = new
|
||||
ArrayList<ParticipantData>();
|
||||
|
||||
|
||||
for (final String recipient : recipients) {
|
||||
participants.add(ParticipantData.getFromRawPhoneBySystemLocale(recipient));
|
||||
}
|
||||
|
||||
// Test that we properly stubbed the SMS provider to return a thread id
|
||||
final long threadId = MmsUtils.getOrCreateThreadId(mContext, recipients);
|
||||
assertEquals(TestDataFactory.SMS_MMS_THREAD_ID_CURSOR_VALUE, threadId);
|
||||
|
||||
ArrayList<StubActionServiceCallLog> calls = mService.getCalls();
|
||||
|
||||
GetOrCreateConversationActionMonitor monitor =
|
||||
GetOrCreateConversationAction.getOrCreateConversation(participants, null,
|
||||
mockListener);
|
||||
|
||||
assertEquals("Failed to start service once for action", calls.size(), 1);
|
||||
assertTrue("Action not GetOrCreateConversationAction", calls.get(0).action instanceof
|
||||
GetOrCreateConversationAction);
|
||||
|
||||
GetOrCreateConversationAction action = (GetOrCreateConversationAction)
|
||||
calls.get(0).action;
|
||||
|
||||
Object result = action.executeAction();
|
||||
|
||||
assertTrue(result instanceof String);
|
||||
|
||||
// Make sure that we created a new conversation
|
||||
int expectedConversationId = TestDataFactory.NUM_TEST_CONVERSATIONS + 1;
|
||||
assertEquals(expectedConversationId, Integer.parseInt((String) result));
|
||||
|
||||
// Now get the conversation that we just created again
|
||||
monitor = GetOrCreateConversationAction.getOrCreateConversation(participants, null,
|
||||
mockListener);
|
||||
|
||||
calls = mService.getCalls();
|
||||
assertEquals("Failed to start service for second action", calls.size(), 2);
|
||||
assertTrue("Action not GetOrCreateConversationAction", calls.get(1).action instanceof
|
||||
GetOrCreateConversationAction);
|
||||
action = (GetOrCreateConversationAction)calls.get(1).action;
|
||||
result = action.executeAction();
|
||||
|
||||
assertTrue(result instanceof String);
|
||||
|
||||
final String conversationId = (String) result;
|
||||
|
||||
// Make sure that we found the same conversation id
|
||||
assertEquals(expectedConversationId, Integer.parseInt((String) result));
|
||||
|
||||
final ArrayList<ParticipantData> conversationParticipants =
|
||||
BugleDatabaseOperations.getParticipantsForConversation(db, conversationId);
|
||||
|
||||
assertEquals("Participant count mismatch", recipients.size(),
|
||||
conversationParticipants.size());
|
||||
for(final ParticipantData participant : conversationParticipants) {
|
||||
assertTrue(recipients.contains(participant.getSendDestination()));
|
||||
}
|
||||
|
||||
final Uri conversationParticipantsUri =
|
||||
MessagingContentProvider.buildConversationParticipantsUri(conversationId);
|
||||
final Cursor cursor = mContext.getContentResolver().query(conversationParticipantsUri,
|
||||
ParticipantData.ParticipantsQuery.PROJECTION, null, null, null);
|
||||
|
||||
int countSelf = 0;
|
||||
while(cursor.moveToNext()) {
|
||||
final ParticipantData participant = ParticipantData.getFromCursor(cursor);
|
||||
if (participant.isSelf()) {
|
||||
countSelf++;
|
||||
} else {
|
||||
assertTrue(recipients.contains(participant.getSendDestination()));
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
assertEquals("Expect one self participant in conversations", 1, countSelf);
|
||||
assertEquals("Cursor count mismatch", recipients.size(), cursor.getCount() - countSelf);
|
||||
|
||||
final String realId = BugleDatabaseOperations.getExistingConversation(db, threadId, false);
|
||||
assertEquals("Conversation already exists", realId, conversationId);
|
||||
}
|
||||
|
||||
private FakeContext mContext;
|
||||
private StubActionService mService;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
mContext = new FakeContext(getTestContext());
|
||||
|
||||
final MockContentProvider mockProvider = new MockContentProvider() {
|
||||
@Override
|
||||
public Cursor query(final Uri uri, final String[] projection, final String selection,
|
||||
final String[] selectionArgs, final String sortOrder) {
|
||||
return TestDataFactory.getSmsMmsThreadIdCursor();
|
||||
}
|
||||
};
|
||||
|
||||
mContext.addContentProvider("mms-sms", mockProvider);
|
||||
final MessagingContentProvider provider = new MessagingContentProvider();
|
||||
final ProviderInfo providerInfo = new ProviderInfo();
|
||||
providerInfo.authority = MessagingContentProvider.AUTHORITY;
|
||||
provider.attachInfo(mContext, providerInfo);
|
||||
mContext.addContentProvider(MessagingContentProvider.AUTHORITY, provider);
|
||||
|
||||
mService = new StubActionService();
|
||||
final FakeDataModel fakeDataModel = new FakeDataModel(mContext)
|
||||
.withActionService(mService);
|
||||
FakeFactory.registerWithFakeContext(getTestContext(), mContext)
|
||||
.withDataModel(fakeDataModel);
|
||||
provider.setDatabaseForTest(fakeDataModel.getDatabase());
|
||||
}
|
||||
}
|
||||
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.action;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeContext;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.BugleDatabaseOperations;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.DatabaseHelper;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ConversationColumns;
|
||||
import com.android.messaging.datamodel.DatabaseWrapper;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.MediaScratchFileProvider;
|
||||
import com.android.messaging.datamodel.MessagingContentProvider;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService.StubActionServiceCallLog;
|
||||
import com.android.messaging.datamodel.action.ReadDraftDataAction.ReadDraftDataActionListener;
|
||||
import com.android.messaging.datamodel.data.MessageData;
|
||||
import com.android.messaging.datamodel.data.MessagePartData;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.util.ContentType;
|
||||
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SmallTest
|
||||
public class ReadWriteDraftMessageActionTest extends BugleTestCase {
|
||||
|
||||
@Mock ReadDraftDataActionListener mockListener;
|
||||
|
||||
// TODO: Add test cases
|
||||
// 1. Make sure drafts can include attachments and multiple parts
|
||||
// 2. Make sure attachments get cleaned up appropriately
|
||||
// 3. Make sure messageId and partIds not reused (currently each draft is a new message).
|
||||
public void testWriteDraft() {
|
||||
final String draftMessage = "draftMessage";
|
||||
final long threadId = 1234567;
|
||||
final boolean senderBlocked = false;
|
||||
final String participantNumber = "5551234567";
|
||||
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
|
||||
final String conversationId = getOrCreateConversation(db, participantNumber, threadId,
|
||||
senderBlocked);
|
||||
final String selfId = getOrCreateSelfId(db);
|
||||
|
||||
// Should clear/stub DB
|
||||
final ArrayList<StubActionServiceCallLog> calls = mService.getCalls();
|
||||
|
||||
final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId,
|
||||
draftMessage);
|
||||
|
||||
WriteDraftMessageAction.writeDraftMessage(conversationId, message);
|
||||
|
||||
assertEquals("Failed to start service once for action", calls.size(), 1);
|
||||
assertTrue("Action not SaveDraftMessageAction",
|
||||
calls.get(0).action instanceof WriteDraftMessageAction);
|
||||
|
||||
final Action save = calls.get(0).action;
|
||||
|
||||
final Object result = save.executeAction();
|
||||
|
||||
assertTrue("Expect row number string as result", result instanceof String);
|
||||
final String messageId = (String) result;
|
||||
|
||||
// Should check DB
|
||||
final MessageData actual = BugleDatabaseOperations.readMessage(db, messageId);
|
||||
assertNotNull("Database missing draft", actual);
|
||||
assertEquals("Draft text changed", draftMessage, actual.getMessageText());
|
||||
}
|
||||
|
||||
private static String getOrCreateSelfId(final DatabaseWrapper db) {
|
||||
db.beginTransaction();
|
||||
final String selfId = BugleDatabaseOperations.getOrCreateParticipantInTransaction(db,
|
||||
ParticipantData.getSelfParticipant(ParticipantData.DEFAULT_SELF_SUB_ID));
|
||||
db.setTransactionSuccessful();
|
||||
db.endTransaction();
|
||||
return selfId;
|
||||
}
|
||||
|
||||
private static String getOrCreateConversation(final DatabaseWrapper db,
|
||||
final String participantNumber, final long threadId, final boolean senderBlocked) {
|
||||
final ArrayList<ParticipantData> participants =
|
||||
new ArrayList<ParticipantData>();
|
||||
participants.add(ParticipantData.getFromRawPhoneBySystemLocale(participantNumber));
|
||||
|
||||
final String conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId,
|
||||
senderBlocked, participants);
|
||||
assertNotNull("No conversation", conversationId);
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
public void testReadDraft() {
|
||||
final Object data = "data";
|
||||
final String draftMessage = "draftMessage";
|
||||
final long threadId = 1234567;
|
||||
final boolean senderBlocked = false;
|
||||
final String participantNumber = "5552345678";
|
||||
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
|
||||
final String conversationId = getOrCreateConversation(db, participantNumber, threadId,
|
||||
senderBlocked);
|
||||
final String selfId = getOrCreateSelfId(db);
|
||||
|
||||
// Should clear/stub DB
|
||||
final ArrayList<StubActionServiceCallLog> calls = mService.getCalls();
|
||||
|
||||
final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId,
|
||||
draftMessage);
|
||||
|
||||
BugleDatabaseOperations.updateDraftMessageData(db, conversationId, message,
|
||||
BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT);
|
||||
|
||||
final ActionMonitor monitor =
|
||||
ReadDraftDataAction.readDraftData(conversationId, null, data, mockListener);
|
||||
|
||||
assertEquals("Unexpected number of calls to service", 1, calls.size());
|
||||
assertTrue("Action not of type ReadDraftMessageAction",
|
||||
calls.get(0).action instanceof ReadDraftDataAction);
|
||||
|
||||
final Action read = calls.get(0).action;
|
||||
|
||||
final Object result = read.executeAction();
|
||||
|
||||
assertTrue(result instanceof ReadDraftDataAction.DraftData);
|
||||
final ReadDraftDataAction.DraftData draft = (ReadDraftDataAction.DraftData) result;
|
||||
|
||||
assertEquals("Draft message text differs", draftMessage, draft.message.getMessageText());
|
||||
assertEquals("Draft self differs", selfId, draft.message.getSelfId());
|
||||
assertEquals("Draft conversation differs", conversationId,
|
||||
draft.conversation.getConversationId());
|
||||
}
|
||||
|
||||
public void testReadDraftForNewConversation() {
|
||||
final Object data = "data";
|
||||
long threadId = 1234567;
|
||||
final boolean senderBlocked = false;
|
||||
long phoneNumber = 5557654567L;
|
||||
final String notConversationId = "ThisIsNotValidConversationId";
|
||||
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
final String selfId = getOrCreateSelfId(db);
|
||||
|
||||
// Unless set a new conversation should have a null draft message
|
||||
final MessageData blank = BugleDatabaseOperations.readDraftMessageData(db,
|
||||
notConversationId, selfId);
|
||||
assertNull(blank);
|
||||
|
||||
String conversationId = null;
|
||||
do {
|
||||
conversationId = BugleDatabaseOperations.getExistingConversation(db,
|
||||
threadId, senderBlocked);
|
||||
threadId++;
|
||||
phoneNumber++;
|
||||
}
|
||||
while(!TextUtils.isEmpty(conversationId));
|
||||
|
||||
final ArrayList<ParticipantData> participants =
|
||||
new ArrayList<ParticipantData>();
|
||||
participants.add(ParticipantData.getFromRawPhoneBySystemLocale(Long.toString(phoneNumber)));
|
||||
|
||||
conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId,
|
||||
senderBlocked, participants);
|
||||
assertNotNull("No conversation", conversationId);
|
||||
|
||||
final MessageData actual = BugleDatabaseOperations.readDraftMessageData(db, conversationId,
|
||||
selfId);
|
||||
assertNull(actual);
|
||||
|
||||
// Should clear/stub DB
|
||||
final ArrayList<StubActionServiceCallLog> calls = mService.getCalls();
|
||||
|
||||
final ActionMonitor monitor =
|
||||
ReadDraftDataAction.readDraftData(conversationId, null, data, mockListener);
|
||||
|
||||
assertEquals("Unexpected number of calls to service", 1, calls.size());
|
||||
assertTrue("Action not of type ReadDraftMessageAction",
|
||||
calls.get(0).action instanceof ReadDraftDataAction);
|
||||
|
||||
final Action read = calls.get(0).action;
|
||||
|
||||
final Object result = read.executeAction();
|
||||
|
||||
assertTrue(result instanceof ReadDraftDataAction.DraftData);
|
||||
final ReadDraftDataAction.DraftData draft = (ReadDraftDataAction.DraftData) result;
|
||||
|
||||
assertEquals("Draft message text differs", "", draft.message.getMessageText());
|
||||
assertEquals("Draft self differs", selfId, draft.message.getSelfId());
|
||||
assertEquals("Draft conversation differs", conversationId,
|
||||
draft.conversation.getConversationId());
|
||||
}
|
||||
|
||||
public void testWriteAndReadDraft() {
|
||||
final Object data = "data";
|
||||
final String draftMessage = "draftMessage";
|
||||
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
final Cursor conversations = db.query(DatabaseHelper.CONVERSATIONS_TABLE,
|
||||
new String[] { ConversationColumns._ID, ConversationColumns.CURRENT_SELF_ID }, null,
|
||||
null, null /* groupBy */, null /* having */, null /* orderBy */);
|
||||
|
||||
if (conversations.moveToFirst()) {
|
||||
final String conversationId = conversations.getString(0);
|
||||
final String selfId = getOrCreateSelfId(db);
|
||||
|
||||
// Should clear/stub DB
|
||||
final ArrayList<StubActionServiceCallLog> calls = mService.getCalls();
|
||||
|
||||
final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId,
|
||||
draftMessage);
|
||||
|
||||
WriteDraftMessageAction.writeDraftMessage(conversationId, message);
|
||||
|
||||
assertEquals("Failed to start service once for action", calls.size(), 1);
|
||||
assertTrue("Action not SaveDraftMessageAction",
|
||||
calls.get(0).action instanceof WriteDraftMessageAction);
|
||||
|
||||
final Action save = calls.get(0).action;
|
||||
|
||||
Object result = save.executeAction();
|
||||
|
||||
assertTrue("Expect row number string as result", result instanceof String);
|
||||
|
||||
// Should check DB
|
||||
|
||||
final ActionMonitor monitor =
|
||||
ReadDraftDataAction.readDraftData(conversationId, null, data,
|
||||
mockListener);
|
||||
|
||||
assertEquals("Expect two calls queued", 2, calls.size());
|
||||
assertTrue("Expect action", calls.get(1).action instanceof ReadDraftDataAction);
|
||||
|
||||
final Action read = calls.get(1).action;
|
||||
|
||||
result = read.executeAction();
|
||||
|
||||
assertTrue(result instanceof ReadDraftDataAction.DraftData);
|
||||
final ReadDraftDataAction.DraftData draft = (ReadDraftDataAction.DraftData) result;
|
||||
|
||||
assertEquals("Draft message text differs", draftMessage, draft.message.getMessageText());
|
||||
// The conversation's self id is used as the draft's self id.
|
||||
assertEquals("Draft self differs", conversations.getString(1),
|
||||
draft.message.getSelfId());
|
||||
assertEquals("Draft conversation differs", conversationId,
|
||||
draft.conversation.getConversationId());
|
||||
} else {
|
||||
fail("No conversations in database");
|
||||
}
|
||||
}
|
||||
|
||||
public void testUpdateDraft() {
|
||||
final String initialMessage = "initialMessage";
|
||||
final String draftMessage = "draftMessage";
|
||||
final long threadId = 1234567;
|
||||
final boolean senderBlocked = false;
|
||||
final String participantNumber = "5553456789";
|
||||
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
|
||||
final String conversationId = getOrCreateConversation(db, participantNumber, threadId,
|
||||
senderBlocked);
|
||||
final String selfId = getOrCreateSelfId(db);
|
||||
|
||||
final ArrayList<StubActionServiceCallLog> calls = mService.getCalls();
|
||||
|
||||
// Insert initial message
|
||||
MessageData initial = MessageData.createDraftSmsMessage(conversationId, selfId,
|
||||
initialMessage);
|
||||
|
||||
BugleDatabaseOperations.updateDraftMessageData(db, conversationId, initial,
|
||||
BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT);
|
||||
|
||||
initial = BugleDatabaseOperations.readDraftMessageData(db,
|
||||
conversationId, selfId);
|
||||
assertEquals("Initial text mismatch", initialMessage, initial.getMessageText());
|
||||
|
||||
// Now update the draft
|
||||
final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId,
|
||||
draftMessage);
|
||||
WriteDraftMessageAction.writeDraftMessage(conversationId, message);
|
||||
|
||||
assertEquals("Failed to start service once for action", calls.size(), 1);
|
||||
assertTrue("Action not SaveDraftMessageAction",
|
||||
calls.get(0).action instanceof WriteDraftMessageAction);
|
||||
|
||||
final Action save = calls.get(0).action;
|
||||
|
||||
final Object result = save.executeAction();
|
||||
|
||||
assertTrue("Expect row number string as result", result instanceof String);
|
||||
|
||||
// Check DB
|
||||
final MessageData actual = BugleDatabaseOperations.readDraftMessageData(db,
|
||||
conversationId, selfId);
|
||||
assertNotNull("Database missing draft", actual);
|
||||
assertEquals("Draft text mismatch", draftMessage, actual.getMessageText());
|
||||
assertNull("Draft messageId should be null", actual.getMessageId());
|
||||
}
|
||||
|
||||
public void testBugleDatabaseDraftOperations() {
|
||||
final String initialMessage = "initialMessage";
|
||||
final String draftMessage = "draftMessage";
|
||||
final long threadId = 1234599;
|
||||
final boolean senderBlocked = false;
|
||||
final String participantNumber = "5553456798";
|
||||
final String subject = "subject here";
|
||||
|
||||
final DatabaseWrapper db = DataModel.get().getDatabase();
|
||||
|
||||
final String conversationId = getOrCreateConversation(db, participantNumber, threadId,
|
||||
senderBlocked);
|
||||
final String selfId = getOrCreateSelfId(db);
|
||||
|
||||
final String text = "This is some text";
|
||||
final Uri mOutputUri = MediaScratchFileProvider.buildMediaScratchSpaceUri("txt");
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
outputStream = mContext.getContentResolver().openOutputStream(mOutputUri);
|
||||
outputStream.write(text.getBytes());
|
||||
} catch (final FileNotFoundException e) {
|
||||
fail("Cannot open output file");
|
||||
} catch (final IOException e) {
|
||||
fail("Cannot write output file");
|
||||
}
|
||||
|
||||
final MessageData initial =
|
||||
MessageData.createDraftMmsMessage(conversationId, selfId, initialMessage, subject);
|
||||
initial.addPart(MessagePartData.createMediaMessagePart(ContentType.MULTIPART_MIXED,
|
||||
mOutputUri, 0, 0));
|
||||
|
||||
final String initialMessageId = BugleDatabaseOperations.updateDraftMessageData(db,
|
||||
conversationId, initial, BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT);
|
||||
assertNotNull(initialMessageId);
|
||||
|
||||
final MessageData initialDraft = BugleDatabaseOperations.readMessage(db, initialMessageId);
|
||||
assertNotNull(initialDraft);
|
||||
int cnt = 0;
|
||||
for(final MessagePartData part : initialDraft.getParts()) {
|
||||
if (part.isAttachment()) {
|
||||
assertEquals(part.getContentUri(), mOutputUri);
|
||||
} else {
|
||||
assertEquals(part.getText(), initialMessage);
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
assertEquals("Wrong number of parts", 2, cnt);
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = mContext.getContentResolver().openInputStream(mOutputUri);
|
||||
final byte[] buffer = new byte[256];
|
||||
final int read = inputStream.read(buffer);
|
||||
assertEquals(read, text.getBytes().length);
|
||||
} catch (final FileNotFoundException e) {
|
||||
fail("Cannot open input file");
|
||||
} catch (final IOException e) {
|
||||
fail("Cannot read input file");
|
||||
}
|
||||
|
||||
final String moreText = "This is some more text";
|
||||
final Uri mAnotherUri = MediaScratchFileProvider.buildMediaScratchSpaceUri("txt");
|
||||
outputStream = null;
|
||||
try {
|
||||
outputStream = mContext.getContentResolver().openOutputStream(mAnotherUri);
|
||||
outputStream.write(moreText.getBytes());
|
||||
} catch (final FileNotFoundException e) {
|
||||
fail("Cannot open output file");
|
||||
} catch (final IOException e) {
|
||||
fail("Cannot write output file");
|
||||
}
|
||||
|
||||
final MessageData another =
|
||||
MessageData.createDraftMmsMessage(conversationId, selfId, draftMessage, subject);
|
||||
another.addPart(MessagePartData.createMediaMessagePart(ContentType.MMS_MULTIPART_MIXED,
|
||||
mAnotherUri, 0, 0));
|
||||
|
||||
final String anotherMessageId = BugleDatabaseOperations.updateDraftMessageData(db,
|
||||
conversationId, another, BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT);
|
||||
assertNotNull(anotherMessageId);
|
||||
|
||||
final MessageData anotherDraft = BugleDatabaseOperations.readMessage(db, anotherMessageId);
|
||||
assertNotNull(anotherDraft);
|
||||
cnt = 0;
|
||||
for(final MessagePartData part : anotherDraft.getParts()) {
|
||||
if (part.isAttachment()) {
|
||||
assertEquals(part.getContentUri(), mAnotherUri);
|
||||
} else {
|
||||
assertEquals(part.getText(), draftMessage);
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
assertEquals("Wrong number of parts", 2, cnt);
|
||||
|
||||
inputStream = null;
|
||||
try {
|
||||
inputStream = mContext.getContentResolver().openInputStream(mOutputUri);
|
||||
assertNull("Original draft content should have been deleted", inputStream);
|
||||
} catch (final FileNotFoundException e) {
|
||||
}
|
||||
inputStream = null;
|
||||
try {
|
||||
inputStream = mContext.getContentResolver().openInputStream(mAnotherUri);
|
||||
final byte[] buffer = new byte[256];
|
||||
final int read = inputStream.read(buffer);
|
||||
assertEquals(read, moreText.getBytes().length);
|
||||
} catch (final FileNotFoundException e) {
|
||||
fail("Cannot open input file");
|
||||
} catch (final IOException e) {
|
||||
fail("Cannot read input file");
|
||||
}
|
||||
|
||||
final MessageData last = null;
|
||||
final String lastPartId = BugleDatabaseOperations.updateDraftMessageData(db,
|
||||
conversationId, last, BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT);
|
||||
assertNull(lastPartId);
|
||||
|
||||
inputStream = null;
|
||||
try {
|
||||
inputStream = mContext.getContentResolver().openInputStream(mAnotherUri);
|
||||
assertNull("Original draft content should have been deleted", inputStream);
|
||||
} catch (final FileNotFoundException e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private StubActionService mService;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
final FakeContext context = new FakeContext(getTestContext());
|
||||
|
||||
final ContentProvider bugleProvider = new MessagingContentProvider();
|
||||
final ProviderInfo bugleProviderInfo = new ProviderInfo();
|
||||
bugleProviderInfo.authority = MessagingContentProvider.AUTHORITY;
|
||||
bugleProvider.attachInfo(mContext, bugleProviderInfo);
|
||||
context.addContentProvider(MessagingContentProvider.AUTHORITY, bugleProvider);
|
||||
final ContentProvider mediaProvider = new MediaScratchFileProvider();
|
||||
final ProviderInfo mediaProviderInfo = new ProviderInfo();
|
||||
mediaProviderInfo.authority = MediaScratchFileProvider.AUTHORITY;
|
||||
mediaProvider.attachInfo(mContext, mediaProviderInfo);
|
||||
context.addContentProvider(MediaScratchFileProvider.AUTHORITY, mediaProvider);
|
||||
|
||||
mService = new StubActionService();
|
||||
final FakeDataModel fakeDataModel = new FakeDataModel(context)
|
||||
.withActionService(mService);
|
||||
FakeFactory.registerWithFakeContext(getTestContext(), context)
|
||||
.withDataModel(fakeDataModel);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.data;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
import com.android.messaging.datamodel.data.ConversationMessageData.ConversationMessageViewColumns;
|
||||
|
||||
@SmallTest
|
||||
public class ConversationMessageDataTest extends BugleTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getTestContext());
|
||||
}
|
||||
|
||||
public void testBindFirstMessage() {
|
||||
final FakeCursor testCursor = TestDataFactory.getConversationMessageCursor();
|
||||
final ConversationMessageData data = new ConversationMessageData();
|
||||
testCursor.moveToFirst();
|
||||
data.bind(testCursor);
|
||||
// TODO: Add before checking in all bound fields...
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.STATUS, 0).equals(
|
||||
MessageData.BUGLE_STATUS_INCOMING_COMPLETE), data.getIsIncoming());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.SENDER_PROFILE_PHOTO_URI,
|
||||
0), data.getSenderProfilePhotoUri());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.SENDER_FULL_NAME, 0),
|
||||
data.getSenderFullName());
|
||||
}
|
||||
|
||||
public void testBindTwice() {
|
||||
final FakeCursor testCursor = TestDataFactory.getConversationMessageCursor();
|
||||
final ConversationMessageData data = new ConversationMessageData();
|
||||
testCursor.moveToPosition(1);
|
||||
data.bind(testCursor);
|
||||
assertEquals(TestDataFactory.getMessageText(testCursor, 1), data.getText());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.RECEIVED_TIMESTAMP, 1),
|
||||
data.getReceivedTimeStamp());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.STATUS, 1).equals(
|
||||
MessageData.BUGLE_STATUS_INCOMING_COMPLETE), data.getIsIncoming());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.SENDER_PROFILE_PHOTO_URI,
|
||||
1), data.getSenderProfilePhotoUri());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.SENDER_FULL_NAME, 1),
|
||||
data.getSenderFullName());
|
||||
testCursor.moveToPosition(2);
|
||||
data.bind(testCursor);
|
||||
assertEquals(TestDataFactory.getMessageText(testCursor, 2), data.getText());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.RECEIVED_TIMESTAMP, 2),
|
||||
data.getReceivedTimeStamp());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.STATUS, 2).equals(
|
||||
MessageData.BUGLE_STATUS_INCOMING_COMPLETE), data.getIsIncoming());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.SENDER_PROFILE_PHOTO_URI,
|
||||
2), data.getSenderProfilePhotoUri());
|
||||
assertEquals(testCursor.getAt(ConversationMessageViewColumns.SENDER_FULL_NAME, 2),
|
||||
data.getSenderFullName());
|
||||
}
|
||||
|
||||
public void testMessageClustering() {
|
||||
final FakeCursor testCursor = TestDataFactory.getConversationMessageCursor();
|
||||
final ConversationMessageData data = new ConversationMessageData();
|
||||
testCursor.moveToPosition(0);
|
||||
data.bind(testCursor);
|
||||
assertFalse(data.getCanClusterWithPreviousMessage());
|
||||
assertFalse(data.getCanClusterWithNextMessage());
|
||||
|
||||
testCursor.moveToPosition(1);
|
||||
data.bind(testCursor);
|
||||
assertFalse(data.getCanClusterWithPreviousMessage());
|
||||
assertFalse(data.getCanClusterWithNextMessage());
|
||||
|
||||
testCursor.moveToPosition(2);
|
||||
data.bind(testCursor);
|
||||
assertFalse(data.getCanClusterWithPreviousMessage());
|
||||
assertTrue(data.getCanClusterWithNextMessage()); // 2 and 3 can be clustered
|
||||
testCursor.moveToPosition(3);
|
||||
|
||||
data.bind(testCursor);
|
||||
assertTrue(data.getCanClusterWithPreviousMessage()); // 2 and 3 can be clustered
|
||||
assertFalse(data.getCanClusterWithNextMessage());
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.data;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ParticipantColumns;
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
|
||||
@SmallTest
|
||||
public class ConversationParticipantsDataTest extends BugleTestCase {
|
||||
public void testBindParticipants() {
|
||||
final FakeCursor testCursor = TestDataFactory.getConversationParticipantsCursor();
|
||||
final ConversationParticipantsData data = new ConversationParticipantsData();
|
||||
data.bind(testCursor);
|
||||
|
||||
assertEquals(data.getParticipantListExcludingSelf().size(), testCursor.getCount());
|
||||
final ParticipantData participant2 = data.getParticipantById("2");
|
||||
assertNotNull(participant2);
|
||||
assertEquals(participant2.getFirstName(), testCursor.getAt(
|
||||
ParticipantColumns.FIRST_NAME, 1) );
|
||||
assertEquals(participant2.getSendDestination(), testCursor.getAt(
|
||||
ParticipantColumns.SEND_DESTINATION, 1));
|
||||
}
|
||||
}
|
||||
@@ -1,347 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.data;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.net.Uri;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.provider.MediaStore.Images.Media;
|
||||
|
||||
import com.android.messaging.datamodel.BugleDatabaseOperations;
|
||||
import com.android.messaging.datamodel.DatabaseHelper;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ConversationColumns;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.MessageColumns;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.PartColumns;
|
||||
import com.android.messaging.datamodel.DatabaseHelper.ParticipantColumns;
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
import com.android.messaging.datamodel.data.ConversationListItemData.ConversationListViewColumns;
|
||||
import com.android.messaging.datamodel.data.ConversationMessageData.ConversationMessageViewColumns;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.ContactUtil;
|
||||
import com.android.messaging.util.ContentType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A factory for fake objects that can be useful for multiple tests.
|
||||
*/
|
||||
public class TestDataFactory {
|
||||
private final static String[] sConversationListCursorColumns = new String[] {
|
||||
ConversationListViewColumns._ID,
|
||||
ConversationListViewColumns.NAME,
|
||||
ConversationListViewColumns.ICON,
|
||||
ConversationListViewColumns.SNIPPET_TEXT,
|
||||
ConversationListViewColumns.PREVIEW_URI,
|
||||
ConversationListViewColumns.SORT_TIMESTAMP,
|
||||
ConversationListViewColumns.READ,
|
||||
ConversationListViewColumns.PREVIEW_CONTENT_TYPE,
|
||||
ConversationListViewColumns.MESSAGE_STATUS,
|
||||
};
|
||||
|
||||
private final static String[] sContactCursorColumns = new String[] {
|
||||
Phone.CONTACT_ID,
|
||||
Phone.DISPLAY_NAME_PRIMARY,
|
||||
Phone.PHOTO_THUMBNAIL_URI,
|
||||
Phone.NUMBER,
|
||||
Phone.TYPE,
|
||||
Phone.LABEL,
|
||||
Phone.LOOKUP_KEY,
|
||||
Phone._ID,
|
||||
Phone.SORT_KEY_PRIMARY,
|
||||
};
|
||||
|
||||
private final static String[] sFrequentContactCursorColumns = new String[] {
|
||||
Contacts._ID,
|
||||
Contacts.DISPLAY_NAME,
|
||||
Contacts.PHOTO_URI,
|
||||
Phone.LOOKUP_KEY,
|
||||
};
|
||||
|
||||
private final static String[] sConversationMessageCursorColumns = new String[] {
|
||||
ConversationMessageViewColumns._ID,
|
||||
ConversationMessageViewColumns.CONVERSATION_ID,
|
||||
ConversationMessageViewColumns.PARTICIPANT_ID,
|
||||
ConversationMessageViewColumns.SENT_TIMESTAMP,
|
||||
ConversationMessageViewColumns.RECEIVED_TIMESTAMP,
|
||||
ConversationMessageViewColumns.STATUS,
|
||||
ConversationMessageViewColumns.SENDER_FULL_NAME,
|
||||
ConversationMessageViewColumns.SENDER_PROFILE_PHOTO_URI,
|
||||
ConversationMessageViewColumns.PARTS_IDS,
|
||||
ConversationMessageViewColumns.PARTS_CONTENT_TYPES,
|
||||
ConversationMessageViewColumns.PARTS_CONTENT_URIS,
|
||||
ConversationMessageViewColumns.PARTS_WIDTHS,
|
||||
ConversationMessageViewColumns.PARTS_HEIGHTS,
|
||||
ConversationMessageViewColumns.PARTS_TEXTS,
|
||||
ConversationMessageViewColumns.PARTS_COUNT
|
||||
};
|
||||
|
||||
private final static String[] sGalleryCursorColumns = new String[] {
|
||||
Media._ID,
|
||||
Media.DATA,
|
||||
Media.WIDTH,
|
||||
Media.HEIGHT,
|
||||
Media.MIME_TYPE
|
||||
};
|
||||
|
||||
public static FakeCursor getConversationListCursor() {
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { Long.valueOf(1), "name1", "content://icon1",
|
||||
"snippetText1", "content://snippetUri1", Long.valueOf(10), 1,
|
||||
ContentType.IMAGE_JPEG, MessageData.BUGLE_STATUS_INCOMING_COMPLETE},
|
||||
new Object[] { Long.valueOf(2), "name2", "content://icon2",
|
||||
"snippetText2", "content://snippetUri2", Long.valueOf(20) + 24*60*60*1000,
|
||||
0, ContentType.IMAGE_JPEG, MessageData.BUGLE_STATUS_INCOMING_COMPLETE},
|
||||
new Object[] { Long.valueOf(3), "name3", "content://icon3",
|
||||
"snippetText3", "content://snippetUri3", Long.valueOf(30) + 2*24*60*60*1000,
|
||||
0, ContentType.IMAGE_JPEG, MessageData.BUGLE_STATUS_OUTGOING_COMPLETE}
|
||||
};
|
||||
return new FakeCursor(ConversationListItemData.PROJECTION, sConversationListCursorColumns,
|
||||
cursorData);
|
||||
}
|
||||
public static final int CONVERSATION_LIST_CURSOR_READ_MESSAGE_INDEX = 0;
|
||||
public static final int CONVERSATION_LIST_CURSOR_UNREAD_MESSAGE_INDEX = 1;
|
||||
|
||||
public static FakeCursor getEmptyConversationListCursor() {
|
||||
return new FakeCursor(ConversationListItemData.PROJECTION, sConversationListCursorColumns,
|
||||
new Object[][] {});
|
||||
}
|
||||
|
||||
public static FakeCursor getConversationMessageCursor() {
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { Long.valueOf(0), Long.valueOf(1), Long.valueOf(1),
|
||||
Long.valueOf(10), Long.valueOf(10),
|
||||
MessageData.BUGLE_STATUS_INCOMING_COMPLETE, "Alice", null,
|
||||
"0", "text/plain", "''", -1, -1, "msg0", 1},
|
||||
new Object[] { Long.valueOf(1), Long.valueOf(1), Long.valueOf(2),
|
||||
Long.valueOf(20), Long.valueOf(20),
|
||||
MessageData.BUGLE_STATUS_OUTGOING_COMPLETE, "Bob", null,
|
||||
"1", "text/plain", "''", -1, -1, "msg1", 1},
|
||||
new Object[] { Long.valueOf(2), Long.valueOf(1), Long.valueOf(1),
|
||||
Long.valueOf(30), Long.valueOf(30),
|
||||
MessageData.BUGLE_STATUS_OUTGOING_COMPLETE, "Alice", null,
|
||||
"2", "contentType3", "'content://fakeUri3'", "0", "0", "msg1", 1},
|
||||
new Object[] { Long.valueOf(3), Long.valueOf(1), Long.valueOf(1),
|
||||
Long.valueOf(40), Long.valueOf(40),
|
||||
MessageData.BUGLE_STATUS_OUTGOING_COMPLETE, "Alice", null,
|
||||
"3|4", "'contentType4'|'text/plain'", "'content://fakeUri4'|''", "0|-1", "0|-1", "''|'msg3'", 2},
|
||||
};
|
||||
return new FakeCursor(
|
||||
ConversationMessageData.getProjection(),
|
||||
sConversationMessageCursorColumns,
|
||||
cursorData);
|
||||
}
|
||||
|
||||
public static String getMessageText(final FakeCursor messageCursor, final int row) {
|
||||
final String allPartsText = messageCursor.getAt(ConversationMessageViewColumns.PARTS_TEXTS, row)
|
||||
.toString();
|
||||
final int partsCount = (Integer) messageCursor.getAt(
|
||||
ConversationMessageViewColumns.PARTS_COUNT, row);
|
||||
final String messageId = messageCursor.getAt(
|
||||
ConversationMessageViewColumns._ID, row).toString();
|
||||
final List<MessagePartData> parts = ConversationMessageData.makeParts(
|
||||
messageCursor.getAt(ConversationMessageViewColumns.PARTS_IDS, row).toString(),
|
||||
messageCursor.getAt(ConversationMessageViewColumns.PARTS_CONTENT_TYPES, row).toString(),
|
||||
messageCursor.getAt(ConversationMessageViewColumns.PARTS_CONTENT_URIS, row).toString(),
|
||||
messageCursor.getAt(ConversationMessageViewColumns.PARTS_WIDTHS, row).toString(),
|
||||
messageCursor.getAt(ConversationMessageViewColumns.PARTS_HEIGHTS, row).toString(),
|
||||
messageCursor.getAt(ConversationMessageViewColumns.PARTS_TEXTS, row).toString(),
|
||||
partsCount,
|
||||
messageId);
|
||||
|
||||
for (final MessagePartData part : parts) {
|
||||
if (part.isText()) {
|
||||
return part.getText();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Indexes where to find consecutive and non consecutive messages from same participant
|
||||
// (respect to index - 1).
|
||||
public static final int MESSAGE_WITH_SAME_PARTICIPANT_AS_PREVIOUS = 3;
|
||||
public static final int MESSAGE_WITH_DIFFERENT_PARTICIPANT_AS_PREVIOUS = 2;
|
||||
|
||||
public static FakeCursor getConversationParticipantsCursor() {
|
||||
final String[] sConversationParticipantsCursorColumns = new String[] {
|
||||
ParticipantColumns._ID,
|
||||
ParticipantColumns.SUB_ID,
|
||||
ParticipantColumns.NORMALIZED_DESTINATION,
|
||||
ParticipantColumns.SEND_DESTINATION,
|
||||
ParticipantColumns.FULL_NAME,
|
||||
ParticipantColumns.FIRST_NAME,
|
||||
ParticipantColumns.PROFILE_PHOTO_URI,
|
||||
};
|
||||
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { 1, ParticipantData.OTHER_THAN_SELF_SUB_ID, "+15554567890",
|
||||
"(555)456-7890", "alice in wonderland", "alice", "alice.png" },
|
||||
new Object[] { 2, ParticipantData.OTHER_THAN_SELF_SUB_ID, "+15551011121",
|
||||
"(555)101-1121", "bob the baker", "bob", "bob.png"},
|
||||
new Object[] { 3, ParticipantData.OTHER_THAN_SELF_SUB_ID, "+15551314152",
|
||||
"(555)131-4152", "charles in charge", "charles", "charles.png" },
|
||||
};
|
||||
|
||||
return new FakeCursor(ParticipantData.ParticipantsQuery.PROJECTION,
|
||||
sConversationParticipantsCursorColumns, cursorData);
|
||||
}
|
||||
|
||||
public static final int CONTACT_LIST_CURSOR_FIRST_LEVEL_CONTACT_INDEX = 0;
|
||||
public static final int CONTACT_LIST_CURSOR_SECOND_LEVEL_CONTACT_INDEX = 2;
|
||||
|
||||
/**
|
||||
* Returns a cursor for the all contacts list consumable by ContactPickerFragment.
|
||||
*/
|
||||
public static FakeCursor getAllContactListCursor() {
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { Long.valueOf(0), "John Smith", "content://uri1",
|
||||
"425-555-1234", Phone.TYPE_HOME, "", "0", Long.valueOf(0), 0 },
|
||||
new Object[] { Long.valueOf(1), "Sun Woo Kong", "content://uri2",
|
||||
"425-555-1235", Phone.TYPE_MOBILE, "", "1", Long.valueOf(1), 1 },
|
||||
new Object[] { Long.valueOf(1), "Sun Woo Kong", "content://uri2",
|
||||
"425-555-1238", Phone.TYPE_HOME, "", "1", Long.valueOf(2), 2 },
|
||||
new Object[] { Long.valueOf(2), "Anna Kinney", "content://uri3",
|
||||
"425-555-1236", Phone.TYPE_MAIN, "", "3", Long.valueOf(3), 3 },
|
||||
new Object[] { Long.valueOf(3), "Mike Jones", "content://uri3",
|
||||
"425-555-1236", Phone.TYPE_MAIN, "", "5", Long.valueOf(4), 4 },
|
||||
};
|
||||
return new FakeCursor(ContactUtil.PhoneQuery.PROJECTION, sContactCursorColumns,
|
||||
cursorData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a cursor for the frequent contacts list consumable by ContactPickerFragment.
|
||||
* Note: make it so that this cursor is the generated result of getStrequentContactsCursor()
|
||||
* and getAllContactListCursor(), i.e., expand the entries in getStrequentContactsCursor()
|
||||
* with the details from getAllContactListCursor()
|
||||
*/
|
||||
public static FakeCursor getFrequentContactListCursor() {
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { Long.valueOf(2), "Anna Kinney", "content://uri3",
|
||||
"425-555-1236", Phone.TYPE_MAIN, "", "3", Long.valueOf(3), 0 },
|
||||
new Object[] { Long.valueOf(1), "Sun Woo Kong", "content://uri2",
|
||||
"425-555-1235", Phone.TYPE_MOBILE, "", "1", Long.valueOf(1), 1},
|
||||
new Object[] { Long.valueOf(1), "Sun Woo Kong", "content://uri2",
|
||||
"425-555-1238", Phone.TYPE_HOME, "", "1", Long.valueOf(2), 2 },
|
||||
new Object[] { Long.valueOf(0), "John Smith", "content://uri1",
|
||||
"425-555-1234", Phone.TYPE_HOME, "", "0", Long.valueOf(0), 3 },
|
||||
};
|
||||
return new FakeCursor(ContactUtil.PhoneQuery.PROJECTION, sContactCursorColumns,
|
||||
cursorData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a strequent (starred + frequent) cursor (like the one produced by android contact
|
||||
* provider's CONTENT_STREQUENT_URI query) that's consumable by FrequentContactsCursorBuilder.
|
||||
*/
|
||||
public static FakeCursor getStrequentContactsCursor() {
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { Long.valueOf(0), "Anna Kinney", "content://uri1", "3" },
|
||||
new Object[] { Long.valueOf(1), "Sun Woo Kong", "content://uri2", "1" },
|
||||
new Object[] { Long.valueOf(2), "John Smith", "content://uri3", "0" },
|
||||
// Email-only entry that shouldn't be included in the result.
|
||||
new Object[] { Long.valueOf(3), "Email Contact", "content://uri4", "100" },
|
||||
};
|
||||
return new FakeCursor(ContactUtil.FrequentContactQuery.PROJECTION,
|
||||
sFrequentContactCursorColumns, cursorData);
|
||||
}
|
||||
|
||||
public static final int SMS_MMS_THREAD_ID_CURSOR_VALUE = 123456789;
|
||||
|
||||
public static FakeCursor getSmsMmsThreadIdCursor() {
|
||||
final String[] ID_PROJECTION = { BaseColumns._ID };
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { Long.valueOf(SMS_MMS_THREAD_ID_CURSOR_VALUE) },
|
||||
};
|
||||
return new FakeCursor(ID_PROJECTION, ID_PROJECTION, cursorData);
|
||||
}
|
||||
|
||||
public static FakeCursor getGalleryGridCursor() {
|
||||
final Object[][] cursorData = new Object[][] {
|
||||
new Object[] { Long.valueOf(0), "/sdcard/image1", 100, 100, "image/jpeg" },
|
||||
new Object[] { Long.valueOf(1), "/sdcard/image2", 200, 200, "image/png" },
|
||||
new Object[] { Long.valueOf(2), "/sdcard/image3", 300, 300, "image/jpeg" },
|
||||
};
|
||||
return new FakeCursor(GalleryGridItemData.MEDIA_PROJECTION, sGalleryCursorColumns,
|
||||
cursorData);
|
||||
}
|
||||
|
||||
public static final int NUM_TEST_CONVERSATIONS = 10;
|
||||
|
||||
/**
|
||||
* Create test data in our db.
|
||||
*
|
||||
* Ideally this will create more realistic data with more variety.
|
||||
*/
|
||||
public static void createTestData(final SQLiteDatabase db) {
|
||||
BugleDatabaseOperations.clearParticipantIdCache();
|
||||
|
||||
// Timestamp for 1 day ago
|
||||
final long yesterday = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
|
||||
|
||||
final ContentValues conversationValues = new ContentValues();
|
||||
for (int i = 1; i <= NUM_TEST_CONVERSATIONS; i++) {
|
||||
conversationValues.put(ConversationColumns.NAME, "Conversation " + i);
|
||||
final long conversationId = db.insert(DatabaseHelper.CONVERSATIONS_TABLE, null,
|
||||
conversationValues);
|
||||
|
||||
final ContentValues messageValues = new ContentValues();
|
||||
for (int m = 1; m <= 25; m++) {
|
||||
// Move forward ten minutes per conversation, 1 minute per message.
|
||||
final long messageTime = yesterday + (i * 10 * 60 * 1000) + (m * 60 * 1000);
|
||||
messageValues.put(MessageColumns.RECEIVED_TIMESTAMP, messageTime);
|
||||
messageValues.put(MessageColumns.CONVERSATION_ID, conversationId);
|
||||
messageValues.put(MessageColumns.SENDER_PARTICIPANT_ID,
|
||||
Math.abs(("" + messageTime).hashCode()) % 2);
|
||||
final long messageId = db.insert(DatabaseHelper.MESSAGES_TABLE, null, messageValues);
|
||||
|
||||
// Create a text part for this message
|
||||
final ContentValues partValues = new ContentValues();
|
||||
partValues.put(PartColumns.MESSAGE_ID, messageId);
|
||||
partValues.put(PartColumns.CONVERSATION_ID, conversationId);
|
||||
partValues.put(PartColumns.TEXT, "Conversation: " + conversationId +
|
||||
" Message: " + m);
|
||||
db.insert(DatabaseHelper.PARTS_TABLE, null, partValues);
|
||||
|
||||
// Update the snippet for this conversation to the latest message inserted
|
||||
conversationValues.clear();
|
||||
conversationValues.put(ConversationColumns.LATEST_MESSAGE_ID, messageId);
|
||||
final int updatedCount = db.update(DatabaseHelper.CONVERSATIONS_TABLE,
|
||||
conversationValues,
|
||||
"_id=?", new String[]{String.valueOf(conversationId)});
|
||||
Assert.isTrue(updatedCount == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<MessagePartData> getTestDraftAttachments() {
|
||||
final MessagePartData[] retParts = new MessagePartData[] {
|
||||
new MessagePartData(ContentType.IMAGE_JPEG, Uri.parse("content://image"),
|
||||
100, 100),
|
||||
new MessagePartData(ContentType.VIDEO_3GPP, Uri.parse("content://video"),
|
||||
100, 100),
|
||||
new MessagePartData(ContentType.TEXT_VCARD, Uri.parse("content://vcard"),
|
||||
0, 0),
|
||||
new MessagePartData(ContentType.AUDIO_3GPP, Uri.parse("content://audio"),
|
||||
0, 0)
|
||||
};
|
||||
return Arrays.asList(retParts);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.media;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FakeImageRequest implements MediaRequest<FakeImageResource> {
|
||||
public static final String INVALID_KEY = "invalid";
|
||||
private final String mKey;
|
||||
private final int mSize;
|
||||
|
||||
public FakeImageRequest(final String key, final int size) {
|
||||
mKey = key;
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FakeImageResource loadMediaBlocking(List<MediaRequest<FakeImageResource>> chainedTask)
|
||||
throws Exception {
|
||||
if (TextUtils.equals(mKey, INVALID_KEY)) {
|
||||
throw new Exception();
|
||||
} else {
|
||||
return new FakeImageResource(mSize, mKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCacheId() {
|
||||
return FakeMediaCacheManager.FAKE_IMAGE_CACHE;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public MediaCache<FakeImageResource> getMediaCache() {
|
||||
return (MediaCache<FakeImageResource>) MediaCacheManager.get().getOrCreateMediaCacheById(
|
||||
getCacheId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequestType() {
|
||||
return MediaRequest.REQUEST_LOAD_MEDIA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaRequestDescriptor<FakeImageResource> getDescriptor() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.media;
|
||||
|
||||
public class FakeImageResource extends RefCountedMediaResource {
|
||||
private boolean mClosed = false;
|
||||
private boolean mCached = false;
|
||||
private final int mSize;
|
||||
private final String mImageId;
|
||||
|
||||
public FakeImageResource(final int size, final String imageId) {
|
||||
super(null);
|
||||
mSize = size;
|
||||
mImageId = imageId;
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return mClosed;
|
||||
}
|
||||
|
||||
public String getImageId() {
|
||||
return mImageId;
|
||||
}
|
||||
|
||||
public void setCached(final boolean cached) {
|
||||
mCached = cached;
|
||||
}
|
||||
|
||||
public boolean getCached() {
|
||||
return mCached;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMediaSize() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close() {
|
||||
mClosed = true;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.media;
|
||||
|
||||
public class FakeMediaCacheManager extends MediaCacheManager {
|
||||
// List of available fake cache ids.
|
||||
public static final int FAKE_IMAGE_CACHE = 1;
|
||||
public static final int FAKE_BATCH_IMAGE_CACHE = 2;
|
||||
|
||||
@Override
|
||||
public MediaCache<?> createMediaCacheById(final int id) {
|
||||
switch (id) {
|
||||
case FAKE_IMAGE_CACHE:
|
||||
// Make a cache of only 3 KB of data.
|
||||
return new MediaCache<FakeImageResource>(3, FAKE_IMAGE_CACHE, "FakeImageCache");
|
||||
|
||||
case FAKE_BATCH_IMAGE_CACHE:
|
||||
return new MediaCache<FakeImageResource>(10, FAKE_BATCH_IMAGE_CACHE,
|
||||
"FakeBatchImageCache");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.media;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.MemoryCacheManager;
|
||||
import com.android.messaging.util.ImageUtils;
|
||||
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@SmallTest
|
||||
public class ImageRequestTest extends BugleTestCase {
|
||||
private static final int DOWNSAMPLE_IMAGE_SIZE = 2;
|
||||
|
||||
@Spy protected ImageUtils spyImageUtils;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getTestContext())
|
||||
.withMemoryCacheManager(new MemoryCacheManager())
|
||||
.withMediaCacheManager(new BugleMediaCacheManager());
|
||||
spyImageUtils = Mockito.spy(new ImageUtils());
|
||||
ImageUtils.set(spyImageUtils);
|
||||
}
|
||||
|
||||
public void testLoadImageUnspecifiedSize() {
|
||||
final String uriString = ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
|
||||
getContext().getPackageName() + "/" + R.drawable.ic_audio_light;
|
||||
final Uri uri = Uri.parse(uriString);
|
||||
final UriImageRequest imageRequest = new UriImageRequest(getContext(),
|
||||
new UriImageRequestDescriptor(uri));
|
||||
try {
|
||||
final ImageResource imageResource = imageRequest.loadMediaBlocking(null);
|
||||
final ArgumentCaptor<BitmapFactory.Options> options =
|
||||
ArgumentCaptor.forClass(BitmapFactory.Options.class);
|
||||
Mockito.verify(spyImageUtils).calculateInSampleSize(
|
||||
options.capture(),
|
||||
Matchers.eq(ImageRequest.UNSPECIFIED_SIZE),
|
||||
Matchers.eq(ImageRequest.UNSPECIFIED_SIZE));
|
||||
assertEquals(1, options.getValue().inSampleSize);
|
||||
assertNotNull(imageResource);
|
||||
assertNotNull(imageResource.getBitmap());
|
||||
|
||||
// Make sure there's no scaling on the bitmap.
|
||||
final int bitmapWidth = imageResource.getBitmap().getWidth();
|
||||
final int bitmapHeight = imageResource.getBitmap().getHeight();
|
||||
assertEquals(options.getValue().outWidth, bitmapWidth);
|
||||
assertEquals(options.getValue().outHeight, bitmapHeight);
|
||||
} catch (final IOException e) {
|
||||
fail("IO exception while trying to load image resource");
|
||||
}
|
||||
}
|
||||
|
||||
public void testLoadImageWithDownsampling() {
|
||||
final String uriString = ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
|
||||
getContext().getPackageName() + "/" + R.drawable.ic_audio_light;
|
||||
final Uri uri = Uri.parse(uriString);
|
||||
final UriImageRequest imageRequest = new UriImageRequest(getContext(),
|
||||
new UriImageRequestDescriptor(uri, DOWNSAMPLE_IMAGE_SIZE, DOWNSAMPLE_IMAGE_SIZE,
|
||||
false, true /* isStatic */, false /* cropToCircle */,
|
||||
ImageUtils.DEFAULT_CIRCLE_BACKGROUND_COLOR /* circleBackgroundColor */,
|
||||
ImageUtils.DEFAULT_CIRCLE_STROKE_COLOR /* circleStrokeColor */));
|
||||
try {
|
||||
final ImageResource imageResource = imageRequest.loadMediaBlocking(null);
|
||||
final ArgumentCaptor<BitmapFactory.Options> options =
|
||||
ArgumentCaptor.forClass(BitmapFactory.Options.class);
|
||||
Mockito.verify(spyImageUtils).calculateInSampleSize(
|
||||
options.capture(),
|
||||
Matchers.eq(DOWNSAMPLE_IMAGE_SIZE), Matchers.eq(DOWNSAMPLE_IMAGE_SIZE));
|
||||
assertNotSame(1, options.getValue().inSampleSize);
|
||||
assertNotNull(imageResource);
|
||||
assertNotNull(imageResource.getBitmap());
|
||||
|
||||
// Make sure there's down sampling on the bitmap.
|
||||
final int bitmapWidth = imageResource.getBitmap().getWidth();
|
||||
final int bitmapHeight = imageResource.getBitmap().getHeight();
|
||||
assertTrue(bitmapWidth >= DOWNSAMPLE_IMAGE_SIZE &&
|
||||
bitmapHeight >= DOWNSAMPLE_IMAGE_SIZE &&
|
||||
(bitmapWidth <= DOWNSAMPLE_IMAGE_SIZE * 4 ||
|
||||
bitmapHeight <= DOWNSAMPLE_IMAGE_SIZE * 4));
|
||||
} catch (final IOException e) {
|
||||
fail("IO exception while trying to load image resource");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.datamodel.media;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.MemoryCacheManager;
|
||||
import com.android.messaging.datamodel.media.MediaResourceManager.MediaResourceLoadListener;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
@SmallTest
|
||||
public class MediaResourceManagerTest extends BugleTestCase {
|
||||
private static final int KB = 1024;
|
||||
|
||||
// Loaded image resource from the MediaResourceManager callback.
|
||||
private FakeImageResource mImageResource;
|
||||
private BindableMediaRequest<FakeImageResource> mImageRequest;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getTestContext())
|
||||
.withMemoryCacheManager(new MemoryCacheManager())
|
||||
.withMediaCacheManager(new FakeMediaCacheManager());
|
||||
}
|
||||
|
||||
public void testLoadFromCache() {
|
||||
final MediaResourceManager mediaResourceManager =
|
||||
new MediaResourceManager();
|
||||
MediaCacheManager.get().reclaim();
|
||||
assertNotNull(mediaResourceManager);
|
||||
|
||||
// Load one image of 1KB
|
||||
loadImage(mediaResourceManager, "image1", 1 * KB, false /* shouldBeCached */, false);
|
||||
assertEquals("image1", mImageResource.getImageId());
|
||||
final FakeImageResource loadedResource = mImageResource;
|
||||
|
||||
// Load the same image.
|
||||
loadImage(mediaResourceManager, "image1", 1 * KB, true /* shouldBeCached */, false);
|
||||
assertEquals(loadedResource, mImageResource);
|
||||
}
|
||||
|
||||
public void testCacheEviction() {
|
||||
final MediaResourceManager mediaResourceManager =
|
||||
new MediaResourceManager();
|
||||
MediaCacheManager.get().reclaim();
|
||||
assertNotNull(mediaResourceManager);
|
||||
|
||||
// Load one image of 1KB
|
||||
loadImage(mediaResourceManager, "image1", 1 * KB, false /* shouldBeCached */, false);
|
||||
assertEquals("image1", mImageResource.getImageId());
|
||||
|
||||
// Load another image
|
||||
loadImage(mediaResourceManager, "image2", 2 * KB, false /* shouldBeCached */, false);
|
||||
assertEquals("image2", mImageResource.getImageId());
|
||||
|
||||
// Load another image. This should fill the cache and cause eviction of image1.
|
||||
loadImage(mediaResourceManager, "image3", 2 * KB, false /* shouldBeCached */, false);
|
||||
assertEquals("image3", mImageResource.getImageId());
|
||||
|
||||
// Load image1. It shouldn't be cached any more.
|
||||
loadImage(mediaResourceManager, "image1", 1 * KB, false /* shouldBeCached */, false);
|
||||
assertEquals("image1", mImageResource.getImageId());
|
||||
}
|
||||
|
||||
public void testReclaimMemoryFromMediaCache() {
|
||||
final MediaResourceManager mediaResourceManager =
|
||||
new MediaResourceManager();
|
||||
MediaCacheManager.get().reclaim();
|
||||
assertNotNull(mediaResourceManager);
|
||||
|
||||
// Load one image of 1KB
|
||||
loadImage(mediaResourceManager, "image1", 1 * KB, false /* shouldBeCached */, false);
|
||||
assertEquals("image1", mImageResource.getImageId());
|
||||
|
||||
// Purge everything from the cache, now the image should no longer be cached.
|
||||
MediaCacheManager.get().reclaim();
|
||||
|
||||
// The image resource should have no ref left.
|
||||
assertEquals(0, mImageResource.getRefCount());
|
||||
assertTrue(mImageResource.isClosed());
|
||||
loadImage(mediaResourceManager, "image1", 1 * KB, false /* shouldBeCached */, false);
|
||||
assertEquals("image1", mImageResource.getImageId());
|
||||
}
|
||||
|
||||
public void testLoadInvalidImage() {
|
||||
final MediaResourceManager mediaResourceManager =
|
||||
new MediaResourceManager();
|
||||
MediaCacheManager.get().reclaim();
|
||||
assertNotNull(mediaResourceManager);
|
||||
|
||||
// Test the failure case with invalid resource.
|
||||
loadImage(mediaResourceManager, FakeImageRequest.INVALID_KEY, 1 * KB, false,
|
||||
true /* shouldFail */);
|
||||
}
|
||||
|
||||
public void testLoadImageSynchronously() {
|
||||
final MediaResourceManager mediaResourceManager =
|
||||
new MediaResourceManager();
|
||||
MediaCacheManager.get().reclaim();
|
||||
assertNotNull(mediaResourceManager);
|
||||
|
||||
// Test a normal sync load.
|
||||
final FakeImageRequest request = new FakeImageRequest("image1", 1 * KB);
|
||||
final FakeImageResource resource = mediaResourceManager.requestMediaResourceSync(request);
|
||||
assertNotNull(resource);
|
||||
assertFalse(resource.isClosed());
|
||||
assertNotSame(0, resource.getRefCount());
|
||||
resource.release();
|
||||
|
||||
// Test a failed sync load.
|
||||
final FakeImageRequest invalidRequest =
|
||||
new FakeImageRequest(FakeImageRequest.INVALID_KEY, 1 * KB);
|
||||
assertNull(mediaResourceManager.requestMediaResourceSync(invalidRequest));
|
||||
}
|
||||
|
||||
private void loadImage(final MediaResourceManager manager, final String key,
|
||||
final int size, final boolean shouldBeCached, final boolean shouldFail) {
|
||||
try {
|
||||
final CountDownLatch signal = new CountDownLatch(1);
|
||||
mImageRequest = AsyncMediaRequestWrapper.createWith(new FakeImageRequest(key, size),
|
||||
createAssertListener(shouldBeCached, shouldFail, signal));
|
||||
mImageRequest.bind("1");
|
||||
manager.requestMediaResourceAsync(mImageRequest);
|
||||
|
||||
// Wait for the asynchronous callback before proceeding.
|
||||
signal.await();
|
||||
} catch (final InterruptedException e) {
|
||||
fail("Something interrupted the signal await.");
|
||||
}
|
||||
}
|
||||
|
||||
private MediaResourceLoadListener<FakeImageResource> createAssertListener(
|
||||
final boolean shouldBeCached, final boolean shouldFail, final CountDownLatch signal) {
|
||||
return new MediaResourceLoadListener<FakeImageResource>() {
|
||||
@Override
|
||||
public void onMediaResourceLoaded(final MediaRequest<FakeImageResource> request,
|
||||
final FakeImageResource resource, final boolean isCached) {
|
||||
assertEquals(mImageRequest, request);
|
||||
assertNotNull(resource);
|
||||
assertFalse(resource.isClosed());
|
||||
assertNotSame(0, resource.getRefCount());
|
||||
assertFalse(shouldFail);
|
||||
assertEquals(shouldBeCached, resource.getCached());
|
||||
resource.setCached(true);
|
||||
mImageResource = resource;
|
||||
signal.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaResourceLoadError(
|
||||
final MediaRequest<FakeImageResource> request, final Exception exception) {
|
||||
assertTrue(shouldFail);
|
||||
mImageResource = null;
|
||||
signal.countDown();
|
||||
}};
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
|
||||
/**
|
||||
* Purpose of this class is providing a workaround for https://b/14561718
|
||||
*/
|
||||
public class ActivityInstrumentationTestCaseIntent extends Intent {
|
||||
public ActivityInstrumentationTestCaseIntent(Context packageContext, Class<?> cls) {
|
||||
super(packageContext, cls);
|
||||
}
|
||||
@Override
|
||||
public Intent setComponent(ComponentName component) {
|
||||
// Ignore the ComponentName set, as the one ActivityUnitTest does is wrong (and actually
|
||||
// unnecessary).
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.TestUtil;
|
||||
|
||||
/**
|
||||
* Helper class that extends ActivityInstrumentationTestCase2 to provide some extra common
|
||||
* initialization (eg. Mockito boilerplate).
|
||||
*/
|
||||
public class BugleActivityInstrumentationTestCase<T extends Activity>
|
||||
extends android.test.ActivityInstrumentationTestCase2<T> {
|
||||
|
||||
static {
|
||||
// Set flag during loading of test cases to prevent application initialization starting
|
||||
BugleTestCase.setTestsRunning();
|
||||
}
|
||||
|
||||
public BugleActivityInstrumentationTestCase(final Class<T> activityClass) {
|
||||
super(activityClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
setActivityInitialTouchMode(false);
|
||||
TestUtil.testSetup(getInstrumentation().getTargetContext(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
TestUtil.testTeardown(this);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public abstract class BugleActivityTest extends BugleActivityUnitTestCase<BugleActionBarActivity> {
|
||||
@Mock protected DataModel mDataModel;
|
||||
|
||||
public BugleActivityTest() {
|
||||
super(BugleActionBarActivity.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// Create activity
|
||||
final ActivityInstrumentationTestCaseIntent intent =
|
||||
new ActivityInstrumentationTestCaseIntent(getInstrumentation().getTargetContext(),
|
||||
TestActivity.class);
|
||||
startActivity(intent, null, null);
|
||||
|
||||
FakeFactory.register(getInstrumentation().getTargetContext())
|
||||
.withDataModel(mDataModel);
|
||||
}
|
||||
|
||||
public void testOnResumeDataModelCallback() {
|
||||
getInstrumentation().callActivityOnStart(getActivity());
|
||||
getInstrumentation().callActivityOnResume(getActivity());
|
||||
Mockito.verify(mDataModel).onActivityResume();
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.ContextThemeWrapper;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.TestUtil;
|
||||
|
||||
/**
|
||||
* Base class for activity unit test cases, provides boilerplate setup/teardown.
|
||||
*/
|
||||
public abstract class BugleActivityUnitTestCase<T extends Activity> extends
|
||||
android.test.ActivityUnitTestCase<T> {
|
||||
|
||||
static {
|
||||
// Set flag during loading of test cases to prevent application initialization starting
|
||||
BugleTestCase.setTestsRunning();
|
||||
}
|
||||
|
||||
public BugleActivityUnitTestCase(final Class<T> activityClass) {
|
||||
super(activityClass);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
TestUtil.testSetup(getInstrumentation().getTargetContext(), this);
|
||||
|
||||
setActivityContext(new ContextThemeWrapper(getInstrumentation().getTargetContext(),
|
||||
R.style.Theme_AppCompat_Light_DarkActionBar));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
TestUtil.testTeardown(this);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.SimpleCursorAdapter;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
|
||||
public class CustomHeaderViewPagerTest extends ViewTest<CustomHeaderViewPager> {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getInstrumentation().getTargetContext());
|
||||
}
|
||||
|
||||
public void testBindFirstLevel() {
|
||||
final CustomHeaderViewPager view = new CustomHeaderViewPager(getActivity(), null);
|
||||
final SimpleCursorAdapter adapter =
|
||||
new SimpleCursorAdapter(getActivity(), 0, null, null, null, 0);
|
||||
final CustomHeaderPagerViewHolder[] viewHolders = {
|
||||
new FakeListViewHolder(getActivity(), adapter),
|
||||
new FakeListViewHolder(getActivity(), adapter)
|
||||
};
|
||||
|
||||
view.setViewHolders(viewHolders);
|
||||
final ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
|
||||
final ViewGroup tabStrip = (ViewGroup) view.findViewById(R.id.tab_strip);
|
||||
final ViewPagerTabStrip realTab = (ViewPagerTabStrip) tabStrip.getChildAt(0);
|
||||
|
||||
assertEquals(2, realTab.getChildCount());
|
||||
View headerTitleButton = realTab.getChildAt(1);
|
||||
// Click on the first page. Now the view pager should switch to that page accordingly.
|
||||
clickButton(headerTitleButton);
|
||||
assertEquals(1, pager.getCurrentItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
// All set up should be done by creating a CustomHeaderViewPager which handles inflating
|
||||
// the layout
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.CursorAdapter;
|
||||
|
||||
import com.android.messaging.R;
|
||||
|
||||
/**
|
||||
* A fake {@link CustomHeaderPagerListViewHolder} for CustomHeaderViewPager tests only.
|
||||
*/
|
||||
public class FakeListViewHolder extends CustomHeaderPagerListViewHolder {
|
||||
public FakeListViewHolder(final Context context, final CursorAdapter adapter) {
|
||||
super(context, adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutResId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPageTitleResId() {
|
||||
return android.R.string.untitled;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyViewResId() {
|
||||
return R.id.empty_view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getListViewResId() {
|
||||
return android.R.id.list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyViewTitleResId() {
|
||||
return R.string.contact_list_empty_text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyViewImageResId() {
|
||||
return R.drawable.ic_oobe_freq_list;
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Helper class that extends Bugle.ui.ActivityInstrumentationTestCase to provide common behavior
|
||||
* across fragment tests.
|
||||
*/
|
||||
public abstract class FragmentTestCase<T extends Fragment>
|
||||
extends BugleActivityInstrumentationTestCase<TestActivity> {
|
||||
|
||||
protected T mFragment;
|
||||
protected Class<T> mFragmentClass;
|
||||
|
||||
public FragmentTestCase(final Class<T> fragmentClass) {
|
||||
super(TestActivity.class);
|
||||
mFragmentClass = fragmentClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
protected T getFragment() {
|
||||
// Fragment creation deferred (typically until test time) so that factory/appcontext is
|
||||
// ready.
|
||||
if (mFragment == null) {
|
||||
try {
|
||||
mFragment = mFragmentClass.newInstance();
|
||||
} catch (final InstantiationException e) {
|
||||
throw new IllegalStateException("Failed to instantiate fragment");
|
||||
} catch (final IllegalAccessException e) {
|
||||
throw new IllegalStateException("Failed to instantiate fragment");
|
||||
}
|
||||
}
|
||||
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
protected void attachFragment() {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final FragmentManager fragmentManager = getActivity().getFragmentManager();
|
||||
fragmentManager.beginTransaction().add(mFragment, null /* tag */).commit();
|
||||
}
|
||||
});
|
||||
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
// In landscape mode, sleep for a second first.
|
||||
// The reason is: our UI tests don't wait for the UI thread to finish settling down
|
||||
// before exiting (because they can't know when the UI thread is done). In portrait mode,
|
||||
// things generally work fine here -- the UI thread is done by the time the test is done.
|
||||
// In landscape mode, though, since the launcher is in portrait mode, there is a lot of
|
||||
// extra work that happens in our UI when the app launches into landscape mode, and the
|
||||
// UI is often not done by the time the test finishes running. So then our teardown
|
||||
// nulls out the Factory, and then the UI keeps running and derefs the null factory,
|
||||
// and things blow up.
|
||||
// So ... as a cheap hack, sleep for one second before finishing the teardown of UI
|
||||
// tests, but only do it in landscape mode (so that developers running it in portrait
|
||||
// mode can still run the tests faster).
|
||||
if (this.getInstrumentation().getTargetContext().getResources().
|
||||
getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected void clickButton(final View view) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.performClick();
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
protected void setFocus(final View view, final boolean focused) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (focused) {
|
||||
view.requestFocus();
|
||||
} else {
|
||||
view.clearFocus();
|
||||
}
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.datamodel.data.MessagePartData;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
@MediumTest
|
||||
public class MultiAttachmentLayoutTest extends ViewTest<MultiAttachmentLayout> {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final Context context = getInstrumentation().getTargetContext();
|
||||
FakeFactory.register(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiAttachmentLayout getView() {
|
||||
if (mView == null) {
|
||||
// View creation deferred (typically until test time) so that factory/appcontext is
|
||||
// ready.
|
||||
mView = new MultiAttachmentLayout(getActivity(), null);
|
||||
mView.setLayoutParams(new ViewGroup.LayoutParams(100, 100));
|
||||
}
|
||||
return mView;
|
||||
}
|
||||
|
||||
protected void verifyContent(
|
||||
final MultiAttachmentLayout view,
|
||||
final int imageCount,
|
||||
final int plusCount) {
|
||||
final int count = view.getChildCount();
|
||||
int actualImageCount = 0;
|
||||
final boolean needPlusText = plusCount > 0;
|
||||
boolean hasPlusText = false;
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = view.getChildAt(i);
|
||||
if (child instanceof AsyncImageView) {
|
||||
actualImageCount++;
|
||||
} else if (child instanceof TextView) {
|
||||
assertTrue(plusCount > 0);
|
||||
assertTrue(((TextView) child).getText().toString().contains("" + plusCount));
|
||||
hasPlusText = true;
|
||||
} else {
|
||||
// Nothing other than image and overflow text view should appear in this layout.
|
||||
fail("unexpected view in layout. view = " + child);
|
||||
}
|
||||
}
|
||||
assertEquals(imageCount, actualImageCount);
|
||||
assertEquals(needPlusText, hasPlusText);
|
||||
}
|
||||
|
||||
public void testBindTwoAttachments() {
|
||||
final MultiAttachmentLayout view = getView();
|
||||
final MessagePartData testAttachment1 = MessagePartData.createMediaMessagePart(
|
||||
"image/jpeg", Uri.parse("content://uri1"), 100, 100);
|
||||
final MessagePartData testAttachment2 = MessagePartData.createMediaMessagePart(
|
||||
"image/jpeg", Uri.parse("content://uri2"), 100, 100);
|
||||
|
||||
view.bindAttachments(createAttachmentList(testAttachment1, testAttachment2),
|
||||
null /* transitionRect */, 2);
|
||||
verifyContent(view, 2, 0);
|
||||
}
|
||||
|
||||
public void testBindFiveAttachments() {
|
||||
final MultiAttachmentLayout view = getView();
|
||||
final MessagePartData testAttachment1 = MessagePartData.createMediaMessagePart(
|
||||
"image/jpeg", Uri.parse("content://uri1"), 100, 100);
|
||||
final MessagePartData testAttachment2 = MessagePartData.createMediaMessagePart(
|
||||
"image/jpeg", Uri.parse("content://uri2"), 100, 100);
|
||||
final MessagePartData testAttachment3 = MessagePartData.createMediaMessagePart(
|
||||
"image/jpeg", Uri.parse("content://uri3"), 100, 100);
|
||||
final MessagePartData testAttachment4 = MessagePartData.createMediaMessagePart(
|
||||
"image/jpeg", Uri.parse("content://uri4"), 100, 100);
|
||||
final MessagePartData testAttachment5 = MessagePartData.createMediaMessagePart(
|
||||
"image/jpeg", Uri.parse("content://uri5"), 100, 100);
|
||||
|
||||
view.bindAttachments(createAttachmentList(testAttachment1, testAttachment2, testAttachment3,
|
||||
testAttachment4, testAttachment5), null /* transitionRect */, 5);
|
||||
verifyContent(view, 4, 1);
|
||||
}
|
||||
|
||||
public void testBindTwice() {
|
||||
// Put the above two tests together so we can simulate binding twice.
|
||||
testBindTwoAttachments();
|
||||
testBindFiveAttachments();
|
||||
}
|
||||
|
||||
private Iterable<MessagePartData> createAttachmentList(final MessagePartData... attachments) {
|
||||
return Collections.unmodifiableList(Arrays.asList(attachments));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
return 0; // We construct the view with getView().
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for view tests. Derived class just has to provide a layout id. Tests can then just
|
||||
* call getView() to get a created view and test its behavior.
|
||||
*/
|
||||
public abstract class ViewTest<T extends View> extends BugleActivityUnitTestCase<TestActivity> {
|
||||
public ViewTest() {
|
||||
super(TestActivity.class);
|
||||
}
|
||||
|
||||
protected T mView;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// Create activity
|
||||
final ActivityInstrumentationTestCaseIntent intent =
|
||||
new ActivityInstrumentationTestCaseIntent(getInstrumentation().getTargetContext(),
|
||||
TestActivity.class);
|
||||
startActivity(intent, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T getView() {
|
||||
if (mView == null) {
|
||||
// View creation deferred (typically until test time) so that factory/appcontext is
|
||||
// ready.
|
||||
mView = (T) getActivity().getLayoutInflater().inflate(getLayoutIdForView(), null);
|
||||
}
|
||||
return mView;
|
||||
}
|
||||
|
||||
protected void clickButton(final View view) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
view.performClick();
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
protected abstract int getLayoutIdForView();
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.attachmentchooser;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData;
|
||||
import com.android.messaging.datamodel.data.MessageData;
|
||||
import com.android.messaging.datamodel.data.MessagePartData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.ui.FragmentTestCase;
|
||||
import com.android.messaging.ui.TestActivity.FragmentEventListener;
|
||||
import com.android.messaging.ui.attachmentchooser.AttachmentChooserFragment.AttachmentChooserFragmentHost;
|
||||
import com.android.messaging.ui.conversationlist.ConversationListFragment;
|
||||
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ConversationListFragment}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class AttachmentChooserFragmentTest extends FragmentTestCase<AttachmentChooserFragment> {
|
||||
|
||||
@Mock protected DataModel mockDataModel;
|
||||
@Mock protected DraftMessageData mockDraftMessageData;
|
||||
@Mock protected AttachmentChooserFragmentHost mockHost;
|
||||
|
||||
private static final String CONVERSATION_ID = "cid";
|
||||
|
||||
/** A custom argument matcher that checks whether the set argument passed in is a set
|
||||
* with identical attachment data as the given set.
|
||||
*/
|
||||
private class IsSetOfGivenAttachments implements ArgumentMatcher<Set<MessagePartData>> {
|
||||
private final Set<MessagePartData> mGivenParts;
|
||||
public IsSetOfGivenAttachments(final Set<MessagePartData> givenParts) {
|
||||
mGivenParts = givenParts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(final Set<MessagePartData> actualSet) {
|
||||
if (actualSet.size() != mGivenParts.size()) {
|
||||
return false;
|
||||
}
|
||||
return mGivenParts.containsAll(actualSet) && actualSet.containsAll(mGivenParts);
|
||||
}
|
||||
}
|
||||
|
||||
public AttachmentChooserFragmentTest() {
|
||||
super(AttachmentChooserFragment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(this.getInstrumentation().getTargetContext())
|
||||
.withDataModel(mockDataModel);
|
||||
}
|
||||
|
||||
private void loadWith(final List<MessagePartData> attachments) {
|
||||
Mockito.when(mockDraftMessageData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
Mockito.doReturn(mockDraftMessageData)
|
||||
.when(mockDataModel)
|
||||
.createDraftMessageData(Mockito.anyString());
|
||||
Mockito.doReturn(attachments)
|
||||
.when(mockDraftMessageData)
|
||||
.getReadOnlyAttachments();
|
||||
Mockito.when(mockDataModel.createDraftMessageData(
|
||||
Matchers.anyString()))
|
||||
.thenReturn(mockDraftMessageData);
|
||||
|
||||
// Create fragment synchronously to avoid need for volatile, synchronization etc.
|
||||
final AttachmentChooserFragment fragment = getFragment();
|
||||
// Binding to model happens when attaching fragment to activity, so hook into test
|
||||
// activity to do so.
|
||||
getActivity().setFragmentEventListener(new FragmentEventListener() {
|
||||
@Override
|
||||
public void onAttachFragment(final Fragment attachedFragment) {
|
||||
if (fragment == attachedFragment) {
|
||||
fragment.setConversationId(CONVERSATION_ID);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fragment.setHost(mockHost);
|
||||
getActivity().setFragment(fragment);
|
||||
Mockito.verify(mockDataModel).createDraftMessageData(
|
||||
Mockito.matches(CONVERSATION_ID));
|
||||
Mockito.verify(mockDraftMessageData).loadFromStorage(
|
||||
Matchers.eq(fragment.mBinding), Matchers.eq((MessageData) null),
|
||||
Matchers.eq(false));
|
||||
}
|
||||
});
|
||||
// Now load the cursor
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fragment.onDraftChanged(mockDraftMessageData, DraftMessageData.ALL_CHANGED);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testUnselect() {
|
||||
final List<MessagePartData> attachments = TestDataFactory.getTestDraftAttachments();
|
||||
loadWith(attachments);
|
||||
final AttachmentGridView attachmentGridView = (AttachmentGridView)
|
||||
getFragment().getView().findViewById(R.id.grid);
|
||||
assertEquals("bad view count", attachments.size(),
|
||||
attachmentGridView.getAdapter().getCount());
|
||||
|
||||
final AttachmentGridItemView itemView = (AttachmentGridItemView)
|
||||
attachmentGridView.getChildAt(0);
|
||||
assertEquals(attachmentGridView, itemView.testGetHostInterface());
|
||||
final CheckBox checkBox = (CheckBox) itemView.findViewById(R.id.checkbox);
|
||||
assertEquals(true, checkBox.isChecked());
|
||||
assertEquals(true, attachmentGridView.isItemSelected(itemView.mAttachmentData));
|
||||
clickButton(checkBox);
|
||||
assertEquals(false, checkBox.isChecked());
|
||||
assertEquals(false, attachmentGridView.isItemSelected(itemView.mAttachmentData));
|
||||
|
||||
final AttachmentGridItemView itemView2 = (AttachmentGridItemView)
|
||||
attachmentGridView.getChildAt(1);
|
||||
final CheckBox checkBox2 = (CheckBox) itemView2.findViewById(R.id.checkbox);
|
||||
clickButton(checkBox2);
|
||||
|
||||
getFragment().confirmSelection();
|
||||
final MessagePartData[] attachmentsToRemove = new MessagePartData[] {
|
||||
itemView.mAttachmentData, itemView2.mAttachmentData };
|
||||
Mockito.verify(mockDraftMessageData).removeExistingAttachments(Matchers.argThat(
|
||||
new IsSetOfGivenAttachments(new HashSet<>(Arrays.asList(attachmentsToRemove)))));
|
||||
Mockito.verify(mockDraftMessageData).saveToStorage(Matchers.eq(getFragment().mBinding));
|
||||
Mockito.verify(mockHost).onConfirmSelection();
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.contact;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.data.ContactListItemData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.ui.ContactIconView;
|
||||
import com.android.messaging.ui.ViewTest;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class ContactListItemViewTest extends ViewTest<ContactListItemView> {
|
||||
|
||||
@Mock ContactListItemView.HostInterface mockHost;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final Context context = getInstrumentation().getTargetContext();
|
||||
FakeFactory.register(context)
|
||||
.withDataModel(new FakeDataModel(context));
|
||||
}
|
||||
|
||||
protected void verifyAddedContactForData(final ContactListItemData data,
|
||||
final ContactListItemView view) {
|
||||
Mockito.verify(mockHost).onContactListItemClicked(data, view);
|
||||
}
|
||||
|
||||
protected void verifyContent(
|
||||
final ContactListItemView view,
|
||||
final String contactName,
|
||||
final String contactDetail,
|
||||
final String avatarUrl,
|
||||
final boolean showAvatar) {
|
||||
final TextView contactNameView = (TextView) view.findViewById(R.id.contact_name);
|
||||
final TextView contactDetailView = (TextView) view.findViewById(R.id.contact_details);
|
||||
final ContactIconView avatarView = (ContactIconView) view.findViewById(R.id.contact_icon);
|
||||
|
||||
assertNotNull(contactNameView);
|
||||
assertEquals(contactName, contactNameView.getText());
|
||||
assertNotNull(contactDetail);
|
||||
assertEquals(contactDetail, contactDetailView.getText());
|
||||
assertNotNull(avatarView);
|
||||
if (showAvatar) {
|
||||
assertTrue(avatarView.mImageRequestBinding.isBound());
|
||||
assertEquals(View.VISIBLE, avatarView.getVisibility());
|
||||
} else {
|
||||
assertFalse(avatarView.mImageRequestBinding.isBound());
|
||||
assertEquals(View.INVISIBLE, avatarView.getVisibility());
|
||||
}
|
||||
}
|
||||
|
||||
public void testBindFirstLevel() {
|
||||
final ContactListItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getAllContactListCursor();
|
||||
final int row = TestDataFactory.CONTACT_LIST_CURSOR_FIRST_LEVEL_CONTACT_INDEX;
|
||||
cursor.moveToPosition(row);
|
||||
view.bind(cursor, mockHost, false, null);
|
||||
verifyContent(view, (String) cursor.getAt(Contacts.DISPLAY_NAME, row),
|
||||
(String) cursor.getAt(Phone.NUMBER, row),
|
||||
(String) cursor.getAt(Contacts.PHOTO_THUMBNAIL_URI, row), true);
|
||||
}
|
||||
|
||||
public void testBindSecondLevel() {
|
||||
final ContactListItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getAllContactListCursor();
|
||||
final int row = TestDataFactory.CONTACT_LIST_CURSOR_SECOND_LEVEL_CONTACT_INDEX;
|
||||
cursor.moveToPosition(row);
|
||||
view.bind(cursor, mockHost, false, null);
|
||||
verifyContent(view, (String) cursor.getAt(Contacts.DISPLAY_NAME, row),
|
||||
(String) cursor.getAt(Phone.NUMBER, row),
|
||||
(String) cursor.getAt(Contacts.PHOTO_THUMBNAIL_URI, row), false);
|
||||
}
|
||||
|
||||
public void testClickAddedContact() {
|
||||
final ContactListItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getAllContactListCursor();
|
||||
cursor.moveToFirst();
|
||||
|
||||
view.bind(cursor, mockHost, false, null);
|
||||
view.performClick();
|
||||
verifyAddedContactForData(view.mData, view);
|
||||
}
|
||||
|
||||
public void testBindTwice() {
|
||||
final ContactListItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getAllContactListCursor();
|
||||
|
||||
cursor.moveToFirst();
|
||||
view.bind(cursor, mockHost, false, null);
|
||||
|
||||
cursor.moveToNext();
|
||||
view.bind(cursor, mockHost, false, null);
|
||||
verifyContent(view, (String) cursor.getAt(Contacts.DISPLAY_NAME, 1),
|
||||
(String) cursor.getAt(Phone.NUMBER, 1),
|
||||
(String) cursor.getAt(Contacts.PHOTO_THUMBNAIL_URI, 1), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
return R.layout.contact_list_item_view;
|
||||
}
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.contact;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.view.View;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers;
|
||||
import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService;
|
||||
import com.android.messaging.datamodel.action.GetOrCreateConversationAction;
|
||||
import com.android.messaging.datamodel.data.ContactPickerData;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.ui.CustomHeaderViewPagerAdapter;
|
||||
import com.android.messaging.ui.FragmentTestCase;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.ui.contact.ContactPickerFragment.ContactPickerFragmentHost;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ContactPickerFragment}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class ContactPickerFragmentTest
|
||||
extends FragmentTestCase<ContactPickerFragment> {
|
||||
|
||||
@Mock protected ContactPickerData mMockContactPickerData;
|
||||
@Mock protected UIIntents mMockUIIntents;
|
||||
@Mock protected ContactPickerFragmentHost mockHost;
|
||||
protected FakeDataModel mFakeDataModel;
|
||||
private ActionTestHelpers.StubActionService mService;
|
||||
|
||||
public ContactPickerFragmentTest() {
|
||||
super(ContactPickerFragment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
final Context context = getInstrumentation().getTargetContext();
|
||||
mService = new StubActionService();
|
||||
mFakeDataModel = new FakeDataModel(context)
|
||||
.withContactPickerData(mMockContactPickerData)
|
||||
.withActionService(mService);
|
||||
FakeFactory.register(context)
|
||||
.withDataModel(mFakeDataModel)
|
||||
.withUIIntents(mMockUIIntents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to initialize the ContactPickerFragment and its data.
|
||||
*/
|
||||
private ContactPickerFragmentTest initFragment(final int initialMode) {
|
||||
Mockito.when(mMockContactPickerData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final ContactPickerFragment fragment = getFragment();
|
||||
fragment.setHost(mockHost);
|
||||
fragment.setContactPickingMode(initialMode, false);
|
||||
|
||||
getActivity().setFragment(fragment);
|
||||
Mockito.verify(mMockContactPickerData).init(fragment.getLoaderManager(),
|
||||
fragment.mBinding);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the datamodel with all contacts cursor to populate the all contacts list in the
|
||||
* fragment.
|
||||
*/
|
||||
private ContactPickerFragmentTest loadWithAllContactsCursor(final Cursor cursor) {
|
||||
Mockito.when(mMockContactPickerData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getFragment().onAllContactsCursorUpdated(cursor);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the datamodel with frequent contacts cursor to populate the contacts list in the
|
||||
* fragment.
|
||||
*/
|
||||
private ContactPickerFragmentTest loadWithFrequentContactsCursor(final Cursor cursor) {
|
||||
Mockito.when(mMockContactPickerData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getFragment().onFrequentContactsCursorUpdated(cursor);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the initial state of the fragment before loading data.
|
||||
*/
|
||||
public void testInitialState() {
|
||||
initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT);
|
||||
|
||||
// Make sure that the frequent contacts view is shown by default.
|
||||
final ViewPager pager = (ViewPager) getFragment().getView().findViewById(R.id.pager);
|
||||
final View currentPagedView = pager.getChildAt(pager.getCurrentItem());
|
||||
final View frequentContactsView = ((CustomHeaderViewPagerAdapter) pager.getAdapter())
|
||||
.getViewHolder(0).getView(null);
|
||||
assertEquals(frequentContactsView, currentPagedView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that list view gets correctly populated given a cursor.
|
||||
*/
|
||||
public void testLoadAllContactsList() {
|
||||
final Cursor cursor = TestDataFactory.getAllContactListCursor();
|
||||
initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT)
|
||||
.loadWithAllContactsCursor(cursor);
|
||||
final ListView listView = (ListView) getFragment().getView()
|
||||
.findViewById(R.id.all_contacts_list);
|
||||
assertEquals(cursor.getCount(), listView.getCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that list view gets correctly populated given a cursor.
|
||||
*/
|
||||
public void testLoadFrequentContactsList() {
|
||||
final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
|
||||
initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT)
|
||||
.loadWithFrequentContactsCursor(cursor);
|
||||
final ListView listView = (ListView) getFragment().getView()
|
||||
.findViewById(R.id.frequent_contacts_list);
|
||||
assertEquals(cursor.getCount(), listView.getCount());
|
||||
}
|
||||
|
||||
public void testPickInitialContact() {
|
||||
final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
|
||||
initFragment(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT)
|
||||
.loadWithFrequentContactsCursor(cursor);
|
||||
final ListView listView = (ListView) getFragment().getView()
|
||||
.findViewById(R.id.frequent_contacts_list);
|
||||
// Click on the first contact to add it.
|
||||
final ContactListItemView cliv = (ContactListItemView) listView.getChildAt(0);
|
||||
clickButton(cliv);
|
||||
final ContactRecipientAutoCompleteView chipsView = (ContactRecipientAutoCompleteView)
|
||||
getFragment().getView()
|
||||
.findViewById(R.id.recipient_text_view);
|
||||
// Verify the contact is added to the chips view.
|
||||
final List<ParticipantData> participants =
|
||||
chipsView.getRecipientParticipantDataForConversationCreation();
|
||||
assertEquals(1, participants.size());
|
||||
assertEquals(cliv.mData.getDestination(), participants.get(0).getSendDestination());
|
||||
assertTrue(mService.getCalls().get(0).action instanceof GetOrCreateConversationAction);
|
||||
}
|
||||
|
||||
public void testLeaveChipsMode() {
|
||||
final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
|
||||
initFragment(ContactPickerFragment.MODE_CHIPS_ONLY)
|
||||
.loadWithFrequentContactsCursor(cursor);
|
||||
// Click on the add more participants button
|
||||
// TODO: Figure out a way to click on the add more participants button now that
|
||||
// it's part of the menu.
|
||||
// final ImageButton AddMoreParticipantsButton = (ImageButton) getFragment().getView()
|
||||
// .findViewById(R.id.add_more_participants_button);
|
||||
// clickButton(AddMoreParticipantsButton);
|
||||
// Mockito.verify(mockHost).onInitiateAddMoreParticipants();
|
||||
}
|
||||
|
||||
public void testPickMoreContacts() {
|
||||
final Cursor cursor = TestDataFactory.getFrequentContactListCursor();
|
||||
initFragment(ContactPickerFragment.MODE_PICK_MORE_CONTACTS)
|
||||
.loadWithFrequentContactsCursor(cursor);
|
||||
final ListView listView = (ListView) getFragment().getView()
|
||||
.findViewById(R.id.frequent_contacts_list);
|
||||
// Click on the first contact to add it.
|
||||
final ContactListItemView cliv = (ContactListItemView) listView.getChildAt(0);
|
||||
clickButton(cliv);
|
||||
// Verify that we don't attempt to create a conversation right away.
|
||||
assertEquals(0, mService.getCalls().size());
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.conversation;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaPlayer;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.binding.Binding;
|
||||
import com.android.messaging.datamodel.binding.BindingBase;
|
||||
import com.android.messaging.datamodel.data.ConversationData;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData.CheckDraftForSendTask;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData.CheckDraftTaskCallback;
|
||||
import com.android.messaging.datamodel.data.MessageData;
|
||||
import com.android.messaging.datamodel.data.MessagePartData;
|
||||
import com.android.messaging.ui.ViewTest;
|
||||
import com.android.messaging.ui.conversation.ComposeMessageView.IComposeMessageViewHost;
|
||||
import com.android.messaging.util.BugleGservices;
|
||||
import com.android.messaging.util.FakeMediaUtil;
|
||||
import com.android.messaging.util.ImeUtil;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
@MediumTest
|
||||
public class ComposeMessageViewTest extends ViewTest<ComposeMessageView> {
|
||||
private Context mContext;
|
||||
|
||||
@Mock protected DataModel mockDataModel;
|
||||
@Mock protected DraftMessageData mockDraftMessageData;
|
||||
@Mock protected BugleGservices mockBugleGservices;
|
||||
@Mock protected ImeUtil mockImeUtil;
|
||||
@Mock protected IComposeMessageViewHost mockIComposeMessageViewHost;
|
||||
@Mock protected MediaPlayer mockMediaPlayer;
|
||||
@Mock protected ConversationInputManager mockInputManager;
|
||||
@Mock protected ConversationData mockConversationData;
|
||||
|
||||
Binding<ConversationData> mConversationBinding;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mContext = getInstrumentation().getTargetContext();
|
||||
FakeFactory.register(mContext)
|
||||
.withDataModel(mockDataModel)
|
||||
.withBugleGservices(mockBugleGservices)
|
||||
.withMediaUtil(new FakeMediaUtil(mockMediaPlayer));
|
||||
|
||||
Mockito.doReturn(true).when(mockConversationData).isBound(Mockito.anyString());
|
||||
mConversationBinding = BindingBase.createBinding(this);
|
||||
mConversationBinding.bind(mockConversationData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ComposeMessageView getView() {
|
||||
final ComposeMessageView view = super.getView();
|
||||
view.setInputManager(mockInputManager);
|
||||
view.setConversationDataModel(BindingBase.createBindingReference(mConversationBinding));
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
return R.layout.compose_message_view;
|
||||
}
|
||||
|
||||
public void testSend() {
|
||||
Mockito.when(mockDraftMessageData.getReadOnlyAttachments())
|
||||
.thenReturn(Collections.unmodifiableList(new ArrayList<MessagePartData>()));
|
||||
Mockito.when(mockDraftMessageData.getIsDefaultSmsApp()).thenReturn(true);
|
||||
Mockito.when(mockIComposeMessageViewHost.isReadyForAction()).thenReturn(true);
|
||||
final ComposeMessageView view = getView();
|
||||
|
||||
final MessageData message = MessageData.createDraftSmsMessage("fake_id", "just_a_self_id",
|
||||
"Sample Message");
|
||||
|
||||
Mockito.when(mockDraftMessageData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
Mockito.when(mockDraftMessageData.getMessageText()).thenReturn(message.getMessageText());
|
||||
Mockito.when(mockDraftMessageData.prepareMessageForSending(
|
||||
Matchers.<BindingBase<DraftMessageData>>any()))
|
||||
.thenReturn(message);
|
||||
Mockito.when(mockDraftMessageData.hasPendingAttachments()).thenReturn(false);
|
||||
Mockito.doAnswer(new Answer() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
// Synchronously pass the draft check and callback.
|
||||
((CheckDraftTaskCallback)invocation.getArguments()[2]).onDraftChecked(
|
||||
mockDraftMessageData, CheckDraftForSendTask.RESULT_PASSED);
|
||||
return null;
|
||||
}
|
||||
}).when(mockDraftMessageData).checkDraftForAction(Mockito.anyBoolean(), Mockito.anyInt(),
|
||||
Mockito.<CheckDraftTaskCallback>any(),
|
||||
Mockito.<Binding<DraftMessageData>>any());
|
||||
|
||||
view.bind(mockDraftMessageData, mockIComposeMessageViewHost);
|
||||
|
||||
final EditText composeEditText = (EditText) view.findViewById(R.id.compose_message_text);
|
||||
final View sendButton = view.findViewById(R.id.send_message_button);
|
||||
|
||||
view.requestDraftMessage(false);
|
||||
|
||||
Mockito.verify(mockDraftMessageData).loadFromStorage(any(BindingBase.class),
|
||||
isNull(), Mockito.eq(false));
|
||||
|
||||
view.onDraftChanged(mockDraftMessageData, DraftMessageData.ALL_CHANGED);
|
||||
|
||||
assertEquals(message.getMessageText(), composeEditText.getText().toString());
|
||||
|
||||
sendButton.performClick();
|
||||
Mockito.verify(mockIComposeMessageViewHost).sendMessage(
|
||||
Mockito.argThat(o -> {
|
||||
assertEquals(message.getMessageText(), o.getMessageText());
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
public void testNotDefaultSms() {
|
||||
Mockito.when(mockDraftMessageData.getReadOnlyAttachments())
|
||||
.thenReturn(Collections.unmodifiableList(new ArrayList<MessagePartData>()));
|
||||
Mockito.when(mockDraftMessageData.getIsDefaultSmsApp()).thenReturn(false);
|
||||
Mockito.when(mockIComposeMessageViewHost.isReadyForAction()).thenReturn(false);
|
||||
final ComposeMessageView view = getView();
|
||||
|
||||
final MessageData message = MessageData.createDraftSmsMessage("fake_id", "just_a_self_id",
|
||||
"Sample Message");
|
||||
|
||||
Mockito.when(mockDraftMessageData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
Mockito.when(mockDraftMessageData.getMessageText()).thenReturn(message.getMessageText());
|
||||
Mockito.when(mockDraftMessageData.prepareMessageForSending(
|
||||
Matchers.<BindingBase<DraftMessageData>>any()))
|
||||
.thenReturn(message);
|
||||
Mockito.when(mockDraftMessageData.hasPendingAttachments()).thenReturn(false);
|
||||
|
||||
view.bind(mockDraftMessageData, mockIComposeMessageViewHost);
|
||||
|
||||
final EditText composeEditText = (EditText) view.findViewById(R.id.compose_message_text);
|
||||
final View sendButton = view.findViewById(R.id.send_message_button);
|
||||
|
||||
view.requestDraftMessage(false);
|
||||
|
||||
Mockito.verify(mockDraftMessageData).loadFromStorage(any(BindingBase.class),
|
||||
isNull(), Mockito.eq(false));
|
||||
|
||||
view.onDraftChanged(mockDraftMessageData, DraftMessageData.ALL_CHANGED);
|
||||
|
||||
assertEquals(message.getMessageText(), composeEditText.getText().toString());
|
||||
|
||||
sendButton.performClick();
|
||||
Mockito.verify(mockIComposeMessageViewHost).warnOfMissingActionConditions(
|
||||
any(Boolean.class), any(Runnable.class));
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.conversation;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.ui.contact.ContactPickerFragment;
|
||||
import com.android.messaging.ui.conversation.ConversationActivityUiState.ConversationActivityUiStateHost;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@SmallTest
|
||||
public class ConversationActivityUiStateTest extends BugleTestCase {
|
||||
@Mock protected ConversationActivityUiStateHost mockListener;
|
||||
|
||||
/**
|
||||
* Test the Ui state where we start off with the contact picker to pick the first contact.
|
||||
*/
|
||||
public void testPickInitialContact() {
|
||||
final ConversationActivityUiState uiState = new ConversationActivityUiState(null);
|
||||
uiState.setHost(mockListener);
|
||||
assertTrue(uiState.shouldShowContactPickerFragment());
|
||||
assertFalse(uiState.shouldShowConversationFragment());
|
||||
assertEquals(ContactPickerFragment.MODE_PICK_INITIAL_CONTACT,
|
||||
uiState.getDesiredContactPickingMode());
|
||||
uiState.onGetOrCreateConversation("conversation1");
|
||||
Mockito.verify(mockListener, Mockito.times(1)).onConversationContactPickerUiStateChanged(
|
||||
Mockito.eq(ConversationActivityUiState.STATE_CONTACT_PICKER_ONLY_INITIAL_CONTACT),
|
||||
Mockito.eq(
|
||||
ConversationActivityUiState.STATE_HYBRID_WITH_CONVERSATION_AND_CHIPS_VIEW),
|
||||
Mockito.anyBoolean());
|
||||
assertTrue(uiState.shouldShowContactPickerFragment());
|
||||
assertTrue(uiState.shouldShowConversationFragment());
|
||||
assertTrue(TextUtils.equals("conversation1", uiState.getConversationId()));
|
||||
assertEquals(ContactPickerFragment.MODE_CHIPS_ONLY,
|
||||
uiState.getDesiredContactPickingMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Ui state where we have both the chips view and the conversation view and we
|
||||
* start message compose.
|
||||
*/
|
||||
public void testHybridUiStateStartCompose() {
|
||||
final ConversationActivityUiState uiState = new ConversationActivityUiState("conv1");
|
||||
uiState.testSetUiState(
|
||||
ConversationActivityUiState.STATE_HYBRID_WITH_CONVERSATION_AND_CHIPS_VIEW);
|
||||
uiState.setHost(mockListener);
|
||||
|
||||
// Start message compose.
|
||||
uiState.onStartMessageCompose();
|
||||
Mockito.verify(mockListener, Mockito.times(1)).onConversationContactPickerUiStateChanged(
|
||||
Mockito.eq(
|
||||
ConversationActivityUiState.STATE_HYBRID_WITH_CONVERSATION_AND_CHIPS_VIEW),
|
||||
Mockito.eq(ConversationActivityUiState.STATE_CONVERSATION_ONLY),
|
||||
Mockito.anyBoolean());
|
||||
assertFalse(uiState.shouldShowContactPickerFragment());
|
||||
assertTrue(uiState.shouldShowConversationFragment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Ui state where we have both the chips view and the conversation view and we
|
||||
* try to add a participant.
|
||||
*/
|
||||
public void testHybridUiStateAddParticipant() {
|
||||
final ConversationActivityUiState uiState = new ConversationActivityUiState("conv1");
|
||||
uiState.testSetUiState(
|
||||
ConversationActivityUiState.STATE_HYBRID_WITH_CONVERSATION_AND_CHIPS_VIEW);
|
||||
uiState.setHost(mockListener);
|
||||
|
||||
uiState.onAddMoreParticipants();
|
||||
Mockito.verify(mockListener, Mockito.times(1)).onConversationContactPickerUiStateChanged(
|
||||
Mockito.eq(
|
||||
ConversationActivityUiState.STATE_HYBRID_WITH_CONVERSATION_AND_CHIPS_VIEW),
|
||||
Mockito.eq(
|
||||
ConversationActivityUiState.STATE_CONTACT_PICKER_ONLY_ADD_MORE_CONTACTS),
|
||||
Mockito.anyBoolean());
|
||||
assertTrue(uiState.shouldShowContactPickerFragment());
|
||||
assertFalse(uiState.shouldShowConversationFragment());
|
||||
assertEquals(ContactPickerFragment.MODE_PICK_MORE_CONTACTS,
|
||||
uiState.getDesiredContactPickingMode());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the Ui state where we are trying to add more participants and commit.
|
||||
*/
|
||||
public void testCommitAddParticipant() {
|
||||
final ConversationActivityUiState uiState = new ConversationActivityUiState(null);
|
||||
uiState.testSetUiState(
|
||||
ConversationActivityUiState.STATE_CONTACT_PICKER_ONLY_ADD_MORE_CONTACTS);
|
||||
uiState.setHost(mockListener);
|
||||
|
||||
uiState.onGetOrCreateConversation("conversation1");
|
||||
|
||||
// After adding more contacts, the terminal state is always conversation only (i.e. we
|
||||
// don't go back to hybrid mode).
|
||||
Mockito.verify(mockListener, Mockito.times(1)).onConversationContactPickerUiStateChanged(
|
||||
Mockito.eq(ConversationActivityUiState.STATE_CONTACT_PICKER_ONLY_ADD_MORE_CONTACTS),
|
||||
Mockito.eq(ConversationActivityUiState.STATE_CONVERSATION_ONLY),
|
||||
Mockito.anyBoolean());
|
||||
assertFalse(uiState.shouldShowContactPickerFragment());
|
||||
assertTrue(uiState.shouldShowConversationFragment());
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.conversation;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.database.Cursor;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.MemoryCacheManager;
|
||||
import com.android.messaging.datamodel.data.ConversationData;
|
||||
import com.android.messaging.datamodel.data.ConversationData.ConversationDataListener;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.datamodel.media.MediaResourceManager;
|
||||
import com.android.messaging.ui.FragmentTestCase;
|
||||
import com.android.messaging.ui.PlainTextEditText;
|
||||
import com.android.messaging.ui.TestActivity.FragmentEventListener;
|
||||
import com.android.messaging.ui.conversation.ConversationFragment.ConversationFragmentHost;
|
||||
import com.android.messaging.ui.conversationlist.ConversationListFragment;
|
||||
import com.android.messaging.util.BugleGservices;
|
||||
import com.android.messaging.util.ImeUtil;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ConversationListFragment}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class ConversationFragmentTest extends FragmentTestCase<ConversationFragment> {
|
||||
|
||||
@Mock protected DataModel mockDataModel;
|
||||
@Mock protected ConversationData mockConversationData;
|
||||
@Mock protected DraftMessageData mockDraftMessageData;
|
||||
@Mock protected MediaResourceManager mockMediaResourceManager;
|
||||
@Mock protected BugleGservices mockBugleGservices;
|
||||
@Mock protected ConversationFragmentHost mockHost;
|
||||
@Mock protected MemoryCacheManager mockMemoryCacheManager;
|
||||
|
||||
private ImeUtil mSpiedImeUtil;
|
||||
|
||||
private static final String CONVERSATION_ID = "cid";
|
||||
|
||||
|
||||
public ConversationFragmentTest() {
|
||||
super(ConversationFragment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
ImeUtil.clearInstance();
|
||||
mSpiedImeUtil = Mockito.spy(new ImeUtil());
|
||||
FakeFactory.register(this.getInstrumentation().getTargetContext())
|
||||
.withDataModel(mockDataModel)
|
||||
.withBugleGservices(mockBugleGservices)
|
||||
.withMemoryCacheManager(mockMemoryCacheManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that will do the 'binding' of ConversationFragmentTest with ConversationData and
|
||||
* leave fragment in 'ready' state.
|
||||
* @param cursor
|
||||
*/
|
||||
private void loadWith(final Cursor cursor) {
|
||||
Mockito.when(mockDraftMessageData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
Mockito.when(mockConversationData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
Mockito.doReturn(mockDraftMessageData)
|
||||
.when(mockDataModel)
|
||||
.createDraftMessageData(Mockito.anyString());
|
||||
Mockito.doReturn(mockDraftMessageData)
|
||||
.when(mockDataModel)
|
||||
.createDraftMessageData(null);
|
||||
Mockito.when(mockDataModel.createConversationData(
|
||||
Matchers.any(Activity.class),
|
||||
Matchers.any(ConversationDataListener.class),
|
||||
Matchers.anyString()))
|
||||
.thenReturn(mockConversationData);
|
||||
|
||||
// Create fragment synchronously to avoid need for volatile, synchronization etc.
|
||||
final ConversationFragment fragment = getFragment();
|
||||
// Binding to model happens when attaching fragment to activity, so hook into test
|
||||
// activity to do so.
|
||||
getActivity().setFragmentEventListener(new FragmentEventListener() {
|
||||
@Override
|
||||
public void onAttachFragment(final Fragment attachedFragment) {
|
||||
if (fragment == attachedFragment) {
|
||||
fragment.setConversationInfo(getActivity(), CONVERSATION_ID, null);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fragment.setHost(mockHost);
|
||||
getActivity().setFragment(fragment);
|
||||
Mockito.verify(mockDataModel).createConversationData(
|
||||
getActivity(), fragment, CONVERSATION_ID);
|
||||
Mockito.verify(mockConversationData).init(fragment.getLoaderManager(),
|
||||
fragment.mBinding);
|
||||
}
|
||||
});
|
||||
// Wait for initial layout pass to work around crash in recycler view
|
||||
getInstrumentation().waitForIdleSync();
|
||||
// Now load the cursor
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fragment.onConversationMessagesCursorUpdated(mockConversationData, cursor, null,
|
||||
false);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that list view gets correctly populated given a cursor.
|
||||
*/
|
||||
public void testLoadListView() {
|
||||
final Cursor cursor = TestDataFactory.getConversationMessageCursor();
|
||||
loadWith(cursor);
|
||||
final RecyclerView listView =
|
||||
(RecyclerView) getFragment().getView().findViewById(android.R.id.list);
|
||||
assertEquals("bad cursor", cursor.getCount(), listView.getAdapter().getItemCount());
|
||||
assertEquals("bad cursor count", cursor.getCount(), listView.getChildCount());
|
||||
}
|
||||
|
||||
public void testClickComposeMessageView() {
|
||||
final Cursor cursor = TestDataFactory.getConversationMessageCursor();
|
||||
loadWith(cursor);
|
||||
|
||||
final PlainTextEditText composeEditText = (PlainTextEditText) getFragment().getView()
|
||||
.findViewById(R.id.compose_message_text);
|
||||
setFocus(composeEditText, false);
|
||||
Mockito.verify(mockHost, Mockito.never()).onStartComposeMessage();
|
||||
setFocus(composeEditText, true);
|
||||
Mockito.verify(mockHost).onStartComposeMessage();
|
||||
}
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.conversation;
|
||||
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.os.Bundle;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.binding.Binding;
|
||||
import com.android.messaging.datamodel.binding.BindingBase;
|
||||
import com.android.messaging.datamodel.data.ConversationData;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData;
|
||||
import com.android.messaging.datamodel.data.SubscriptionListData;
|
||||
import com.android.messaging.ui.conversation.ConversationInputManager.ConversationInputHost;
|
||||
import com.android.messaging.ui.conversation.ConversationInputManager.ConversationInputSink;
|
||||
import com.android.messaging.ui.mediapicker.MediaPicker;
|
||||
import com.android.messaging.util.BugleGservices;
|
||||
import com.android.messaging.util.ImeUtil;
|
||||
import com.android.messaging.util.ImeUtil.ImeStateHost;
|
||||
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
|
||||
@SmallTest
|
||||
public class ConversationInputManagerTest extends BugleTestCase {
|
||||
@Spy protected ImeUtil spyImeUtil;
|
||||
@Mock protected BugleGservices mockBugleGservices;
|
||||
@Mock protected FragmentManager mockFragmentManager;
|
||||
@Mock protected ConversationInputHost mockConversationInputHost;
|
||||
@Mock protected ConversationInputSink mockConversationInputSink;
|
||||
@Mock protected ImeStateHost mockImeStateHost;
|
||||
@Mock protected ConversationData mockConversationData;
|
||||
@Mock protected DraftMessageData mockDraftMessageData;
|
||||
@Mock protected MediaPicker mockMediaPicker;
|
||||
@Mock protected SubscriptionListData mockSubscriptionListData;
|
||||
@Mock protected FragmentTransaction mockFragmentTransaction;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getTestContext())
|
||||
.withBugleGservices(mockBugleGservices);
|
||||
spyImeUtil = Mockito.spy(new ImeUtil());
|
||||
ImeUtil.set(spyImeUtil);
|
||||
}
|
||||
|
||||
private ConversationInputManager initNewInputManager(final Bundle savedState) {
|
||||
// Set up the mocks.
|
||||
Mockito.when(mockConversationInputHost.getSimSelectorView())
|
||||
.thenReturn(new SimSelectorView(getTestContext(), null));
|
||||
Mockito.when(mockConversationInputHost.createMediaPicker()).thenReturn(mockMediaPicker);
|
||||
Mockito.when(mockConversationInputSink.getComposeEditText())
|
||||
.thenReturn(new EditText(getTestContext()));
|
||||
Mockito.doReturn(mockFragmentTransaction).when(mockFragmentTransaction).replace(
|
||||
Mockito.eq(R.id.mediapicker_container), Mockito.any(MediaPicker.class),
|
||||
Mockito.anyString());
|
||||
Mockito.when(mockFragmentManager.findFragmentByTag(MediaPicker.FRAGMENT_TAG))
|
||||
.thenReturn(null);
|
||||
Mockito.when(mockFragmentManager.beginTransaction()).thenReturn(mockFragmentTransaction);
|
||||
Mockito.when(mockSubscriptionListData.hasData()).thenReturn(true);
|
||||
Mockito.when(mockConversationData.getSubscriptionListData())
|
||||
.thenReturn(mockSubscriptionListData);
|
||||
Mockito.doReturn(true).when(mockConversationData).isBound(Mockito.anyString());
|
||||
Mockito.doReturn(true).when(mockDraftMessageData).isBound(Mockito.anyString());
|
||||
|
||||
final Binding<ConversationData> dataBinding = BindingBase.createBinding(this);
|
||||
dataBinding.bind(mockConversationData);
|
||||
final Binding<DraftMessageData> draftBinding = BindingBase.createBinding(this);
|
||||
draftBinding.bind(mockDraftMessageData);
|
||||
final ConversationInputManager inputManager = new ConversationInputManager(getTestContext(),
|
||||
mockConversationInputHost, mockConversationInputSink, mockImeStateHost,
|
||||
mockFragmentManager, dataBinding, draftBinding, savedState);
|
||||
return inputManager;
|
||||
}
|
||||
|
||||
public void testShowHideInputs() {
|
||||
final ConversationInputManager inputManager = initNewInputManager(new Bundle());
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(true);
|
||||
inputManager.showHideMediaPicker(true /* show */, true /* animate */);
|
||||
Mockito.verify(mockFragmentTransaction).replace(
|
||||
Mockito.eq(R.id.mediapicker_container), Mockito.any(MediaPicker.class),
|
||||
Mockito.anyString());
|
||||
Mockito.verify(mockMediaPicker).open(Mockito.anyInt(), Mockito.eq(true /* animate */));
|
||||
|
||||
assertEquals(true, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(false, inputManager.isImeKeyboardVisible());
|
||||
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(false);
|
||||
inputManager.showHideMediaPicker(false /* show */, true /* animate */);
|
||||
Mockito.verify(mockMediaPicker).dismiss(Mockito.eq(true /* animate */));
|
||||
|
||||
assertEquals(false, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(false, inputManager.isImeKeyboardVisible());
|
||||
}
|
||||
|
||||
public void testShowTwoInputsSequentially() {
|
||||
// First show the media picker, then show the IME keyboard.
|
||||
final ConversationInputManager inputManager = initNewInputManager(new Bundle());
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(true);
|
||||
inputManager.showHideMediaPicker(true /* show */, true /* animate */);
|
||||
|
||||
assertEquals(true, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(false, inputManager.isImeKeyboardVisible());
|
||||
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(false);
|
||||
inputManager.showHideImeKeyboard(true /* show */, true /* animate */);
|
||||
|
||||
assertEquals(false, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(true, inputManager.isImeKeyboardVisible());
|
||||
}
|
||||
|
||||
public void testOnKeyboardShow() {
|
||||
final ConversationInputManager inputManager = initNewInputManager(new Bundle());
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(true);
|
||||
inputManager.showHideMediaPicker(true /* show */, true /* animate */);
|
||||
|
||||
assertEquals(true, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(false, inputManager.isImeKeyboardVisible());
|
||||
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(false);
|
||||
inputManager.testNotifyImeStateChanged(true /* imeOpen */);
|
||||
|
||||
assertEquals(false, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(true, inputManager.isImeKeyboardVisible());
|
||||
}
|
||||
|
||||
public void testRestoreState() {
|
||||
final ConversationInputManager inputManager = initNewInputManager(new Bundle());
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(true);
|
||||
inputManager.showHideMediaPicker(true /* show */, true /* animate */);
|
||||
|
||||
assertEquals(true, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(false, inputManager.isImeKeyboardVisible());
|
||||
|
||||
Bundle savedInstanceState = new Bundle();
|
||||
inputManager.onSaveInputState(savedInstanceState);
|
||||
|
||||
// Now try to restore the state
|
||||
final ConversationInputManager restoredInputManager =
|
||||
initNewInputManager(savedInstanceState);
|
||||
|
||||
// Make sure the state is preserved.
|
||||
assertEquals(true, restoredInputManager.isMediaPickerVisible());
|
||||
assertEquals(false, restoredInputManager.isSimSelectorVisible());
|
||||
assertEquals(false, restoredInputManager.isImeKeyboardVisible());
|
||||
}
|
||||
|
||||
public void testBackPress() {
|
||||
final ConversationInputManager inputManager = initNewInputManager(new Bundle());
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(true);
|
||||
inputManager.showHideMediaPicker(true /* show */, true /* animate */);
|
||||
|
||||
assertEquals(true, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(false, inputManager.isImeKeyboardVisible());
|
||||
|
||||
Mockito.when(mockMediaPicker.isOpen()).thenReturn(false);
|
||||
assertEquals(true, inputManager.onBackPressed());
|
||||
|
||||
assertEquals(false, inputManager.isMediaPickerVisible());
|
||||
assertEquals(false, inputManager.isSimSelectorVisible());
|
||||
assertEquals(false, inputManager.isImeKeyboardVisible());
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.conversation;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.ui.ViewTest;
|
||||
import com.android.messaging.ui.conversation.ConversationMessageView.ConversationMessageViewHost;
|
||||
import com.android.messaging.util.Dates;
|
||||
|
||||
import org.mockito.Mock;
|
||||
|
||||
@MediumTest
|
||||
public class ConversationMessageViewTest extends ViewTest<ConversationMessageView> {
|
||||
@Mock ConversationMessageViewHost mockHost;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getInstrumentation().getTargetContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConversationMessageView getView() {
|
||||
final ConversationMessageView view = super.getView();
|
||||
view.setHost(mockHost);
|
||||
return view;
|
||||
}
|
||||
|
||||
protected void verifyContent(final ConversationMessageView view, final String messageText,
|
||||
final boolean showTimestamp, final String timestampText) {
|
||||
|
||||
final TextView messageTextView = (TextView) view.findViewById(R.id.message_text);
|
||||
final TextView statusTextView = (TextView) view.findViewById(R.id.message_status);
|
||||
|
||||
assertNotNull(messageTextView);
|
||||
assertEquals(messageText, messageTextView.getText());
|
||||
|
||||
if (showTimestamp) {
|
||||
assertEquals(View.VISIBLE, statusTextView.getVisibility());
|
||||
assertEquals(timestampText, statusTextView.getText());
|
||||
} else {
|
||||
assertEquals(View.GONE, statusTextView.getVisibility());
|
||||
}
|
||||
}
|
||||
|
||||
public void testBind() {
|
||||
final ConversationMessageView view = getView();
|
||||
|
||||
final FakeCursor cursor = TestDataFactory.getConversationMessageCursor();
|
||||
cursor.moveToFirst();
|
||||
|
||||
view.bind(cursor);
|
||||
verifyContent(view, TestDataFactory.getMessageText(cursor, 0), true, Dates
|
||||
.getMessageTimeString((Long) cursor.getAt("received_timestamp", 0)).toString());
|
||||
}
|
||||
|
||||
public void testBindTwice() {
|
||||
final ConversationMessageView view = getView();
|
||||
|
||||
final FakeCursor cursor = TestDataFactory.getConversationMessageCursor();
|
||||
cursor.moveToFirst();
|
||||
view.bind(cursor);
|
||||
|
||||
cursor.moveToNext();
|
||||
view.bind(cursor);
|
||||
verifyContent(view, TestDataFactory.getMessageText(cursor, 1), true, Dates
|
||||
.getMessageTimeString((Long) cursor.getAt("received_timestamp", 1)).toString());
|
||||
}
|
||||
|
||||
public void testBindLast() {
|
||||
final ConversationMessageView view = getView();
|
||||
|
||||
final FakeCursor cursor = TestDataFactory.getConversationMessageCursor();
|
||||
final int lastPos = cursor.getCount() - 1;
|
||||
cursor.moveToPosition(lastPos);
|
||||
|
||||
view.bind(cursor);
|
||||
verifyContent(view, TestDataFactory.getMessageText(cursor, lastPos), true, Dates
|
||||
.getMessageTimeString((Long) cursor.getAt("received_timestamp", lastPos))
|
||||
.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
return R.layout.conversation_message_view;
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.conversationlist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.data.ConversationListData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.ui.FragmentTestCase;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.ui.conversationlist.ConversationListFragment.ConversationListFragmentHost;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ConversationListFragment}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class ConversationListFragmentTest
|
||||
extends FragmentTestCase<ConversationListFragment> {
|
||||
|
||||
@Mock protected ConversationListData mMockConversationListData;
|
||||
@Mock protected ConversationListFragmentHost mMockConversationHostListHost;
|
||||
@Mock protected UIIntents mMockUIIntents;
|
||||
protected FakeDataModel mFakeDataModel;
|
||||
|
||||
public ConversationListFragmentTest() {
|
||||
super(ConversationListFragment.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
final Context context = getInstrumentation().getTargetContext();
|
||||
mFakeDataModel = new FakeDataModel(context)
|
||||
.withConversationListData(mMockConversationListData);
|
||||
FakeFactory.register(context)
|
||||
.withDataModel(mFakeDataModel)
|
||||
.withUIIntents(mMockUIIntents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that will do the 'binding' of ConversationListFragmentTest with ConversationListData
|
||||
* and leave fragment in 'ready' state.
|
||||
* @param cursor
|
||||
*/
|
||||
private void loadWith(final Cursor cursor) {
|
||||
Mockito.when(mMockConversationListData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
|
||||
final ConversationListFragment fragment = getFragment();
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fragment.setHost(mMockConversationHostListHost);
|
||||
getActivity().setFragment(fragment);
|
||||
Mockito.verify(mMockConversationListData).init(fragment.getLoaderManager(),
|
||||
fragment.mListBinding);
|
||||
fragment.onConversationListCursorUpdated(mMockConversationListData, cursor);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that list view gets correctly populated given a cursor.
|
||||
*/
|
||||
public void testLoadListView() {
|
||||
final Cursor cursor = TestDataFactory.getConversationListCursor();
|
||||
loadWith(cursor);
|
||||
final RecyclerView listView =
|
||||
(RecyclerView) getFragment().getView().findViewById(android.R.id.list);
|
||||
//assertEquals(cursor.getCount(), listView.getCount());
|
||||
assertEquals(cursor.getCount(), listView.getChildCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that 'empty list' promo is rendered with an empty cursor.
|
||||
*/
|
||||
public void testEmptyView() {
|
||||
loadWith(TestDataFactory.getEmptyConversationListCursor());
|
||||
final RecyclerView listView =
|
||||
(RecyclerView) getFragment().getView().findViewById(android.R.id.list);
|
||||
final View emptyMessageView =
|
||||
getFragment().getView().findViewById(R.id.no_conversations_view);
|
||||
assertEquals(View.VISIBLE, emptyMessageView.getVisibility());
|
||||
assertEquals(0, listView.getChildCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the button to start a new conversation works.
|
||||
*/
|
||||
public void testStartNewConversation() {
|
||||
final Cursor cursor = TestDataFactory.getConversationListCursor();
|
||||
loadWith(cursor);
|
||||
final ImageView startNewConversationButton = (ImageView)
|
||||
getFragment().getView().findViewById(R.id.start_new_conversation_button);
|
||||
|
||||
clickButton(startNewConversationButton);
|
||||
Mockito.verify(mMockConversationHostListHost).onCreateConversationClick();
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.conversationlist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
import com.android.messaging.Factory;
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.data.ConversationListItemData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.ui.AsyncImageView;
|
||||
import com.android.messaging.ui.UIIntentsImpl;
|
||||
import com.android.messaging.ui.ViewTest;
|
||||
import com.android.messaging.util.Dates;
|
||||
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MediumTest
|
||||
public class ConversationListItemViewTest extends ViewTest<ConversationListItemView> {
|
||||
|
||||
@Mock private ConversationListItemView.HostInterface mockHost;
|
||||
private FakeCursor mCursor;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final Context context = getInstrumentation().getTargetContext();
|
||||
FakeFactory.register(context)
|
||||
.withDataModel(new FakeDataModel(context))
|
||||
.withUIIntents(new UIIntentsImpl());
|
||||
mCursor = TestDataFactory.getConversationListCursor();
|
||||
}
|
||||
|
||||
|
||||
protected void verifyLaunchedConversationForId(final String id,
|
||||
final ConversationListItemView conversationView) {
|
||||
// Must be a short click.
|
||||
final ArgumentMatcher<ConversationListItemData> itemDataIdMatcher =
|
||||
arg -> TextUtils.equals(id, arg.getConversationId());
|
||||
Mockito.verify(mockHost).onConversationClicked(
|
||||
Mockito.argThat(itemDataIdMatcher), Mockito.eq(false),
|
||||
Mockito.eq(conversationView));
|
||||
}
|
||||
|
||||
protected void verifyContent(
|
||||
final ConversationListItemView view, final FakeCursor cursor, final int index) {
|
||||
/* ConversationQueryColumns.NAME */
|
||||
final String conversationQueryColumnsName = "name";
|
||||
final String name = (String) cursor.getAt(conversationQueryColumnsName, index);
|
||||
|
||||
/* ConversationQueryColumns.SNIPPET_TEXT */
|
||||
final String conversationQueryColumnsSnippetText = "snippet_text";
|
||||
final String snippet = (String) cursor.getAt(conversationQueryColumnsSnippetText, index);
|
||||
|
||||
/* ConversationQueryColumns.SORT_TIMESTAMP */
|
||||
final String conversationQueryColumnsSortTimestamp = "sort_timestamp";
|
||||
final String timestamp = Dates.getConversationTimeString(
|
||||
(Long) cursor.getAt(conversationQueryColumnsSortTimestamp, index)).toString();
|
||||
|
||||
final boolean unread = !isRead(cursor, index);
|
||||
verifyContent(view, name, snippet, timestamp, unread);
|
||||
}
|
||||
|
||||
protected void verifyContent(
|
||||
final ConversationListItemView view,
|
||||
final String conversationName,
|
||||
final String snippet,
|
||||
final String timestamp,
|
||||
final boolean unread) {
|
||||
final TextView conversationNameView =
|
||||
(TextView) view.findViewById(R.id.conversation_name);
|
||||
final TextView snippetTextView = (TextView) view.findViewById(R.id.conversation_snippet);
|
||||
final TextView timestampTextView = (TextView) view.findViewById(
|
||||
R.id.conversation_timestamp);
|
||||
final AsyncImageView imagePreviewView =
|
||||
(AsyncImageView) view.findViewById(R.id.conversation_image_preview);
|
||||
|
||||
final Context context = Factory.get().getApplicationContext();
|
||||
assertNotNull(conversationNameView);
|
||||
assertEquals(conversationName, conversationNameView.getText());
|
||||
assertNotNull(snippetTextView);
|
||||
if (unread) {
|
||||
assertEquals(ConversationListItemView.UNREAD_SNIPPET_LINE_COUNT,
|
||||
snippetTextView.getMaxLines());
|
||||
assertEquals(context.getResources().getColor(R.color.conversation_list_item_unread),
|
||||
snippetTextView.getCurrentTextColor());
|
||||
assertEquals(context.getResources().getColor(R.color.conversation_list_item_unread),
|
||||
conversationNameView.getCurrentTextColor());
|
||||
|
||||
} else {
|
||||
assertEquals(ConversationListItemView.NO_UNREAD_SNIPPET_LINE_COUNT,
|
||||
snippetTextView.getMaxLines());
|
||||
assertEquals(context.getResources().getColor(R.color.conversation_list_item_read),
|
||||
snippetTextView.getCurrentTextColor());
|
||||
assertEquals(context.getResources().getColor(R.color.conversation_list_item_read),
|
||||
conversationNameView.getCurrentTextColor());
|
||||
}
|
||||
|
||||
assertEquals(View.VISIBLE, imagePreviewView.getVisibility());
|
||||
assertTrue(snippetTextView.getText().toString().contains(snippet));
|
||||
assertEquals(timestamp, timestampTextView.getText());
|
||||
}
|
||||
|
||||
protected boolean isRead(final FakeCursor cursor, final int index) {
|
||||
return 1 == ((Integer) cursor.getAt("read", index)).intValue();
|
||||
}
|
||||
|
||||
public void testBindUnread() {
|
||||
final ConversationListItemView view = getView();
|
||||
final int messageIndex = TestDataFactory.CONVERSATION_LIST_CURSOR_UNREAD_MESSAGE_INDEX;
|
||||
mCursor.moveToPosition(messageIndex);
|
||||
assertFalse(isRead(mCursor, messageIndex));
|
||||
view.bind(mCursor, mockHost);
|
||||
verifyContent(view, mCursor, messageIndex);
|
||||
}
|
||||
|
||||
public void testBindRead() {
|
||||
final ConversationListItemView view = getView();
|
||||
|
||||
final int messageIndex = TestDataFactory.CONVERSATION_LIST_CURSOR_READ_MESSAGE_INDEX;
|
||||
mCursor.moveToPosition(messageIndex);
|
||||
assertTrue(isRead(mCursor, messageIndex));
|
||||
view.bind(mCursor, mockHost);
|
||||
verifyContent(view, mCursor, messageIndex);
|
||||
}
|
||||
|
||||
public void testClickLaunchesConversation() {
|
||||
final ConversationListItemView view = getView();
|
||||
final View swipeableContainer = view.findViewById(R.id.swipeableContainer);
|
||||
mCursor.moveToFirst();
|
||||
view.bind(mCursor, mockHost);
|
||||
swipeableContainer.performClick();
|
||||
verifyLaunchedConversationForId(
|
||||
mCursor.getAt("_id" /* ConversationQueryColumns._ID */, 0).toString(), view);
|
||||
}
|
||||
|
||||
public void testBindTwice() {
|
||||
final ConversationListItemView view = getView();
|
||||
|
||||
mCursor.moveToFirst();
|
||||
view.bind(mCursor, mockHost);
|
||||
|
||||
mCursor.moveToNext();
|
||||
view.bind(mCursor, mockHost);
|
||||
verifyContent(view, mCursor, mCursor.getPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
return R.layout.conversation_list_item_view;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.mediapicker;
|
||||
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.MediaRecorder.OnErrorListener;
|
||||
import android.media.MediaRecorder.OnInfoListener;
|
||||
import android.net.Uri;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.data.MessagePartData;
|
||||
import com.android.messaging.ui.ViewTest;
|
||||
import com.android.messaging.util.FakeMediaUtil;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class AudioRecordViewTest extends ViewTest<AudioRecordView> {
|
||||
|
||||
@Mock AudioRecordView.HostInterface mockHost;
|
||||
@Mock LevelTrackingMediaRecorder mockRecorder;
|
||||
@Mock MediaPlayer mockMediaPlayer;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
FakeFactory.register(getInstrumentation().getContext())
|
||||
.withMediaUtil(new FakeMediaUtil(mockMediaPlayer));
|
||||
}
|
||||
|
||||
private void verifyAudioSubmitted() {
|
||||
Mockito.verify(mockHost).onAudioRecorded(Matchers.any(MessagePartData.class));
|
||||
}
|
||||
|
||||
private AudioRecordView initView() {
|
||||
final AudioRecordView view = getView();
|
||||
view.testSetMediaRecorder(mockRecorder);
|
||||
view.setHostInterface(mockHost);
|
||||
return view;
|
||||
}
|
||||
|
||||
public void testRecording() {
|
||||
Mockito.when(mockRecorder.isRecording()).thenReturn(false);
|
||||
Mockito.when(mockRecorder.startRecording(Matchers.<OnErrorListener>any(),
|
||||
Matchers.<OnInfoListener>any(), Matchers.anyInt())).thenReturn(true);
|
||||
Mockito.when(mockRecorder.stopRecording()).thenReturn(Uri.parse("content://someaudio/2"));
|
||||
final AudioRecordView view = initView();
|
||||
view.onRecordButtonTouchDown();
|
||||
Mockito.verify(mockRecorder).startRecording(Matchers.<OnErrorListener>any(),
|
||||
Matchers.<OnInfoListener>any(), Matchers.anyInt());
|
||||
Mockito.when(mockRecorder.isRecording()).thenReturn(true);
|
||||
// Record for 1 second to make it meaningful.
|
||||
sleepNoThrow(1000);
|
||||
view.onRecordButtonTouchUp();
|
||||
// We added some buffer to the end of the audio recording, so sleep for sometime and
|
||||
// verify audio is recorded.
|
||||
sleepNoThrow(700);
|
||||
Mockito.verify(mockRecorder).stopRecording();
|
||||
verifyAudioSubmitted();
|
||||
}
|
||||
|
||||
private void sleepNoThrow(final long duration) {
|
||||
try {
|
||||
Thread.sleep(duration);
|
||||
} catch (final InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
return R.layout.mediapicker_audio_chooser;
|
||||
}
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.mediapicker;
|
||||
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.CameraInfo;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.ui.mediapicker.CameraManager.CameraWrapper;
|
||||
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@SmallTest
|
||||
public class CameraManagerTest extends BugleTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
// Force each test to set up a camera wrapper to match their needs
|
||||
CameraManager.setCameraWrapper(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
MockCameraFactory.cleanup();
|
||||
}
|
||||
|
||||
public void testNoCameraDeviceGetInfo() {
|
||||
CameraManager.setCameraWrapper(MockCameraFactory.createCameraWrapper());
|
||||
assertEquals(false, CameraManager.get().hasAnyCamera());
|
||||
assertEquals(false, CameraManager.get().hasFrontAndBackCamera());
|
||||
boolean threw = false;
|
||||
try {
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_BACK);
|
||||
} catch (AssertionError e) {
|
||||
threw = true;
|
||||
}
|
||||
if (!threw) {
|
||||
fail("selectCamera should have thrown");
|
||||
}
|
||||
}
|
||||
|
||||
public void testFrontFacingOnlyGetInfo() {
|
||||
CameraManager.setCameraWrapper(MockCameraFactory.createCameraWrapper(
|
||||
MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_FRONT)
|
||||
));
|
||||
assertEquals(true, CameraManager.get().hasAnyCamera());
|
||||
assertEquals(false, CameraManager.get().hasFrontAndBackCamera());
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_FRONT);
|
||||
assertEquals(CameraInfo.CAMERA_FACING_FRONT, CameraManager.get().getCameraInfo().facing);
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_BACK);
|
||||
assertEquals(CameraInfo.CAMERA_FACING_FRONT, CameraManager.get().getCameraInfo().facing);
|
||||
}
|
||||
|
||||
public void testBackFacingOnlyGetInfo() {
|
||||
CameraManager.setCameraWrapper(MockCameraFactory.createCameraWrapper(
|
||||
MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_BACK)
|
||||
));
|
||||
assertEquals(true, CameraManager.get().hasAnyCamera());
|
||||
assertEquals(false, CameraManager.get().hasFrontAndBackCamera());
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_FRONT);
|
||||
assertEquals(CameraInfo.CAMERA_FACING_BACK, CameraManager.get().getCameraInfo().facing);
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_BACK);
|
||||
assertEquals(CameraInfo.CAMERA_FACING_BACK, CameraManager.get().getCameraInfo().facing);
|
||||
}
|
||||
|
||||
public void testFrontAndBackGetInfo() {
|
||||
CameraManager.setCameraWrapper(MockCameraFactory.createCameraWrapper(
|
||||
MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_FRONT),
|
||||
MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_BACK)
|
||||
));
|
||||
assertEquals(true, CameraManager.get().hasAnyCamera());
|
||||
assertEquals(true, CameraManager.get().hasFrontAndBackCamera());
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_FRONT);
|
||||
assertEquals(CameraInfo.CAMERA_FACING_FRONT, CameraManager.get().getCameraInfo().facing);
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_BACK);
|
||||
assertEquals(CameraInfo.CAMERA_FACING_BACK, CameraManager.get().getCameraInfo().facing);
|
||||
}
|
||||
|
||||
public void testSwapCamera() {
|
||||
CameraManager.setCameraWrapper(MockCameraFactory.createCameraWrapper(
|
||||
MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_FRONT),
|
||||
MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_BACK)
|
||||
));
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_FRONT);
|
||||
assertEquals(CameraInfo.CAMERA_FACING_FRONT, CameraManager.get().getCameraInfo().facing);
|
||||
CameraManager.get().swapCamera();
|
||||
assertEquals(CameraInfo.CAMERA_FACING_BACK, CameraManager.get().getCameraInfo().facing);
|
||||
}
|
||||
|
||||
public void testOpenCamera() {
|
||||
Camera backCamera = MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_BACK);
|
||||
Camera frontCamera = MockCameraFactory.createCamera(CameraInfo.CAMERA_FACING_FRONT);
|
||||
CameraWrapper wrapper = MockCameraFactory.createCameraWrapper(frontCamera, backCamera);
|
||||
CameraManager.setCameraWrapper(wrapper);
|
||||
CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_BACK);
|
||||
CameraManager.get().openCamera();
|
||||
CameraManager.get().openCamera();
|
||||
CameraManager.get().openCamera();
|
||||
waitForPendingAsyncTasks();
|
||||
Mockito.verify(wrapper, Mockito.never()).open(0);
|
||||
Mockito.verify(wrapper).open(1);
|
||||
Mockito.verify(wrapper, Mockito.never()).release(frontCamera);
|
||||
Mockito.verify(wrapper, Mockito.never()).release(backCamera);
|
||||
CameraManager.get().swapCamera();
|
||||
waitForPendingAsyncTasks();
|
||||
Mockito.verify(wrapper).open(0);
|
||||
Mockito.verify(wrapper).open(1);
|
||||
Mockito.verify(wrapper, Mockito.never()).release(frontCamera);
|
||||
Mockito.verify(wrapper).release(backCamera);
|
||||
InOrder inOrder = Mockito.inOrder(wrapper);
|
||||
inOrder.verify(wrapper).open(1);
|
||||
inOrder.verify(wrapper).release(backCamera);
|
||||
inOrder.verify(wrapper).open(0);
|
||||
}
|
||||
|
||||
private void waitForPendingAsyncTasks() {
|
||||
try {
|
||||
final Object lockObject = new Object();
|
||||
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
super.onPostExecute(aVoid);
|
||||
synchronized (lockObject) {
|
||||
lockObject.notifyAll();
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
|
||||
synchronized (lockObject) {
|
||||
lockObject.wait(500);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.mediapicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.MediaStore.Images.Media;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.FakeCursor;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.data.GalleryGridItemData;
|
||||
import com.android.messaging.datamodel.data.TestDataFactory;
|
||||
import com.android.messaging.ui.AsyncImageView;
|
||||
import com.android.messaging.ui.ViewTest;
|
||||
import com.android.messaging.util.UriUtil;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class GalleryGridItemViewTest extends ViewTest<GalleryGridItemView> {
|
||||
|
||||
@Mock GalleryGridItemView.HostInterface mockHost;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final Context context = getInstrumentation().getTargetContext();
|
||||
FakeFactory.register(context)
|
||||
.withDataModel(new FakeDataModel(context));
|
||||
}
|
||||
|
||||
protected void verifyClickedItem(final View view, final GalleryGridItemData data) {
|
||||
Mockito.verify(mockHost).onItemClicked(view, data, false /* longClick */);
|
||||
}
|
||||
|
||||
protected void verifyContent(
|
||||
final GalleryGridItemView view,
|
||||
final String imageUrl,
|
||||
final boolean showCheckbox,
|
||||
final boolean isSelected) {
|
||||
final AsyncImageView imageView = (AsyncImageView) view.findViewById(R.id.thumbnail);
|
||||
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
|
||||
|
||||
assertNotNull(imageView);
|
||||
assertTrue(imageView.mImageRequestBinding.isBound());
|
||||
assertTrue(imageView.mImageRequestBinding.getData().getKey().startsWith(imageUrl));
|
||||
assertNotNull(checkBox);
|
||||
if (showCheckbox) {
|
||||
assertEquals(View.VISIBLE, checkBox.getVisibility());
|
||||
assertEquals(isSelected, checkBox.isChecked());
|
||||
} else {
|
||||
assertNotSame(View.VISIBLE, checkBox.getVisibility());
|
||||
}
|
||||
}
|
||||
|
||||
public void testBind() {
|
||||
Mockito.when(mockHost.isMultiSelectEnabled()).thenReturn(false);
|
||||
Mockito.when(mockHost.isItemSelected(Matchers.<GalleryGridItemData>any()))
|
||||
.thenReturn(false);
|
||||
final GalleryGridItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getGalleryGridCursor();
|
||||
cursor.moveToFirst();
|
||||
final String path = (String) cursor.getAt(Media.DATA, 0);
|
||||
view.bind(cursor, mockHost);
|
||||
verifyContent(view, UriUtil.getUriForResourceFile(path).toString(),
|
||||
false, false);
|
||||
}
|
||||
|
||||
public void testBindMultiSelectUnSelected() {
|
||||
Mockito.when(mockHost.isMultiSelectEnabled()).thenReturn(true);
|
||||
Mockito.when(mockHost.isItemSelected(Matchers.<GalleryGridItemData>any()))
|
||||
.thenReturn(false);
|
||||
final GalleryGridItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getGalleryGridCursor();
|
||||
cursor.moveToFirst();
|
||||
final String path = (String) cursor.getAt(Media.DATA, 0);
|
||||
view.bind(cursor, mockHost);
|
||||
verifyContent(view, UriUtil.getUriForResourceFile(path).toString(),
|
||||
true, false);
|
||||
}
|
||||
|
||||
public void testBindMultiSelectSelected() {
|
||||
Mockito.when(mockHost.isMultiSelectEnabled()).thenReturn(true);
|
||||
Mockito.when(mockHost.isItemSelected(Matchers.<GalleryGridItemData>any()))
|
||||
.thenReturn(true);
|
||||
final GalleryGridItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getGalleryGridCursor();
|
||||
cursor.moveToFirst();
|
||||
final String path = (String) cursor.getAt(Media.DATA, 0);
|
||||
view.bind(cursor, mockHost);
|
||||
verifyContent(view, UriUtil.getUriForResourceFile(path).toString(),
|
||||
true, true);
|
||||
}
|
||||
|
||||
public void testClick() {
|
||||
Mockito.when(mockHost.isMultiSelectEnabled()).thenReturn(false);
|
||||
Mockito.when(mockHost.isItemSelected(Matchers.<GalleryGridItemData>any()))
|
||||
.thenReturn(false);
|
||||
final GalleryGridItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getGalleryGridCursor();
|
||||
cursor.moveToFirst();
|
||||
view.bind(cursor, mockHost);
|
||||
view.performClick();
|
||||
verifyClickedItem(view, view.mData);
|
||||
}
|
||||
|
||||
public void testBindTwice() {
|
||||
Mockito.when(mockHost.isMultiSelectEnabled()).thenReturn(true);
|
||||
Mockito.when(mockHost.isItemSelected(Matchers.<GalleryGridItemData>any()))
|
||||
.thenReturn(false);
|
||||
final GalleryGridItemView view = getView();
|
||||
final FakeCursor cursor = TestDataFactory.getGalleryGridCursor();
|
||||
|
||||
cursor.moveToFirst();
|
||||
view.bind(cursor, mockHost);
|
||||
|
||||
cursor.moveToNext();
|
||||
final String path = (String) cursor.getAt(Media.DATA, 1);
|
||||
view.bind(cursor, mockHost);
|
||||
verifyContent(view, UriUtil.getUriForResourceFile(path).toString(),
|
||||
true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutIdForView() {
|
||||
return R.layout.gallery_grid_item_view;
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.mediapicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
|
||||
import com.android.messaging.FakeFactory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.FakeDataModel;
|
||||
import com.android.messaging.datamodel.binding.Binding;
|
||||
import com.android.messaging.datamodel.binding.BindingBase;
|
||||
import com.android.messaging.datamodel.data.DraftMessageData;
|
||||
import com.android.messaging.datamodel.data.MediaPickerData;
|
||||
import com.android.messaging.ui.FragmentTestCase;
|
||||
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
public class MediaPickerTest extends FragmentTestCase<MediaPicker> {
|
||||
@Mock protected MediaPickerData mMockMediaPickerData;
|
||||
@Mock protected DraftMessageData mMockDraftMessageData;
|
||||
protected FakeDataModel mFakeDataModel;
|
||||
|
||||
public MediaPickerTest() {
|
||||
super(MediaPicker.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MediaPicker getFragment() {
|
||||
if (mFragment == null) {
|
||||
mFragment = new MediaPicker(getInstrumentation().getTargetContext());
|
||||
}
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
final Context context = getInstrumentation().getTargetContext();
|
||||
mFakeDataModel = new FakeDataModel(context)
|
||||
.withMediaPickerData(mMockMediaPickerData);
|
||||
FakeFactory.register(context)
|
||||
.withDataModel(mFakeDataModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to initialize the MediaPicker and its data.
|
||||
*/
|
||||
private void initFragment(final int supportedMediaTypes, final Integer[] expectedLoaderIds,
|
||||
final boolean filterTabBeforeAttach) {
|
||||
Mockito.when(mMockMediaPickerData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
Mockito.when(mMockDraftMessageData.isBound(Matchers.anyString()))
|
||||
.thenReturn(true);
|
||||
final Binding<DraftMessageData> draftBinding = BindingBase.createBinding(this);
|
||||
draftBinding.bind(mMockDraftMessageData);
|
||||
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final MediaPicker fragment = getFragment();
|
||||
if (filterTabBeforeAttach) {
|
||||
fragment.setSupportedMediaTypes(supportedMediaTypes);
|
||||
getActivity().setFragment(fragment);
|
||||
} else {
|
||||
getActivity().setFragment(fragment);
|
||||
fragment.setSupportedMediaTypes(supportedMediaTypes);
|
||||
}
|
||||
fragment.setDraftMessageDataModel(draftBinding);
|
||||
Mockito.verify(mMockMediaPickerData,
|
||||
Mockito.atLeastOnce()).init(
|
||||
Matchers.eq(fragment.getLoaderManager()));
|
||||
fragment.open(MediaPicker.MEDIA_TYPE_ALL, false);
|
||||
}
|
||||
});
|
||||
getInstrumentation().waitForIdleSync();
|
||||
}
|
||||
|
||||
public void testDefaultTabs() {
|
||||
Mockito.when(mMockMediaPickerData.getSelectedChooserIndex()).thenReturn(0);
|
||||
initFragment(MediaPicker.MEDIA_TYPE_ALL, new Integer[] {
|
||||
MediaPickerData.GALLERY_MEDIA_LOADER },
|
||||
false);
|
||||
final MediaPicker mediaPicker = getFragment();
|
||||
final View view = mediaPicker.getView();
|
||||
assertNotNull(view);
|
||||
final ViewGroup tabStrip = (ViewGroup) view.findViewById(R.id.mediapicker_tabstrip);
|
||||
assertEquals(tabStrip.getChildCount(), 4);
|
||||
for (int i = 0; i < tabStrip.getChildCount(); i++) {
|
||||
final ImageButton tabButton = (ImageButton) tabStrip.getChildAt(i);
|
||||
assertEquals(View.VISIBLE, tabButton.getVisibility());
|
||||
assertEquals(i == 0, tabButton.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
public void testFilterTabsBeforeAttach() {
|
||||
Mockito.when(mMockMediaPickerData.getSelectedChooserIndex()).thenReturn(0);
|
||||
initFragment(MediaPicker.MEDIA_TYPE_IMAGE, new Integer[] {
|
||||
MediaPickerData.GALLERY_MEDIA_LOADER },
|
||||
true);
|
||||
final MediaPicker mediaPicker = getFragment();
|
||||
final View view = mediaPicker.getView();
|
||||
assertNotNull(view);
|
||||
final ViewGroup tabStrip = (ViewGroup) view.findViewById(R.id.mediapicker_tabstrip);
|
||||
assertEquals(tabStrip.getChildCount(), 4);
|
||||
for (int i = 0; i < tabStrip.getChildCount(); i++) {
|
||||
final ImageButton tabButton = (ImageButton) tabStrip.getChildAt(i);
|
||||
assertEquals(i == 0, tabButton.isSelected());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.ui.mediapicker;
|
||||
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.CameraInfo;
|
||||
|
||||
import com.android.messaging.ui.mediapicker.CameraManager.CameraWrapper;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class MockCameraFactory {
|
||||
private static Map<Camera, CameraInfo> sCameraInfos = new HashMap<Camera, CameraInfo>();
|
||||
|
||||
public static Camera createCamera(int facing) {
|
||||
Camera camera = Mockito.mock(Camera.class);
|
||||
CameraInfo cameraInfo = new CameraInfo();
|
||||
cameraInfo.facing = facing;
|
||||
sCameraInfos.put(camera, cameraInfo);
|
||||
return camera;
|
||||
}
|
||||
|
||||
public static void getCameraInfo(Camera camera, CameraInfo outCameraInfo) {
|
||||
CameraInfo cameraInfo = sCameraInfos.get(camera);
|
||||
outCameraInfo.facing = cameraInfo.facing;
|
||||
outCameraInfo.orientation = cameraInfo.orientation;
|
||||
outCameraInfo.canDisableShutterSound = cameraInfo.canDisableShutterSound;
|
||||
}
|
||||
|
||||
public static CameraWrapper createCameraWrapper(final Camera... cameras) {
|
||||
CameraWrapper wrapper = Mockito.mock(CameraWrapper.class);
|
||||
Mockito.when(wrapper.getNumberOfCameras()).thenReturn(cameras.length);
|
||||
Mockito.when(wrapper.open(Mockito.anyInt())).then(new Answer<Camera>() {
|
||||
@Override
|
||||
public Camera answer(InvocationOnMock invocation) {
|
||||
return cameras[(Integer) invocation.getArguments()[0]];
|
||||
}
|
||||
});
|
||||
Mockito.doAnswer(new Answer<Void>() {
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
getCameraInfo(
|
||||
cameras[(Integer) invocation.getArguments()[0]],
|
||||
(CameraInfo) invocation.getArguments()[1]
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}).when(wrapper).getCameraInfo(Mockito.anyInt(), Mockito.any(CameraInfo.class));
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
public static void cleanup() {
|
||||
sCameraInfos.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.util;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
|
||||
@SmallTest
|
||||
public class BugleGservicesTest extends BugleTestCase {
|
||||
|
||||
public void testGServiceGet() {
|
||||
final BugleGservices bugleGservices = new FakeBugleGservices();
|
||||
|
||||
assertEquals(BugleGservicesKeys.SMS_IGNORE_MESSAGE_REGEX_DEFAULT,
|
||||
bugleGservices.getString(
|
||||
BugleGservicesKeys.SMS_IGNORE_MESSAGE_REGEX,
|
||||
BugleGservicesKeys.SMS_IGNORE_MESSAGE_REGEX_DEFAULT));
|
||||
}
|
||||
}
|
||||
@@ -1,307 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.util;
|
||||
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.Contacts;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
import com.android.messaging.FakeFactory;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
* Class for testing ContactUtil.
|
||||
*/
|
||||
@LargeTest
|
||||
public class ContactUtilTest extends BugleTestCase {
|
||||
private static final String TEST_NAME_PREFIX = "BugleTest:";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// TODO: This test will actually mess with contacts on your phone.
|
||||
// Ideally we would use a fake content provider to give us contact data...
|
||||
FakeFactory.registerWithoutFakeContext(getTestContext());
|
||||
|
||||
// add test contacts.
|
||||
addTestContact("John", "650-123-1233", "john@gmail.com", false);
|
||||
addTestContact("Joe", "(650)123-1233", "joe@gmail.com", false);
|
||||
addTestContact("Jim", "650 123 1233", "jim@gmail.com", false);
|
||||
addTestContact("Samantha", "650-123-1235", "samantha@gmail.com", true);
|
||||
addTestContact("Adrienne", "650-123-1236", "adrienne@gmail.com", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
deleteTestContacts();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a test contact based on contact name, phone and email.
|
||||
*/
|
||||
private void addTestContact(
|
||||
final String name, final String phone, final String email, final boolean starred)
|
||||
throws Exception {
|
||||
final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
|
||||
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
|
||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
|
||||
.build());
|
||||
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE,
|
||||
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
|
||||
TEST_NAME_PREFIX + name).build());
|
||||
|
||||
if (phone != null) {
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE,
|
||||
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
|
||||
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
|
||||
ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
|
||||
.build());
|
||||
}
|
||||
|
||||
if (email != null) {
|
||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||
.withValue(ContactsContract.Data.MIMETYPE,
|
||||
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
|
||||
.withValue(ContactsContract.CommonDataKinds.Email.DATA, email)
|
||||
.withValue(ContactsContract.CommonDataKinds.Email.TYPE,
|
||||
ContactsContract.CommonDataKinds.Email.TYPE_WORK)
|
||||
.build());
|
||||
}
|
||||
|
||||
mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
|
||||
|
||||
// Star the whole contact if needed.
|
||||
if (starred) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(Contacts.STARRED, 1);
|
||||
getContext().getContentResolver().update(Contacts.CONTENT_URI, values,
|
||||
Contacts.DISPLAY_NAME + "= ?", new String[] { TEST_NAME_PREFIX + name });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove test contacts added during test setup.
|
||||
*/
|
||||
private void deleteTestContacts() {
|
||||
final Uri contactUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
|
||||
Uri.encode(TEST_NAME_PREFIX));
|
||||
final Cursor cur =
|
||||
mContext.getContentResolver().query(contactUri, null, null, null, null);
|
||||
try {
|
||||
if (cur.moveToFirst()) {
|
||||
do {
|
||||
final String lookupKey = cur.getString(cur.getColumnIndex(Contacts.LOOKUP_KEY));
|
||||
final Uri uri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
|
||||
mContext.getContentResolver().delete(uri, null, null);
|
||||
} while (cur.moveToNext());
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
LogUtil.e(LogUtil.BUGLE_TAG, "Failed to delete test contacts", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.getPhone will return all phones, including the ones added for test.
|
||||
*/
|
||||
public void ingoredTestGetPhones() {
|
||||
final Cursor cur = ContactUtil.getPhones(getContext())
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testGetPhones: Number of phones on the device:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Joe");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Jim");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Samantha");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Adrienne");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.filterPhone will work on name based matches.
|
||||
*/
|
||||
public void ingoredTestFilterPhonesByName() {
|
||||
final Cursor cur = ContactUtil.filterPhones(getContext(), TEST_NAME_PREFIX)
|
||||
.performSynchronousQuery();
|
||||
|
||||
if (cur.getCount() != 5) {
|
||||
Assert.fail("Cursor should have size of 5");
|
||||
return;
|
||||
}
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Joe");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Jim");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Samantha");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Adrienne");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.filterPhone will work on partial number matches.
|
||||
*/
|
||||
public void ingoredTestFilterPhonesByPartialNumber() {
|
||||
final String[] filters = new String[] { "650123", "650-123", "(650)123", "650 123" };
|
||||
|
||||
for (final String filter : filters) {
|
||||
final Cursor cur = ContactUtil.filterPhones(getContext(), filter)
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testFilterPhonesByPartialNumber: Number of phones:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Joe");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Jim");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Samantha");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Adrienne");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.filterPhone will work on full number matches.
|
||||
*/
|
||||
public void ingoredTestFilterPhonesByFullNumber() {
|
||||
final String[] filters = new String[] {
|
||||
"6501231233", "650-123-1233", "(650)123-1233", "650 123 1233" };
|
||||
|
||||
for (final String filter : filters) {
|
||||
final Cursor cur = ContactUtil.filterPhones(getContext(), filter)
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testFilterPhonesByFullNumber: Number of phones:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Joe");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Jim");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.lookPhone will work on number including area code.
|
||||
*/
|
||||
public void ingoredTestLookupPhoneWithAreaCode() {
|
||||
final String[] filters = new String[] {
|
||||
"6501231233", "650-123-1233", "(650)123-1233", "650 123 1233" };
|
||||
|
||||
for (final String filter : filters) {
|
||||
final Cursor cur = ContactUtil.lookupPhone(getContext(), filter)
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testLookupPhoneWithAreaCode: Number of phones:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Joe");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Jim");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.lookPhone will work on number without area code.
|
||||
*/
|
||||
public void ingoredTestLookupPhoneWithoutAreaCode() {
|
||||
final String[] filters = new String[] {
|
||||
"1231233", "123-1233", "123 1233" };
|
||||
|
||||
for (final String filter : filters) {
|
||||
final Cursor cur = ContactUtil.lookupPhone(getContext(), filter)
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testLookupPhoneWithoutAreaCode: Number of phones:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Joe");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Jim");
|
||||
}
|
||||
}
|
||||
|
||||
public void ingoredTestGetFrequentPhones() {
|
||||
final Cursor cur = ContactUtil.getFrequentContacts(getContext())
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testGetFrequentPhones: Number of phones on the device:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Samantha");
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "Adrienne");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.filterEmails will work on partial email.
|
||||
*/
|
||||
public void ingoredTestFilterEmails() {
|
||||
final Cursor cur = ContactUtil.filterEmails(getContext(), "john@")
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testFilterEmails: Number of emails:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify ContactUtil.lookupEmail will work on full email.
|
||||
*/
|
||||
public void ingoredTestLookupEmail() {
|
||||
final Cursor cur = ContactUtil.lookupEmail(getContext(), "john@gmail.com")
|
||||
.performSynchronousQuery();
|
||||
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "testLookupEmail: Number of emails:" +
|
||||
cur.getCount());
|
||||
|
||||
verifyCursorContains(cur, TEST_NAME_PREFIX + "John");
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to check whether cursor contains a particular contact.
|
||||
*/
|
||||
private void verifyCursorContains(final Cursor cursor, final String nameToVerify) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
final String name = cursor.getString(ContactUtil.INDEX_DISPLAY_NAME);
|
||||
if (TextUtils.equals(name, nameToVerify)) {
|
||||
return;
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
Assert.fail("Cursor should have " + nameToVerify);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.util;
|
||||
|
||||
/**
|
||||
* Fake implementation which just returns the default values.
|
||||
*/
|
||||
public class FakeBugleGservices extends BugleGservices {
|
||||
public FakeBugleGservices() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerForChanges(final Runnable r) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(final String key, final long defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final String key, final int defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(final String key, final boolean defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(final String key, final String defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(String key, float defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.util;
|
||||
|
||||
|
||||
/**
|
||||
* Fake implementation which just returns the default values and ignores put operations.
|
||||
*/
|
||||
public class FakeBuglePrefs extends BuglePrefs {
|
||||
public FakeBuglePrefs() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final String key, final int defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(final String key, final long defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(final String key, final boolean defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(final String key, final String defaultValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putInt(final String key, final int value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(final String key, final long value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBoolean(final String key, final boolean value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putString(final String key, final String value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBytes(String key, byte[] value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSharedPreferencesName() {
|
||||
return "FakeBuglePrefs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(int oldVersion, int newVersion) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String key) {
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaPlayer;
|
||||
|
||||
public class FakeMediaUtil extends MediaUtil {
|
||||
private final MediaPlayer mMediaPlayer;
|
||||
public FakeMediaUtil(final MediaPlayer mediaPlayer) {
|
||||
mMediaPlayer = mediaPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Context context, int resId, OnCompletionListener completionListener) {
|
||||
if (completionListener != null) {
|
||||
completionListener.onCompletion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.android.messaging.util;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.messaging.BugleTestCase;
|
||||
|
||||
/*
|
||||
* Class for testing YouTubeUtil.
|
||||
*/
|
||||
@SmallTest
|
||||
public class YouTubeUtilTest extends BugleTestCase {
|
||||
public void testGetYoutubePreviewImageLink() {
|
||||
final String videoId = "dQw4w9WgXcQ";
|
||||
final String videoThumbnailUrl = YouTubeUtil.YOUTUBE_STATIC_THUMBNAIL_PREFIX + videoId
|
||||
+ YouTubeUtil.YOUTUBE_STATIC_THUMBNAIL_END;
|
||||
|
||||
// Check known valid youtube links to videos
|
||||
assertEquals(
|
||||
YouTubeUtil.getYoutubePreviewImageLink("http://www.youtube.com/watch?v=" + videoId),
|
||||
videoThumbnailUrl);
|
||||
assertEquals(
|
||||
YouTubeUtil.getYoutubePreviewImageLink("https://www.youtube.com/watch?v=" + videoId
|
||||
+ "&feature=youtu.be"), videoThumbnailUrl);
|
||||
assertEquals(
|
||||
YouTubeUtil.getYoutubePreviewImageLink("www.youtube.com/watch?v=" + videoId),
|
||||
videoThumbnailUrl);
|
||||
assertEquals(
|
||||
YouTubeUtil.getYoutubePreviewImageLink("http://www.youtube.com/embed/" + videoId),
|
||||
videoThumbnailUrl);
|
||||
assertEquals(YouTubeUtil.getYoutubePreviewImageLink("http://www.youtube.com/v/" + videoId),
|
||||
videoThumbnailUrl);
|
||||
assertEquals(
|
||||
YouTubeUtil.getYoutubePreviewImageLink("https://youtube.googleapis.com/v/"
|
||||
+ videoId), videoThumbnailUrl);
|
||||
assertEquals(
|
||||
YouTubeUtil.getYoutubePreviewImageLink("http://www.youtube.com/apiplayer?video_id="
|
||||
+ videoId), videoThumbnailUrl);
|
||||
// This is the type of links that are used as shares from YouTube and will be the most
|
||||
// likely case that we see
|
||||
assertEquals(YouTubeUtil.getYoutubePreviewImageLink("http://youtu.be/" + videoId),
|
||||
videoThumbnailUrl);
|
||||
|
||||
// Try links that shouldn't work
|
||||
assertNull(YouTubeUtil.getYoutubePreviewImageLink("http://www.youtube.com"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user