package io.github.hidroh.materialistic;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import org.junit.After;
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 io.github.hidroh.materialistic.test.TestRunner;
import org.robolectric.shadows.ShadowAlertDialog;
import org.robolectric.shadows.ShadowToast;
import org.robolectric.util.ActivityController;
import java.io.IOException;
import javax.inject.Inject;
import io.github.hidroh.materialistic.accounts.UserServices;
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.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
@RunWith(TestRunner.class)
public class ComposeActivityTest {
private ActivityController<ComposeActivity> controller;
private ComposeActivity activity;
@Inject UserServices userServices;
@Captor ArgumentCaptor<UserServices.Callback> replyCallback;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
TestApplication.applicationGraph.inject(this);
reset(userServices);
controller = Robolectric.buildActivity(ComposeActivity.class);
activity = controller.get();
Intent intent = new Intent();
intent.putExtra(ComposeActivity.EXTRA_PARENT_ID, "1");
intent.putExtra(ComposeActivity.EXTRA_PARENT_TEXT, "Paragraph 1<br/><br/>Paragraph 2<br/>");
controller.withIntent(intent).create().start().resume().visible();
}
@Test
public void testNoId() {
controller = Robolectric.buildActivity(ComposeActivity.class)
.create().start().resume().visible();
activity = controller.get();
assertThat(activity).isFinishing();
}
@Test
public void testToggle() {
assertThat(activity.findViewById(R.id.toggle)).isVisible();
assertThat(activity.findViewById(R.id.text)).isNotVisible();
activity.findViewById(R.id.toggle).performClick();
assertThat(activity.findViewById(R.id.text)).isVisible();
assertThat((TextView) activity.findViewById(R.id.text))
.hasTextString("Paragraph 1\n\nParagraph 2");
activity.findViewById(R.id.toggle).performClick();
assertThat(activity.findViewById(R.id.text)).isNotVisible();
}
@Test
public void testHomeButtonClick() {
shadowOf(activity).clickMenuItem(android.R.id.home);
assertThat(activity).isFinishing();
}
@Test
public void testExitSaveDraft() {
((EditText) activity.findViewById(R.id.edittext_body)).setText("Reply");
shadowOf(activity).clickMenuItem(android.R.id.home);
AlertDialog alertDialog = ShadowAlertDialog.getLatestAlertDialog();
assertNotNull(alertDialog);
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
assertThat(activity).isFinishing();
assertThat(Preferences.getDraft(activity, "1")).contains("Reply");
}
@Test
public void testExitDiscardDraft() {
((EditText) activity.findViewById(R.id.edittext_body)).setText("Reply");
shadowOf(activity).clickMenuItem(android.R.id.home);
AlertDialog alertDialog = ShadowAlertDialog.getLatestAlertDialog();
assertNotNull(alertDialog);
alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
assertThat(activity).isFinishing();
assertThat(Preferences.getDraft(activity, "1")).isNullOrEmpty();
}
@Test
public void testSendEmpty() {
shadowOf(activity).clickMenuItem(R.id.menu_send);
assertEquals(activity.getString(R.string.comment_required), ShadowToast.getTextOfLatestToast());
}
@Test
public void testQuote() {
assertTrue(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_quote).isVisible());
((EditText) activity.findViewById(R.id.edittext_body)).setText("Reply");
shadowOf(activity).clickMenuItem(R.id.menu_quote);
assertThat((EditText) activity.findViewById(R.id.edittext_body))
.hasTextString("> Paragraph 1\n\n> Paragraph 2\n\nReply");
}
@Test
public void testSaveDiscardDraft() {
((EditText) activity.findViewById(R.id.edittext_body)).setText("Reply");
shadowOf(activity).clickMenuItem(R.id.menu_save_draft);
assertThat(Preferences.getDraft(activity, "1")).contains("Reply");
shadowOf(activity).clickMenuItem(R.id.menu_discard_draft);
assertThat(Preferences.getDraft(activity, "1")).isNullOrEmpty();
}
@Test
public void testClickEmptyFocusEditText() {
View editText = activity.findViewById(R.id.edittext_body);
editText.clearFocus();
assertThat(editText).isNotFocused();
activity.findViewById(R.id.empty).performClick();
assertThat(editText).isFocused();
}
@Test
public void testGuidelines() {
shadowOf(activity).clickMenuItem(R.id.menu_guidelines);
assertNotNull(ShadowAlertDialog.getLatestAlertDialog());
}
@Test
public void testEmptyQuote() {
Intent intent = new Intent();
intent.putExtra(ComposeActivity.EXTRA_PARENT_ID, "1");
controller = Robolectric.buildActivity(ComposeActivity.class)
.withIntent(intent).create().start().resume().visible();
activity = controller.get();
assertThat(activity.findViewById(R.id.quote)).isNotVisible();
assertFalse(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_quote).isVisible());
}
@Test
public void testSendPromptToLogin() {
doSend();
replyCallback.getValue().onDone(false);
assertThat(shadowOf(activity).getNextStartedActivity())
.hasComponent(activity, LoginActivity.class);
}
@Test
public void testSendSuccessful() {
doSend();
assertThat(Preferences.getDraft(activity, "1")).isNotEmpty();
replyCallback.getValue().onDone(true);
assertThat(activity).isFinishing();
assertThat(Preferences.getDraft(activity, "1")).isNullOrEmpty();
}
@Test
public void testSendFailed() {
doSend();
assertFalse(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_send).isEnabled());
assertFalse(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_quote).isVisible());
assertFalse(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_save_draft).isEnabled());
assertFalse(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_discard_draft).isEnabled());
replyCallback.getValue().onError(new IOException());
assertTrue(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_send).isEnabled());
assertTrue(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_quote).isVisible());
assertTrue(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_save_draft).isEnabled());
assertTrue(shadowOf(activity).getOptionsMenu().findItem(R.id.menu_discard_draft).isEnabled());
assertThat(activity).isNotFinishing();
assertEquals(activity.getString(R.string.comment_failed), ShadowToast.getTextOfLatestToast());
}
@Test
public void testDelayedSuccessfulResponse() {
doSend();
shadowOf(activity).clickMenuItem(android.R.id.home);
assertThat(activity).isFinishing();
replyCallback.getValue().onDone(true);
assertEquals(activity.getString(R.string.comment_successful), ShadowToast.getTextOfLatestToast());
}
@Test
public void testDelayedFailedResponse() {
doSend();
shadowOf(activity).clickMenuItem(android.R.id.home);
replyCallback.getValue().onDone(false);
assertNull(shadowOf(activity).getNextStartedActivity());
}
@Test
public void testDelayedError() {
doSend();
shadowOf(activity).clickMenuItem(android.R.id.home);
replyCallback.getValue().onError(new IOException());
assertEquals(activity.getString(R.string.comment_failed), ShadowToast.getTextOfLatestToast());
}
@After
public void tearDown() {
controller.pause().stop().destroy();
}
private void doSend() {
((EditText) activity.findViewById(R.id.edittext_body)).setText("Reply");
shadowOf(activity).clickMenuItem(R.id.menu_send);
verify(userServices).reply(any(Context.class), eq("1"), eq("Reply"), replyCallback.capture());
}
}