package io.github.hidroh.materialistic; import android.accounts.Account; import android.accounts.AccountManager; import android.app.Activity; import android.content.Context; import android.net.ConnectivityManager; import android.support.design.widget.AppBarLayout; import android.support.design.widget.FloatingActionButton; import android.support.v4.content.LocalBroadcastManager; import android.text.format.DateUtils; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.RuntimeEnvironment; import org.robolectric.shadows.ShadowAccountManager; import org.robolectric.shadows.ShadowAlertDialog; import org.robolectric.shadows.ShadowApplication; import org.robolectric.shadows.ShadowNetworkInfo; import org.robolectric.util.ActivityController; import javax.inject.Inject; import io.github.hidroh.materialistic.data.HackerNewsClient; import io.github.hidroh.materialistic.data.TestHnItem; import io.github.hidroh.materialistic.test.TestRunner; import io.github.hidroh.materialistic.test.TestListActivity; import io.github.hidroh.materialistic.widget.PopupMenu; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; import static org.assertj.android.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; 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.robolectric.Shadows.shadowOf; import static org.robolectric.shadows.support.v4.Shadows.shadowOf; @RunWith(TestRunner.class) public class AppUtilsTest { @Inject AlertDialogBuilder alertDialogBuilder; @Test public void testSetTextWithLinks() { TextView textView = new TextView(RuntimeEnvironment.application); AppUtils.setTextWithLinks(textView, AppUtils.fromHtml("<a href=\\\"http://www.justin.tv/problems/bml\\\" rel=\\\"nofollow\\\">http://www.justin.tv/problems/bml</a>")); MotionEvent event = mock(MotionEvent.class); when(event.getAction()).thenReturn(MotionEvent.ACTION_DOWN); when(event.getX()).thenReturn(0f); when(event.getY()).thenReturn(0f); assertTrue(shadowOf(textView).getOnTouchListener().onTouch(textView, event)); when(event.getAction()).thenReturn(MotionEvent.ACTION_UP); when(event.getX()).thenReturn(0f); when(event.getY()).thenReturn(0f); assertTrue(shadowOf(textView).getOnTouchListener().onTouch(textView, event)); assertNotNull(ShadowApplication.getInstance().getNextStartedActivity()); } @Test public void testDefaultTextSize() { Activity activity = Robolectric.setupActivity(Activity.class); float expected = activity.getTheme().obtainStyledAttributes(R.style.AppTextSize, new int[]{R.attr.contentTextSize}).getDimension(0, 0); float actual = activity.getTheme().obtainStyledAttributes( new int[]{R.attr.contentTextSize}).getDimension(0, 0); assertThat(actual).isEqualTo(expected); } @Test public void testGetAbbreviatedTimeSpan() { assertEquals("0m", AppUtils.getAbbreviatedTimeSpan(System.currentTimeMillis() + DateUtils.SECOND_IN_MILLIS)); assertEquals("0m", AppUtils.getAbbreviatedTimeSpan(System.currentTimeMillis())); assertEquals("5m", AppUtils.getAbbreviatedTimeSpan(System.currentTimeMillis() - 5 * DateUtils.MINUTE_IN_MILLIS - 10 * DateUtils.SECOND_IN_MILLIS)); assertEquals("1h", AppUtils.getAbbreviatedTimeSpan(System.currentTimeMillis() - DateUtils.HOUR_IN_MILLIS - DateUtils.MINUTE_IN_MILLIS)); assertEquals("6d", AppUtils.getAbbreviatedTimeSpan(System.currentTimeMillis() - DateUtils.WEEK_IN_MILLIS + DateUtils.MINUTE_IN_MILLIS)); assertEquals("1w", AppUtils.getAbbreviatedTimeSpan(System.currentTimeMillis() - DateUtils.WEEK_IN_MILLIS - DateUtils.MINUTE_IN_MILLIS)); assertEquals("10y", AppUtils.getAbbreviatedTimeSpan(System.currentTimeMillis() - 10 * DateUtils.YEAR_IN_MILLIS - DateUtils.MINUTE_IN_MILLIS)); } @Test public void testNoActiveNetwork() { shadowOf((ConnectivityManager) RuntimeEnvironment.application .getSystemService(Context.CONNECTIVITY_SERVICE)).setActiveNetworkInfo(null); assertFalse(AppUtils.isOnWiFi(RuntimeEnvironment.application)); } @Test public void testDisconnectedNetwork() { shadowOf((ConnectivityManager) RuntimeEnvironment.application .getSystemService(Context.CONNECTIVITY_SERVICE)) .setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null, 0, 0, false, false)); assertFalse(AppUtils.isOnWiFi(RuntimeEnvironment.application)); } @Test public void testNonWiFiNetwork() { shadowOf((ConnectivityManager) RuntimeEnvironment.application .getSystemService(Context.CONNECTIVITY_SERVICE)) .setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null, ConnectivityManager.TYPE_MOBILE, 0, true, true)); assertFalse(AppUtils.isOnWiFi(RuntimeEnvironment.application)); } @Test public void testWiFiNetwork() { shadowOf((ConnectivityManager) RuntimeEnvironment.application .getSystemService(Context.CONNECTIVITY_SERVICE)) .setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null, ConnectivityManager.TYPE_WIFI, 0, true, true)); assertTrue(AppUtils.isOnWiFi(RuntimeEnvironment.application)); } @Test public void testRemoveAccount() { Preferences.setUsername(RuntimeEnvironment.application, "olduser"); AppUtils.registerAccountsUpdatedListener(RuntimeEnvironment.application); shadowOf(AccountManager.get(RuntimeEnvironment.application)).addAccount( new Account("newuser", BuildConfig.APPLICATION_ID)); assertNull(Preferences.getUsername(RuntimeEnvironment.application)); Preferences.setUsername(RuntimeEnvironment.application, "newuser"); shadowOf(AccountManager.get(RuntimeEnvironment.application)).addAccount( new Account("olduser", BuildConfig.APPLICATION_ID)); assertEquals("newuser", Preferences.getUsername(RuntimeEnvironment.application)); } @Test public void testShareComment() { AppUtils.share(RuntimeEnvironment.application, mock(PopupMenu.class), new View(RuntimeEnvironment.application), new TestHnItem(1)); assertNull(ShadowAlertDialog.getLatestAlertDialog()); AppUtils.share(RuntimeEnvironment.application, mock(PopupMenu.class), new View(RuntimeEnvironment.application), new TestHnItem(1) { @Override public String getUrl() { return String.format(HackerNewsClient.WEB_ITEM_PATH, "1"); } }); assertNull(ShadowAlertDialog.getLatestAlertDialog()); } @Test public void testOpenExternalComment() { ActivityController<TestListActivity> controller = Robolectric.buildActivity(TestListActivity.class); TestListActivity activity = controller.create().start().resume().get(); AppUtils.openExternal(activity, mock(PopupMenu.class), new View(activity), new TestHnItem(1), null); assertNull(ShadowAlertDialog.getLatestAlertDialog()); AppUtils.openExternal(activity, mock(PopupMenu.class), new View(activity), new TestHnItem(1) { @Override public String getUrl() { return String.format(HackerNewsClient.WEB_ITEM_PATH, "1"); } }, null); assertNull(ShadowAlertDialog.getLatestAlertDialog()); controller.destroy(); } @Test public void testLoginNoAccounts() { AppUtils.showLogin(RuntimeEnvironment.application, null); assertThat(shadowOf(RuntimeEnvironment.application).getNextStartedActivity()) .hasComponent(RuntimeEnvironment.application, LoginActivity.class); } @Test public void testLoginStaleAccount() { Preferences.setUsername(RuntimeEnvironment.application, "username"); shadowOf(ShadowAccountManager.get(RuntimeEnvironment.application)) .addAccount(new Account("username", BuildConfig.APPLICATION_ID)); AppUtils.showLogin(RuntimeEnvironment.application, null); assertThat(shadowOf(RuntimeEnvironment.application).getNextStartedActivity()) .hasComponent(RuntimeEnvironment.application, LoginActivity.class); } @Test public void testLoginShowChooser() { TestApplication.applicationGraph.inject(this); shadowOf(ShadowAccountManager.get(RuntimeEnvironment.application)) .addAccount(new Account("username", BuildConfig.APPLICATION_ID)); AppUtils.showLogin(RuntimeEnvironment.application, alertDialogBuilder); assertNotNull(ShadowAlertDialog.getLatestAlertDialog()); } @Test public void testTrimHtmlWhitespaces() { TextView textView = new TextView(RuntimeEnvironment.application); textView.setText(AppUtils.fromHtml("<p>paragraph</p><p><br/><br/><br/></p>")); assertThat(textView).hasTextString("paragraph"); textView.setText(AppUtils.fromHtml("")); assertThat(textView).hasTextString(""); textView.setText(AppUtils.fromHtml("paragraph")); assertThat(textView).hasTextString("paragraph"); } @Test public void testOpenExternalUrlNoConnection() { shadowOf((ConnectivityManager) RuntimeEnvironment.application .getSystemService(Context.CONNECTIVITY_SERVICE)) .setActiveNetworkInfo(null); AppUtils.openWebUrlExternal(RuntimeEnvironment.application, new TestHnItem(1L) { @Override public String getUrl() { return "http://example.com"; } }, "http://example.com", null); assertThat(shadowOf(RuntimeEnvironment.application).getNextStartedActivity()) .hasComponent(RuntimeEnvironment.application, OfflineWebActivity.class) .hasExtra(OfflineWebActivity.EXTRA_URL, "http://example.com"); } @Test public void testFullscreenButton() { ActivityController<TestListActivity> controller = Robolectric.buildActivity(TestListActivity.class); TestListActivity activity = controller.create().start().resume().get(); FloatingActionButton fab = new FloatingActionButton(activity); AppUtils.toggleFabAction(fab, null, false); fab.performClick(); assertThat(shadowOf(LocalBroadcastManager.getInstance(activity)).getSentBroadcastIntents()).isNotEmpty(); controller.destroy(); } @Test public void testNavigate() { AppBarLayout appBar = mock(AppBarLayout.class); when(appBar.getBottom()).thenReturn(1); Navigable navigable = mock(Navigable.class); AppUtils.navigate(Navigable.DIRECTION_DOWN, appBar, navigable); verify(appBar).setExpanded(eq(false), anyBoolean()); verify(navigable, never()).onNavigate(anyInt()); when(appBar.getBottom()).thenReturn(0); AppUtils.navigate(Navigable.DIRECTION_DOWN, appBar, navigable); verify(navigable).onNavigate(eq(Navigable.DIRECTION_DOWN)); AppUtils.navigate(Navigable.DIRECTION_RIGHT, appBar, navigable); verify(navigable).onNavigate(eq(Navigable.DIRECTION_RIGHT)); AppUtils.navigate(Navigable.DIRECTION_UP, appBar, navigable); verify(navigable).onNavigate(eq(Navigable.DIRECTION_UP)); AppUtils.navigate(Navigable.DIRECTION_LEFT, appBar, navigable); verify(navigable).onNavigate(eq(Navigable.DIRECTION_LEFT)); } }