/*
*
* * Copyright 2015. Appsi Mobile
* *
* * 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.appsimobile.appsii.module.home;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.util.LongSparseArray;
import android.test.mock.MockContentProvider;
import com.appsimobile.appsii.MockApplicationComponent;
import com.appsimobile.appsii.MockAppsiApplication;
import com.appsimobile.appsii.R;
import com.appsimobile.appsii.module.home.YahooLocationChooserDialogFragment.LocationUpdateHelper;
import com.appsimobile.appsii.module.home.config.HomeItemConfiguration;
import com.appsimobile.appsii.module.home.config.HomeItemConfiguration.ConfigurationProperty;
import com.appsimobile.appsii.module.home.config.HomeItemConfigurationHelper;
import com.appsimobile.appsii.module.home.config.HomeItemConfigurationHelper
.HomeItemConfigurationLoader;
import com.appsimobile.appsii.module.home.provider.HomeContract;
import com.appsimobile.appsii.permissions.PermissionUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import javax.inject.Inject;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static com.appsimobile.appsii.module.home.YahooLocationChooserDialogFragment
.LOCATION_REQUEST_RESULT_PERMISSION_DENIED;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
/**
* Created by nick on 24/03/15.
*/
@RunWith(AndroidJUnit4.class)
public class WeatherActivityTest {
@Rule
public ActivityTestRule<CellWeatherActivity> mActivityRule = new ActivityTestRule<>(
CellWeatherActivity.class,
true, // initialTouchMode
false); // launchActivity. False so we can customize the intent per test method
@Inject
SharedPreferences mSharedPreferences;
@Inject
PermissionUtils mPermissionUtils;
@Inject
HomeItemConfigurationLoader mHomeItemConfigurationLoader;
@Inject
LocationUpdateHelper mLocationUpdateHelper;
@Inject
HomeItemConfiguration mHomeItemConfiguration;
MockContentProvider mContentProvider;
ConfigurationProperty mConfigurationProperty;
private Intent mLaunchIntent;
static Context anyContext() {
return any(Context.class);
}
static <T> ArrayList<T> anyList(Class<T> c) {
return any(ArrayList.class);
}
private static void initializeConfigurationProperty(ConfigurationProperty prop,
String unit, String location, String woeid, String timezone) {
prop.put(WeatherFragment.PREFERENCE_WEATHER_UNIT, unit)
.put(WeatherFragment.PREFERENCE_WEATHER_LOCATION, location)
.put(WeatherFragment.PREFERENCE_WEATHER_WOEID, woeid)
.put(WeatherFragment.PREFERENCE_WEATHER_TIMEZONE, timezone);
}
@Before
public void setUp() {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
MockAppsiApplication app =
(MockAppsiApplication) instrumentation.getTargetContext().getApplicationContext();
MockApplicationComponent component =
(MockApplicationComponent) app.getApplicationComponent();
component.inject(this);
mContentProvider = new MockContentProvider(app);
Mockito.reset(mSharedPreferences, mPermissionUtils);
when(mSharedPreferences.getBoolean(eq("cling_preferences_shown"), anyBoolean()))
.thenReturn(true);
mLaunchIntent = new Intent(app, CellWeatherActivity.class);
mLaunchIntent.putExtra(CellWeatherActivity.EXTRA_CELL_ID, 1L);
mLaunchIntent.putExtra(CellWeatherActivity.EXTRA_CELL_TYPE,
HomeContract.Cells.DISPLAY_TYPE_WEATHER_TEMP);
mConfigurationProperty = new ConfigurationProperty();
}
@After
public void tearDown() throws Exception {
nullifyStaticFields(HomeItemConfigurationHelper.class);
nullifyStaticFields(YahooLocationChooserDialogFragment.class);
}
/**
* This function is called by various TestCase implementations, at tearDown() time, in order
* to scrub out any class variables. This protects against memory leaks in the case where a
* test case creates a non-static inner class (thus referencing the test case) and gives it to
* someone else to hold onto.
*
* @param testCaseClass The class of the derived TestCase implementation.
* @throws IllegalAccessException
*/
protected void nullifyStaticFields(final Class<?> testCaseClass)
throws IllegalAccessException {
final Field[] fields = testCaseClass.getDeclaredFields();
for (Field field : fields) {
if (!field.getType().isPrimitive()
&& (field.getModifiers() & Modifier.STATIC) != 0
&& (field.getModifiers() & Modifier.FINAL) == 0) {
try {
field.setAccessible(true);
field.set(null, null);
} catch (Exception e) {
android.util.Log.d("TestCase", "Error: Could not nullify field!");
}
if (field.get(null) != null) {
android.util.Log.d("TestCase", "Error: Could not nullify field!");
}
}
}
}
@Test
public void testPreSelections_setToImperial() {
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_UNIT), Matchers.anyString())).thenReturn("f");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_LOCATION), Matchers.anyString())).thenReturn("mock_location");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_WOEID), Matchers.anyString())).thenReturn("10000");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_TIMEZONE), Matchers.anyString())).thenReturn("Europe/Amsterdam");
mActivityRule.launchActivity(mLaunchIntent);
onView(withId(R.id.weather_location)).check(matches(withText("mock_location")));
onView(withId(R.id.weather_unit)).check(matches(withText(R.string.imperial)));
}
@Test
public void testPreSelections_setToMetric() {
Mockito.reset(mHomeItemConfiguration);
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_UNIT), Matchers.anyString())).thenReturn("c");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_LOCATION), Matchers.anyString())).thenReturn("mock_location");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_WOEID), Matchers.anyString())).thenReturn("10000");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_TIMEZONE), Matchers.anyString())).thenReturn("Europe/Amsterdam");
mActivityRule.launchActivity(mLaunchIntent);
onView(withId(R.id.weather_location)).check(matches(withText("mock_location")));
onView(withId(R.id.weather_unit)).check(matches(withText(R.string.metric)));
}
@Test
public void testPreSelections_none() {
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_UNIT), eq("f"))).thenReturn("f");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_UNIT), eq("c"))).thenReturn("c");
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_LOCATION), Matchers.anyString())).thenReturn(null);
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_WOEID), Matchers.anyString())).thenReturn(null);
when(mHomeItemConfiguration.getProperty(eq(1L), eq(WeatherFragment.PREFERENCE_WEATHER_TIMEZONE), Matchers.anyString())).thenReturn(null);
mActivityRule.launchActivity(mLaunchIntent);
onView(withId(R.id.weather_location)).check(
matches(withText(R.string.weather_auto_location)));
onView(withId(R.id.weather_unit)).check(matches(withText(R.string.metric)));
}
@Test
public void testPickLocation_locationDisabled() {
when(mHomeItemConfigurationLoader.loadConfigurations(any(Context.class)))
.thenReturn(new LongSparseArray<ConfigurationProperty>());
when(mLocationUpdateHelper.startLocationUpdateIfNeeded(Mockito.any(Context.class)))
.thenReturn(YahooLocationChooserDialogFragment.LOCATION_REQUEST_RESULT_DISABLED);
mActivityRule.launchActivity(mLaunchIntent);
onView(withId(R.id.weather_location)).perform(click());
onView(withId(R.id.location_title)).check(matches(withText(R.string.cant_access_location)));
onView(withId(R.id.location_search)).
check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
onView(withId(R.id.location_unavailable)).
check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
onView(withId(R.id.cancel_enable_location_button)).perform(click());
onView(withId(R.id.location_unavailable)).
check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
// TODO choose auto option and verify
}
@Test
public void testPickLocation_locationPermissionDenied() {
when(mLocationUpdateHelper.startLocationUpdateIfNeeded(Mockito.any(Context.class)))
.thenReturn(LOCATION_REQUEST_RESULT_PERMISSION_DENIED);
LongSparseArray<ConfigurationProperty> result = new LongSparseArray<>();
when(mHomeItemConfigurationLoader.loadConfigurations(any(Context.class)))
.thenReturn(result);
mActivityRule.launchActivity(mLaunchIntent);
onView(withId(R.id.weather_location)).perform(click());
onView(withId(R.id.location_title)).check(
matches(withText(R.string.location_permission_denied)));
onView(withId(R.id.location_search)).
check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
onView(withId(R.id.location_unavailable)).
check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));
onView(withId(R.id.cancel_enable_location_button)).perform(click());
onView(withId(R.id.location_unavailable)).
check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
// TODO choose auto option and verify
}
}