lobsters-api: init

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-09-22 05:33:18 +05:30
parent 7bb1fd6947
commit 7489100c26
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
13 changed files with 183 additions and 0 deletions

1
.idea/gradle.xml generated
View file

@ -13,6 +13,7 @@
<option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/data" /> <option value="$PROJECT_DIR$/data" />
<option value="$PROJECT_DIR$/lobsters-api" />
</set> </set>
</option> </option>
<option name="resolveModulePerSourceSet" value="false" /> <option name="resolveModulePerSourceSet" value="false" />

1
lobsters-api/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

19
lobsters-api/build.gradle Normal file
View file

@ -0,0 +1,19 @@
plugins {
id 'kotlin-android'
id 'kotlin-kapt'
}
dependencies {
def moshi_version = "1.9.3"
def retrofit_version = "2.9.0"
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
implementation "com.squareup.moshi:moshi:$moshi_version"
implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"
implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
kaptTest "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
testImplementation 'junit:junit:4.13'
// retrofit uses 3.14.9, so shall we.
//noinspection GradleDependency
testImplementation "com.squareup.okhttp3:mockwebserver:3.14.9"
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.msfjarvis.lobsters.api">
</manifest>

View file

@ -0,0 +1,14 @@
package dev.msfjarvis.lobsters.api
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
object ApiClient {
inline fun <reified T> getClient(baseUrl: String): T {
return Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(MoshiConverterFactory.create())
.build()
.create(T::class.java)
}
}

View file

@ -0,0 +1,10 @@
package dev.msfjarvis.lobsters.api
import dev.msfjarvis.lobsters.api.model.LobstersPost
import retrofit2.Call
import retrofit2.http.GET
interface LobstersApi {
@GET("hottest.json")
fun getHottestPosts(): Call<List<LobstersPost>>
}

View file

@ -0,0 +1,12 @@
package dev.msfjarvis.lobsters.api.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
class KeybaseSignature(
@Json(name = "kb_username")
val kbUsername: String,
@Json(name = "sig_hash")
val sigHash: String
)

View file

@ -0,0 +1,26 @@
package dev.msfjarvis.lobsters.api.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
class LobstersPost(
@Json(name = "short_id")
val shortId: String,
@Json(name = "short_id_url")
val shortIdUrl: String,
@Json(name = "created_at")
val createdAt: String,
val title: String,
val url: String,
val score: Long,
val flags: Long,
@Json(name = "comment_count")
val commentCount: Long,
val description: String,
@Json(name = "comments_url")
val commentsUrl: String,
@Json(name = "submitter_user")
val submitterUser: Submitter,
val tags: List<String>
)

View file

@ -0,0 +1,27 @@
package dev.msfjarvis.lobsters.api.model
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
class Submitter(
val username: String,
@Json(name = "created_at")
val createdAt: String,
@Json(name = "is_admin")
val isAdmin: Boolean,
val about: String,
@Json(name = "is_moderator")
val isModerator: Boolean,
val karma: Long,
@Json(name = "avatar_url")
val avatarUrl: String,
@Json(name = "invited_by_user")
val invitedByUser: String,
@Json(name = "github_username")
val githubUsername: String?,
@Json(name = "twitter_username")
val twitterUsername: String?,
@Json(name = "keybase_signatures")
val keybaseSignatures: List<KeybaseSignature>?
)

View file

@ -0,0 +1,54 @@
package dev.msfjarvis.lobsters.api
import dev.msfjarvis.lobsters.api.model.LobstersPost
import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class LobstersApiTest {
private val webServer = MockWebServer()
private val apiData = TestUtils.getJson("hottest.json")
private val apiClient = ApiClient.getClient<LobstersApi>("http://localhost:8080")
@Before
fun setUp() {
webServer.start(8080)
webServer.dispatcher = object : Dispatcher() {
override fun dispatch(request: RecordedRequest): MockResponse {
return MockResponse().setBody(apiData).setResponseCode(200)
}
}
}
@Test
fun `api gets correct number of items`() {
apiClient.getHottestPosts().enqueue(object : Callback<List<LobstersPost>> {
override fun onResponse(
call: Call<List<LobstersPost>>,
response: Response<List<LobstersPost>>
) {
val posts = response.body()
require(posts != null)
assertEquals(25, posts.size)
}
override fun onFailure(call: Call<List<LobstersPost>>, t: Throwable) {
fail("Call cannot fail in tests")
}
})
}
@After
fun tearDown() {
webServer.shutdown()
}
}

View file

@ -0,0 +1,12 @@
package dev.msfjarvis.lobsters.api
import java.io.File
object TestUtils {
fun getJson(path : String) : String {
// Load the JSON response
val uri = javaClass.classLoader.getResource(path)
val file = File(uri.path)
return String(file.readBytes())
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,4 @@
rootProject.name = "lobste.rs" rootProject.name = "lobste.rs"
include ':app' include ':app'
include ':data' include ':data'
include ':lobsters-api'