diff --git a/app/build.gradle b/app/build.gradle index 03a4906..e49b15e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,13 +2,13 @@ apply plugin: 'com.android.application' apply plugin: 'com.getkeepsafe.dexcount' android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.2" defaultConfig { applicationId "com.tapglue.example" minSdkVersion 15 - targetSdkVersion 23 + targetSdkVersion 25 versionCode 1 versionName "1.0" } @@ -23,9 +23,8 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:23.2.1' - compile 'com.android.support:design:23.2.1' - compile 'io.reactivex:rxandroid:1.1.0' + compile 'com.android.support:appcompat-v7:25.2.0' + compile 'com.android.support:design:25.2.0' compile 'io.reactivex:rxjava:1.1.2' compile project(':tapglue-android-sdk') } diff --git a/app/src/main/java/com/tapglue/example/MainActivity.java b/app/src/main/java/com/tapglue/example/MainActivity.java index fbd79c6..3ed4cb3 100644 --- a/app/src/main/java/com/tapglue/example/MainActivity.java +++ b/app/src/main/java/com/tapglue/example/MainActivity.java @@ -47,7 +47,7 @@ public void onCompleted() { @Override public void onError(Throwable e) { - + Log.d("MainActivity", "onError"); } @Override diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/core/.gitignore @@ -0,0 +1 @@ +/build diff --git a/core/build.gradle b/core/build.gradle new file mode 100644 index 0000000..9ccab17 --- /dev/null +++ b/core/build.gradle @@ -0,0 +1,53 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + + defaultConfig { + minSdkVersion 15 + targetSdkVersion 25 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile project(':entities') + compile 'com.squareup.retrofit2:retrofit:2.2.0' + compile 'com.squareup.retrofit2:converter-gson:2.2.0' + + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:25.2.0' + compile 'com.google.firebase:firebase-messaging:9.0.2' + compile 'com.squareup.okhttp3:logging-interceptor:3.6.0' + compile 'com.squareup.okhttp3:okhttp:3.6.0' + + testCompile 'junit:junit:4.12' + testCompile 'org.hamcrest:hamcrest-all:1.3' + testCompile('org.mockito:mockito-core:1.10.8') { + exclude module: 'hamcrest-core' + } + + testCompile('org.powermock:powermock-api-mockito:1.6.1') { + exclude module: 'mockito-all' + } + testCompile 'org.powermock:powermock-module-junit4-rule-agent:1.6.1' + testCompile 'org.powermock:powermock-module-junit4-rule:1.6.1' + testCompile('org.powermock:powermock-module-junit4:1.6.1') { + exclude module: 'hamcrest-core' + } + +} diff --git a/core/proguard-rules.pro b/core/proguard-rules.pro new file mode 100644 index 0000000..0569ea6 --- /dev/null +++ b/core/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/gauravvashisth/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/core/src/androidTest/java/com/tapglue/android/ExampleInstrumentedTest.java b/core/src/androidTest/java/com/tapglue/android/ExampleInstrumentedTest.java new file mode 100644 index 0000000..42ddae8 --- /dev/null +++ b/core/src/androidTest/java/com/tapglue/android/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.tapglue.android; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.tapglue.android.test", appContext.getPackageName()); + } +} diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b2e2a99 --- /dev/null +++ b/core/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/Configuration.java b/core/src/main/java/com/tapglue/android/Configuration.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/Configuration.java rename to core/src/main/java/com/tapglue/android/Configuration.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/Base64Encoder.java b/core/src/main/java/com/tapglue/android/http/Base64Encoder.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/Base64Encoder.java rename to core/src/main/java/com/tapglue/android/http/Base64Encoder.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/ClientFactory.java b/core/src/main/java/com/tapglue/android/http/ClientFactory.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/ClientFactory.java rename to core/src/main/java/com/tapglue/android/http/ClientFactory.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/ErrorInterceptor.java b/core/src/main/java/com/tapglue/android/http/ErrorInterceptor.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/ErrorInterceptor.java rename to core/src/main/java/com/tapglue/android/http/ErrorInterceptor.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/HeaderInterceptor.java b/core/src/main/java/com/tapglue/android/http/HeaderInterceptor.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/HeaderInterceptor.java rename to core/src/main/java/com/tapglue/android/http/HeaderInterceptor.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/PaginationInterceptor.java b/core/src/main/java/com/tapglue/android/http/PaginationInterceptor.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/PaginationInterceptor.java rename to core/src/main/java/com/tapglue/android/http/PaginationInterceptor.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/sims/DevicePayload.java b/core/src/main/java/com/tapglue/android/sims/DevicePayload.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/sims/DevicePayload.java rename to core/src/main/java/com/tapglue/android/sims/DevicePayload.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/sims/NotificationServiceIdListener.java b/core/src/main/java/com/tapglue/android/sims/NotificationServiceIdListener.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/sims/NotificationServiceIdListener.java rename to core/src/main/java/com/tapglue/android/sims/NotificationServiceIdListener.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/sims/SimsIdListenerService.java b/core/src/main/java/com/tapglue/android/sims/SimsIdListenerService.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/sims/SimsIdListenerService.java rename to core/src/main/java/com/tapglue/android/sims/SimsIdListenerService.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/sims/SimsMessagingService.java b/core/src/main/java/com/tapglue/android/sims/SimsMessagingService.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/sims/SimsMessagingService.java rename to core/src/main/java/com/tapglue/android/sims/SimsMessagingService.java diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml new file mode 100644 index 0000000..6f8e4f6 --- /dev/null +++ b/core/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + core + diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/ConfigurationTest.java b/core/src/test/java/com/tapglue/android/ConfigurationTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/ConfigurationTest.java rename to core/src/test/java/com/tapglue/android/ConfigurationTest.java diff --git a/core/src/test/java/com/tapglue/android/ExampleUnitTest.java b/core/src/test/java/com/tapglue/android/ExampleUnitTest.java new file mode 100644 index 0000000..ac1c099 --- /dev/null +++ b/core/src/test/java/com/tapglue/android/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.tapglue.android; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/ClientFactoryTest.java b/core/src/test/java/com/tapglue/android/http/ClientFactoryTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/ClientFactoryTest.java rename to core/src/test/java/com/tapglue/android/http/ClientFactoryTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/ErrorInterceptorTest.java b/core/src/test/java/com/tapglue/android/http/ErrorInterceptorTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/ErrorInterceptorTest.java rename to core/src/test/java/com/tapglue/android/http/ErrorInterceptorTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/HeaderInterceptorTest.java b/core/src/test/java/com/tapglue/android/http/HeaderInterceptorTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/HeaderInterceptorTest.java rename to core/src/test/java/com/tapglue/android/http/HeaderInterceptorTest.java diff --git a/entities/.gitignore b/entities/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/entities/.gitignore @@ -0,0 +1 @@ +/build diff --git a/entities/build.gradle b/entities/build.gradle new file mode 100644 index 0000000..43b2d18 --- /dev/null +++ b/entities/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'java' + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.google.code.gson:gson:2.7' + + testCompile 'junit:junit:4.12' + testCompile 'org.hamcrest:hamcrest-all:1.3' + testCompile('org.mockito:mockito-core:1.10.8') { + exclude module: 'hamcrest-core' + } + + testCompile('org.powermock:powermock-api-mockito:1.6.1') { + exclude module: 'mockito-all' + } + testCompile 'org.powermock:powermock-module-junit4-rule-agent:1.6.1' + testCompile 'org.powermock:powermock-module-junit4-rule:1.6.1' + testCompile('org.powermock:powermock-module-junit4:1.6.1') { + exclude module: 'hamcrest-core' + } +} + +sourceCompatibility = "1.7" +targetCompatibility = "1.7" diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Comment.java b/entities/src/main/java/com/tapglue/android/entities/Comment.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Comment.java rename to entities/src/main/java/com/tapglue/android/entities/Comment.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Connection.java b/entities/src/main/java/com/tapglue/android/entities/Connection.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Connection.java rename to entities/src/main/java/com/tapglue/android/entities/Connection.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/ConnectionList.java b/entities/src/main/java/com/tapglue/android/entities/ConnectionList.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/ConnectionList.java rename to entities/src/main/java/com/tapglue/android/entities/ConnectionList.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Event.java b/entities/src/main/java/com/tapglue/android/entities/Event.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Event.java rename to entities/src/main/java/com/tapglue/android/entities/Event.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Follow.java b/entities/src/main/java/com/tapglue/android/entities/Follow.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Follow.java rename to entities/src/main/java/com/tapglue/android/entities/Follow.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Friend.java b/entities/src/main/java/com/tapglue/android/entities/Friend.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Friend.java rename to entities/src/main/java/com/tapglue/android/entities/Friend.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Like.java b/entities/src/main/java/com/tapglue/android/entities/Like.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Like.java rename to entities/src/main/java/com/tapglue/android/entities/Like.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/NewsFeed.java b/entities/src/main/java/com/tapglue/android/entities/NewsFeed.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/NewsFeed.java rename to entities/src/main/java/com/tapglue/android/entities/NewsFeed.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Post.java b/entities/src/main/java/com/tapglue/android/entities/Post.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Post.java rename to entities/src/main/java/com/tapglue/android/entities/Post.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Reaction.java b/entities/src/main/java/com/tapglue/android/entities/Reaction.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/Reaction.java rename to entities/src/main/java/com/tapglue/android/entities/Reaction.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/User.java b/entities/src/main/java/com/tapglue/android/entities/User.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/entities/User.java rename to entities/src/main/java/com/tapglue/android/entities/User.java index 195d3b6..c4a53a0 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/entities/User.java +++ b/entities/src/main/java/com/tapglue/android/entities/User.java @@ -16,10 +16,10 @@ */ package com.tapglue.android.entities; -import java.util.Map; - import com.google.gson.annotations.SerializedName; +import java.util.Map; + public class User { @SerializedName("id_string") private String id; diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/ApiPage.java b/entities/src/main/java/com/tapglue/android/http/ApiPage.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/ApiPage.java rename to entities/src/main/java/com/tapglue/android/http/ApiPage.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/CommentsFeed.java b/entities/src/main/java/com/tapglue/android/http/CommentsFeed.java similarity index 96% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/CommentsFeed.java rename to entities/src/main/java/com/tapglue/android/http/CommentsFeed.java index a3f5e56..c7e7219 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/CommentsFeed.java +++ b/entities/src/main/java/com/tapglue/android/http/CommentsFeed.java @@ -25,7 +25,7 @@ import java.util.List; import java.util.Map; -class CommentsFeed extends FlattenableFeed> { +public class CommentsFeed extends FlattenableFeed> { List comments; Map users; diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/ConnectionsFeed.java b/entities/src/main/java/com/tapglue/android/http/ConnectionsFeed.java similarity index 95% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/ConnectionsFeed.java rename to entities/src/main/java/com/tapglue/android/http/ConnectionsFeed.java index 356cc0d..3c10b7b 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/ConnectionsFeed.java +++ b/entities/src/main/java/com/tapglue/android/http/ConnectionsFeed.java @@ -2,7 +2,6 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; - import com.tapglue.android.entities.Connection; import com.tapglue.android.entities.ConnectionList; import com.tapglue.android.entities.User; @@ -12,7 +11,7 @@ import java.util.List; import java.util.Map; -class ConnectionsFeed extends FlattenableFeed { +public class ConnectionsFeed extends FlattenableFeed { List incoming; List outgoing; List users; diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/ErrorFeed.java b/entities/src/main/java/com/tapglue/android/http/ErrorFeed.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/ErrorFeed.java rename to entities/src/main/java/com/tapglue/android/http/ErrorFeed.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/EventListFeed.java b/entities/src/main/java/com/tapglue/android/http/EventListFeed.java similarity index 96% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/EventListFeed.java rename to entities/src/main/java/com/tapglue/android/http/EventListFeed.java index 93d5cb9..e72ab4b 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/EventListFeed.java +++ b/entities/src/main/java/com/tapglue/android/http/EventListFeed.java @@ -19,7 +19,6 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.annotations.SerializedName; - import com.tapglue.android.entities.Event; import com.tapglue.android.entities.Post; import com.tapglue.android.entities.User; @@ -28,7 +27,7 @@ import java.util.List; import java.util.Map; -class EventListFeed extends FlattenableFeed> { +public class EventListFeed extends FlattenableFeed> { List events; Map users; @SerializedName("post_map") diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/FlattenableFeed.java b/entities/src/main/java/com/tapglue/android/http/FlattenableFeed.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/FlattenableFeed.java rename to entities/src/main/java/com/tapglue/android/http/FlattenableFeed.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/LikesFeed.java b/entities/src/main/java/com/tapglue/android/http/LikesFeed.java similarity index 96% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/LikesFeed.java rename to entities/src/main/java/com/tapglue/android/http/LikesFeed.java index 17705d7..ddbc487 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/LikesFeed.java +++ b/entities/src/main/java/com/tapglue/android/http/LikesFeed.java @@ -19,16 +19,15 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.annotations.SerializedName; - import com.tapglue.android.entities.Like; import com.tapglue.android.entities.Post; import com.tapglue.android.entities.User; -import java.util.List; import java.util.ArrayList; +import java.util.List; import java.util.Map; -class LikesFeed extends FlattenableFeed> { +public class LikesFeed extends FlattenableFeed> { List likes; Map users; @SerializedName("post_map") diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/PostListFeed.java b/entities/src/main/java/com/tapglue/android/http/PostListFeed.java similarity index 93% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/PostListFeed.java rename to entities/src/main/java/com/tapglue/android/http/PostListFeed.java index f04cedb..6ea45a0 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/PostListFeed.java +++ b/entities/src/main/java/com/tapglue/android/http/PostListFeed.java @@ -2,7 +2,6 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; - import com.tapglue.android.entities.Post; import com.tapglue.android.entities.User; @@ -10,7 +9,7 @@ import java.util.List; import java.util.Map; -class PostListFeed extends FlattenableFeed> { +public class PostListFeed extends FlattenableFeed> { List posts; Map users; diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/TapglueError.java b/entities/src/main/java/com/tapglue/android/http/TapglueError.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/TapglueError.java rename to entities/src/main/java/com/tapglue/android/http/TapglueError.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/UsersFeed.java b/entities/src/main/java/com/tapglue/android/http/UsersFeed.java similarity index 93% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/UsersFeed.java rename to entities/src/main/java/com/tapglue/android/http/UsersFeed.java index b26447c..22133a9 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/UsersFeed.java +++ b/entities/src/main/java/com/tapglue/android/http/UsersFeed.java @@ -2,14 +2,13 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; -import com.tapglue.android.entities.User; - import com.google.gson.annotations.SerializedName; +import com.tapglue.android.entities.User; import java.util.ArrayList; import java.util.List; -class UsersFeed extends FlattenableFeed> { +public class UsersFeed extends FlattenableFeed> { @SerializedName("users") private List users; diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/EmailLoginPayload.java b/entities/src/main/java/com/tapglue/android/http/payloads/EmailLoginPayload.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/EmailLoginPayload.java rename to entities/src/main/java/com/tapglue/android/http/payloads/EmailLoginPayload.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/EmailSearchPayload.java b/entities/src/main/java/com/tapglue/android/http/payloads/EmailSearchPayload.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/EmailSearchPayload.java rename to entities/src/main/java/com/tapglue/android/http/payloads/EmailSearchPayload.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/SocialConnections.java b/entities/src/main/java/com/tapglue/android/http/payloads/SocialConnections.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/SocialConnections.java rename to entities/src/main/java/com/tapglue/android/http/payloads/SocialConnections.java index cf6f50a..eb03c45 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/SocialConnections.java +++ b/entities/src/main/java/com/tapglue/android/http/payloads/SocialConnections.java @@ -16,10 +16,10 @@ package com.tapglue.android.http.payloads; -import java.util.List; - import com.google.gson.annotations.SerializedName; +import java.util.List; + import static com.tapglue.android.entities.Connection.Type; public class SocialConnections { diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/SocialSearchPayload.java b/entities/src/main/java/com/tapglue/android/http/payloads/SocialSearchPayload.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/SocialSearchPayload.java rename to entities/src/main/java/com/tapglue/android/http/payloads/SocialSearchPayload.java diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/UsernameLoginPayload.java b/entities/src/main/java/com/tapglue/android/http/payloads/UsernameLoginPayload.java similarity index 100% rename from tapglue-android-sdk/src/main/java/com/tapglue/android/http/payloads/UsernameLoginPayload.java rename to entities/src/main/java/com/tapglue/android/http/payloads/UsernameLoginPayload.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/CommentsFeedTest.java b/entities/src/test/java/com/tapglue/android/http/CommentsFeedTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/CommentsFeedTest.java rename to entities/src/test/java/com/tapglue/android/http/CommentsFeedTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/ConnectionFeedTest.java b/entities/src/test/java/com/tapglue/android/http/ConnectionFeedTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/ConnectionFeedTest.java rename to entities/src/test/java/com/tapglue/android/http/ConnectionFeedTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/EventListFeedTest.java b/entities/src/test/java/com/tapglue/android/http/EventListFeedTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/EventListFeedTest.java rename to entities/src/test/java/com/tapglue/android/http/EventListFeedTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/LikesFeedTest.java b/entities/src/test/java/com/tapglue/android/http/LikesFeedTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/LikesFeedTest.java rename to entities/src/test/java/com/tapglue/android/http/LikesFeedTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/EmailLoginPayloadTest.java b/entities/src/test/java/com/tapglue/android/http/payloads/EmailLoginPayloadTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/EmailLoginPayloadTest.java rename to entities/src/test/java/com/tapglue/android/http/payloads/EmailLoginPayloadTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/EmailSearchPayloadTest.java b/entities/src/test/java/com/tapglue/android/http/payloads/EmailSearchPayloadTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/EmailSearchPayloadTest.java rename to entities/src/test/java/com/tapglue/android/http/payloads/EmailSearchPayloadTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/SocialConnectionsTest.java b/entities/src/test/java/com/tapglue/android/http/payloads/SocialConnectionsTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/SocialConnectionsTest.java rename to entities/src/test/java/com/tapglue/android/http/payloads/SocialConnectionsTest.java diff --git a/tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/UsernameLoginPayloadTest.java b/entities/src/test/java/com/tapglue/android/http/payloads/UsernameLoginPayloadTest.java similarity index 100% rename from tapglue-android-sdk/src/test/java/com/tapglue/android/http/payloads/UsernameLoginPayloadTest.java rename to entities/src/test/java/com/tapglue/android/http/payloads/UsernameLoginPayloadTest.java diff --git a/rxjava2sample/.gitignore b/rxjava2sample/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/rxjava2sample/.gitignore @@ -0,0 +1 @@ +/build diff --git a/rxjava2sample/build.gradle b/rxjava2sample/build.gradle new file mode 100644 index 0000000..d6c159a --- /dev/null +++ b/rxjava2sample/build.gradle @@ -0,0 +1,42 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + + defaultConfig { + applicationId "com.tapglue.rxjava2sample" + minSdkVersion 15 + targetSdkVersion 25 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + compile 'com.android.support:appcompat-v7:25.2.0' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + testCompile 'junit:junit:4.12' +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' + compile 'com.android.support:appcompat-v7:25.2.0' + compile 'com.android.support:design:25.2.0' + compile 'io.reactivex.rxjava2:rxandroid:2.0.1' + compile project(':tapglue-android-sdk-rxjava2') +} diff --git a/rxjava2sample/proguard-rules.pro b/rxjava2sample/proguard-rules.pro new file mode 100644 index 0000000..0569ea6 --- /dev/null +++ b/rxjava2sample/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/gauravvashisth/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/rxjava2sample/src/androidTest/java/com/tapglue/android/ExampleInstrumentedTest.java b/rxjava2sample/src/androidTest/java/com/tapglue/android/ExampleInstrumentedTest.java new file mode 100644 index 0000000..6f444f2 --- /dev/null +++ b/rxjava2sample/src/androidTest/java/com/tapglue/android/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.tapglue.android; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.tapglue.android", appContext.getPackageName()); + } +} diff --git a/rxjava2sample/src/main/AndroidManifest.xml b/rxjava2sample/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b0e5e94 --- /dev/null +++ b/rxjava2sample/src/main/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/rxjava2sample/src/main/java/com/tapglue/rxjava2sample/MainActivity.java b/rxjava2sample/src/main/java/com/tapglue/rxjava2sample/MainActivity.java new file mode 100644 index 0000000..d79eb37 --- /dev/null +++ b/rxjava2sample/src/main/java/com/tapglue/rxjava2sample/MainActivity.java @@ -0,0 +1,59 @@ +package com.tapglue.rxjava2sample; + +import android.support.annotation.Nullable; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; + +import com.tapglue.android.Configuration; +import com.tapglue.android.RxTapglue; +import com.tapglue.android.entities.User; + +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + +public class MainActivity extends AppCompatActivity { + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + Configuration configuration = new Configuration("https://api.tapglue.com", "2da2d79336c2773c630ce46f5d24cb76"); + configuration.setLogging(true); + final RxTapglue tapglue; + try { + tapglue = new RxTapglue(configuration, this); + User user = new User("pablo", "supersecret"); + tapglue.createUser(user).subscribeOn(Schedulers.io()).subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + Log.d("MainActivity", "onSubscribe"); + } + + @Override + public void onNext(User user) { + Log.d("MainActivity", "onNext"); + } + + @Override + public void onError(Throwable e) { + Log.d("MainActivity", "onError"); + } + + @Override + public void onComplete() { + Log.d("MainActivity", "onComplete"); + tapglue.loginWithUsername("pablo", "supersecret").subscribe(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + } + + } +} diff --git a/rxjava2sample/src/main/res/layout/activity_main.xml b/rxjava2sample/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..96714b7 --- /dev/null +++ b/rxjava2sample/src/main/res/layout/activity_main.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/rxjava2sample/src/main/res/mipmap-hdpi/ic_launcher.png b/rxjava2sample/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/rxjava2sample/src/main/res/mipmap-hdpi/ic_launcher_round.png b/rxjava2sample/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..9a078e3 Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/rxjava2sample/src/main/res/mipmap-mdpi/ic_launcher.png b/rxjava2sample/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c133a0c Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/rxjava2sample/src/main/res/mipmap-mdpi/ic_launcher_round.png b/rxjava2sample/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..efc028a Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/rxjava2sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/rxjava2sample/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..bfa42f0 Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/rxjava2sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/rxjava2sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..3af2608 Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/rxjava2sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/rxjava2sample/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..324e72c Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/rxjava2sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/rxjava2sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..9bec2e6 Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/rxjava2sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/rxjava2sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/rxjava2sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/rxjava2sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..34947cd Binary files /dev/null and b/rxjava2sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/rxjava2sample/src/main/res/values/colors.xml b/rxjava2sample/src/main/res/values/colors.xml new file mode 100644 index 0000000..3ab3e9c --- /dev/null +++ b/rxjava2sample/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/rxjava2sample/src/main/res/values/strings.xml b/rxjava2sample/src/main/res/values/strings.xml new file mode 100644 index 0000000..8bb0da7 --- /dev/null +++ b/rxjava2sample/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + RxJava2Sample + diff --git a/rxjava2sample/src/main/res/values/styles.xml b/rxjava2sample/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/rxjava2sample/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/rxjava2sample/src/test/java/com/tapglue/android/ExampleUnitTest.java b/rxjava2sample/src/test/java/com/tapglue/android/ExampleUnitTest.java new file mode 100644 index 0000000..ac1c099 --- /dev/null +++ b/rxjava2sample/src/test/java/com/tapglue/android/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.tapglue.android; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 133dcd5..1aae693 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':tapglue-android-sdk' +include ':app', ':tapglue-android-sdk', ':entities', ':tapglue-android-sdk-rxjava2', ':core', ':rxjava2sample' diff --git a/tapglue-android-sdk-rxjava2/.gitignore b/tapglue-android-sdk-rxjava2/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/tapglue-android-sdk-rxjava2/.gitignore @@ -0,0 +1 @@ +/build diff --git a/tapglue-android-sdk-rxjava2/build.gradle b/tapglue-android-sdk-rxjava2/build.gradle new file mode 100644 index 0000000..18f993e --- /dev/null +++ b/tapglue-android-sdk-rxjava2/build.gradle @@ -0,0 +1,47 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 25 + buildToolsVersion "25.0.2" + + defaultConfig { + minSdkVersion 15 + targetSdkVersion 25 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + + compile 'io.reactivex.rxjava2:rxjava:2.0.6' + compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' + compile 'com.google.code.gson:gson:2.7' + compile project(':core') + compile 'com.android.support:appcompat-v7:25.2.0' + + testCompile 'junit:junit:4.12' + testCompile 'org.hamcrest:hamcrest-all:1.3' + testCompile('org.mockito:mockito-core:1.10.8') { + exclude module: 'hamcrest-core' + } + + testCompile('org.powermock:powermock-api-mockito:1.6.1') { + exclude module: 'mockito-all' + } + testCompile 'org.powermock:powermock-module-junit4-rule-agent:1.6.1' + testCompile 'org.powermock:powermock-module-junit4-rule:1.6.1' + testCompile('org.powermock:powermock-module-junit4:1.6.1') { + exclude module: 'hamcrest-core' + } + androidTestCompile 'junit:junit:4.12' +} diff --git a/tapglue-android-sdk-rxjava2/proguard-rules.pro b/tapglue-android-sdk-rxjava2/proguard-rules.pro new file mode 100644 index 0000000..0569ea6 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/proguard-rules.pro @@ -0,0 +1,25 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/gauravvashisth/Library/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/tapglue-android-sdk-rxjava2/src/androidTest/java/com/vashisthg/tapglue_android_sdk_rxjava2/ExampleInstrumentedTest.java b/tapglue-android-sdk-rxjava2/src/androidTest/java/com/vashisthg/tapglue_android_sdk_rxjava2/ExampleInstrumentedTest.java new file mode 100644 index 0000000..aca934a --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/androidTest/java/com/vashisthg/tapglue_android_sdk_rxjava2/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.vashisthg.tapglue_android_sdk_rxjava2; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.vashisthg.tapglue_android_sdk_rxjava2.test", appContext.getPackageName()); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/AndroidManifest.xml b/tapglue-android-sdk-rxjava2/src/main/AndroidManifest.xml new file mode 100644 index 0000000..48e703e --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxPage.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxPage.java new file mode 100644 index 0000000..a6dea2e --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxPage.java @@ -0,0 +1,53 @@ +package com.tapglue.android; + +import com.google.gson.JsonObject; +import com.tapglue.android.http.FlattenableFeed; +import com.tapglue.android.http.Network; + +import io.reactivex.Observable; +import io.reactivex.functions.Function; +import okhttp3.RequestBody; + + +public class RxPage { + FlattenableFeed feed; + Network network; + RequestBody payload; + + public RxPage(FlattenableFeed feed, Network network) { + this.feed = feed; + this.network = network; + } + + public RxPage(FlattenableFeed feed, Network network, RequestBody payload) { + this.feed = feed; + this.network = network; + this.payload = payload; + } + + public T getData() { + return feed.flatten(); + } + + public Observable> getPrevious() { + if(payload == null) { + return network.paginatedGet(feed.previousPointer()).map(new PreviousPageGenerator()); + } else { + return network.paginatedPost(feed.previousPointer(), payload) + .map(new PreviousPageGenerator()); + } + } + + private class PreviousPageGenerator implements Function> { + + @Override + public RxPage apply(JsonObject jsonObject) { + FlattenableFeed previousFeed = feed.parse(jsonObject); + if(payload == null) { + return new RxPage<>(previousFeed, network); + } else { + return new RxPage<>(previousFeed, network, payload); + } + } + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxTapglue.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxTapglue.java new file mode 100644 index 0000000..892c24e --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxTapglue.java @@ -0,0 +1,475 @@ +/** + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + +import android.content.Context; + +import com.tapglue.android.entities.Comment; +import com.tapglue.android.entities.Connection; +import com.tapglue.android.entities.Connection.Type; +import com.tapglue.android.entities.ConnectionList; +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.Like; +import com.tapglue.android.entities.NewsFeed; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.Reaction; +import com.tapglue.android.entities.User; +import com.tapglue.android.http.payloads.SocialConnections; +import com.tapglue.android.http.Network; +import com.tapglue.android.http.ServiceFactory; +import com.tapglue.android.internal.UserStore; +import com.tapglue.android.sims.TapglueSims; + +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; + + +public class RxTapglue { + + private static TapglueSims sims; + private static AtomicBoolean firstInstance = new AtomicBoolean(true); + private Network network; + private UserStore currentUser; + + /** + * @param configuration configuration of the tapglue instance + * @param context the context will be used for persisting session token and current user + */ + public RxTapglue(Configuration configuration, Context context) throws Exception{ + this.network = new Network(new ServiceFactory(configuration), context); + this.currentUser = new UserStore(context); + initializeSims(configuration, context); + } + + /** + * Logs in user with username and password. The user is persisted and can be requested by calling + * {@link #getCurrentUser() getCurrentUser} and will be persisted until explicit log out. + * @param username username of the user to be logged in + * @param password password of the user to be logged in + * @return the {@link User user} that was logged in + * @see com.tapglue.android.http.TapglueError + */ + public Observable loginWithUsername(String username, String password) { + return network.loginWithUsername(username, password).map(currentUser.store()) + .doOnComplete(new SimsSessionTokenNotifier()); + } + + /** + * Logs in user with email and password. The user is persisted and can be requested by calling + * {@link #getCurrentUser() getCurrentUser} and will be persisted until explicit log out. + * @param email email of the user to be logged in + * @param password password of the user to be logged in + * @return the {@link User user} that was logged in + * @see com.tapglue.android.http.TapglueError + */ + public Observable loginWithEmail(String email, String password) { + return network.loginWithEmail(email, password).map(currentUser.store()) + .doOnComplete(new SimsSessionTokenNotifier()); + } + + /** + * Logs out user. This will delete the persisted current user. + */ + public Observable logout() { + Observable unregisterSims = Observable.fromCallable(new SimsUnregistration()); + return Observable.concat(unregisterSims, network.logout()) + .doOnComplete(currentUser.clear()); + } + + /** + * Gets the persisted current user. Will only be available after a successful login. + * @return the current {@link User user} + */ + public Observable getCurrentUser() { + return currentUser.get(); + } + + /** + * checks if theres a user currently logged in + * @return true if theres a logged in user, false otherwise + */ + public boolean isLoggedIn() { + return !currentUser.isEmpty(); + } + + /** + * Creates a user. + * @param user the user to create + * @return the created {@link User user}. + */ + public Observable createUser(User user) { + return network.createUser(user); + } + + /** + * Deletes current user. + */ + public Observable deleteCurrentUser() throws Exception { + sims.unregisterDevice(); + return network.deleteCurrentUser().doOnComplete(currentUser.clear()); + } + + /** + * Updates current user + * @param user The updated user + * @return updated {@link User user}. + */ + public Observable updateCurrentUser(User user) { + return network.updateCurrentUser(user).map(currentUser.store()) + .doOnComplete(new SimsSessionTokenNotifier()); + } + + /** + * refreshses the persisted current user. After a successful call the refreshed user will be + * persisted and available at {@link #getCurrentUser() getCurrentUser} + * @return refreshed current {@link User user}. + */ + public Observable refreshCurrentUser() { + return network.refreshCurrentUser().map(currentUser.store()) + .doOnComplete(new SimsSessionTokenNotifier()); + } + + /** + * Clears locally stored copy of the current user. If the token of a user is invalidated + * from the server side this is useful to set the state back to no logged in user. + */ + public void clearLocalCurrentUser() throws Exception { + currentUser.clear().run(); + sims.unregisterDevice(); + network.clearLocalSessionToken(); + } + + /** + * Retrieve user. + * @param id user id of the wanted user + * @return the {@link User user}. + */ + public Observable retrieveUser(String id) { + return network.retrieveUser(id); + } + + /** + * retrieve the users followed by the current user + * @return List of followed {@link User users}. + */ + public Observable>> retrieveFollowings() { + return network.retrieveFollowings(); + } + + /** + * retrieve the users following the current user. + * @return List of {@link User users} following the current user. + */ + public Observable>> retrieveFollowers() { + return network.retrieveFollowers(); + } + + /** + * retrieves users followed by a user + * @param userId user id of the user of whom we want the followings + * @return list of users followed + */ + public Observable>> retrieveUserFollowings(String userId) { + return network.retrieveUserFollowings(userId); + } + + /** + * retrieves users following a user + * @param userId user id of the users of whom we want the followers + * @return list of users following + */ + public Observable>> retrieveUserFollowers(String userId) { + return network.retrieveUserFollowers(userId); + } + + /** + * Retrieve friends of the current user. + * @return list of {@link User friends}. + */ + public Observable>> retrieveFriends() { + return network.retrieveFriends(); + } + + /** + * retrieves the list of friends of a user. + * @param userId user id of the user of whom we want the friend list + * @return list of friends + */ + public Observable>> retrieveUserFriends(String userId) { + return network.retrieveUserFriends(userId); + } + + /** + * @return list of {@link Connection connections} in a pending state. + */ + public Observable> retrievePendingConnections() { + return network.retrievePendingConnections(); + } + + /** + * @return list of {@link Connection connections} in a rejected state. + */ + public Observable> retrieveRejectedConnections() { + return network.retrieveRejectedConnections(); + } + + /** + * @param connection {@link Connection connection} to be created + * @return the created {@link Connection connection} + */ + public Observable createConnection(Connection connection) { + return network.createConnection(connection); + } + + /** + * create connections with users retrieved from other social networks + * @param connections the {@link SocialConnections connections} + * @return list of users to whom connections were created + */ + public Observable> createSocialConnections(SocialConnections connections) { + return network.createSocialConnections(connections); + } + + public Observable deleteConnection(String userId, Type type) { + return network.deleteConnection(userId, type); + } + + /** + * Search will be conducted as in specified in the web documentation + * @param searchTerm + * @return search result as a list of {@link User users}. + */ + public Observable>> searchUsers(String searchTerm) { + return network.searchUsers(searchTerm); + } + + /** + * Search for users on tapglue by email. + * @param emails emails to search for. + * @return search result as a list of {@link User users}. + */ + public Observable>> searchUsersByEmail(List emails) { + return network.searchUsersByEmail(emails); + } + + /** + * Search for users on tapglue by social ids belonging to another social platform. + * @param platform the platform the ids belong to. + * @param socialIds the userIds to search for. + * @return search result as a list of {@link User users}. + */ + public Observable>> searchUsersBySocialIds(String platform, + List socialIds) { + return network.searchUsersBySocialIds(platform, socialIds); + } + + /** + * @param post {@link Post post} to be created. + * @return created post. + */ + public Observable createPost(Post post) { + return network.createPost(post); + } + + /** + * @param id id of the post to be retrieved. + * @return the retrieved {@link Post post}. + */ + public Observable retrievePost(String id) { + return network.retrievePost(id); + } + + /** + * @param id id of the {@link Post post} to be updated. + * @param post new post that will replace the old post. + * @return the updated post. + */ + public Observable updatePost(String id, Post post) { + return network.updatePost(id, post); + } + + /** + * @param id id of the {@link Post post} to be deleted. + */ + public Observable deletePost(String id) { + return network.deletePost(id); + } + + /** + * @return all available {@link Post posts} on the network. + */ + public Observable>> retrievePosts() { + return network.retrievePosts(); + } + + /** + * retrive all posts by a user. + * @param userId id of the user of whom the posts are. + * @return posts created by the user defined by userId + */ + public Observable>> retrievePostsByUser(String userId) { + return network.retrievePostsByUser(userId); + } + + /** + * creates a like event on a post. + * @param postId id of the post to be liked. + * @return created like event. + */ + public Observable createLike(String postId) { + return network.createLike(postId); + } + + /** + * Deletes like. + * @param postId id of the post that was liked. + */ + public Observable deleteLike(String postId) { + return network.deleteLike(postId); + } + + /** + * Retrieve all likes for a post. + * @param postId id for which the likes will be retrieved. + * @return likes. + */ + public Observable>> retrieveLikesForPost(String postId) { + return network.retrieveLikesForPost(postId); + } + + /** + * Retrieve list of likes by a user. + * @param userId id for which the likes will be retrieved. + * @return first page of likes. + */ + public Observable>> retrieveLikesByUser(String userId) { + return network.retrieveLikesByUser(userId); + } + + /** + * Creates a reaction on a post + * @param postId id of the post on which the reaction is created. + * @param reaction {@link Reaction reaction} + */ + public Observable createReaction(String postId, Reaction reaction) { + return network.createReaction(postId, reaction); + } + + public Observable deleteReaction(String postId, Reaction reaction) { + return network.deleteReaction(postId, reaction); + } + + /** + * @param postId id of the post to be commented. + * @param comment {@link Comment comment} + * @return created comment. + */ + public Observable createComment(String postId, Comment comment) { + return network.createComment(postId, comment); + } + + /** + * delete comment. + * @param postId id of the post that was commented. + * @param commentId id of the comment to be deleted. + */ + public Observable deleteComment(String postId, String commentId) { + return network.deleteComment(postId, commentId); + } + + /** + * Update comment. + * @param postId id of the post that was commented. + * @param commentId id of the comment to be updated. + * @param comment {@link Comment comment} to replace the old comment. + * @return updated comment. + */ + public Observable updateComment(String postId, String commentId, Comment comment) { + return network.updateComment(postId, commentId, comment); + } + + /** + * retrieves all comments for a post. + * @param postId id of the post for which the comments will be retrieved. + * @return comments + */ + public Observable>> retrieveCommentsForPost(String postId) { + return network.retrieveCommentsForPost(postId); + } + + /** + * Retrieve current users post feed. + * @return list of {@link Post posts}. + */ + public Observable>> retrievePostFeed() { + return network.retrievePostFeed(); + } + + /** + * Retrieve current users event feed. + * @return list of {@link Event events}. + */ + public Observable> retrieveEventFeed() { + return network.retrieveEventFeed(); + } + + /** + * Retrieve current users news feed. + * @return {@link NewsFeed news feed}. + */ + public Observable> retrieveNewsFeed() { + return network.retrieveNewsFeed(); + } + + /** + * Retrieve event feed of content centered around the current user and the current users + * content. + * @return list of {@link Event events}. + */ + public Observable>> retrieveMeFeed() { + return network.retrieveMeFeed(); + } + + private void initializeSims(Configuration configuration, Context context) { + if(sims == null) { + synchronized(RxTapglue.class) { + if(sims == null) { + sims = new TapglueSims(configuration, context); + } + } + } + } + + private static class SimsSessionTokenNotifier implements Action { + @Override + public void run() throws Exception { + sims.sessionTokenChanged(); + } + } + + private static class SimsUnregistration implements Callable { + @Override + public Void call() throws Exception { + sims.unregisterDevice(); + return null; + } + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxWrapper.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxWrapper.java new file mode 100644 index 0000000..70da3f5 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/RxWrapper.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + +import java.io.IOException; + +import io.reactivex.Observable; + +public class RxWrapper { + public T unwrap(Observable observable) throws IOException { + final Holder holder = new Holder<>(); + final Throwable[] throwable = new Throwable[1]; + + try { + holder.obj = observable.blockingFirst(); + } catch (Exception t) { + throwable[0] = t; + } + + if(throwable[0] != null) { + System.out.println(throwable[0]); + if(throwable[0] instanceof IOException) { + throw (IOException) throwable[0]; + } else if (throwable[0].getCause() instanceof IOException) { + throw (IOException) throwable[0].getCause(); + } else { + // test expected null + return null; + } + } else { + return holder.obj; + } + } + + static class Holder { + T obj; + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/Tapglue.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/Tapglue.java new file mode 100644 index 0000000..14beba0 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/Tapglue.java @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + +import android.content.Context; + +import com.tapglue.android.entities.Comment; +import com.tapglue.android.entities.Connection; +import com.tapglue.android.entities.Connection.Type; +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.Like; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; +import com.tapglue.android.http.payloads.SocialConnections; + +import java.io.IOException; +import java.util.List; + +/** + * Depending on the paradigm used all interactions with Tapglue will happen through this class or + * RxTapglue. Internally this class uses the Rx solution through a unwrapping process. + * @see RxTapglue + */ +public class Tapglue { + + private RxTapglue rxTapglue; + + /** + * + * @param configuration configuration of the tapglue instance + * @param context the context will be used for persisting session token and current user + */ + public Tapglue(Configuration configuration, Context context) throws Exception { + rxTapglue = new RxTapglue(configuration, context); + } + + /** + * Logs in user with username and password. The user is persisted and can be requested by calling + * {@link #getCurrentUser() getCurrentUser} and will be persisted until explicit log out. + * @param username username of the user to be logged in + * @param password password of the user to be logged in + * @return the {@link User user} that was logged in + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public User loginWithUsername(String username, String password) throws IOException { + return new RxWrapper().unwrap(rxTapglue.loginWithUsername(username, password)); + } + + /** + * Logs in user with email and password. The user is persisted and can be requested by calling + * {@link #getCurrentUser() getCurrentUser} and will be persisted until explicit log out. + * @param email email of the user to be logged in + * @param password password of the user to be logged in + * @return the {@link User user} that was logged in + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public User loginWithEmail(String email, String password) throws IOException { + return new RxWrapper().unwrap(rxTapglue.loginWithEmail(email, password)); + } + + /** + * Logs out user. This will delete the persisted current user. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public void logout() throws IOException { + new RxWrapper().unwrap(rxTapglue.logout()); + } + + /** + * Gets the persisted current user. Will only be available after a successful login. + * @return the current {@link User user} + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public User getCurrentUser() throws IOException { + return new RxWrapper().unwrap(rxTapglue.getCurrentUser()); + } + + /** + * Creates a user. + * @param user the user to create + * @return the created {@link com.tapglue.android.entities.User user}. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public User createUser(User user) throws IOException { + return new RxWrapper().unwrap(rxTapglue.createUser(user)); + } + + /** + * Deletes current user. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public void deleteCurrentUser() throws Exception { + new RxWrapper().unwrap(rxTapglue.deleteCurrentUser()); + } + + /** + * Updates current user + * @param updatedUser The updated user + * @return updated {@link User user}. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public User updateCurrentUser(User updatedUser) throws IOException { + return new RxWrapper().unwrap(rxTapglue.updateCurrentUser(updatedUser)); + } + + /** + * refreshses the persisted current user. After a successful call the refreshed user will be + * persisted and available at {@link #getCurrentUser() getCurrentUser} + * @return refreshed current {@link User user}. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public User refreshCurrentUser() throws IOException { + return new RxWrapper().unwrap(rxTapglue.refreshCurrentUser()); + } + + /** + * Retrieve user. + * @param id user id of the wanted user + * @return the {@link User user}. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public User retrieveUser(String id) throws IOException { + return new RxWrapper().unwrap(rxTapglue.retrieveUser(id)); + } + + /** + * @param connection {@link Connection connection} to be created + * @return the created connection + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public Connection createConnection(Connection connection) throws IOException { + return new RxWrapper().unwrap(rxTapglue.createConnection(connection)); + } + + /** + * create connections with users retrieved from other social networks + * @param connections the {@link SocialConnections connections} + * @return list of users to whom connections were created + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public List createSocialConnections(SocialConnections connections) throws IOException { + return new RxWrapper>().unwrap(rxTapglue.createSocialConnections(connections)); + } + + public void deleteConnection(String userId, Type type) throws IOException { + new RxWrapper().unwrap(rxTapglue.deleteConnection(userId, type)); + } + + /** + * @param post {@link Post post} to be created. + * @return created post. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public Post createPost(Post post) throws IOException { + return new RxWrapper().unwrap(rxTapglue.createPost(post)); + } + + /** + * @param postId id of the post to be retrieved. + * @return the retrieved post. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public Post retrievePost(String postId) throws IOException { + return new RxWrapper().unwrap(rxTapglue.retrievePost(postId)); + } + + /** + * @param id id of the post to be updated. + * @param post new post that will replace the old post. + * @return the updated post. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public Post updatePost(String id, Post post) throws IOException { + return new RxWrapper().unwrap(rxTapglue.updatePost(id, post)); + } + + /** + * @param postId id of the post to be deleted. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public void deletePost(String postId) throws IOException { + new RxWrapper().unwrap(rxTapglue.deletePost(postId)); + } + + /** + * creates a like event on a post. + * @param postId id of the post to be liked. + * @return created like event. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public Like createLike(String postId) throws IOException { + return new RxWrapper().unwrap(rxTapglue.createLike(postId)); + } + + /** + * Deletes like. + * @param postId id of the post that was liked. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public void deleteLike(String postId) throws IOException { + new RxWrapper().unwrap(rxTapglue.deleteLike(postId)); + } + + /** + * @param postId id of the post to be commented. + * @param comment {@link Comment comment} + * @return created comment. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public Comment createComment(String postId, Comment comment) throws IOException { + return new RxWrapper().unwrap(rxTapglue.createComment(postId, comment)); + } + + /** + * delete comment. + * @param postId id of the post that was commented. + * @param commentId id of the comment to be deleted. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public void deleteComment(String postId, String commentId) throws IOException { + new RxWrapper().unwrap(rxTapglue.deleteComment(postId,commentId)); + } + + /** + * Update comment. + * @param postId id of the post that was commented. + * @param commentId id of the comment to be updated. + * @param comment {@link Comment comment} to replace the old comment. + * @return updated comment. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public Comment updateComment(String postId, String commentId, Comment comment) throws IOException { + return new RxWrapper().unwrap(rxTapglue.updateComment(postId, commentId, comment)); + } + + /** + * Retrieve current users event feed. + * @return list of {@link Event events}. + * @throws IOException exceptions thrown will be IOExceptions when there are IO issues with the + * connection it self, or the subclass TapglueError when there was an API error. + * @see com.tapglue.android.http.TapglueError + */ + public List retrieveEventFeed() throws IOException { + return new RxWrapper>().unwrap(rxTapglue.retrieveEventFeed()); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/TapglueSchedulers.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/TapglueSchedulers.java new file mode 100644 index 0000000..5581c43 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/TapglueSchedulers.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + + +import io.reactivex.Scheduler; +import io.reactivex.schedulers.Schedulers; + +class TapglueSchedulers { + + private TapglueSchedulers() {} + + public static Scheduler analytics() { + return Schedulers.io(); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/EventFeedToList.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/EventFeedToList.java new file mode 100644 index 0000000..7270576 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/EventFeedToList.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import io.reactivex.functions.Function; + +public class EventFeedToList implements Function> { + @Override + public List apply(EventListFeed feed) { + if(feed == null || feed.events == null) { + return new ArrayList<>(); + } + Map users = feed.users; + Map posts = feed.posts; + for(Event event : feed.events) { + event.setUser(users.get(event.getUserId())); + event.setPost(posts.get(event.getPostId())); + } + return feed.events; + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/Network.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/Network.java new file mode 100644 index 0000000..10a33d2 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/Network.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import android.content.Context; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.tapglue.android.entities.Comment; +import com.tapglue.android.entities.Connection; +import com.tapglue.android.entities.Connection.Type; +import com.tapglue.android.entities.ConnectionList; +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.Like; +import com.tapglue.android.entities.NewsFeed; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.Reaction; +import com.tapglue.android.entities.User; +import com.tapglue.android.http.payloads.EmailLoginPayload; +import com.tapglue.android.http.payloads.EmailSearchPayload; +import com.tapglue.android.http.payloads.SocialConnections; +import com.tapglue.android.http.payloads.SocialSearchPayload; +import com.tapglue.android.http.payloads.UsernameLoginPayload; +import com.tapglue.android.internal.SessionStore; +import com.tapglue.android.internal.UUIDStore; +import com.tapglue.android.RxPage; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.Observable; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import okhttp3.MediaType; +import okhttp3.RequestBody; + +public class Network { + + TapglueService service; + PaginatedService paginatedService; + private ServiceFactory serviceFactory; + private SessionStore sessionStore; + private UUIDStore uuidStore; + + public Network(ServiceFactory serviceFactory, Context context) throws Exception { + this.serviceFactory = serviceFactory; + service = serviceFactory.createTapglueService(); + paginatedService = serviceFactory.createPaginatedService(); + sessionStore = new SessionStore(context); + uuidStore = new UUIDStore(context); + uuidStore.get().doOnNext(new UUIDConsumer()).subscribe(); + sessionStore.get().map(new SessionTokenExtractor()).subscribe(); + } + + public Observable loginWithUsername(String username, String password) { + UsernameLoginPayload payload = new UsernameLoginPayload(username, password); + return service.login(payload).map(new SessionTokenExtractor()).map(sessionStore.store()); + } + + public Observable loginWithEmail(String email, String password) { + EmailLoginPayload payload = new EmailLoginPayload(email, password); + return service.login(payload).map(new SessionTokenExtractor()).map(sessionStore.store()); + } + + public Observable logout() { + return service.logout().doOnComplete(sessionStore.clear()); + } + + public Observable createUser(User user) { + return service.createUser(user); + } + + public Observable deleteCurrentUser() { + return service.deleteCurrentUser().doOnComplete(sessionStore.clear()); + } + + public Observable updateCurrentUser(User user) { + return service.updateCurrentUser(user) + .map(new SessionTokenExtractor()).map(sessionStore.store()); + } + + public Observable retrieveUser(String id) { + return service.retrieveUser(id); + } + + public Observable refreshCurrentUser() { + return service.refreshCurrentUser() + .map(new SessionTokenExtractor()).map(sessionStore.store()); + } + + public void clearLocalSessionToken() throws Exception { + sessionStore.clear().run(); + } + + public Observable>> retrieveFollowings() { + return service.retrieveFollowings() + .map(new RxPageCreator>(this, new UsersFeed())); + } + + public Observable>> retrieveFollowers() { + return service.retrieveFollowers() + .map(new RxPageCreator>(this, new UsersFeed())); + } + + public Observable>> retrieveUserFollowings(String userId) { + return service.retrieveUserFollowings(userId) + .map(new RxPageCreator>(this, new UsersFeed())); + } + + public Observable>> retrieveUserFollowers(String userId) { + return service.retrieveUserFollowers(userId) + .map(new RxPageCreator>(this, new UsersFeed())); + } + + public Observable>> retrieveFriends() { + return paginatedService.retrieveFriends() + .map(new RxPageCreator>(this, new UsersFeed())); + } + + public Observable>> retrieveUserFriends(String userId) { + return paginatedService.retrieveUserFriends(userId) + .map(new RxPageCreator>(this, new UsersFeed())); + } + + public Observable createConnection(Connection connection) { + return service.createConnection(connection); + } + + public Observable> createSocialConnections(SocialConnections connections) { + return service.createSocialConnections(connections).map(new UsersExtractor()); + } + + public Observable deleteConnection(String userId, Type type) { + return service.deleteConnection(userId, type); + } + + public Observable>> searchUsers(String searchTerm) { + return paginatedService.searchUsers(searchTerm) + .map(new RxPageCreator>(this, new UsersFeed())); + } + + public Observable>> searchUsersByEmail(List emails) { + Gson g = new Gson(); + String payload = g.toJson(new EmailSearchPayload(emails)); + return paginatedService.searchUsersByEmail(new EmailSearchPayload(emails)) + .map(new RxPageCreator>(this, new UsersFeed(), payload)); + } + + public Observable>> searchUsersBySocialIds(String platform, List socialIds) { + Gson g = new Gson(); + String payload = g.toJson(new SocialSearchPayload(socialIds)); + return paginatedService + .searchUsersBySocialIds(platform, new SocialSearchPayload(socialIds)) + .map(new RxPageCreator>(this, new UsersFeed(),payload)); + } + + public Observable> retrievePendingConnections() { + return paginatedService.retrievePendingConnections() + .map(new RxPageCreator(this, new ConnectionsFeed())); + } + + public Observable> retrieveRejectedConnections() { + return paginatedService.retrieveRejectedConnections() + .map(new RxPageCreator(this, new ConnectionsFeed())); + } + + public Observable createPost(Post post) { + return service.createPost(post); + } + + public Observable retrievePost(String id) { + return service.retrievePost(id); + } + + public Observable updatePost(String id, Post post) { + return service.updatePost(id, post); + } + + public Observable deletePost(String id) { + return service.deletePost(id); + } + + public Observable>> retrievePosts() { + return paginatedService.retrievePosts().map(new RxPageCreator>(this, new PostListFeed())); + } + + public Observable>> retrievePostsByUser(String id) { + return paginatedService.retrievePostsByUser(id).map(new RxPageCreator>(this, new PostListFeed())); + } + + public Observable createLike(String id) { + return service.createLike(id); + } + + public Observable deleteLike(String id) { + return service.deleteLike(id); + } + + public Observable>> retrieveLikesForPost(String id) { + return paginatedService.retrieveLikesForPost(id).map(new RxPageCreator>(this, new LikesFeed())); + } + + public Observable>> retrieveLikesByUser(String userId) { + return paginatedService.retrieveLikesByUser(userId).map(new RxPageCreator>(this, new LikesFeed())); + } + + public Observable createReaction(String postId, Reaction reaction) { + return service.createReaction(postId, reaction); + } + + public Observable deleteReaction(String postId, Reaction reaction) { + return service.deleteReaction(postId, reaction); + } + + public Observable createComment(String postId, Comment comment) { + return service.createComment(postId, comment); + } + + public Observable deleteComment(String postId, String commentId) { + return service.deleteComment(postId, commentId); + } + + public Observable updateComment(String postId, String commentId, Comment comment) { + return service.updateComment(postId, commentId, comment); + } + + public Observable sendAnalytics() { + return service.sendAnalytics(); + } + + public Observable>> retrieveCommentsForPost(String postId) { + return paginatedService.retrieveCommentsForPost(postId) + .map(new RxPageCreator>(this, new CommentsFeed())); + } + + public Observable>> retrievePostFeed() { + return paginatedService.retrievePostFeed().map(new RxPageCreator>(this, new PostListFeed())); + } + + public Observable> retrieveEventFeed() { + return service.retrieveEventFeed().map(new EventFeedToList()); + } + + public Observable> retrieveNewsFeed() { + return paginatedService.retrieveNewsFeed().map(new RxPageCreator(this, new RawNewsFeed())); + } + + public Observable>> retrieveMeFeed() { + return paginatedService.retrieveMeFeed().map(new RxPageCreator>(this, new EventListFeed())); + } + + public Observable paginatedGet(String pointer) { + return service.paginatedGet(pointer); + } + + public Observable paginatedPost(String pointer, RequestBody payload) { + return service.paginatedPost(pointer, payload); + } + + private class SessionTokenExtractor implements Function { + + @Override + public User apply(User user) { + serviceFactory.setSessionToken(user.getSessionToken()); + service = serviceFactory.createTapglueService(); + paginatedService = serviceFactory.createPaginatedService(); + return user; + } + } + + private class UsersExtractor implements Function> { + @Override + public List apply(UsersFeed feed) { + if(feed == null || feed.getUsers() == null) { + return new ArrayList<>(); + } + return feed.getUsers(); + } + } + + private class UUIDConsumer implements Consumer { + + @Override + public void accept(String uuid) { + serviceFactory.setUserUUID(uuid); + service = serviceFactory.createTapglueService(); + paginatedService = serviceFactory.createPaginatedService(); + } + } + + private static class RxPageCreator implements Function, RxPage> { + private final FlattenableFeed defaultFeed; + private final Network network; + private String payload; + + RxPageCreator(Network network, FlattenableFeed defaultFeed) { + this.network = network; + this.defaultFeed = defaultFeed; + } + + RxPageCreator(Network network, FlattenableFeed defaultFeed, String payload) { + this.network = network; + this.payload = payload; + this.defaultFeed = defaultFeed; + } + + @Override + public RxPage apply(FlattenableFeed feed) { + FlattenableFeed returnFeed; + if(feed == null) { + returnFeed = defaultFeed; + } else { + returnFeed = feed; + } + if(payload == null) { + return new RxPage<>(returnFeed, network); + } else { + RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=UTF-8"), payload); + return new RxPage<>(returnFeed, network, body); + } + } + } + +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/PaginatedService.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/PaginatedService.java new file mode 100644 index 0000000..aad0805 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/PaginatedService.java @@ -0,0 +1,67 @@ +package com.tapglue.android.http; + +import com.tapglue.android.http.CommentsFeed; +import com.tapglue.android.http.ConnectionsFeed; +import com.tapglue.android.http.EventListFeed; +import com.tapglue.android.http.LikesFeed; +import com.tapglue.android.http.PostListFeed; +import com.tapglue.android.http.RawNewsFeed; +import com.tapglue.android.http.UsersFeed; +import com.tapglue.android.http.payloads.EmailSearchPayload; +import com.tapglue.android.http.payloads.SocialSearchPayload; + +import retrofit2.http.Body; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.Path; +import retrofit2.http.Query; +import io.reactivex.Observable; + +interface PaginatedService { + + @GET("/0.4/users/{id}/likes") + Observable retrieveLikesByUser(@Path("id") String userId); + + @GET("/0.4/me/feed") + Observable retrieveNewsFeed(); + + @GET("/0.4/users/search") + Observable searchUsers(@Query("q") String searchTerm); + + @POST("/0.4/users/search/emails") + Observable searchUsersByEmail(@Body EmailSearchPayload payload); + + @POST("/0.4/users/search/{platform}") + Observable searchUsersBySocialIds(@Path("platform") String platform, + @Body SocialSearchPayload payload); + + @GET("/0.4/me/friends") + Observable retrieveFriends(); + + @GET("/0.4/users/{id}/friends") + Observable retrieveUserFriends(@Path("id") String id); + + @GET("/0.4/me/connections/pending") + Observable retrievePendingConnections(); + + @GET("/0.4/me/connections/rejected") + Observable retrieveRejectedConnections(); + + @GET("/0.4/posts/{id}/comments") + Observable retrieveCommentsForPost(@Path("id") String postId); + + @GET("/0.4/posts/{id}/likes") + Observable retrieveLikesForPost(@Path("id") String postId); + + @GET("/0.4/posts") + Observable retrievePosts(); + + @GET("/0.4/users/{id}/posts") + Observable retrievePostsByUser(@Path("id") String id); + + @GET("/0.4/me/feed/posts") + Observable retrievePostFeed(); + + @GET("/0.4/me/feed/notifications/self") + Observable retrieveMeFeed(); +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/PostFeedToList.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/PostFeedToList.java new file mode 100644 index 0000000..08ebddd --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/PostFeedToList.java @@ -0,0 +1,26 @@ +package com.tapglue.android.http; + +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import io.reactivex.functions.Function; + +class PostFeedToList implements Function> { + + @Override + public List apply(PostListFeed feed) { + if(feed == null || feed.posts == null) { + return new ArrayList<>(); + } + List posts = feed.posts; + Map users = feed.users; + for(Post post: posts) { + post.setUser(users.get(post.getUserId())); + } + return posts; + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/RawNewsFeed.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/RawNewsFeed.java new file mode 100644 index 0000000..4090642 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/RawNewsFeed.java @@ -0,0 +1,51 @@ +package com.tapglue.android.http; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.NewsFeed; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class RawNewsFeed extends FlattenableFeed { + List events; + List posts; + Map users; + @SerializedName("post_map") + Map postMap; + + @Override + public NewsFeed flatten() { + EventListFeed eventFeed = new EventListFeed(); + eventFeed.events = events; + eventFeed.users = users; + eventFeed.posts = postMap; + List events = new EventFeedToList().apply(eventFeed); + + PostListFeed postFeed = new PostListFeed(); + postFeed.posts = posts; + postFeed.users = users; + List posts = new PostFeedToList().apply(postFeed); + return new NewsFeed(events, posts); + } + + @Override + FlattenableFeed constructDefaultFeed() { + RawNewsFeed feed = new RawNewsFeed(); + feed.events = new ArrayList<>(); + feed.posts = new ArrayList<>(); + return feed; + } + + @Override + FlattenableFeed parseJson(JsonObject jsonObject) { + Gson g = new Gson(); + RawNewsFeed feed = g.fromJson(jsonObject, RawNewsFeed.class); + return feed; + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/ServiceFactory.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/ServiceFactory.java new file mode 100644 index 0000000..370c824 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/ServiceFactory.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import com.tapglue.android.Configuration; + +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +public class ServiceFactory { + String sessionToken = ""; + Configuration configuration; + String userUUID = ""; + + public ServiceFactory(Configuration configuration) { + this.configuration = configuration; + } + + public TapglueService createTapglueService() { + OkHttpClient client = ClientFactory.createClient(configuration, sessionToken, userUUID); + + Retrofit retrofit = buildRetrofit(client); + return retrofit.create(TapglueService.class); + } + + public PaginatedService createPaginatedService() { + OkHttpClient client = ClientFactory + .createPaginatedClient(configuration, sessionToken, userUUID); + + Retrofit retrofit = buildRetrofit(client); + return retrofit.create(PaginatedService.class); + } + + private Retrofit buildRetrofit(OkHttpClient client) { + return new Retrofit.Builder().client(client) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) + .baseUrl(configuration.getBaseUrl()).build(); + } + + public void setSessionToken(String token) { + this.sessionToken = token; + } + + public void setUserUUID(String userUUID) { + this.userUUID = userUUID; + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/TapglueService.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/TapglueService.java new file mode 100644 index 0000000..36cdd18 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/http/TapglueService.java @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import com.google.gson.JsonObject; +import com.tapglue.android.entities.Comment; +import com.tapglue.android.entities.Connection; +import com.tapglue.android.entities.Connection.Type; +import com.tapglue.android.entities.Like; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.Reaction; +import com.tapglue.android.entities.User; +import com.tapglue.android.http.EventListFeed; +import com.tapglue.android.http.PostListFeed; +import com.tapglue.android.http.UsersFeed; +import com.tapglue.android.http.payloads.EmailLoginPayload; +import com.tapglue.android.http.payloads.SocialConnections; +import com.tapglue.android.http.payloads.UsernameLoginPayload; + +import io.reactivex.Observable; +import okhttp3.RequestBody; +import retrofit2.http.Body; +import retrofit2.http.DELETE; +import retrofit2.http.GET; +import retrofit2.http.POST; +import retrofit2.http.PUT; +import retrofit2.http.Path; +import retrofit2.http.Url; + +interface TapglueService { + @POST("/0.4/me/login") + Observable login(@Body UsernameLoginPayload payload); + + @POST("/0.4/me/login") + Observable login(@Body EmailLoginPayload payload); + + @DELETE("/0.4/me/logout") + Observable logout(); + + @POST("/0.4/analytics") + Observable sendAnalytics(); + + @POST("/0.4/users") + Observable createUser(@Body User user); + + @DELETE("/0.4/me") + Observable deleteCurrentUser(); + + @PUT("/0.4/me") + Observable updateCurrentUser(@Body User user); + + @GET("/0.4/me") + Observable refreshCurrentUser(); + + @GET("/0.4/users/{userId}") + Observable retrieveUser(@Path("userId") String id); + + @GET("/0.4/me/follows") + Observable retrieveFollowings(); + + @GET("/0.4/me/followers") + Observable retrieveFollowers(); + + @GET("/0.4/users/{id}/follows") + Observable retrieveUserFollowings(@Path("id") String id); + + @GET("/0.4/users/{id}/followers") + Observable retrieveUserFollowers(@Path("id") String id); + + @PUT("/0.4/me/connections") + Observable createConnection(@Body Connection connection); + + @POST("/0.4/me/connections/social") + Observable createSocialConnections(@Body SocialConnections connections); + + @DELETE("/0.4/me/connections/{type}/{id}") + Observable deleteConnection(@Path("id") String userId, + @Path("type") Type type); + + @POST("/0.4/posts") + Observable createPost(@Body Post post); + + @GET("/0.4/posts/{id}") + Observable retrievePost(@Path("id") String id); + + @PUT("/0.4/posts/{id}") + Observable updatePost(@Path("id") String id, @Body Post post); + + @DELETE("/0.4/posts/{id}") + Observable deletePost(@Path("id") String id); + + @POST("/0.4/posts/{id}/likes") + Observable createLike(@Path("id") String postId); + + @DELETE("/0.4/posts/{id}/likes") + Observable deleteLike(@Path("id") String postId); + + @POST("/0.4/posts/{id}/reactions/{reaction}") + Observable createReaction(@Path("id") String postId, + @Path("reaction") Reaction reaction); + + @DELETE("/0.4/posts/{id}/reactions/{reaction}") + Observable deleteReaction(@Path("id") String postId, + @Path("reaction") Reaction reaction); + + @POST("/0.4/posts/{id}/comments") + Observable createComment(@Path("id") String postId, + @Body Comment comment); + + @DELETE("/0.4/posts/{postId}/comments/{commentId}") + Observable deleteComment(@Path("postId") String postId, + @Path("commentId") String commentId); + + @PUT("/0.4/posts/{postId}/comments/{commentId}") + Observable updateComment(@Path("postId") String postId, + @Path("commentId") String commentId, + @Body Comment comment); + + @GET("/0.4/me/feed/posts") + Observable retrievePostFeed(); + + @GET("/0.4/me/feed/events") + Observable retrieveEventFeed(); + + @GET + Observable paginatedGet(@Url String pointer); + + @POST + Observable paginatedPost(@Url String pointer, @Body RequestBody payload); +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/NotificationServiceIdStore.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/NotificationServiceIdStore.java new file mode 100644 index 0000000..371958e --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/NotificationServiceIdStore.java @@ -0,0 +1,24 @@ +package com.tapglue.android.internal; + +import android.content.Context; +import android.content.SharedPreferences; + +import io.reactivex.Observable; + +public class NotificationServiceIdStore { + private static final String NOTIFICATION_ID = "notificationServiceId"; + Store store; + + public NotificationServiceIdStore(Context context) { + SharedPreferences prefs = context.getSharedPreferences(NOTIFICATION_ID, Context.MODE_PRIVATE); + store = new Store<>(prefs, String.class); + } + + public void store(String id) throws Exception { + store.store().apply(id); + } + + public Observable get() { + return store.get(); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/SessionStore.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/SessionStore.java new file mode 100644 index 0000000..93355b9 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/SessionStore.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.tapglue.android.entities.User; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Function; + +public class SessionStore { + + Store store; + + public SessionStore(Context context) { + SharedPreferences prefs = context.getSharedPreferences("sessionToken", Context.MODE_PRIVATE); + store = new Store<>(prefs, User.class); + } + + public Observable get() { + return store.get(); + } + + public Function store() { + return store.store(); + } + + public Action clear() { + return store.clear(); + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/Store.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/Store.java new file mode 100644 index 0000000..3ae330a --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/Store.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; + +import com.google.gson.Gson; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Function; + + +public class Store { + private static final String TAG = "object"; + SharedPreferences prefs; + Class cls; + T obj; + + Store(SharedPreferences prefs, Class cls) { + this.prefs = prefs; + this.cls = cls; + } + + Function store() { + final Store store = this; + return new Function() { + @Override + public T apply(T obj) { + store.setObject(obj); + String objJson = new Gson().toJson(obj); + Editor editor = store.prefs.edit(); + editor.putString(TAG, objJson); + editor.apply(); + return obj; + } + }; + } + + Observable get() { + if(obj == null) { + String objJson = prefs.getString(TAG, null); + obj = new Gson().fromJson(objJson, cls); + } + return obj == null ? Observable.empty():Observable.just(obj); + } + + Action clear() { + return new Action() { + @Override + public void run() { + obj = null; + Editor editor = prefs.edit(); + editor.clear(); + editor.apply(); + } + }; + } + + boolean isEmpty() { + String objJson = prefs.getString(TAG, null); + obj = new Gson().fromJson(objJson, cls); + return obj == null; + } + + private void setObject(T obj) { + this.obj = obj; + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/UUIDStore.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/UUIDStore.java new file mode 100644 index 0000000..33bba4b --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/UUIDStore.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.Context; + +import java.util.UUID; + +import io.reactivex.Observable; + + +public class UUIDStore { + private static final String UUID_TAG = "uuid"; + Store store; + + public UUIDStore(Context context) { + store = new Store<>(context.getSharedPreferences(UUID_TAG, Context.MODE_PRIVATE), String.class); + } + + public Observable get() throws Exception { + if(store.isEmpty()) { + return generateUUIDAndStore(); + } + return store.get(); + } + + private Observable generateUUIDAndStore() throws Exception { + String uuid = UUID.randomUUID().toString(); + store.store().apply(uuid); + + return store.get(); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/UserStore.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/UserStore.java new file mode 100644 index 0000000..335186d --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/internal/UserStore.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.tapglue.android.entities.User; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Function; + + +public class UserStore { + + private static final String USER_TAG = "user"; + + Store store; + + public UserStore(Context context) { + SharedPreferences prefs = context.getSharedPreferences(USER_TAG, Context.MODE_PRIVATE); + store = new Store(prefs, User.class); + } + + public Function store() { + return store.store(); + } + + public Observable get() { + return store.get(); + } + + public Action clear() { + return store.clear(); + } + + public boolean isEmpty() { + return store.isEmpty(); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/SimsService.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/SimsService.java new file mode 100644 index 0000000..c1d0cb6 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/SimsService.java @@ -0,0 +1,15 @@ +package com.tapglue.android.sims; + +import io.reactivex.Observable; +import retrofit2.http.Body; +import retrofit2.http.DELETE; +import retrofit2.http.PUT; +import retrofit2.http.Path; + +public interface SimsService { + @PUT("/0.4/me/devices/{deviceId}") + Observable registerDevice(@Path("deviceId") String deviceUUID, @Body DevicePayload payload); + + @DELETE("/0.4/me/devices/{deviceId}") + Observable deleteDevice(@Path("deviceId") String deviceUUID); +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/SimsServiceFactory.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/SimsServiceFactory.java new file mode 100644 index 0000000..5f58472 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/SimsServiceFactory.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.sims; + +import com.tapglue.android.Configuration; +import com.tapglue.android.http.ClientFactory; + +import okhttp3.OkHttpClient; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +public class SimsServiceFactory { + String sessionToken = ""; + Configuration configuration; + String userUUID = ""; + + public SimsServiceFactory(Configuration configuration) { + this.configuration = configuration; + } + + public SimsService createService() { + OkHttpClient client = ClientFactory.createClient(configuration, sessionToken, userUUID); + + Retrofit retrofit = new Retrofit.Builder().client(client) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) + .addConverterFactory(GsonConverterFactory.create()) + .baseUrl(configuration.getBaseUrl()).build(); + return retrofit.create(SimsService.class); + } + + public void setSessionToken(String token) { + this.sessionToken = token; + } + + public void setUserUUID(String userUUID) { + this.userUUID = userUUID; + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/TapglueSims.java b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/TapglueSims.java new file mode 100644 index 0000000..fad66ac --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/java/com/tapglue/android/sims/TapglueSims.java @@ -0,0 +1,159 @@ +package com.tapglue.android.sims; + +import android.content.Context; + +import com.tapglue.android.Configuration; +import com.tapglue.android.entities.User; +import com.tapglue.android.internal.NotificationServiceIdStore; +import com.tapglue.android.internal.SessionStore; +import com.tapglue.android.internal.UUIDStore; + +import java.util.Locale; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.Observer; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; +import io.reactivex.functions.Function3; +import io.reactivex.schedulers.Schedulers; + + +public class TapglueSims implements NotificationServiceIdListener { + + private static AtomicBoolean isRegistered = new AtomicBoolean(false); + + NotificationServiceIdStore notificationIdStore; + SessionStore sessionStore; + UUIDStore uuidStore; + final Configuration configuration; + final Locale locale; + + public TapglueSims(Configuration configuration, Context context) { + this.configuration = configuration; + notificationIdStore = new NotificationServiceIdStore(context); + sessionStore = new SessionStore(context); + uuidStore = new UUIDStore(context); + locale = context.getResources().getConfiguration().locale; + SimsIdListenerService.setListener(this); + } + + @Override + public void idChanged(String id) { + try { + notificationIdStore.store(id); + registerDeviceForSims(); + } catch (Exception e) { + // TODO handle error + } + } + + public void sessionTokenChanged() throws Exception{ + registerDeviceForSims(); + } + + public void unregisterDevice() throws Exception { + if(!isRegistered.get()) { + return; + } + Observable parameterGathering = Observable.combineLatest(notificationIdStore.get(), sessionStore.get(), uuidStore.get(), new Function3() { + @Override + public DeviceRegistrationParams apply(String notificationId, User session, String uuid) { + DeviceRegistrationParams params = new DeviceRegistrationParams(); + params.uuid = uuid; + params.session = session; + return params; + } + }); + + parameterGathering.flatMap(new Function>() { + @Override + public Observable apply(DeviceRegistrationParams params) { + SimsServiceFactory serviceFactory = new SimsServiceFactory(configuration); + serviceFactory.setSessionToken(params.session.getSessionToken()); + serviceFactory.setUserUUID(params.uuid); + SimsService service = serviceFactory.createService(); + return service.deleteDevice(params.uuid); + } + }).subscribeOn(Schedulers.io()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(Void aVoid) { + isRegistered.set(false); + } + + @Override + public void onError(Throwable e) { + sessionStore.clear(); + } + + @Override + public void onComplete() { + sessionStore.clear(); + } + }); + } + + private void registerDeviceForSims() throws Exception { + if(isRegistered.get()) { + return; + } + Observable parameterGathering = Observable.combineLatest(notificationIdStore.get(), sessionStore.get(), uuidStore.get(), new Function3() { + @Override + public DeviceRegistrationParams apply(String notificationId, User session, String uuid) { + DevicePayload payload = new DevicePayload(); + payload.token = notificationId; + payload.language = locale.toString(); + DeviceRegistrationParams params = new DeviceRegistrationParams(); + params.payload = payload; + params.uuid = uuid; + params.session = session; + return params; + } + }); + + parameterGathering.flatMap(new Function>() { + + @Override + public Observable apply(DeviceRegistrationParams params) { + SimsServiceFactory serviceFactory = new SimsServiceFactory(configuration); + serviceFactory.setSessionToken(params.session.getSessionToken()); + serviceFactory.setUserUUID(params.uuid); + SimsService service = serviceFactory.createService(); + return service.registerDevice(params.uuid, params.payload); + } + }).subscribeOn(Schedulers.io()).subscribe(new Observer() { + @Override + public void onComplete() { + + } + + @Override + public void onError(Throwable e) { + + } + + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(Void aVoid) { + isRegistered.set(true); + } + }); + } + + private static class DeviceRegistrationParams { + String uuid; + DevicePayload payload; + User session; + } +} diff --git a/tapglue-android-sdk-rxjava2/src/main/res/values/strings.xml b/tapglue-android-sdk-rxjava2/src/main/res/values/strings.xml new file mode 100644 index 0000000..6f2fffd --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + tapglue-android-sdk-rxjava2 + diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/RxJava2TapglueTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/RxJava2TapglueTest.java new file mode 100644 index 0000000..4495bf1 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/RxJava2TapglueTest.java @@ -0,0 +1,424 @@ +/** + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; + +import com.tapglue.android.entities.Comment; +import com.tapglue.android.entities.Connection; +import com.tapglue.android.entities.Connection.Type; +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.Like; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; +import com.tapglue.android.http.Network; +import com.tapglue.android.http.payloads.SocialConnections; +import com.tapglue.android.internal.UserStore; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; + +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Function; +import io.reactivex.observers.TestObserver; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({RxTapglue.class, TapglueSchedulers.class}) +public class RxJava2TapglueTest { + private static final String TOKEN = "sampleToken"; + private static final String BASE_URL = "https://api.tapglue.com"; + private static final String USERNAME = "username"; + private static final String EMAIL = "user@domain.com"; + private static final String PASSWORD = "password"; + + @Mock + Configuration configuration; + @Mock + Context context; + @Mock + SharedPreferences prefs; + @Mock + Network network; + @Mock + UserStore currentUser; + @Mock + Exception e; + @Mock + Action clearAction; + @Mock + AtomicBoolean firstInstance; + @Mock + Resources resources; + + + @Mock + User user; + @Mock + List users; + + @Mock + RxPage> userPage; + + //SUT + RxTapglue tapglue; + + @Before + public void setUp() throws Exception{ + whenNew(Network.class).withAnyArguments().thenReturn(network); + whenNew(UserStore.class).withArguments(context).thenReturn(currentUser); + Whitebox.setInternalState(RxTapglue.class, firstInstance); + + when(firstInstance.compareAndSet(true, false)).thenReturn(true); + when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(prefs); + when(context.getResources()).thenReturn(resources); + when(resources.getConfiguration()).thenReturn(mock(android.content.res.Configuration.class)); + when(currentUser.clear()).thenReturn(clearAction); + when(network.sendAnalytics()).thenReturn(Observable.empty()); + when(network.loginWithEmail(EMAIL, PASSWORD)).thenReturn(Observable.just(user)); + when(network.loginWithUsername(USERNAME, PASSWORD)).thenReturn(Observable.just(user)); + when(currentUser.store()).thenReturn(new Function() { + @Override + public User apply(User user) { + return user; + } + }); + when(configuration.getToken()).thenReturn(TOKEN); + when(configuration.getBaseUrl()).thenReturn(BASE_URL); + tapglue = new RxTapglue(configuration, context); + } + + @Test + public void loginWithUserNameCallsNetwork() { + TestObserver to = tapglue.loginWithUsername(USERNAME, PASSWORD).test(); + + to.assertValue(user); + } + + @Test + public void loginWithEmailCallsNetwork() { + TestObserver to = tapglue.loginWithEmail(EMAIL, PASSWORD).test(); + + to.assertValue(user); + } + + @Test + public void loginUserWithUsernameStoresCurrentUser() { + tapglue.loginWithUsername(USERNAME, PASSWORD).test(); + + verify(currentUser).store(); + } + + @Test + public void loginUserWithEmailStoresCurrentUser() { + tapglue.loginWithEmail(EMAIL, PASSWORD).test(); + + verify(currentUser).store(); + } + + @Test + public void logoutCallsNetwork() { + when(network.logout()).thenReturn(Observable.empty()); + TestObserver to = tapglue.logout().test(); + + to.assertComplete(); + to.assertNoErrors(); + } + + @Test + public void logoutClearsUserStoreOnSuccess() throws Exception { + when(network.logout()).thenReturn(Observable.empty()); + tapglue.logout().test(); + + verify(clearAction).run(); + } + + @Test + public void logoutDoesntClearsUserStoreOnError() throws Exception { + when(currentUser.clear()).thenReturn(clearAction); + when(network.logout()).thenReturn(Observable.error(e)); + + tapglue.logout().test(); + + verify(clearAction, never()).run(); + } + + + @Test + public void getCurrentUserGetsFromStore() { + when(currentUser.get()).thenReturn(Observable.just(user)); + TestObserver to = tapglue.getCurrentUser().test(); + + to.assertValue(user); + } + + @Test + public void createUserCallsNetwork() { + when(network.createUser(user)).thenReturn(Observable.just(user)); + TestObserver to = tapglue.createUser(user).test(); + + to.assertValue(user); + } + + @Test + public void deleteUserCallsNetwork() throws Exception { + when(network.deleteCurrentUser()).thenReturn(Observable.empty()); + TestObserver to = tapglue.deleteCurrentUser().test(); + + to.assertComplete(); + to.assertNoErrors(); + } + + @Test + public void deleteCurrentUserClearsUserStoreOnSuccess() throws Exception { + when(network.deleteCurrentUser()).thenReturn(Observable.empty()); + tapglue.deleteCurrentUser().test(); + + verify(clearAction).run(); + } + + @Test + public void deleteCurrentUserDoesntClearsUserStoreOnError() throws Exception { + when(currentUser.clear()).thenReturn(clearAction); + when(network.deleteCurrentUser()).thenReturn(Observable.error(e)); + tapglue.deleteCurrentUser().test(); + + verify(clearAction, never()).run(); + } + + @Test + public void updateCurrentUserCallsNetwork() { + when(network.updateCurrentUser(user)).thenReturn(Observable.just(user)); + TestObserver to = tapglue.updateCurrentUser(user).test(); + + to.assertValue(user); + } + + @Test + public void updateCurrentUserUpdatesCurrentUser() { + when(network.updateCurrentUser(user)).thenReturn(Observable.just(user)); + tapglue.updateCurrentUser(user).test(); + + verify(currentUser).store(); + } + + @Test + public void refreshCurrentUserCallsNetwork() { + when(network.refreshCurrentUser()).thenReturn(Observable.just(user)); + TestObserver to = tapglue.refreshCurrentUser().test(); + + to.assertValue(user); + } + + @Test + public void refreshCurrentUserUpdatesCurrentUser() { + when(network.refreshCurrentUser()).thenReturn(Observable.just(user)); + tapglue.refreshCurrentUser().test(); + + verify(currentUser).store(); + } + + @Test + public void retrieveUserCallsNetwork() { + String id = "someId"; + when(network.retrieveUser(id)).thenReturn(Observable.just(user)); + TestObserver to = tapglue.retrieveUser(id).test(); + + to.assertValue(user); + } + + @Test + public void retrieveFollowingsCallsNetwork() { + when(network.retrieveFollowings()).thenReturn(Observable.just(userPage)); + TestObserver>> to = tapglue.retrieveFollowings().test(); + + to.assertValue(userPage); + } + + @Test + public void retrieveFollowersCallsNetwork() { + when(network.retrieveFollowers()).thenReturn(Observable.just(userPage)); + TestObserver>> to = tapglue.retrieveFollowers().test(); + + to.assertValue(userPage); + } + + @Test + public void retrieveUserFollowingsCallsNetwork() { + String id = "userId"; + when(network.retrieveUserFollowings(id)).thenReturn(Observable.just(userPage)); + TestObserver>> to = tapglue.retrieveUserFollowings(id).test(); + + to.assertValue(userPage); + } + + @Test + public void retrieveUserFollowersCallsNetwork() { + String id = "userId"; + when(network.retrieveUserFollowers(id)).thenReturn(Observable.just(userPage)); + TestObserver>> to = tapglue.retrieveUserFollowers(id).test(); + + to.assertValue(userPage); + } + + @Test + public void createConnectionCallsNetwork() { + Connection connection = mock(Connection.class); + when(network.createConnection(connection)).thenReturn(Observable.just(connection)); + TestObserver to = tapglue.createConnection(connection).test(); + + to.assertValue(connection); + } + + @Test + public void createSocialConnectionsCallsNetwork() { + SocialConnections connections = mock(SocialConnections.class); + when(network.createSocialConnections(connections)).thenReturn(Observable.just(users)); + TestObserver> to = tapglue.createSocialConnections(connections).test(); + + to.assertValue(users); + } + + @Test + public void deleteConnectionCallsNetwork() { + String id = "userId"; + Type type = Type.FOLLOW; + when(network.deleteConnection(id, type)).thenReturn(Observable.empty()); + TestObserver to = tapglue.deleteConnection(id, type).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void createPostCallsNetwork() { + Post post = mock(Post.class); + when(network.createPost(post)).thenReturn(Observable.just(post)); + TestObserver to = tapglue.createPost(post).test(); + + to.assertValue(post); + } + + @Test + public void retrievePostCallsNetwork() { + Post post = mock(Post.class); + String id = "id"; + when(network.retrievePost(id)).thenReturn(Observable.just(post)); + TestObserver to = tapglue.retrievePost(id).test(); + + to.assertValue(post); + } + + @Test + public void updatePostCallsNetwork() { + Post post = mock(Post.class); + String id = "id"; + when(network.updatePost(id, post)).thenReturn(Observable.just(post)); + TestObserver to = tapglue.updatePost(id, post).test(); + + to.assertValue(post); + } + + @Test + public void deletePostCallsNetwork() { + String id = "id24"; + when(network.deletePost(id)).thenReturn(Observable.empty()); + TestObserver to = tapglue.deletePost(id).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void createLikeCallsNetwork() { + String id = "postId"; + Like like = mock(Like.class); + when(network.createLike(id)).thenReturn(Observable.just(like)); + TestObserver to = tapglue.createLike(id).test(); + + to.assertValue(like); + } + + @Test + public void deleteLikeCallsNetwork() { + String id = "postId"; + when(network.deleteLike(id)).thenReturn(Observable.empty()); + TestObserver to = tapglue.deleteLike(id).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void createCommentCallsNetwork() { + String id = "postId"; + Comment comment = mock(Comment.class); + when(network.createComment(id, comment)).thenReturn(Observable.just(comment)); + TestObserver to = tapglue.createComment(id, comment).test(); + + to.assertValue(comment); + } + + @Test + public void deleteCommentCallsNetwork() { + String postId = "postId"; + String commentId = "commentId"; + when(network.deleteComment(postId, commentId)).thenReturn(Observable.empty()); + TestObserver to = tapglue.deleteComment(postId, commentId).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void updateCommentCallsNetwork() { + String postId = "postId"; + String commentId = "commentID"; + Comment comment = mock(Comment.class); + when(network.updateComment(postId, commentId, comment)).thenReturn(Observable.just(comment)); + TestObserver to = tapglue.updateComment(postId, commentId, comment).test(); + + to.assertValue(comment); + } + + @Test + public void retrieveEventFeedCallsNetwork() { + List events = mock(List.class); + when(network.retrieveEventFeed()).thenReturn(Observable.just(events)); + TestObserver> to = tapglue.retrieveEventFeed().test(); + + to.assertValue(events); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/RxWrapperTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/RxWrapperTest.java new file mode 100644 index 0000000..0e78bd5 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/RxWrapperTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + +import com.tapglue.android.internal.TestEntity; + +import org.junit.Test; + +import java.io.IOException; + +import io.reactivex.Observable; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.hamcrest.core.IsNull.nullValue; + +public class RxWrapperTest { + + RxWrapper wrapper = new RxWrapper<>(); + + @Test + public void unwrapsObservable() throws IOException { + TestEntity entity = new TestEntity(10); + + assertThat(wrapper.unwrap(Observable.just(entity)), equalTo(entity)); + } + + @Test (expected = IOException.class) + public void throwsExceptionOnError() throws IOException { + wrapper.unwrap(Observable.error(new IOException())); + } + + @Test + public void emptyObservableReturnsNull() throws IOException { + TestEntity entity = wrapper.unwrap(Observable.empty()); + + assertThat(entity, nullValue()); + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/TapglueSchedulersTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/TapglueSchedulersTest.java new file mode 100644 index 0000000..6ead740 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/TapglueSchedulersTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + +import org.junit.Test; + +import io.reactivex.Scheduler; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; + +public class TapglueSchedulersTest { + + @Test + public void analyticsReturnsScheduler() { + assertThat(TapglueSchedulers.analytics(), instanceOf(Scheduler.class)); + } + +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/TapglueTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/TapglueTest.java new file mode 100644 index 0000000..51a5bca --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/TapglueTest.java @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android; + +import android.content.Context; + +import com.tapglue.android.entities.Comment; +import com.tapglue.android.entities.Connection; +import com.tapglue.android.entities.Connection.Type; +import com.tapglue.android.entities.ConnectionList; +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.Like; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; +import com.tapglue.android.http.payloads.SocialConnections; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.List; + +import io.reactivex.Observable; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Tapglue.class) +public class TapglueTest { + + private static final String USERNAME = "username"; + private static final String EMAIL = "user@domain.com"; + private static final String PASSWORD = "password"; + + @Mock + User user; + @Mock + Configuration configuration; + @Mock + Context context; + @Mock + RxTapglue rxTapglue; + @Mock + Observable voidObservable; + @Mock + Connection connection; + @Mock + ConnectionList connectionList; + @Mock + SocialConnections socialConnections; + + @Mock + RxWrapper voidWrapper; + @Mock + List userList; + + //SUT + Tapglue tapglue; + + @Before + public void setUp() throws Exception { + whenNew(RxTapglue.class).withArguments(configuration, context).thenReturn(rxTapglue); + + tapglue = new Tapglue(configuration, context); + } + + @Test + public void usernameLogin() throws Throwable { + when(rxTapglue.loginWithUsername(USERNAME, PASSWORD)).thenReturn(Observable.just(user)); + + assertThat(tapglue.loginWithUsername(USERNAME, PASSWORD), equalTo(user)); + } + + @Test + public void emailLogin() throws Throwable { + when(rxTapglue.loginWithEmail(EMAIL, PASSWORD)).thenReturn(Observable.just(user)); + + assertThat(tapglue.loginWithEmail(EMAIL, PASSWORD), equalTo(user)); + } + + @Test + public void logout() throws Throwable { + whenNew(RxWrapper.class).withNoArguments().thenReturn(voidWrapper); + when(rxTapglue.logout()).thenReturn(voidObservable); + + tapglue.logout(); + + verify(voidWrapper).unwrap(voidObservable); + } + + @Test + public void currentUser() throws Throwable { + when(rxTapglue.getCurrentUser()).thenReturn(Observable.just(user)); + + assertThat(tapglue.getCurrentUser(), equalTo(user)); + } + + @Test + public void createUser() throws Exception { + when(rxTapglue.createUser(user)).thenReturn(Observable.just(user)); + + assertThat(tapglue.createUser(user), equalTo(user)); + } + + @Test + public void deleteCurrentUser() throws Exception { + whenNew(RxWrapper.class).withNoArguments().thenReturn(voidWrapper); + when(rxTapglue.deleteCurrentUser()).thenReturn(voidObservable); + + tapglue.deleteCurrentUser(); + + verify(voidWrapper).unwrap(voidObservable); + } + + @Test + public void updateCurrentUser() throws Exception { + when(rxTapglue.updateCurrentUser(user)).thenReturn(Observable.just(user)); + + assertThat(tapglue.updateCurrentUser(user), equalTo(user)); + } + + @Test + public void refreshCurrentUser() throws Exception { + when(rxTapglue.refreshCurrentUser()).thenReturn(Observable.just(user)); + + assertThat(tapglue.refreshCurrentUser(), equalTo(user)); + } + + @Test + public void retrieveUser() throws Exception { + String id = "101"; + when(rxTapglue.retrieveUser(id)).thenReturn(Observable.just(user)); + + assertThat(tapglue.retrieveUser(id), equalTo(user)); + } + + @Test + public void createConnection() throws Exception { + when(rxTapglue.createConnection(connection)).thenReturn(Observable.just(connection)); + + assertThat(tapglue.createConnection(connection), equalTo(connection)); + } + + @Test + public void createSocialConnections() throws Exception { + when(rxTapglue.createSocialConnections(socialConnections)).thenReturn(Observable.just(userList)); + + assertThat(tapglue.createSocialConnections(socialConnections), equalTo(userList)); + } + + @Test + public void deleteConnection() throws Exception { + String id = "someUserId"; + Type type = Type.FOLLOW; + when(rxTapglue.deleteConnection(id, type)).thenReturn(voidObservable); + whenNew(RxWrapper.class).withNoArguments().thenReturn(voidWrapper); + + tapglue.deleteConnection(id, type); + + verify(voidWrapper).unwrap(voidObservable); + } + + @Test + public void createPost() throws Exception { + Post post = mock(Post.class); + when(rxTapglue.createPost(post)).thenReturn(Observable.just(post)); + + assertThat(tapglue.createPost(post), equalTo(post)); + } + + @Test + public void retrievePost() throws Exception { + Post post = mock(Post.class); + String id = "id"; + when(rxTapglue.retrievePost(id)).thenReturn(Observable.just(post)); + + assertThat(tapglue.retrievePost(id), equalTo(post)); + } + + @Test + public void updatePost() throws Exception { + String id = "id"; + Post post = mock(Post.class); + when(rxTapglue.updatePost(id, post)).thenReturn(Observable.just(post)); + + assertThat(tapglue.updatePost(id, post), equalTo(post)); + } + + @Test + public void deletePost() throws Exception { + String id = "id1"; + when(rxTapglue.deletePost(id)).thenReturn(voidObservable); + whenNew(RxWrapper.class).withNoArguments().thenReturn(voidWrapper); + + tapglue.deletePost(id); + + verify(voidWrapper).unwrap(voidObservable); + } + + @Test + public void createLike() throws Exception { + String id = "postId"; + Like like = mock(Like.class); + when(rxTapglue.createLike(id)).thenReturn(Observable.just(like)); + + assertThat(tapglue.createLike(id), equalTo(like)); + } + + @Test + public void deleteLike() throws Exception { + String id = "postId"; + when(rxTapglue.deleteLike(id)).thenReturn(voidObservable); + whenNew(RxWrapper.class).withNoArguments().thenReturn(voidWrapper); + + tapglue.deleteLike(id); + + verify(voidWrapper).unwrap(voidObservable); + } + + @Test + public void createComment() throws Exception { + String id = "postId"; + Comment comment = mock(Comment.class); + when(rxTapglue.createComment(id, comment)).thenReturn(Observable.just(comment)); + + assertThat(tapglue.createComment(id, comment), equalTo(comment)); + } + + @Test + public void deleteComment() throws Exception { + String postId = "postId"; + String commentId = "commentId"; + whenNew(RxWrapper.class).withNoArguments().thenReturn(voidWrapper); + when(rxTapglue.deleteComment(postId, commentId)).thenReturn(voidObservable); + + tapglue.deleteComment(postId, commentId); + + verify(voidWrapper).unwrap(voidObservable); + } + + @Test + public void updateComment() throws Exception { + String postId = "postId"; + String commentId = "commentId"; + Comment comment = mock(Comment.class); + when(rxTapglue.updateComment(postId, commentId, comment)).thenReturn(Observable.just(comment)); + + assertThat(tapglue.updateComment(postId, commentId, comment), equalTo(comment)); + } + + @Test + public void retrieveEventFeed() throws Exception { + List events = mock(List.class); + when(rxTapglue.retrieveEventFeed()).thenReturn(Observable.just(events)); + + assertThat(tapglue.retrieveEventFeed(), equalTo(events)); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/NetworkTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/NetworkTest.java new file mode 100644 index 0000000..aaa6af3 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/NetworkTest.java @@ -0,0 +1,498 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.tapglue.android.RxPage; +import com.tapglue.android.entities.Comment; +import com.tapglue.android.entities.Connection; +import com.tapglue.android.entities.ConnectionList; +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.Like; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; +import com.tapglue.android.http.payloads.EmailLoginPayload; +import com.tapglue.android.http.payloads.SocialConnections; +import com.tapglue.android.http.payloads.UsernameLoginPayload; +import com.tapglue.android.internal.SessionStore; +import com.tapglue.android.internal.Store; +import com.tapglue.android.internal.UUIDStore; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Function; +import io.reactivex.observers.TestObserver; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.whenNew; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(Network.class) +public class NetworkTest { + private static final String EMAIL = "user@domain.com"; + private static final String USERNAME = "username"; + private static final String PASSWORD = "password"; + + + @Mock + Context context; + @Mock + SharedPreferences prefs; + @Mock + ServiceFactory serviceFactory; + @Mock + TapglueService service; + @Mock + TapglueService secondService; + @Mock + SessionStore sessionStore; + @Mock + UUIDStore uuidStore; + @Mock + Function storeFunc; + @Mock + Store internalUUIDStore; + @Mock + ConnectionList connectionList; + @Mock + Action clearAction; + @Mock + UsersFeed usersFeed; + @Mock + User user; + List users = new ArrayList(); + + //SUT + Network network; + + @Before + public void setUp() throws Exception { + when(context.getSharedPreferences(anyString(), anyInt())).thenReturn(prefs); + when(service.login(isA(UsernameLoginPayload.class))).thenReturn(Observable.just(user)); + when(service.login(isA(EmailLoginPayload.class))).thenReturn(Observable.just(user)); + when(serviceFactory.createTapglueService()).thenReturn(service) + .thenReturn(secondService); + + whenNew(UUIDStore.class).withAnyArguments().thenReturn(uuidStore); + whenNew(SessionStore.class).withAnyArguments().thenReturn(sessionStore); + when(uuidStore.get()).thenReturn(Observable.empty()); + + when(sessionStore.get()).thenReturn(Observable.empty()); + when(sessionStore.store()).thenReturn(storeFunc); + when(storeFunc.apply(user)).thenReturn(user); + when(sessionStore.clear()).thenReturn(clearAction); + network = new Network(serviceFactory, context); + } + + @Test + public void loginWithUsernameReturnsUserFromService() { + TestObserver to = network.loginWithUsername(USERNAME, PASSWORD).test(); + to.assertValue(user); + } + + @Test + public void loginWithEmailReturnsUserFromService() { + TestObserver to = network.loginWithEmail(EMAIL, PASSWORD).test(); + + to.assertValue(user); + } + + + @Test + public void usernameLoginSetsSessionTokenToServiceFactory() { + when(user.getSessionToken()).thenReturn("sessionToken"); + network.loginWithUsername(USERNAME, PASSWORD).test(); + + verify(serviceFactory).setSessionToken("sessionToken"); + } + + @Test + public void emailLoginSetsSessionTokenToServiceFactory() { + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.loginWithEmail(EMAIL, PASSWORD).test(); + + verify(serviceFactory).setSessionToken("sessionToken"); + } + + @Test + public void usernameLoginStoresSessionToken() throws Exception { + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.loginWithUsername(USERNAME, PASSWORD).test(); + + verify(storeFunc).apply(user); + } + + @Test + public void emailLoginStoresSessionToken() throws Exception { + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.loginWithEmail(EMAIL, PASSWORD).test(); + + verify(storeFunc).apply(user); + } + + @Test + public void usernameLoginCreatesNewService() { + when(user.getSessionToken()).thenReturn("sessionToken"); + TestObserver ts = new TestObserver<>(); + + network.loginWithUsername(USERNAME, PASSWORD).test(); + + assertThat(network.service, equalTo(secondService)); + } + + @Test + public void logoutReturnsObservableFromNetwork() { + when(service.logout()).thenReturn(Observable.empty()); + TestObserver to = network.logout().test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void logoutClearsSession() throws Exception { + when(service.logout()).thenReturn(Observable.empty()); + + network.logout().test(); + + verify(clearAction).run(); + } + + @Test + public void createUserReturnsUserFromService() { + when(service.createUser(user)).thenReturn(Observable.just(user)); + TestObserver to = network.createUser(user).test(); + + to.assertValue(user); + } + + @Test + public void deleteCurrentUserReturnsObservableFromService() { + when(service.deleteCurrentUser()).thenReturn(Observable.empty()); + TestObserver to = network.deleteCurrentUser().test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void deleteCurrentUserClearsSession() throws Exception { + when(service.deleteCurrentUser()).thenReturn(Observable.empty()); + + network.deleteCurrentUser().test(); + + verify(clearAction).run(); + } + + @Test + public void updateCurrentUserReturnsUserFromService() { + when(service.updateCurrentUser(user)).thenReturn(Observable.just(user)); + TestObserver to = network.updateCurrentUser(user).test(); + + to.assertValue(user); + } + + @Test + public void updateCurrentUserStoresSessionToken() throws Exception { + when(service.updateCurrentUser(user)).thenReturn(Observable.just(user)); + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.updateCurrentUser(user).test(); + + verify(storeFunc).apply(user); + } + + @Test + public void updateCurrentUserCreatesNewService() { + when(service.updateCurrentUser(user)).thenReturn(Observable.just(user)); + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.updateCurrentUser(user).test(); + + verify(serviceFactory).setSessionToken("sessionToken"); + } + + @Test + public void updateCurrentUserSetsSessionTokenToServiceFactory() { + when(service.updateCurrentUser(user)).thenReturn(Observable.just(user)); + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.updateCurrentUser(user).test(); + + assertThat(network.service, equalTo(secondService)); + } + + @Test + public void refreshCurrentUserReturnsUserFromService() { + when(service.refreshCurrentUser()).thenReturn(Observable.just(user)); + TestObserver to = network.refreshCurrentUser().test(); + + to.assertValue(user); + } + + @Test + public void refreshCurrentUserStoresSessionToken() throws Exception { + when(service.refreshCurrentUser()).thenReturn(Observable.just(user)); + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.refreshCurrentUser().test(); + + verify(storeFunc).apply(user); + } + + @Test + public void refreshCurrentUserCreatesNewService() { + when(service.refreshCurrentUser()).thenReturn(Observable.just(user)); + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.refreshCurrentUser().test(); + + verify(serviceFactory).setSessionToken("sessionToken"); + } + + @Test + public void refreshCurrentUserSetsSessionTokenToServiceFactory() { + when(service.refreshCurrentUser()).thenReturn(Observable.just(user)); + when(user.getSessionToken()).thenReturn("sessionToken"); + + network.refreshCurrentUser().test(); + + assertThat(network.service, equalTo(secondService)); + } + + @Test + public void retrieveUserReturnsUserFromService() { + String id = "someID"; + when(service.retrieveUser(id)).thenReturn(Observable.just(user)); + TestObserver to = network.retrieveUser(id).test(); + + to.assertValue(user); + } + + @Test + public void retrieveFollowignsReturnsUsersFromService() { + when(usersFeed.getUsers()).thenReturn(users); + when(service.retrieveFollowings()).thenReturn(Observable.just(usersFeed)); + TestObserver>> to = network.retrieveFollowings().test(); + + List result = to.values().get(0).getData(); + + assertThat(result, equalTo(users)); + + + } + + @Test + public void retrieveFollowersReturnsUsersFromService() { + when(usersFeed.getUsers()).thenReturn(users); + when(service.retrieveFollowers()).thenReturn(Observable.just(usersFeed)); + TestObserver>> ts = network.retrieveFollowers().test(); + + List result = ts.values().get(0).getData(); + + assertThat(result, equalTo(users)); + } + + @Test + public void retrieveUserFollowignsReturnsUsersFromService() { + String id = "userId"; + when(usersFeed.getUsers()).thenReturn(users); + when(service.retrieveUserFollowings(id)).thenReturn(Observable.just(usersFeed)); + TestObserver>> to = network.retrieveUserFollowings(id).test(); + + List result = to.values().get(0).getData(); + + assertThat(result, equalTo(users)); + } + + @Test + public void retrieveUserFollowersReturnsUsersFromService() { + String id = "userId"; + when(usersFeed.getUsers()).thenReturn(users); + when(service.retrieveUserFollowers(id)).thenReturn(Observable.just(usersFeed)); + TestObserver>> to = network.retrieveUserFollowers(id).test(); + + List result = to.values().get(0).getData(); + + assertThat(result, equalTo(users)); + } + + @Test + public void createConnectionReturnsConnectionFromService() { + Connection connection = mock(Connection.class); + when(service.createConnection(connection)).thenReturn(Observable.just(connection)); + TestObserver to = network.createConnection(connection).test(); + + to.assertValue(connection); + } + + @Test + public void createSocialConnectionsReturnsUsersFromService() { + SocialConnections connections = mock(SocialConnections.class); + when(usersFeed.getUsers()).thenReturn(users); + when(service.createSocialConnections(connections)).thenReturn(Observable.just(usersFeed)); + TestObserver> to = network.createSocialConnections(connections).test(); + + to.assertValue(users); + } + + @Test + public void deleteConnectionReturnsFromService() { + String id = "userId"; + Connection.Type type = Connection.Type.FOLLOW; + when(service.deleteConnection(id, type)).thenReturn(Observable.empty()); + TestObserver to = network.deleteConnection(id, type).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void createPostReturnsPostFromService() { + Post post = mock(Post.class); + when(service.createPost(post)).thenReturn(Observable.just(post)); + TestObserver to = network.createPost(post).test(); + + to.assertValue(post); + } + + @Test + public void retrievePostReturnsPostFromService() { + Post post = mock(Post.class); + String id = "id"; + when(service.retrievePost(id)).thenReturn(Observable.just(post)); + TestObserver to = network.retrievePost(id).test(); + + to.assertValue(post); + } + + @Test + public void updatePostReturnsPostFromService() { + Post post = mock(Post.class); + String id = "id"; + when(service.updatePost(id, post)).thenReturn(Observable.just(post)); + TestObserver to = network.updatePost(id, post).test(); + + to.assertValue(post); + } + + @Test + public void deletePostReturnsFromService() { + String id = "id1231"; + when(service.deletePost(id)).thenReturn(Observable.empty()); + TestObserver ts = network.deletePost(id).test(); + + ts.assertNoErrors(); + ts.assertComplete(); + } + + @Test + public void createLikeReturnsLikeFromService() { + String id = "postId"; + Like like = mock(Like.class); + when(service.createLike(id)).thenReturn(Observable.just(like)); + TestObserver to = network.createLike(id).test(); + + to.assertValue(like); + } + + @Test + public void deleteLikeDeletesOnService() { + String id = "postId"; + when(service.deleteLike(id)).thenReturn(Observable.empty()); + TestObserver to = network.deleteLike(id).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void createCommentPostsToService() { + String id = "postId"; + Comment comment = mock(Comment.class); + when(service.createComment(id, comment)).thenReturn(Observable.just(comment)); + TestObserver to = network.createComment(id, comment).test(); + + to.assertValue(comment); + } + + @Test + public void deleteCommentDeletesOnService() { + String postId = "postId"; + String commentId = "commentiD"; + when(service.deleteComment(postId, commentId)).thenReturn(Observable.empty()); + TestObserver to = network.deleteComment(postId, commentId).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void updateCommentUpdatesOnService() { + String postId = "postId"; + String commentId = "commentID"; + Comment comment = mock(Comment.class); + when(service.updateComment(postId, commentId, comment)).thenReturn(Observable.just(comment)); + TestObserver to = network.updateComment(postId, commentId, comment).test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void retrieveEventFeedRetrievesFromService() throws Exception { + List events = mock(List.class); + EventListFeed feed = mock(EventListFeed.class); + EventFeedToList converter = mock(EventFeedToList.class); + whenNew(EventFeedToList.class).withNoArguments().thenReturn(converter); + when(converter.apply(feed)).thenReturn(events); + when(service.retrieveEventFeed()).thenReturn(Observable.just(feed)); + TestObserver> ts = network.retrieveEventFeed().test(); + + ts.assertValue(events); + } + + @Test + public void sendAnalyticsCallsService() { + when(service.sendAnalytics()).thenReturn(Observable.empty()); + TestObserver to = network.sendAnalytics().test(); + + to.assertNoErrors(); + to.assertComplete(); + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/PostFeedToListTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/PostFeedToListTest.java new file mode 100644 index 0000000..b7686d5 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/PostFeedToListTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class PostFeedToListTest { + + @Test + public void nullFeedReturnsEmptyFeed() { + List posts = new PostFeedToList().apply(null); + + assertThat(posts, notNullValue()); + } + + @Test + public void setsUsersToPosts() { + String userId = "userId"; + Post post = mock(Post.class); + when(post.getUserId()).thenReturn(userId); + User user = mock(User.class); + List posts = Arrays.asList(post); + Map userMap = new HashMap<>(); + userMap.put(userId, user); + + PostListFeed feed = new PostListFeed(); + feed.posts = posts; + feed.users = userMap; + + PostFeedToList converter = new PostFeedToList(); + converter.apply(feed); + + verify(post).setUser(user); + } + + @Test + public void returnsPostsFromFeed() { + String userId = "userId"; + Post post = mock(Post.class); + when(post.getUserId()).thenReturn(userId); + User user = mock(User.class); + List posts = Arrays.asList(post); + Map userMap = new HashMap<>(); + userMap.put(userId, user); + + PostListFeed feed = new PostListFeed(); + feed.posts = posts; + feed.users = userMap; + + PostFeedToList converter = new PostFeedToList(); + + List result = converter.apply(feed); + + assertThat(result, equalTo(posts)); + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/RawNewsFeedTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/RawNewsFeedTest.java new file mode 100644 index 0000000..537eacc --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/RawNewsFeedTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import com.tapglue.android.entities.Event; +import com.tapglue.android.entities.NewsFeed; +import com.tapglue.android.entities.Post; +import com.tapglue.android.entities.User; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class RawNewsFeedTest { + @Test + public void nullFeedParsesToNotNull() { + NewsFeed feed = new RawNewsFeed().flatten(); + + assertThat(feed, notNullValue()); + } + + @Test + public void populatesUsersToEvents(){ + String id = "someId"; + RawNewsFeed rawFeed = new RawNewsFeed(); + Event event = mock(Event.class); + List events = Arrays.asList(event); + when(event.getUserId()).thenReturn(id); + Map users = new HashMap<>(); + User user = mock(User.class); + users.put(id, user); + + rawFeed.events = events; + rawFeed.users = users; + rawFeed.postMap = new HashMap<>(); + + rawFeed.flatten(); + + verify(event).setUser(user); + } + + @Test + public void returnsEvents() { + String id = "someId"; + RawNewsFeed rawFeed = new RawNewsFeed(); + Event event = mock(Event.class); + List events = Arrays.asList(event); + when(event.getUserId()).thenReturn(id); + Map users = new HashMap<>(); + User user = mock(User.class); + users.put(id, user); + + rawFeed.events = events; + rawFeed.users = users; + rawFeed.postMap = new HashMap<>(); + + NewsFeed feed = rawFeed.flatten(); + + assertThat(feed.getEvents(), equalTo(events)); + } + + @Test + public void populatesUsersToPosts() { + String id = "someId"; + RawNewsFeed rawFeed = new RawNewsFeed(); + Post post = mock(Post.class); + when(post.getUserId()).thenReturn(id); + List posts = Arrays.asList(post); + Map users = new HashMap<>(); + User user = mock(User.class); + users.put(id, user); + + rawFeed.posts = posts; + rawFeed.users = users; + rawFeed.postMap = new HashMap<>(); + + rawFeed.flatten(); + + verify(post).setUser(user); + } + + @Test + public void returnsPosts() { + String id = "someId"; + RawNewsFeed rawFeed = new RawNewsFeed(); + Post post = mock(Post.class); + when(post.getUserId()).thenReturn(id); + List posts = Arrays.asList(post); + Map users = new HashMap<>(); + User user = mock(User.class); + users.put(id, user); + + rawFeed.posts = posts; + rawFeed.users = users; + rawFeed.postMap = new HashMap<>(); + + NewsFeed feed = rawFeed.flatten(); + + assertThat(feed.getPosts(), equalTo(posts)); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/ServiceFactoryTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/ServiceFactoryTest.java new file mode 100644 index 0000000..3a29ac2 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/http/ServiceFactoryTest.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.http; + +import com.tapglue.android.Configuration; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class ServiceFactoryTest { + + @Mock + Configuration configuration; + + //SUT + ServiceFactory serviceFactory; + + @Before public void setup() { + when(configuration.getBaseUrl()).thenReturn("https://someapi.tapglue.com"); + serviceFactory = new ServiceFactory(configuration); + } + + @Test + public void serviceForIsNotNull() { + TapglueService service = serviceFactory.createTapglueService(); + assertThat(service, notNullValue()); + } + + @Test + public void createServiceAsksForBaseUrl() { + serviceFactory.createTapglueService(); + verify(configuration).getBaseUrl(); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/NotificationServiceIdStoreTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/NotificationServiceIdStoreTest.java new file mode 100644 index 0000000..1613321 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/NotificationServiceIdStoreTest.java @@ -0,0 +1,55 @@ +package com.tapglue.android.internal; + +import android.content.Context; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import io.reactivex.Observable; +import io.reactivex.functions.Function; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class NotificationServiceIdStoreTest { + + private static final String ID = "someId"; + @Mock + Context context; + @Mock + Store internalStore; + @Mock + Function storeFunc; + @Mock + Observable getObservable; + + NotificationServiceIdStore store; + + @Before + public void setUp() { + store = new NotificationServiceIdStore(context); + store.store = internalStore; + } + + @Test + public void storeStoresOnInternalStore() throws Exception { + when(internalStore.store()).thenReturn(storeFunc); + + store.store(ID); + + verify(storeFunc).apply(ID); + } + + @Test + public void getGetsFromInternalStore() { + when(internalStore.get()).thenReturn(getObservable); + + assertThat(store.get(), equalTo(getObservable)); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/SessionStoreTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/SessionStoreTest.java new file mode 100644 index 0000000..5e8ceb5 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/SessionStoreTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.Context; + +import com.tapglue.android.entities.User; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Function; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class SessionStoreTest { + + @Mock + Context context; + @Mock + Store internalStore; + @Mock + Function storeFunc; + @Mock + Observable getObservable; + @Mock + Action clearAction; + + //SUT + SessionStore store; + + @Before + public void setUp() { + store = new SessionStore(context); + store.store = internalStore; + } + + @Test + public void storeCallsInternal() { + when(internalStore.store()).thenReturn(storeFunc); + + assertThat(store.store(), equalTo(internalStore.store())); + } + + @Test + public void getCallsInternal() { + when(internalStore.get()).thenReturn(getObservable); + + assertThat(store.get(), equalTo(getObservable)); + } + + @Test + public void clearCallsInternal() { + when(internalStore.clear()).thenReturn(clearAction); + + assertThat(store.clear(), equalTo(clearAction)); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/StoreTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/StoreTest.java new file mode 100644 index 0000000..920694e --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/StoreTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.SharedPreferences; + +import com.google.gson.Gson; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import io.reactivex.Observable; +import io.reactivex.observers.TestObserver; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsCollectionContaining.hasItems; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class StoreTest { + + private static final long ID = 10; + + @Mock + public SharedPreferences prefs; + @Mock + public SharedPreferences.Editor editor; + + TestEntity entity = new TestEntity(ID); + + //SUT + Store store; + @Before + public void setUp() { + when(prefs.edit()).thenReturn(editor); + store = new Store<>(prefs, TestEntity.class); + } + + @Test + public void storeEntity() { + + Observable.just(entity).map(store.store()).subscribe(); + + TestObserver to = store.get().test(); + + to.assertValue(entity); + } + + @Test + public void nullEntityReturnsEmptyObservable() { + TestObserver to = store.get().test(); + + to.assertNoErrors(); + to.assertComplete(); + } + + @Test + public void entityGetsPersisted() { + Observable.just(entity).map(store.store()).subscribe(); + + InOrder inOrder = inOrder(editor); + + inOrder.verify(editor).putString(eq("object"), eq(new Gson().toJson(entity))); + inOrder.verify(editor).apply(); + } + + @Test + public void clearFunctionDeletesEntity() throws Exception { + Observable.just(entity).map(store.store()).subscribe(); + + store.clear().run(); + + TestObserver to = store.get().test(); + + assertThat(to.valueCount(), equalTo(0)); + } + + @Test + public void getEntityReturnsPersistedWhenNull() { + when(prefs.getString("object", null)).thenReturn(new Gson().toJson(entity)); + TestObserver to = store.get().test(); + + to.assertValue(entity); + } + + @Test + public void isEmptyReturnsFalse() { + when(prefs.getString("object", null)).thenReturn(new Gson().toJson(entity)); + + assertThat(store.isEmpty(), equalTo(false)); + } + + @Test + public void isEmptyReturnsTrue() { + when(prefs.getString("object", null)).thenReturn(null); + + assertThat(store.isEmpty(), equalTo(true)); + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/TestEntity.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/TestEntity.java new file mode 100644 index 0000000..3381c17 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/TestEntity.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +public class TestEntity{ + long id; + + public TestEntity(long id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + TestEntity that = (TestEntity) o; + + return id == that.id; + + } + + @Override + public int hashCode() { + return (int) (id ^ (id >>> 32)); + } +} \ No newline at end of file diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/UUIDStoreTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/UUIDStoreTest.java new file mode 100644 index 0000000..62de274 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/UUIDStoreTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.Context; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import io.reactivex.Observable; +import io.reactivex.functions.Function; +import io.reactivex.observers.TestObserver; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class UUIDStoreTest { + + @Mock + Context context; + @Mock + Store internalStore; + @Mock + Function storeFunc; + + //SUT + UUIDStore store; + + @Before + public void setUp() { + when(internalStore.store()).thenReturn(storeFunc); + + store = new UUIDStore(context); + store.store = internalStore; + } + + @Test + public void getsFromInternalStore() throws Exception { + Observable internalObservable = Observable.just("uuid"); + when(internalStore.get()).thenReturn(internalObservable); + TestObserver to = store.get().test(); + + to.assertValue("uuid"); + } + + @Test + public void whenEmptyUUIDIsGenerated() throws Exception { + when(internalStore.isEmpty()).thenReturn(true); + when(internalStore.get()).thenReturn(Observable.just("uuid")); + + TestObserver to = store.get().test(); + + assertThat(to.values().size(), equalTo(1)); + verify(internalStore).store(); + } + + @Test + public void whenEmptyUUIDIsStored() throws Exception { + Observable internalObservable = Observable.empty(); + when(internalStore.isEmpty()).thenReturn(true); + when(internalStore.get()).thenReturn(internalObservable); + + store.get().subscribe(); + + verify(storeFunc).apply(anyString()); + } +} diff --git a/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/UserStoreTest.java b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/UserStoreTest.java new file mode 100644 index 0000000..07ead71 --- /dev/null +++ b/tapglue-android-sdk-rxjava2/src/test/java/com/tapglue/android/internal/UserStoreTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015-2016 Tapglue (https://www.tapglue.com/). All rights reserved. + * + * 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.tapglue.android.internal; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.tapglue.android.entities.User; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import io.reactivex.Observable; +import io.reactivex.functions.Action; +import io.reactivex.functions.Function; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class UserStoreTest { + + @Mock + public Context context; + @Mock + public SharedPreferences prefs; + @Mock + public SharedPreferences.Editor editor; + @Mock + public Store internalStore; + @Mock + public Function storeFunc; + @Mock + public Observable getObservable; + @Mock + public Action clearAction; + + //SUT + UserStore store; + + @Before + public void setUp() { + when(context.getSharedPreferences("user", Context.MODE_PRIVATE)).thenReturn(prefs); + when(prefs.edit()).thenReturn(editor); + + store = new UserStore(context); + store.store = internalStore; + } + + @Test + public void storeUser() { + when(internalStore.store()).thenReturn(storeFunc); + + assertThat(store.store(), equalTo(storeFunc)); + } + + @Test + public void getUserCallsInternalStore() { + when(internalStore.get()).thenReturn(getObservable); + + assertThat(store.get(), equalTo(getObservable)); + } + + @Test + public void clearCallsInternalStore() { + when(internalStore.clear()).thenReturn(clearAction); + + assertThat(store.clear(), equalTo(clearAction)); + } +} diff --git a/tapglue-android-sdk/build.gradle b/tapglue-android-sdk/build.gradle index 90ceceb..25fd376 100644 --- a/tapglue-android-sdk/build.gradle +++ b/tapglue-android-sdk/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'jacoco' apply plugin: 'sonar-runner' android { - compileSdkVersion 23 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion "25.0.2" defaultConfig { minSdkVersion 15 - targetSdkVersion 23 + targetSdkVersion 25 versionCode 10 versionName "2.1.2" } @@ -83,13 +83,11 @@ task integrationTest(type: Test) { dependencies { compile 'io.reactivex:rxjava:1.1.6' - compile 'com.squareup.retrofit2:retrofit:2.1.0' - compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' - compile 'com.squareup.retrofit2:converter-gson:2.1.0' - compile 'com.google.code.gson:gson:2.7' - compile 'com.squareup.okhttp3:logging-interceptor:3.3.1' - compile 'com.android.support:appcompat-v7:23.2.1' - compile 'com.google.firebase:firebase-messaging:9.0.2' + + compile project(':core') + compile 'com.android.support:appcompat-v7:25.2.0' + compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0' + testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-all:1.3' testCompile('org.mockito:mockito-core:1.10.8') { diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/EventFeedToList.java b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/EventFeedToList.java index 5ad5067..9f72863 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/EventFeedToList.java +++ b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/EventFeedToList.java @@ -26,7 +26,7 @@ import rx.functions.Func1; -class EventFeedToList implements Func1> { +public class EventFeedToList implements Func1> { @Override public List call(EventListFeed feed) { if(feed == null || feed.events == null) { diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/Network.java b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/Network.java index 2df1443..2847846 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/Network.java +++ b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/Network.java @@ -20,8 +20,6 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import com.tapglue.android.RxPage; -import com.tapglue.android.internal.SessionStore; -import com.tapglue.android.internal.UUIDStore; import com.tapglue.android.entities.Comment; import com.tapglue.android.entities.Connection; import com.tapglue.android.entities.Connection.Type; @@ -32,14 +30,16 @@ import com.tapglue.android.entities.Post; import com.tapglue.android.entities.Reaction; import com.tapglue.android.entities.User; -import com.tapglue.android.http.payloads.SocialConnections; import com.tapglue.android.http.payloads.EmailLoginPayload; import com.tapglue.android.http.payloads.EmailSearchPayload; +import com.tapglue.android.http.payloads.SocialConnections; import com.tapglue.android.http.payloads.SocialSearchPayload; import com.tapglue.android.http.payloads.UsernameLoginPayload; +import com.tapglue.android.internal.SessionStore; +import com.tapglue.android.internal.UUIDStore; -import java.util.List; import java.util.ArrayList; +import java.util.List; import okhttp3.MediaType; import okhttp3.RequestBody; diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/RawNewsFeed.java b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/RawNewsFeed.java index 9b64fac..66a5179 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/RawNewsFeed.java +++ b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/RawNewsFeed.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.Map; -class RawNewsFeed extends FlattenableFeed { +public class RawNewsFeed extends FlattenableFeed { List events; List posts; Map users; diff --git a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/TapglueService.java b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/TapglueService.java index fbad634..edc1c12 100644 --- a/tapglue-android-sdk/src/main/java/com/tapglue/android/http/TapglueService.java +++ b/tapglue-android-sdk/src/main/java/com/tapglue/android/http/TapglueService.java @@ -17,24 +17,24 @@ package com.tapglue.android.http; import com.google.gson.JsonObject; -import com.tapglue.android.entities.User; import com.tapglue.android.entities.Comment; import com.tapglue.android.entities.Connection; import com.tapglue.android.entities.Connection.Type; import com.tapglue.android.entities.Like; import com.tapglue.android.entities.Post; import com.tapglue.android.entities.Reaction; +import com.tapglue.android.entities.User; import com.tapglue.android.http.payloads.EmailLoginPayload; import com.tapglue.android.http.payloads.SocialConnections; import com.tapglue.android.http.payloads.UsernameLoginPayload; import okhttp3.RequestBody; import retrofit2.http.Body; -import retrofit2.http.Path; import retrofit2.http.DELETE; import retrofit2.http.GET; import retrofit2.http.POST; import retrofit2.http.PUT; +import retrofit2.http.Path; import retrofit2.http.Url; import rx.Observable; @@ -85,7 +85,7 @@ interface TapglueService { Observable createSocialConnections(@Body SocialConnections connections); @DELETE("/0.4/me/connections/{type}/{id}") - Observable deleteConnection(@Path("id") String userId, + Observable deleteConnection(@Path("id") String userId, @Path("type") Type type); @POST("/0.4/posts")