Mholloway has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/365427 )

Change subject: Add offline compilation client
......................................................................

Add offline compilation client

Bug: T163714
Change-Id: I2b11abad2e62293a8a59b7b50b90c836a6ca961e
---
A app/src/main/java/org/wikipedia/offline/CompilationClient.java
A app/src/main/java/org/wikipedia/offline/CompilationInfo.java
A app/src/test/java/org/wikipedia/offline/CompilationClientTest.java
3 files changed, 230 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/27/365427/1

diff --git a/app/src/main/java/org/wikipedia/offline/CompilationClient.java 
b/app/src/main/java/org/wikipedia/offline/CompilationClient.java
new file mode 100644
index 0000000..1d1a06c
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/offline/CompilationClient.java
@@ -0,0 +1,104 @@
+package org.wikipedia.offline;
+
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+
+import org.wikipedia.dataclient.WikiSite;
+import org.wikipedia.dataclient.retrofit.RetrofitFactory;
+import org.wikipedia.json.annotations.Required;
+import org.wikipedia.settings.Prefs;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+import retrofit2.Call;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.http.GET;
+import retrofit2.http.Headers;
+
+import static org.wikipedia.Constants.ACCEPT_HEADER_PREFIX;
+
+class CompilationClient {
+    interface Callback {
+        void success(@NonNull List<CompilationInfo> compilations);
+        void error(@NonNull Throwable caught);
+    }
+
+    @Nullable private Call<CallbackAdapter.CompilationResponse> call;
+
+    // todo: according to Jake Wharton, Retrofit service objects are very 
expensive and should only
+    // be created once for the application and then cached for reuse. Figure 
out how to make these
+    // WikiSite-independent, and create once.
+    // https://stackoverflow.com/a/20627010/5520737
+    public void request(@NonNull WikiSite wiki, @NonNull Callback cb) {
+        cancel();
+        Retrofit retrofit = RetrofitFactory.newInstance(getEndpoint(wiki), 
wiki);
+        Service service = retrofit.create(Service.class);
+        call = request(service);
+        call.enqueue(new CallbackAdapter(cb));
+    }
+
+    public void cancel() {
+        if (call == null) {
+            return;
+        }
+        call.cancel();
+        call = null;
+    }
+
+    @VisibleForTesting @NonNull
+    Call<CallbackAdapter.CompilationResponse> request(@NonNull Service 
service) {
+        return service.get();
+    }
+
+    @VisibleForTesting
+    static class CallbackAdapter implements 
retrofit2.Callback<CallbackAdapter.CompilationResponse> {
+        private Callback cb;
+
+        CallbackAdapter(Callback cb) {
+            this.cb = cb;
+        }
+
+        @Override
+        public void onResponse(@NonNull Call<CompilationResponse> call,
+                               @NonNull Response<CompilationResponse> 
response) {
+            // noinspection ConstantConditions
+            if (response.body() != null && response.body().compilations() != 
null) {
+                // noinspection ConstantConditions
+                cb.success(response.body().compilations());
+            } else {
+                cb.error(new IOException("An unknown error occurred."));
+            }
+        }
+
+        @Override
+        public void onFailure(@NonNull Call<CompilationResponse> call, 
@NonNull Throwable t) {
+            cb.error(t);
+        }
+
+        static class CompilationResponse {
+            @SuppressWarnings("unused,NullableProblems") @NonNull @Required
+            private List<CompilationInfo> compilations;
+
+            @Nullable
+            List<CompilationInfo> compilations() {
+                return compilations;
+            }
+        }
+    }
+
+    // todo: update endpoint path when finalized
+    @VisibleForTesting
+    interface Service {
+        @NonNull @Headers(ACCEPT_HEADER_PREFIX + "compilations/0.1.0\"") 
@GET("/compilations")
+        Call<CallbackAdapter.CompilationResponse> get();
+    }
+
+    private String getEndpoint(WikiSite wiki) {
+        return String.format(Locale.ROOT, Prefs.getRestbaseUriFormat(), 
wiki.scheme(), wiki.authority());
+    }
+}
diff --git a/app/src/main/java/org/wikipedia/offline/CompilationInfo.java 
b/app/src/main/java/org/wikipedia/offline/CompilationInfo.java
new file mode 100644
index 0000000..386dcab
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/offline/CompilationInfo.java
@@ -0,0 +1,59 @@
+package org.wikipedia.offline;
+
+
+import android.net.Uri;
+import android.support.annotation.NonNull;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Date;
+
+// A Gson POJO that will model the compilations endpoint response. TODO: 
Finalize when the spec is defined.
+class CompilationInfo {
+    @SuppressWarnings("unused,NullableProblems") @NonNull private String 
filename;
+    @SuppressWarnings("unused,NullableProblems") @NonNull private String 
summary;
+    @SuppressWarnings("unused,NullableProblems") @NonNull private String 
description;
+    @SuppressWarnings("unused,NullableProblems") @SerializedName("thumb_url") 
@NonNull private Uri thumbUrl;
+    @SuppressWarnings("unused,NullableProblems") @SerializedName("image_url") 
@NonNull private Uri imageUrl; // full-size image
+    @SuppressWarnings("unused") @SerializedName("article_count") private int 
articleCount;
+    @SuppressWarnings("unused") private long size; // bytes
+    @SuppressWarnings("unused") private long timestamp;
+
+    @NonNull
+    public String getFilename() {
+        return filename;
+    }
+
+    @NonNull
+    public String getSummary() {
+        return summary;
+    }
+
+    @NonNull
+    public String getDescription() {
+        return description;
+    }
+
+    @NonNull
+    public Uri getThumbUrl() {
+        return thumbUrl;
+    }
+
+    @NonNull
+    public Uri getImageUrl() {
+        return imageUrl;
+    }
+
+    public int getArticleCount() {
+        return articleCount;
+    }
+
+    public long getSize() {
+        return size;
+    }
+
+    @NonNull
+    public Date getDate() {
+        return new Date(timestamp);
+    }
+}
diff --git a/app/src/test/java/org/wikipedia/offline/CompilationClientTest.java 
b/app/src/test/java/org/wikipedia/offline/CompilationClientTest.java
new file mode 100644
index 0000000..38d23b2
--- /dev/null
+++ b/app/src/test/java/org/wikipedia/offline/CompilationClientTest.java
@@ -0,0 +1,67 @@
+package org.wikipedia.offline;
+
+import android.support.annotation.NonNull;
+
+import org.junit.Test;
+import org.wikipedia.offline.CompilationClient.Callback;
+import org.wikipedia.test.MockWebServerTest;
+
+import retrofit2.Call;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class CompilationClientTest extends MockWebServerTest {
+    @NonNull private CompilationClient subject = new CompilationClient();
+
+    // todo: update when compilation info spec is finalized
+    @Test
+    public void testRequestSuccess() throws Throwable {
+        server().enqueue("{ \"compilations\": [] }");
+        Callback cb = mock(Callback.class);
+        request(cb);
+        server().takeRequest();
+        verify(cb).success(anyListOf(CompilationInfo.class));
+        //noinspection unchecked
+        verify(cb, never()).error(any(Throwable.class));
+    }
+
+    @Test
+    public void testRequestMalformed() throws Throwable {
+        server().enqueue("ææææææææææææææææææ");
+        Callback cb = mock(Callback.class);
+        request(cb);
+        server().takeRequest();
+        verify(cb, never()).success(anyListOf(CompilationInfo.class));
+        verify(cb).error(any(Throwable.class));
+    }
+
+    @Test
+    public void testRequestEmpty() throws Throwable {
+        enqueueEmptyJson();
+        Callback cb = mock(Callback.class);
+        request(cb);
+        server().takeRequest();
+        verify(cb, never()).success(anyListOf(CompilationInfo.class));
+        verify(cb).error(any(Throwable.class));
+    }
+
+    @Test
+    public void testRequestNotFound() throws Throwable {
+        enqueue404();
+        Callback cb = mock(Callback.class);
+        request(cb);
+        server().takeRequest();
+        verify(cb, never()).success(anyListOf(CompilationInfo.class));
+        verify(cb).error(any(Throwable.class));
+    }
+
+    private void request(@NonNull CompilationClient.Callback cb) {
+        Call<CompilationClient.CallbackAdapter.CompilationResponse> call
+                = subject.request(service(CompilationClient.Service.class));
+        call.enqueue(new CompilationClient.CallbackAdapter(cb));
+    }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/365427
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2b11abad2e62293a8a59b7b50b90c836a6ca961e
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <mhollo...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to