Skip to content

Commit

Permalink
started with mock server, increased gradle speed, GenericApp supports…
Browse files Browse the repository at this point in the history
… test variant.
  • Loading branch information
Zeyad-37 committed Jun 15, 2017
1 parent a1b4792 commit e5fb11f
Show file tree
Hide file tree
Showing 13 changed files with 277 additions and 7 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
org.gradle.jvmargs=-Xmx3072m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

org.gradle.caching=true
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
Expand Down
20 changes: 19 additions & 1 deletion sampleApp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ android {

defaultConfig {
applicationId "com.zeyad.usecase.accesslayer"
minSdkVersion 17
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "com.zeyad.usecases.app.UseCasesTestRunner"
}

signingConfigs {
Expand All @@ -47,6 +48,7 @@ android {

buildTypes {
debug {
ext.alwaysUpdateBuildId = false
minifyEnabled false
shrinkResources false
debuggable true
Expand Down Expand Up @@ -92,6 +94,17 @@ android {
exclude 'META-INF/NOTICE'
exclude 'META-INF/rxjava.properties'
}

if (project.hasProperty('devBuild')) {
splits.abi.enable = false
splits.density.enable = false
aaptOptions.cruncherEnabled = false
}
sourceSets {
main {
assets.srcDirs = ['src/main/assets', 'src/androidTest/java/com/zeyad/usecases/app/assets/']
}
}
}

ext {
Expand Down Expand Up @@ -155,6 +168,11 @@ dependencies {
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile('com.jakewharton.espresso:okhttp3-idling-resource:1.0.0') {
exclude group: 'com.android.support'
}
androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.8.0'
androidTestCompile 'com.github.andrzejchm.RESTMock:android:0.1.4'

testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.zeyad.usecases.app;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import okhttp3.internal.tls.SslClient;
import okhttp3.mockwebserver.MockWebServer;

/**
* @author by ZIaDo on 6/15/17.
*/

public class MockWebServerRule implements TestRule {
public final MockWebServer server = new MockWebServer();

@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
server.useHttps(SslClient.localhost().socketFactory, false);
server.start();
base.evaluate();
server.shutdown();
}
};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.zeyad.usecases.app;

import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.IdlingResource;

import com.jakewharton.espresso.OkHttp3IdlingResource;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

/**
* @author by ZIaDo on 6/15/17.
*/
public class OkHttpIdlingResourceRule implements TestRule {
@Override
public Statement apply(final Statement base, Description description) {
TestGenericApplication app = (TestGenericApplication)
InstrumentationRegistry.getTargetContext().getApplicationContext();
return new Statement() {
@Override
public void evaluate() throws Throwable {
IdlingResource idlingResource = OkHttp3IdlingResource.create(
"okhttp", app.getOkHttpBuilder().build());
Espresso.registerIdlingResources(idlingResource);
base.evaluate();
Espresso.unregisterIdlingResources(idlingResource);
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.zeyad.usecases.app;

import android.support.annotation.NonNull;

import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

import io.appflate.restmock.RESTMockServer;
import okhttp3.internal.tls.SslClient;

/**
* @author by ZIaDo on 6/15/17.
*/

public class TestGenericApplication extends GenericApplication {
@NonNull
@Override
public String getApiBaseUrl() {
return RESTMockServer.getUrl();
}

@Override
X509TrustManager getX509TrustManager() {
return SslClient.localhost().trustManager;
}

@Override
SSLSocketFactory getSSlSocketFactory() {
return SslClient.localhost().socketFactory;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.zeyad.usecases.app;

import android.app.Application;
import android.content.Context;

import io.appflate.restmock.android.RESTMockTestRunner;

/**
* @author by ZIaDo on 6/15/17.
*/
public class UseCasesTestRunner extends RESTMockTestRunner {
@Override
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return super.newApplication(cl, TestGenericApplication.class.getName(), context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"login": "octocat",
"followers": 1500
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.zeyad.usecases.app.screens.user.list;

import android.support.test.rule.ActivityTestRule;

import com.zeyad.usecases.app.OkHttpIdlingResourceRule;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import io.appflate.restmock.RESTMockServer;
import io.appflate.restmock.RequestsVerifier;
import okhttp3.mockwebserver.MockResponse;

import static io.appflate.restmock.utils.RequestMatchers.pathEndsWith;
import static io.appflate.restmock.utils.RequestMatchers.pathStartsWith;

/**
* @author by ZIaDo on 6/15/17.
*/
public class UserListActivityTest {
private static final String USER_LIST_BODY = "{ \"login\" : \"octocat\", \"followers\" : 1500 }";
private final String urlPart = "users?since=0";
@Rule
public ActivityTestRule<UserListActivity> activityRule
= new ActivityTestRule<>(UserListActivity.class, true, false);

@Rule
public OkHttpIdlingResourceRule okHttpIdlingResourceRule = new OkHttpIdlingResourceRule();

// @Rule
// public MockWebServerRule mockWebServerRule = new MockWebServerRule();

@Before
public void before() {
RESTMockServer.reset();
}

@Test
public void followers() throws IOException, InterruptedException {
RESTMockServer.whenGET(pathEndsWith(urlPart))
.thenReturnFile("users/userList.json");

activityRule.launchActivity(null);

// onView(withId(R.id.followers))
// .check(matches(withText("1500")));

RequestsVerifier.verifyGET(pathStartsWith("/" + urlPart)).invoked();
}

@Test
public void status404() throws IOException {
RESTMockServer.whenGET(pathEndsWith(urlPart))
.thenReturnEmpty(404);

activityRule.launchActivity(null);

// onView(withId(R.id.followers))
// .check(matches(withText("404")));
}

@Test
public void malformedJson() throws IOException {
RESTMockServer.whenGET(pathEndsWith(urlPart)).thenReturn(new MockResponse().setBody("Jason"));

activityRule.launchActivity(null);

// onView(withId(R.id.followers))
// .check(matches(withText("IOException")));
}

@Test
public void timeout() throws IOException {
RESTMockServer.whenGET(pathEndsWith(urlPart)).thenReturn(
new MockResponse().setBody(USER_LIST_BODY).throttleBody(1, 1, TimeUnit.SECONDS));

activityRule.launchActivity(null);

// onView(withId(R.id.followers))
// .check(matches(withText("SocketTimeoutException")));
}
}
2 changes: 2 additions & 0 deletions sampleApp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
<application
android:name=".GenericApplication"
android:allowBackup="true"
android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--android:resizeableActivity="false"-->
<!--<meta-data-->
<!--android:name="com.zeyad.usecases.app.components.MyGlideModule"-->
<!--android:value="GlideModule" />-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.StrictMode;
import android.support.annotation.NonNull;
import android.util.Base64;
import android.util.Log;

Expand All @@ -17,14 +18,21 @@
import com.zeyad.usecases.api.DataServiceFactory;

import java.security.MessageDigest;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

import io.flowup.FlowUp;
import io.reactivex.Completable;
import io.reactivex.schedulers.Schedulers;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.rx.RealmObservableFactory;
import okhttp3.CertificatePinner;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;

import static com.zeyad.usecases.app.utils.Constants.URLS.API_BASE_URL;

Expand Down Expand Up @@ -105,12 +113,36 @@ public void onCreate() {
}, Throwable::printStackTrace);
initializeRealm();
DataServiceFactory.init(new DataServiceConfig.Builder(this)
.baseUrl(API_BASE_URL)
.baseUrl(getApiBaseUrl())
.okHttpBuilder(getOkHttpBuilder())
.withCache(3, TimeUnit.MINUTES)
.withRealm()
.build());
}

@NonNull
OkHttpClient.Builder getOkHttpBuilder() {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.certificatePinner(new CertificatePinner.Builder()
.add(API_BASE_URL,
"sha256/6wJsqVDF8K19zxfLxV5DGRneLyzso9adVdUN/exDacw")
.add(API_BASE_URL,
"sha256/k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws=")
.add(API_BASE_URL,
"sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=")
.build())
.connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS,
ConnectionSpec.COMPATIBLE_TLS));
if (getSSlSocketFactory() != null && getX509TrustManager() != null)
builder.sslSocketFactory(getSSlSocketFactory(), getX509TrustManager());
return builder;
}

@NonNull
String getApiBaseUrl() {
return API_BASE_URL;
}

private void initializeStrictMode() {
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(
Expand Down Expand Up @@ -143,4 +175,12 @@ && verifyInstaller(context)
&& checkEmulator()
&& checkDebuggable(context);
}

X509TrustManager getX509TrustManager() {
return null;
}

SSLSocketFactory getSSlSocketFactory() {
return null;
}
}
14 changes: 14 additions & 0 deletions usecases/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ android {
exclude 'META-INF/NOTICE'
exclude 'META-INF/rxjava.properties'
}

if (project.hasProperty('devBuild')) {
splits.abi.enable = false
splits.density.enable = false
aaptOptions.cruncherEnabled = false
}
}

ext {
Expand Down Expand Up @@ -149,6 +155,14 @@ dependencies {
testCompile "org.powermock:powermock-module-junit4-rule:$powerMock"
testCompile "org.powermock:powermock-api-mockito:$powerMock"
testCompile "org.powermock:powermock-classloading-xstream:$powerMock"

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
exclude group: 'com.android.support'
}
androidTestCompile('com.jakewharton.espresso:okhttp3-idling-resource:1.0.0') {
exclude group: 'com.android.support'
}
androidTestCompile "com.squareup.okhttp3:mockwebserver:$okhttpVersion"
}

task createPom {
Expand Down
Loading

0 comments on commit e5fb11f

Please sign in to comment.