Add test code

This commit is contained in:
Peter Stuifzand 2018-03-04 23:34:20 +01:00
parent c685f0a944
commit f2afb939c6
8 changed files with 229 additions and 10 deletions

View File

@ -6,8 +6,8 @@ android {
applicationId "eu.stuifzand.micropub"
minSdkVersion 15
targetSdkVersion 26
versionCode 4
versionName '0.0.3-alpha'
versionCode 5
versionName '0.0.5-alpha'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
@ -20,6 +20,11 @@ android {
targetCompatibility 1.8
sourceCompatibility 1.8
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
dataBinding {
enabled = true
}
@ -36,6 +41,9 @@ dependencies {
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:26.1.0'
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
testImplementation 'com.squareup.okhttp3:mockwebserver:3.9.1';
testImplementation "org.robolectric:robolectric:3.7.1"
// Logging
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'
// ViewModel and LiveData
@ -46,6 +54,9 @@ dependencies {
implementation 'org.jsoup:jsoup:1.11.2'
implementation 'com.google.code.gson:gson:2.8.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
compile 'com.android.support:support-annotations:22.2.0'
}

View File

@ -0,0 +1,27 @@
package eu.stuifzand.micropub;
import android.support.test.filters.LargeTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class HelloWorldEspressoTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule(MainActivity.class);
@Test
public void createPost() throws Exception {
onView(withId(R.id.content)).perform(typeText("This is a test message"));
}
}

View File

@ -1,9 +1,8 @@
package eu.stuifzand.micropub.client;
import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
import android.databinding.ObservableArrayList;
import android.support.annotation.NonNull;
@ -11,8 +10,6 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.http.params.HttpParams;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@ -21,7 +18,7 @@ import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
public class Client extends AndroidViewModel {
public class Client extends ViewModel {
private final OkHttpClient httpClient;
private MutableLiveData<Response> response = new MutableLiveData<>();
@ -33,9 +30,7 @@ public class Client extends AndroidViewModel {
private String token;
private HttpUrl mediaEndpoint;
public Client(@NonNull Application application) {
super(application);
public Client() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
@ -118,4 +113,8 @@ public class Client extends AndroidViewModel {
public void setMediaEndpoint(String mediaEndpoint) {
this.mediaEndpoint = HttpUrl.parse(mediaEndpoint);
}
public String getMediaEndpoint() {
return this.mediaEndpoint.toString();
}
}

View File

@ -5,6 +5,7 @@ import android.util.Log;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import java.io.IOException;
@ -53,6 +54,8 @@ class MicropubConfigTask extends AsyncTask<String, Void, String> {
}
} catch (IOException e) {
Log.e("micropub", "Error while getting syndicate-to", e);
} catch (JsonSyntaxException e) {
Log.e("micropub", "Error while getting parsing json response", e);
} finally {
if (httpResponse != null) {
httpResponse.close();

View File

@ -27,6 +27,9 @@ public class Post {
this.name = name;
this.content = content;
this.categories = categories.split("\\s+");
if (this.categories.length == 1 && this.categories[0].length() == 0) {
this.categories = new String[]{};
}
this.syndicationUids = new String[]{};
}

View File

@ -0,0 +1,103 @@
package eu.stuifzand.micropub;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import eu.stuifzand.micropub.client.Client;
import eu.stuifzand.micropub.client.Post;
import eu.stuifzand.micropub.client.Response;
import okhttp3.HttpUrl;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import static junit.framework.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(RobolectricTestRunner.class)
public class MicropubBackendTest {
@Test
public void createPost() throws Exception {
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setResponseCode(201).addHeader("Location", "http://example.com/post/1"));
server.start();
HttpUrl baseUrl = server.url("/micropub");
Client client = new Client();
Post post = new Post("Hello world");
client.createPost(post, "token", baseUrl);
Robolectric.flushBackgroundThreadScheduler();
RecordedRequest request = server.takeRequest();
assertEquals(request.getPath(), "/micropub");
assertEquals(request.getHeader("Authorization"), "Bearer token");
assertEquals(request.getMethod(), "POST");
Response value = client.getResponse().getValue();
assertTrue(value.isSuccess());
assertTrue(value.getUrl().endsWith("/post/1"));
}
@Test
public void createPostWithMicropubError() throws Exception {
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setResponseCode(400));
server.start();
HttpUrl baseUrl = server.url("/micropub");
Client client = new Client();
Post post = new Post("Hello world");
client.createPost(post, "token", baseUrl);
Robolectric.flushBackgroundThreadScheduler();
Response value = client.getResponse().getValue();
assertFalse(value.isSuccess());
}
@Test
public void loadConfigMediaEndpoint() throws Exception {
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setResponseCode(200).setBody("{\"media-endpoint\":\"http://example.com/media\", \"syndicate-to\":[]}"));
server.start();
HttpUrl baseUrl = server.url("/micropub");
Client client = new Client();
client.loadConfig(baseUrl);
Robolectric.flushBackgroundThreadScheduler();
assertEquals("http://example.com/media", client.getMediaEndpoint());
}
@Test
public void loadConfigSyndicateTo() throws Exception {
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setResponseCode(200).setBody("{\"media-endpoint\":\"http://example.com/media\", \"syndicate-to\":[{\"uid\":\"test\",\"name\":\"Test\"}]}"));
server.start();
HttpUrl baseUrl = server.url("/micropub");
Client client = new Client();
client.loadConfig(baseUrl);
Robolectric.flushBackgroundThreadScheduler();
assertEquals("Test", client.syndicates.get(0).name.get());
assertEquals("test", client.syndicates.get(0).uid.get());
}
@Test
public void loadConfigParseError() throws Exception {
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setResponseCode(200).setBody("{"));
server.start();
HttpUrl baseUrl = server.url("/micropub");
Client client = new Client();
client.loadConfig(baseUrl);
Robolectric.flushBackgroundThreadScheduler();
}
}

View File

@ -0,0 +1,46 @@
package eu.stuifzand.micropub;
import org.junit.Test;
import eu.stuifzand.micropub.client.Post;
import okhttp3.HttpUrl;
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class PostTest {
@Test public void postWithContent() {
Post post = new Post("hello world");
assertEquals(post.getContent(), "hello world");
String[] categories = post.getCategories();
assertEquals(categories.length, 0);
}
@Test public void postWithNameAndContent() {
Post post = new Post("title", "content");
assertEquals(post.getName(), "title");
assertEquals(post.getContent(), "content");
}
@Test public void postWithNameContentAndEmptyCategories() {
Post post = new Post("title", "content", "");
assertEquals(post.getName(), "title");
assertEquals(post.getContent(), "content");
String[] categories = post.getCategories();
assertEquals(0, categories.length);
assertFalse(post.hasInReplyTo());
assertFalse(post.hasPhoto());
}
@Test public void emptyHasNoPhoto() {
Post post = new Post("Content");
assertFalse(post.hasPhoto());
}
@Test public void postWithInReplyTo() {
Post post = new Post("title", "content", "", HttpUrl.parse("http://example.com"));
assertTrue(post.hasInReplyTo());
assertEquals("http://example.com/", post.getInReplyTo());
}
}

View File

@ -0,0 +1,27 @@
package eu.stuifzand.micropub.util;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.support.annotation.Nullable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class LiveDataTestUtil {
public static <T> T getValue(LiveData<T> liveData) throws InterruptedException {
final Object[] data = new Object[1];
CountDownLatch latch = new CountDownLatch(1);
Observer<T> observer = new Observer<T>() {
@Override
public void onChanged(@Nullable T o) {
data[0] = o;
latch.countDown();
liveData.removeObserver(this);
}
};
liveData.observeForever(observer);
latch.await(2, TimeUnit.SECONDS);
//noinspection unchecked
return (T) data[0];
}
}