blob: c720a2a9d3933142a4f6f4ad7cde50ac37cd3288 [file] [log] [blame]
// Copyright 2015 The Vanadium 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 io.v.baku.toolkit.blessings;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.SettableFuture;
import junit.framework.AssertionFailedError;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.junit4.PowerMockRunner;
import io.v.android.libs.security.BlessingsManager;
import io.v.v23.security.Blessings;
import rx.functions.Action1;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor({"io.v.android.libs.security.BlessingsManager", "android.app.Fragment"})
@PrepareForTest({Blessings.class, BlessingsManager.class})
public class BlessingsManagerBlessingsProviderTest {
@Before
public void setUp() {
mockStatic(BlessingsManager.class);
}
@Test
public void testColdPassive() {
new BlessingsManagerBlessingsProvider(null, null)
.getPassiveRxBlessings()
.subscribe(b -> fail("Unexpected blessings " + b));
}
@SuppressWarnings("unchecked")
@Test
public void testBlessingsFromManager() throws Exception {
final Action1<Blessings>
cold = mock(Action1.class),
hot = mock(Action1.class);
final Blessings
b1 = PowerMockito.mock(Blessings.class),
b2 = PowerMockito.mock(Blessings.class);
when(BlessingsManager.getBlessings(any(), any(), any(), anyBoolean()))
.thenReturn(Futures.immediateFuture(b1), Futures.immediateFuture(b2));
final RefreshableBlessingsProvider t = new BlessingsManagerBlessingsProvider(null, null);
t.getPassiveRxBlessings().subscribe(cold);
t.getRxBlessings().subscribe(hot);
verify(hot).call(b1);
verify(cold).call(b1);
verify(hot, never()).call(b2);
t.refreshBlessings();
verify(hot).call(b2);
verify(cold).call(b2);
}
/**
* Verifies that if a new subscriber needs to seek blessings, the new subscriber does not
* receive blessings until the seek completes (does not receive old blessings), and that the old
* subscriber is refreshed as well.
*/
@SuppressWarnings("unchecked")
@Test
public void testDeferOnNewSubscriber() throws Exception {
final Action1<Blessings>
s1 = mock(Action1.class),
s2 = mock(Action1.class);
final Blessings
b1 = PowerMockito.mock(Blessings.class),
b2 = PowerMockito.mock(Blessings.class);
final SettableFuture<Blessings>
bf1 = SettableFuture.create(),
bf2 = SettableFuture.create();
when(BlessingsManager.getBlessings(any(), any(), any(), anyBoolean()))
.thenReturn(bf1, bf2);
final RefreshableBlessingsProvider t = new BlessingsManagerBlessingsProvider(null, null);
t.getRxBlessings().subscribe(s1);
bf1.set(b1);
t.getRxBlessings().subscribe(s2);
verify(s2, never()).call(any());
bf2.set(b2);
verify(s1).call(b2);
verify(s2).call(b2);
}
@SuppressWarnings("unchecked")
@Test
public void testConcurrentSeeks() {
final Action1<Blessings>
s1 = mock(Action1.class),
s2 = mock(Action1.class);
final Blessings b = PowerMockito.mock(Blessings.class);
final SettableFuture<Blessings>
bf = SettableFuture.create();
when(BlessingsManager.getBlessings(any(), any(), any(), anyBoolean()))
.thenReturn(bf, Futures.immediateFailedFuture(
new AssertionFailedError("Expected at most one getBlessings call.")));
final RefreshableBlessingsProvider t = new BlessingsManagerBlessingsProvider(null, null);
t.getRxBlessings().subscribe(s1);
t.getRxBlessings().subscribe(s2);
bf.set(b);
verify(s1).call(b);
verify(s2).call(b);
}
}