Chromium Code Reviews| Index: chrome/android/junit/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderUnitTest.java |
| diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderUnitTest.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c223857c797a3a3b7993cc5bf6fcaba43088441d |
| --- /dev/null |
| +++ b/chrome/android/junit/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProviderUnitTest.java |
| @@ -0,0 +1,203 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.chrome.browser.superviseduser; |
| + |
| +import static org.hamcrest.CoreMatchers.is; |
| +import static org.junit.Assert.assertThat; |
| +import static org.mockito.Matchers.anyLong; |
| +import static org.mockito.Matchers.anyString; |
| +import static org.mockito.Mockito.doAnswer; |
| +import static org.mockito.Mockito.times; |
| +import static org.mockito.Mockito.verify; |
| + |
| +import android.os.Handler; |
| +import android.os.Looper; |
| +import android.util.Pair; |
| + |
| +import org.chromium.testing.local.LocalRobolectricTestRunner; |
| +import org.junit.Before; |
| +import org.junit.Test; |
| +import org.junit.runner.RunWith; |
| +import org.mockito.Mockito; |
| +import org.mockito.invocation.InvocationOnMock; |
| +import org.mockito.stubbing.Answer; |
| +import org.robolectric.Robolectric; |
| +import org.robolectric.annotation.Config; |
| +import org.robolectric.annotation.Implementation; |
| +import org.robolectric.annotation.Implements; |
| + |
| +import java.util.concurrent.CountDownLatch; |
| + |
| +/** |
| + * Tests of SupervisedUserContentProvider. This is tested as a simple class, not as a content |
| + * provider. The content provider aspects are tested with WebRestrictionsContentProviderTest. |
| + */ |
| +@RunWith(LocalRobolectricTestRunner.class) |
| +@Config(manifest = Config.NONE, |
| + shadows = {SupervisedUserContentProviderUnitTest.ShadowHander.class}) |
| +public class SupervisedUserContentProviderUnitTest { |
| + private static CountDownLatch sLatch; |
| + |
| + /** |
| + * Special Handler shadow class that allows the test to wait for a post() call. |
| + */ |
| + @Implements(Handler.class) |
| + public static class ShadowHander extends org.robolectric.shadows.ShadowHandler { |
| + @Override |
| + @Implementation |
| + public boolean post(Runnable r) { |
| + boolean result = super.post(r); |
| + // If the test wants to wait it should initialize sLatch before post is called. |
| + if (sLatch != null) sLatch.countDown(); |
| + return result; |
| + } |
| + } |
| + |
| + private SupervisedUserContentProvider mSupervisedUserContentProvider; |
| + private Looper mNativeCallLooper; |
| + |
| + @Before |
| + public void setUp() { |
| + sLatch = null; |
| + mNativeCallLooper = null; |
| + mSupervisedUserContentProvider = Mockito.spy(new SupervisedUserContentProvider()); |
| + mSupervisedUserContentProvider.setNativeSupervisedUserContentProviderForTesting(1234); |
| + } |
| + |
| + @Test |
| + public void testShouldProceed() throws InterruptedException { |
| + // Runnable for test thread. |
| + class TestRunnable implements Runnable { |
| + private Pair<Boolean, String> mResult; |
| + |
| + @Override |
| + public void run() { |
| + this.mResult = mSupervisedUserContentProvider.shouldProceed("url"); |
| + } |
| + |
| + public Pair<Boolean, String> getResult() { |
| + return mResult; |
| + } |
| + } |
| + // Mock the native call for a permitted URL |
| + doAnswer(new Answer<Void>() { |
| + |
| + @Override |
| + public Void answer(InvocationOnMock invocation) throws Throwable { |
| + mNativeCallLooper = Looper.myLooper(); |
| + mSupervisedUserContentProvider.onQueryComplete(true, null); |
| + return null; |
| + } |
| + |
| + }) |
| + .when(mSupervisedUserContentProvider) |
| + .nativeShouldProceed(anyLong(), anyString()); |
| + TestRunnable r1 = new TestRunnable(); |
| + // Because supervisedUserContentProvider uses a SynchronousQueue (which is a java.util |
|
Bernhard Bauer
2015/12/16 17:52:09
Nit: SupervisedUserContentProvider with capital le
aberent
2015/12/16 22:15:17
Done.
|
| + // class, so can't be shadowed or mocked) we need to make the calls to shouldProceed on a |
| + // real thread. This can't be the main thread because Robolectric emulates UI event handling |
| + // on the main thread. |
| + Thread t1 = new Thread(r1); |
| + sLatch = new CountDownLatch(1); |
| + t1.start(); |
| + // Wait for the event to be posted to the emulated UI thread. |
| + sLatch.await(); |
| + Robolectric.runUiThreadTasks(); |
| + t1.join(); |
| + verify(mSupervisedUserContentProvider).nativeShouldProceed(1234, "url"); |
| + // Assert has to be on main thread for failures to cause test failure. |
| + assertThat(r1.getResult(), is(new Pair<Boolean, String>(true, null))); |
| + // Check that the native code was called on the right thread. |
| + assertThat(mNativeCallLooper, is(Looper.getMainLooper())); |
| + // Mock the native call for a forbidden URL |
| + doAnswer(new Answer<Void>() { |
| + |
| + @Override |
| + public Void answer(InvocationOnMock invocation) throws Throwable { |
| + mNativeCallLooper = Looper.myLooper(); |
| + mSupervisedUserContentProvider.onQueryComplete(false, "Hello"); |
| + return null; |
| + } |
| + |
| + }) |
| + .when(mSupervisedUserContentProvider) |
| + .nativeShouldProceed(anyLong(), anyString()); |
| + TestRunnable r2 = new TestRunnable(); |
| + // Create a new thread for the second call |
| + Thread t2 = new Thread(r2); |
| + sLatch = new CountDownLatch(1); |
| + t2.start(); |
| + // Wait for the event to be posted to the emulated UI thread. |
| + sLatch.await(); |
| + Robolectric.runUiThreadTasksIncludingDelayedTasks(); |
| + t2.join(); |
| + assertThat(r2.getResult(), is(new Pair<Boolean, String>(false, "Hello"))); |
| + // Check that the native code was called on the UI thread. |
| + assertThat(mNativeCallLooper, is(Looper.getMainLooper())); |
| + } |
| + |
| + @Test |
| + public void testRequestInsert() throws InterruptedException { |
| + // Runnable for test thread. |
| + class TestRunnable implements Runnable { |
| + private boolean mResult; |
| + |
| + @Override |
| + public void run() { |
| + this.mResult = mSupervisedUserContentProvider.requestInsert("url"); |
| + } |
| + |
| + public boolean getResult() { |
| + return mResult; |
| + } |
| + } |
| + // Mock native call. |
| + doAnswer(new Answer<Void>() { |
| + |
| + @Override |
| + public Void answer(InvocationOnMock invocation) throws Throwable { |
| + mNativeCallLooper = Looper.myLooper(); |
| + mSupervisedUserContentProvider.onInsertRequestSendComplete(true); |
| + return null; |
| + } |
| + |
| + }) |
| + .when(mSupervisedUserContentProvider) |
| + .nativeRequestInsert(anyLong(), anyString()); |
| + TestRunnable r1 = new TestRunnable(); |
| + Thread t1 = new Thread(r1); |
| + sLatch = new CountDownLatch(1); |
| + t1.start(); |
| + sLatch.await(); |
| + Robolectric.runUiThreadTasks(); |
| + t1.join(); |
| + verify(mSupervisedUserContentProvider).nativeRequestInsert(1234, "url"); |
| + assertThat(r1.getResult(), is(true)); |
| + assertThat(mNativeCallLooper, is(Looper.getMainLooper())); |
| + doAnswer(new Answer<Void>() { |
| + |
| + @Override |
| + public Void answer(InvocationOnMock invocation) throws Throwable { |
| + mNativeCallLooper = Looper.myLooper(); |
| + mSupervisedUserContentProvider.onInsertRequestSendComplete(false); |
| + return null; |
| + } |
| + |
| + }) |
| + .when(mSupervisedUserContentProvider) |
| + .nativeRequestInsert(anyLong(), anyString()); |
| + TestRunnable r2 = new TestRunnable(); |
| + Thread t2 = new Thread(r2); |
| + sLatch = new CountDownLatch(1); |
| + t2.start(); |
| + sLatch.await(); |
| + Robolectric.runUiThreadTasks(); |
| + t2.join(); |
| + Robolectric.runUiThreadTasks(); |
| + verify(mSupervisedUserContentProvider, times(2)).nativeRequestInsert(1234, "url"); |
| + assertThat(r2.getResult(), is(false)); |
| + assertThat(mNativeCallLooper, is(Looper.getMainLooper())); |
| + } |
| +} |