/*
* Copyright (C) 2015 Twitter, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.digits.sdk.android;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.twitter.sdk.android.core.TwitterApiErrorConstants;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class FailureActivityDelegateImplTests {
Activity activity;
FailureController controller;
FailureActivityDelegateImpl delegate;
ArgumentCaptor<View.OnClickListener> captorClick;
Intent intent;
Button button;
TextView textView;
Bundle bundle;
DigitsException exception;
ResultReceiver resultReceiver;
private DigitsEventCollector digitsEventCollector;
ArgumentCaptor<DigitsEventDetails> detailsArgumentCaptor;
ArgumentCaptor<DigitsEventDetailsBuilder> detailsBuilderArgumentCaptor;
DigitsEventDetailsBuilder digitsEventDetailsBuilder;
@Before
public void setUp() throws Exception {
activity = mock(Activity.class);
controller = mock(FailureController.class);
digitsEventCollector = mock(DigitsEventCollector.class);
delegate = spy(new FailureActivityDelegateImpl(activity, controller, digitsEventCollector));
captorClick = ArgumentCaptor.forClass(View.OnClickListener.class);
intent = mock(Intent.class);
button = mock(Button.class);
textView = mock(TextView.class);
bundle = new Bundle();
resultReceiver = new ResultReceiver(null);
exception = new DigitsException("", TwitterApiErrorConstants.UNKNOWN_ERROR,
new AuthConfig());
detailsArgumentCaptor = ArgumentCaptor.forClass(DigitsEventDetails.class);
detailsBuilderArgumentCaptor = ArgumentCaptor.forClass(DigitsEventDetailsBuilder.class);
digitsEventDetailsBuilder = new DigitsEventDetailsBuilder()
.withLanguage("lang")
.withCountry("US")
.withAuthStartTime(1L);
bundle.putParcelable(DigitsClient.EXTRA_RESULT_RECEIVER, resultReceiver);
bundle.putSerializable(DigitsClient.EXTRA_FALLBACK_REASON, exception);
bundle.putParcelable(DigitsClient.EXTRA_EVENT_DETAILS_BUILDER, digitsEventDetailsBuilder);
when(intent.getExtras()).thenReturn(bundle);
when(activity.getIntent()).thenReturn(intent);
}
@Test
public void testInit_validBundle() {
when(activity.findViewById(R.id.dgts__dismiss_button)).thenReturn(button);
when(activity.findViewById(R.id.dgts__try_another_phone)).thenReturn(button);
delegate.eventDetailsBuilder = new DigitsEventDetailsBuilder()
.withLanguage("lang")
.withCountry("US")
.withAuthStartTime(1L);
delegate.init();
verify(delegate).setContentView();
verify(delegate).setUpViews();
verify(digitsEventCollector).failureScreenImpression(detailsArgumentCaptor.capture());
final DigitsEventDetails details = detailsArgumentCaptor.getValue();
assertNotNull(details.language);
assertNotNull(details.country);
assertNotNull(details.elapsedTimeInMillis);
}
@Test
public void testInit_invalidBundle() {
when(intent.getExtras()).thenReturn(null);
try {
delegate.init();
fail("Expected IllegalAccessError to be thrown");
} catch (IllegalAccessError e) {
assertEquals("This activity can only be started from Digits", e.getMessage());
}
}
@Test
public void testSetContentView() {
delegate.setContentView();
verify(activity).setContentView(R.layout.dgts__activity_failure);
}
@Test
public void testSetUpViews() {
when(activity.findViewById(R.id.dgts__dismiss_button)).thenReturn(button);
when(activity.findViewById(R.id.dgts__try_another_phone)).thenReturn(button);
delegate.eventDetailsBuilder = new DigitsEventDetailsBuilder()
.withLanguage("lang")
.withCountry("US")
.withAuthStartTime(1L);
delegate.setUpViews();
verify(delegate).setUpDismissButton(button);
verify(delegate).setUpTryAnotherPhoneButton(button);
}
@Test
public void testSetUpDismissButton() {
delegate.eventDetailsBuilder = new DigitsEventDetailsBuilder()
.withLanguage("lang")
.withCountry("US")
.withAuthStartTime(1L);
delegate.setUpDismissButton(button);
verify(button).setOnClickListener(captorClick.capture());
final View.OnClickListener listener = captorClick.getValue();
listener.onClick(null);
verify(digitsEventCollector).dismissClickOnFailureScreen(detailsArgumentCaptor.capture());
final DigitsEventDetails details = detailsArgumentCaptor.getValue();
assertNotNull(details.language);
assertNotNull(details.country);
assertNotNull(details.elapsedTimeInMillis);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
verify(activity).finishAffinity();
} else {
verify(activity).setResult(anyInt());
verify(activity).finish();
}
verify(controller).sendFailure(eq(resultReceiver), eq(exception),
detailsBuilderArgumentCaptor.capture());
final DigitsEventDetailsBuilder capturedDetails = detailsBuilderArgumentCaptor.getValue();
assertNotNull(capturedDetails.language);
assertNotNull(capturedDetails.country);
}
@Test
public void testSetUpTryAnotherPhoneButton() {
delegate.eventDetailsBuilder = new DigitsEventDetailsBuilder()
.withLanguage("lang")
.withCountry("US")
.withAuthStartTime(1L);
delegate.setUpTryAnotherPhoneButton(button);
verify(button).setOnClickListener(captorClick.capture());
final View.OnClickListener listener = captorClick.getValue();
listener.onClick(null);
verify(digitsEventCollector).retryClickOnFailureScreen(detailsArgumentCaptor.capture());
final DigitsEventDetails details = detailsArgumentCaptor.getValue();
assertNotNull(details.language);
assertNotNull(details.country);
assertNotNull(details.elapsedTimeInMillis);
verify(controller).tryAnotherNumber(eq(activity), any(ResultReceiver.class));
verify(activity).finish();
}
}