package fr.prcaen.externalresources;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import com.squareup.okhttp.mockwebserver.Dispatcher;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import fr.prcaen.externalresources.converter.Converter;
import fr.prcaen.externalresources.converter.JsonConverter;
import fr.prcaen.externalresources.exception.ExternalResourceException;
import fr.prcaen.externalresources.exception.ResponseException;
import fr.prcaen.externalresources.url.DefaultUrl;
import java.util.Locale;
import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.HONEYCOMB_MR2;
import static android.os.Build.VERSION_CODES.JELLY_BEAN;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
import static android.os.Build.VERSION_CODES.KITKAT;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static java.util.Locale.US;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@RunWith(RobolectricTestRunner.class) @Config(manifest = "/src/main/AndroidManifest.xml", sdk = KITKAT)
public final class DownloaderTest {
private static final String BASE_URL = "http://test.com";
private static final int ORIENTATION = 0;
private static final int KEYBOARD = 0;
private static final int TOUCH_SCREEN = 0;
private static final int MCC = 0;
private static final int NAVIGATION_HIDDEN = 0;
private static final int SMALLEST_SCREEN_WIDTH_DP = 0;
private static final int SCREEN_WIDTH_DP = 0;
private static final int KEYBOARD_HIDDEN = 0;
private static final int NAVIGATION = 0;
private static final int SCREEN_LAYOUT = 82;
private static final int SCREEN_HEIGHT_DP = 0;
private static final int MNC = 0;
private static final int UI_MODE = 0;
private static final int HARD_KEYBOARD_HIDDEN = 0;
private static final int DENSITY_DPI = 160;
private static final float FONT_SCALE = 1.0f;
private static final Locale LOCALE = US;
private final Converter converter = new JsonConverter();
private final Options options = Options.createDefault();
private final MockWebServer server = new MockWebServer();
@Mock private Context context;
@Mock private Resources resources;
@Mock private Configuration configuration;
@Before public void setUp() throws Exception {
initMocks(this);
setDefaultConfiguration();
when(context.getApplicationContext()).thenReturn(RuntimeEnvironment.application);
final String successJson =
IOUtils.toString(getClass().getResourceAsStream("/test.json"), "UTF-8");
server.setDispatcher(new Dispatcher() {
@Override public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
if (request.getPath().startsWith("/success")) {
return new MockResponse().setResponseCode(200).setBody(successJson);
} else {
return new MockResponse().setResponseCode(400);
}
}
});
}
@Test public void testLoad() throws Exception {
server.start();
DefaultUrl url = new DefaultUrl(server.url("/success").toString());
Downloader downloader = new Downloader(context, converter, url, options);
assertNotNull("From network", downloader.load(Cache.POLICY_ALL));
server.shutdown();
assertNotNull("From cache", downloader.load(Cache.POLICY_OFFLINE));
}
@Test(expected = ExternalResourceException.class) public void testLoadWithException()
throws Exception {
server.start();
DefaultUrl url = new DefaultUrl(server.url("/error").toString());
Downloader downloader = new Downloader(context, converter, url, options);
downloader.load(Cache.POLICY_NONE);
server.shutdown();
}
@Config(sdk = JELLY_BEAN) @Test public void testBuildUrlOnJellyBean() throws Exception {
setDefaultConfiguration();
DefaultUrl url = new DefaultUrl(BASE_URL);
Downloader downloader = new Downloader(context, converter, url, options);
downloader.buildUrl();
String urlString = url.build();
assertThat("Contains orientation", urlString, containsString("orientation=" + ORIENTATION));
assertThat("Contains keyboard", urlString, containsString("keyboard=" + KEYBOARD));
assertThat("Contains touch_screen", urlString, containsString("touch_screen=" + TOUCH_SCREEN));
assertThat("Contains font_scale", urlString, containsString("font_scale=" + FONT_SCALE));
assertThat("Contains mcc", urlString, containsString("mcc=" + MCC));
assertThat("Contains navigation_hidden", urlString,
containsString("navigation_hidden=" + NAVIGATION_HIDDEN));
assertThat("Contains locale", urlString, containsString("locale=" + LOCALE));
assertThat("Contains smallest_screen_width_dp", urlString,
containsString("smallest_screen_width_dp=" + SMALLEST_SCREEN_WIDTH_DP));
assertThat("Contains keyboard_hidden", urlString,
containsString("keyboard_hidden=" + KEYBOARD_HIDDEN));
assertThat("Contains navigation", urlString, containsString("navigation=" + NAVIGATION));
assertThat("Contains screen_layout", urlString,
containsString("screen_layout=" + SCREEN_LAYOUT));
assertThat("Contains screen_height_dp", urlString,
containsString("screen_height_dp=" + SCREEN_HEIGHT_DP));
assertThat("Contains mnc", urlString, containsString("mnc=" + MNC));
assertThat("Contains ui_mode", urlString, containsString("ui_mode=" + UI_MODE));
assertThat("Contains hard_keyboard_hidden", urlString,
containsString("hard_keyboard_hidden=" + HARD_KEYBOARD_HIDDEN));
}
@Config(sdk = LOLLIPOP) @Test public void testBuildUrlOnLollipop() throws Exception {
setDefaultConfiguration();
DefaultUrl url = new DefaultUrl(BASE_URL);
Downloader downloader = new Downloader(context, converter, url, options);
downloader.buildUrl();
String urlString = url.build();
assertThat("Contains orientation", urlString, containsString("orientation=" + ORIENTATION));
assertThat("Contains keyboard", urlString, containsString("keyboard=" + KEYBOARD));
assertThat("Contains touch_screen", urlString, containsString("touch_screen=" + TOUCH_SCREEN));
assertThat("Contains font_scale", urlString, containsString("font_scale=" + FONT_SCALE));
assertThat("Contains mcc", urlString, containsString("mcc=" + MCC));
assertThat("Contains navigation_hidden", urlString,
containsString("navigation_hidden=" + NAVIGATION_HIDDEN));
assertThat("Contains locale", urlString, containsString("locale=" + LOCALE));
assertThat("Contains smallest_screen_width_dp", urlString,
containsString("smallest_screen_width_dp=" + SMALLEST_SCREEN_WIDTH_DP));
assertThat("Contains keyboard_hidden", urlString,
containsString("keyboard_hidden=" + KEYBOARD_HIDDEN));
assertThat("Contains navigation", urlString, containsString("navigation=" + NAVIGATION));
assertThat("Contains screen_layout", urlString,
containsString("screen_layout=" + SCREEN_LAYOUT));
assertThat("Contains screen_height_dp", urlString,
containsString("screen_height_dp=" + SCREEN_HEIGHT_DP));
assertThat("Contains mnc", urlString, containsString("mnc=" + MNC));
assertThat("Contains ui_mode", urlString, containsString("ui_mode=" + UI_MODE));
assertThat("Contains hard_keyboard_hidden", urlString,
containsString("hard_keyboard_hidden=" + HARD_KEYBOARD_HIDDEN));
assertThat("Contains density_dpi", urlString, containsString("density_dpi=" + DENSITY_DPI));
}
@SuppressWarnings("ThrowableInstanceNeverThrown") @Test public void testResponseException() {
ResponseException exception = new ResponseException("test", Cache.POLICY_NONE, 404);
assertEquals("Exception message", exception.getMessage(), "test");
assertFalse("LocalCacheOnly", exception.isLocalCacheOnly());
assertEquals("Exception response code", exception.getResponseCode(), 404);
}
private void setDefaultConfiguration() {
Configuration configuration = RuntimeEnvironment.application.getResources().getConfiguration();
configuration.orientation = ORIENTATION;
configuration.keyboard = KEYBOARD;
configuration.touchscreen = TOUCH_SCREEN;
configuration.mcc = MCC;
configuration.navigationHidden = NAVIGATION_HIDDEN;
configuration.keyboardHidden = KEYBOARD_HIDDEN;
configuration.navigation = NAVIGATION;
configuration.screenLayout = SCREEN_LAYOUT;
configuration.mnc = MNC;
configuration.uiMode = UI_MODE;
configuration.hardKeyboardHidden = HARD_KEYBOARD_HIDDEN;
configuration.fontScale = FONT_SCALE;
configuration.locale = LOCALE;
if (SDK_INT >= HONEYCOMB_MR2) {
configuration.smallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP;
configuration.screenWidthDp = SCREEN_WIDTH_DP;
configuration.screenHeightDp = SCREEN_HEIGHT_DP;
}
if (SDK_INT >= JELLY_BEAN_MR1) {
configuration.densityDpi = DENSITY_DPI;
}
}
}