mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-14 21:07:04 +05:30
feat(tags): add api to fetch posts by tags and a utility class Tags
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
parent
e62e257154
commit
3da0674031
7 changed files with 66 additions and 2 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright © 2021-2022 Harsh Shandilya.
|
* Copyright © 2021-2023 Harsh Shandilya.
|
||||||
* Use of this source code is governed by an MIT-style
|
* Use of this source code is governed by an MIT-style
|
||||||
* license that can be found in the LICENSE file or at
|
* license that can be found in the LICENSE file or at
|
||||||
* https://opensource.org/licenses/MIT.
|
* https://opensource.org/licenses/MIT.
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
package dev.msfjarvis.claw.api
|
package dev.msfjarvis.claw.api
|
||||||
|
|
||||||
import com.slack.eithernet.ApiResult
|
import com.slack.eithernet.ApiResult
|
||||||
|
import dev.msfjarvis.claw.api.util.Tags
|
||||||
import dev.msfjarvis.claw.model.LobstersPost
|
import dev.msfjarvis.claw.model.LobstersPost
|
||||||
import dev.msfjarvis.claw.model.LobstersPostDetails
|
import dev.msfjarvis.claw.model.LobstersPostDetails
|
||||||
import dev.msfjarvis.claw.model.User
|
import dev.msfjarvis.claw.model.User
|
||||||
|
@ -29,6 +30,12 @@ interface LobstersApi {
|
||||||
@GET("u/{username}.json")
|
@GET("u/{username}.json")
|
||||||
suspend fun getUser(@Path("username") username: String): ApiResult<User, Unit>
|
suspend fun getUser(@Path("username") username: String): ApiResult<User, Unit>
|
||||||
|
|
||||||
|
@GET("t/{tags}.json")
|
||||||
|
suspend fun getPostsByTags(
|
||||||
|
@Path("tags") tag: Tags,
|
||||||
|
@Query("page") page: Int,
|
||||||
|
): ApiResult<List<LobstersPost>, Unit>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val BASE_URL = "https://lobste.rs"
|
const val BASE_URL = "https://lobste.rs"
|
||||||
}
|
}
|
||||||
|
|
23
api/src/main/kotlin/dev/msfjarvis/claw/api/util/Tags.kt
Normal file
23
api/src/main/kotlin/dev/msfjarvis/claw/api/util/Tags.kt
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2023 Harsh Shandilya.
|
||||||
|
* Use of this source code is governed by an MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT.
|
||||||
|
*/
|
||||||
|
package dev.msfjarvis.claw.api.util
|
||||||
|
|
||||||
|
class Tags {
|
||||||
|
private var tags: MutableList<String> = emptyList<String>().toMutableList()
|
||||||
|
|
||||||
|
fun addTag(tag: String) {
|
||||||
|
this.tags.add(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeTag(tag: String) {
|
||||||
|
this.tags.remove(tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return tags.joinToString(",")
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright © 2022 Harsh Shandilya.
|
* Copyright © 2022-2023 Harsh Shandilya.
|
||||||
* Use of this source code is governed by an MIT-style
|
* Use of this source code is governed by an MIT-style
|
||||||
* license that can be found in the LICENSE file or at
|
* license that can be found in the LICENSE file or at
|
||||||
* https://opensource.org/licenses/MIT.
|
* https://opensource.org/licenses/MIT.
|
||||||
|
@ -8,6 +8,7 @@ package dev.msfjarvis.claw.api
|
||||||
|
|
||||||
import com.slack.eithernet.ApiResult.Success
|
import com.slack.eithernet.ApiResult.Success
|
||||||
import com.slack.eithernet.test.newEitherNetController
|
import com.slack.eithernet.test.newEitherNetController
|
||||||
|
import dev.msfjarvis.claw.api.util.Tags
|
||||||
import dev.msfjarvis.claw.model.LobstersPost
|
import dev.msfjarvis.claw.model.LobstersPost
|
||||||
import dev.msfjarvis.claw.model.LobstersPostDetails
|
import dev.msfjarvis.claw.model.LobstersPostDetails
|
||||||
import dev.msfjarvis.claw.model.User
|
import dev.msfjarvis.claw.model.User
|
||||||
|
@ -46,5 +47,24 @@ class ApiTest : FunSpec() {
|
||||||
user.shouldBeTypeOf<Success<User>>()
|
user.shouldBeTypeOf<Success<User>>()
|
||||||
user.value.username shouldBe "msfjarvis"
|
user.value.username shouldBe "msfjarvis"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("get posts by single tag") {
|
||||||
|
var tags = Tags()
|
||||||
|
tags.addTag("meta")
|
||||||
|
val posts = api.getPostsByTags(tags, 1)
|
||||||
|
posts.shouldBeTypeOf<Success<List<LobstersPost>>>()
|
||||||
|
posts.value shouldHaveSize 25
|
||||||
|
posts.value[0].tags.contains("meta")
|
||||||
|
}
|
||||||
|
|
||||||
|
test("get posts by multiple tags") {
|
||||||
|
var tags = Tags()
|
||||||
|
tags.addTag("programming")
|
||||||
|
tags.addTag("rust")
|
||||||
|
val posts = api.getPostsByTags(tags, 1)
|
||||||
|
posts.shouldBeTypeOf<Success<List<LobstersPost>>>()
|
||||||
|
posts.value shouldHaveSize 25
|
||||||
|
posts.value[0].tags.contains("programming") or posts.value[0].tags.contains("rust")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@ class ApiWrapper(controller: EitherNetController<LobstersApi>) {
|
||||||
private val postDetails: LobstersPostDetails =
|
private val postDetails: LobstersPostDetails =
|
||||||
json.decodeFromString(getJson("post_details_tdfoqh.json"))
|
json.decodeFromString(getJson("post_details_tdfoqh.json"))
|
||||||
private val user: User = json.decodeFromString(getJson("msfjarvis.json"))
|
private val user: User = json.decodeFromString(getJson("msfjarvis.json"))
|
||||||
|
private val metaPosts: List<LobstersPost> = json.decodeFromString(getJson("meta.json"))
|
||||||
|
private val programmingRustPosts: List<LobstersPost> =
|
||||||
|
json.decodeFromString(getJson("programming_rust.json"))
|
||||||
|
|
||||||
val api = controller.api
|
val api = controller.api
|
||||||
|
|
||||||
|
@ -36,5 +39,7 @@ class ApiWrapper(controller: EitherNetController<LobstersApi>) {
|
||||||
controller.enqueue(LobstersApi::getHottestPosts) { success(hottest) }
|
controller.enqueue(LobstersApi::getHottestPosts) { success(hottest) }
|
||||||
controller.enqueue(LobstersApi::getPostDetails) { success(postDetails) }
|
controller.enqueue(LobstersApi::getPostDetails) { success(postDetails) }
|
||||||
controller.enqueue(LobstersApi::getUser) { success(user) }
|
controller.enqueue(LobstersApi::getUser) { success(user) }
|
||||||
|
controller.enqueue(LobstersApi::getPostsByTags) { success(metaPosts) }
|
||||||
|
controller.enqueue(LobstersApi::getPostsByTags) { success(programmingRustPosts) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
api/src/test/resources/meta.json
Normal file
1
api/src/test/resources/meta.json
Normal file
File diff suppressed because one or more lines are too long
1
api/src/test/resources/programming_rust.json
Normal file
1
api/src/test/resources/programming_rust.json
Normal file
File diff suppressed because one or more lines are too long
7
detekt-baselines/api.xml
Normal file
7
detekt-baselines/api.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" ?>
|
||||||
|
<SmellBaseline>
|
||||||
|
<ManuallySuppressedIssues></ManuallySuppressedIssues>
|
||||||
|
<CurrentIssues>
|
||||||
|
<ID>MemberNameEqualsClassName:Tags.kt$Tags$private var tags: MutableList<String> = emptyList<String>().toMutableList()</ID>
|
||||||
|
</CurrentIssues>
|
||||||
|
</SmellBaseline>
|
Loading…
Add table
Add a link
Reference in a new issue