package io.github.hidroh.materialistic;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.widget.NestedScrollView;
import android.webkit.WebView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.fakes.RoboMenuItem;
import org.robolectric.shadows.ShadowNetworkInfo;
import org.robolectric.shadows.ShadowPopupMenu;
import org.robolectric.shadows.ShadowToast;
import org.robolectric.shadows.support.v4.ShadowLocalBroadcastManager;
import org.robolectric.util.ActivityController;
import javax.inject.Inject;
import io.github.hidroh.materialistic.data.ReadabilityClient;
import io.github.hidroh.materialistic.data.WebItem;
import io.github.hidroh.materialistic.test.TestReadabilityActivity;
import io.github.hidroh.materialistic.test.TestRunner;
import io.github.hidroh.materialistic.test.TestWebItem;
import io.github.hidroh.materialistic.test.shadow.ShadowNestedScrollView;
import io.github.hidroh.materialistic.test.shadow.ShadowPreferenceFragmentCompat;
import io.github.hidroh.materialistic.test.shadow.ShadowWebView;
import static io.github.hidroh.materialistic.test.shadow.CustomShadows.customShadowOf;
import static junit.framework.Assert.assertEquals;
import static org.assertj.android.api.Assertions.assertThat;
import static org.assertj.android.support.v4.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
@SuppressWarnings("ConstantConditions")
@Config(shadows = {ShadowWebView.class, ShadowPreferenceFragmentCompat.class})
@RunWith(TestRunner.class)
public class ReadabilityFragmentTest {
private TestReadabilityActivity activity;
private ActivityController<TestReadabilityActivity> controller;
@Inject ReadabilityClient readabilityClient;
@Captor ArgumentCaptor<ReadabilityClient.Callback> callback;
private WebFragment fragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
TestApplication.applicationGraph.inject(this);
reset(readabilityClient);
controller = Robolectric.buildActivity(TestReadabilityActivity.class);
activity = controller.create().start().resume().visible().get();
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putBoolean(activity.getString(R.string.pref_lazy_load), false)
.putString(activity.getString(R.string.pref_story_display),
activity.getString(R.string.pref_story_display_value_readability))
.apply();
shadowOf((ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE))
.setActiveNetworkInfo(ShadowNetworkInfo.newInstance(null,
ConnectivityManager.TYPE_WIFI, 0, true, true));
Bundle args = new Bundle();
WebItem item = new TestWebItem() {
@Override
public String getId() {
return "1";
}
@Override
public String getUrl() {
return "http://example.com/article.html";
}
};
args.putParcelable(WebFragment.EXTRA_ITEM, item);
fragment = (WebFragment) Fragment.instantiate(activity, WebFragment.class.getName(), args);
activity.getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, fragment, "tag")
.commit();
}
@Test
public void testParseAndBind() {
assertThat(activity.findViewById(R.id.progress)).isVisible();
verify(readabilityClient).parse(eq("1"), eq("http://example.com/article.html"),
callback.capture());
callback.getValue().onResponse("<div>content</div>");
WebView webView = (WebView) activity.findViewById(R.id.web_view);
shadowOf(webView).getWebViewClient().onPageFinished(webView, "about:blank");
assertThat(shadowOf(webView).getLastLoadDataWithBaseURL().data).contains("content");
shadowOf(activity).recreate();
webView = (WebView) activity.findViewById(R.id.web_view);
shadowOf(webView).getWebViewClient().onPageFinished(webView, "about:blank");
assertThat(shadowOf(webView).getLastLoadDataWithBaseURL().data).contains("content");
controller.pause().stop().destroy();
}
@Test
public void testParseFailed() {
assertThat(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_font_options)).isNotVisible();
assertThat(activity.findViewById(R.id.progress)).isVisible();
verify(readabilityClient).parse(eq("1"), eq("http://example.com/article.html"),
callback.capture());
callback.getValue().onResponse(null);
reset(readabilityClient);
assertThat(ShadowToast.getTextOfLatestToast())
.contains(activity.getString(R.string.readability_failed));
WebView webView = (WebView) activity.findViewById(R.id.web_view);
shadowOf(webView).getWebViewClient().onPageFinished(webView, "about:blank");
assertThat(ShadowWebView.getLastGlobalLoadedUrl())
.contains("http://example.com/article.html");
assertThat(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_font_options)).isNotVisible();
controller.pause().stop().destroy();
}
@Config(shadows = ShadowNestedScrollView.class)
@Test
public void testScrollToTop() {
NestedScrollView scrollView = (NestedScrollView) activity.findViewById(R.id.nested_scroll_view);
scrollView.smoothScrollTo(0, 1);
assertThat(customShadowOf(scrollView).getSmoothScrollY()).isEqualTo(1);
fragment.scrollToTop();
assertThat(customShadowOf(scrollView).getSmoothScrollY()).isEqualTo(0);
controller.pause().stop().destroy();
}
@Test
public void testFontSizeMenu() {
verify(readabilityClient).parse(eq("1"), eq("http://example.com/article.html"),
callback.capture());
callback.getValue().onResponse("<div>content</div>");
fragment.onOptionsItemSelected(new RoboMenuItem(R.id.menu_font_options));
assertThat(fragment.getFragmentManager())
.hasFragmentWithTag(PopupSettingsFragment.class.getName());
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putString(activity.getString(R.string.pref_readability_text_size), "3")
.apply();
WebView webView = (WebView) activity.findViewById(R.id.web_view);
shadowOf(webView).getWebViewClient().onPageFinished(webView, "about:blank");
assertThat(shadowOf(webView).getLastLoadDataWithBaseURL().data).contains("20");
assertEquals(R.style.AppTextSize_XLarge,
Preferences.Theme.resolvePreferredReadabilityTextSize(activity));
controller.pause().stop().destroy();
}
@Test
public void testFontMenu() {
verify(readabilityClient).parse(eq("1"), eq("http://example.com/article.html"),
callback.capture());
callback.getValue().onResponse("<div>content</div>");
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putString(activity.getString(R.string.pref_readability_font), "DroidSans.ttf")
.apply();
WebView webView = (WebView) activity.findViewById(R.id.web_view);
shadowOf(webView).getWebViewClient().onPageFinished(webView, "about:blank");
assertThat(shadowOf(webView).getLastLoadDataWithBaseURL().data).contains("DroidSans.ttf");
assertEquals("DroidSans.ttf", Preferences.Theme.getReadabilityTypeface(activity));
controller.pause().stop().destroy();
}
@Test
public void testWebToggle() {
fragment.onOptionsItemSelected(new RoboMenuItem(R.id.menu_readability));
WebView webView = (WebView) activity.findViewById(R.id.web_view);
shadowOf(webView).getWebViewClient().onPageFinished(webView, "about:blank");
assertThat(shadowOf(webView).getLastLoadedUrl()).isEqualTo("http://example.com/article.html");
}
@SuppressLint("NewApi")
@Test
public void testFullscreenMenu() {
verify(readabilityClient).parse(eq("1"), eq("http://example.com/article.html"),
callback.capture());
callback.getValue().onResponse("<div>content</div>");
ShadowLocalBroadcastManager.getInstance(activity)
.sendBroadcast(new Intent(WebFragment.ACTION_FULLSCREEN)
.putExtra(WebFragment.EXTRA_FULLSCREEN, true));
activity.findViewById(R.id.button_more).performClick();
shadowOf(ShadowPopupMenu.getLatestPopupMenu()).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_font_options));
assertThat(fragment.getFragmentManager())
.hasFragmentWithTag(PopupSettingsFragment.class.getName());
}
@Test
public void testBindAfterDetached() {
assertThat(activity.findViewById(R.id.progress)).isVisible();
controller.pause().stop().destroy();
verify(readabilityClient).parse(eq("1"), eq("http://example.com/article.html"),
callback.capture());
callback.getValue().onResponse("<div>content</div>");
}
}