Skip to content

Commit 7ec580d

Browse files
committed
fix: update selectors and test assertions
1 parent 18b33e5 commit 7ec580d

7 files changed

Lines changed: 65 additions & 56 deletions

File tree

api/src/main/kotlin/dev/msfjarvis/claw/api/converters/SearchConverter.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ object SearchConverter : Converter<ResponseBody, List<LobstersPost>> {
3131
val url = titleElement.attr("href")
3232
val tags = elem.select("span.tags > a").map(Element::text)
3333
val (commentCount, commentsUrl) = getCommentsData(elem.select("span.comments_label"))
34-
val submitter = elem.select("div.byline > a.u-author").text()
34+
val submitter =
35+
elem.select("div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])").text()
3536
val userIsAuthor =
3637
(elem.select("div.byline > span").first()?.text() ?: "").contains(
3738
"authored",

api/src/test/kotlin/dev/msfjarvis/claw/api/ApiTest.kt

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,34 @@ class ApiTest {
4545
assertIs<Success<PostsPage>>(posts)
4646

4747
val firstPost = posts.value.posts[0]
48-
assertThat(firstPost.shortId).isEqualTo("ho7nqt")
49-
assertThat(firstPost.title).isEqualTo("On forking the Web")
50-
assertThat(firstPost.submitter).isEqualTo("spc476")
51-
assertThat(firstPost.commentCount).isEqualTo(33)
52-
assertThat(firstPost.commentsUrl).isEqualTo("https://lobste.rs/s/ho7nqt/on_forking_web")
53-
assertThat(firstPost.tags).containsExactly("web")
54-
assertThat(firstPost.userIsAuthor).isFalse()
55-
assertThat(firstPost.createdAt).isEqualTo("2026-05-09T10:03:17Z")
48+
assertThat(firstPost.shortId).isEqualTo("jp3nva")
49+
assertThat(firstPost.title).isEqualTo("You probably don't need Yocto, and that's fine")
50+
assertThat(firstPost.submitter).isEqualTo("rw-rw-rw-")
51+
assertThat(firstPost.commentCount).isEqualTo(9)
52+
assertThat(firstPost.commentsUrl)
53+
.isEqualTo("https://lobste.rs/s/jp3nva/you_probably_don_t_need_yocto_s_fine")
54+
assertThat(firstPost.tags).containsExactly("linux")
55+
assertThat(firstPost.userIsAuthor).isTrue()
56+
assertThat(firstPost.createdAt).isEqualTo("2026-05-29T09:08:12Z")
5657
DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(firstPost.createdAt)
5758

5859
val secondPost = posts.value.posts[1]
59-
assertThat(secondPost.shortId).isEqualTo("vbit2a")
60-
assertThat(secondPost.title).isEqualTo("I Will Not Add Query Strings to Your URLs")
61-
assertThat(secondPost.submitter).isEqualTo("susam")
62-
assertThat(secondPost.commentCount).isEqualTo(2)
60+
assertThat(secondPost.shortId).isEqualTo("lc26ar")
61+
assertThat(secondPost.title).isEqualTo("SQLite Does Not Accept Agentic Code")
62+
assertThat(secondPost.submitter).isEqualTo("hoistbypetard")
63+
assertThat(secondPost.commentCount).isEqualTo(15)
6364
assertThat(secondPost.commentsUrl)
64-
.isEqualTo("https://lobste.rs/s/vbit2a/i_will_not_add_query_strings_your_urls")
65-
assertThat(secondPost.tags).containsExactly("web")
66-
assertThat(secondPost.userIsAuthor).isTrue()
65+
.isEqualTo("https://lobste.rs/s/lc26ar/sqlite_does_not_accept_agentic_code")
66+
assertThat(secondPost.tags).containsExactly("vibecoding")
67+
assertThat(secondPost.userIsAuthor).isFalse()
6768

68-
val noCommentsPost = posts.value.posts.first { it.shortId == "sjbrlg" }
69-
assertThat(noCommentsPost.title).isEqualTo("Yggdrasil Network as an Embedded Go Library")
70-
assertThat(noCommentsPost.submitter).isEqualTo("asciimoth")
69+
val noCommentsPost = posts.value.posts.first { it.shortId == "1fkt8w" }
70+
assertThat(noCommentsPost.title).isEqualTo("Patching my guitar amp's firmware")
71+
assertThat(noCommentsPost.submitter).isEqualTo("mcf")
7172
assertThat(noCommentsPost.commentCount).isEqualTo(0)
7273
assertThat(noCommentsPost.commentsUrl)
73-
.isEqualTo("https://lobste.rs/s/sjbrlg/yggdrasil_network_as_embedded_go_library")
74-
assertThat(noCommentsPost.tags)
75-
.containsExactly("distributed", "go", "networking", "programming")
74+
.isEqualTo("https://lobste.rs/s/1fkt8w/patching_my_guitar_amp_s_firmware")
75+
assertThat(noCommentsPost.tags).containsExactly("hardware", "reversing")
7676
assertThat(noCommentsPost.userIsAuthor).isTrue()
7777
}
7878

@@ -166,7 +166,7 @@ class ApiTest {
166166
assertIs<Success<CSRFToken>>(token)
167167
assertThat(token.value.value)
168168
.isEqualTo(
169-
"RPe1m3JaXAq0ti7t15hNixpLvmgJ793Ti6y4fOpxtfenyXQK3WU19m7MJb8RGoIf-tC3C9Ilwb8pv0WJUWLbNA"
169+
"dvJ8r_CkOImcHQ5ZLUWlJeQVoPEPQ3rK85DNgiZJcehafqwYP8jESW8AhMf0uQGLqqLbsarYiISCghnDaUd6wA"
170170
)
171171
}
172172

api/src/test/kotlin/dev/msfjarvis/claw/api/SearchApiTest.kt

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,26 @@ class SearchApiTest {
3131
private val results =
3232
listOf(
3333
LobstersPost(
34-
shortId = "vvky3g",
34+
shortId = "kgem4b",
3535
createdAt = "",
36-
title = "2024 State of Rust Survey Results",
37-
url = "https://blog.rust-lang.org/2025/02/13/2024-State-Of-Rust-Survey-results.html",
36+
title = "The social contract of writing",
37+
url = "https://jola.dev/posts/the-social-contract-of-writing",
3838
description = "",
39-
commentCount = 10,
40-
commentsUrl = "https://lobste.rs/s/vvky3g/2024_state_rust_survey_results",
41-
submitter = "obsoleszenz",
42-
userIsAuthor = false,
43-
tags = listOf("rust"),
39+
commentCount = 38,
40+
commentsUrl = "https://lobste.rs/s/kgem4b/social_contract_writing",
41+
submitter = "joladev",
42+
userIsAuthor = true,
43+
tags = listOf("philosophy", "vibecoding"),
4444
),
4545
LobstersPost(
46-
shortId = "wjoric",
46+
shortId = "gydtkf",
4747
createdAt = "",
48-
title = "New hack uses prompt injection to corrupt Gemini’s long-term memory",
49-
url =
50-
"https://arstechnica.com/security/2025/02/new-hack-uses-prompt-injection-to-corrupt-geminis-long-term-memory/",
48+
title = "AI Resist List",
49+
url = "https://airesistlist.org/",
5150
description = "",
5251
commentCount = 0,
53-
commentsUrl = "https://lobste.rs/s/wjoric/new_hack_uses_prompt_injection_corrupt",
54-
submitter = "laktak",
52+
commentsUrl = "https://lobste.rs/s/gydtkf/ai_resist_list",
53+
submitter = "chobeat",
5554
userIsAuthor = false,
5655
tags = listOf("ai"),
5756
),

api/src/test/kotlin/dev/msfjarvis/claw/api/converters/CSRFTokenConverterTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class CSRFTokenConverterTest {
2222

2323
assertThat(token.value)
2424
.isEqualTo(
25-
"RPe1m3JaXAq0ti7t15hNixpLvmgJ793Ti6y4fOpxtfenyXQK3WU19m7MJb8RGoIf-tC3C9Ilwb8pv0WJUWLbNA"
25+
"dvJ8r_CkOImcHQ5ZLUWlJeQVoPEPQ3rK85DNgiZJcehafqwYP8jESW8AhMf0uQGLqqLbsarYiISCghnDaUd6wA"
2626
)
2727
}
2828

api/src/test/kotlin/dev/msfjarvis/claw/api/converters/SearchConverterTest.kt

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,26 @@ class SearchConverterTest {
2525
assertThat(posts)
2626
.containsAtLeast(
2727
LobstersPost(
28-
shortId = "vvky3g",
28+
shortId = "kgem4b",
2929
createdAt = "",
30-
title = "2024 State of Rust Survey Results",
31-
url = "https://blog.rust-lang.org/2025/02/13/2024-State-Of-Rust-Survey-results.html",
30+
title = "The social contract of writing",
31+
url = "https://jola.dev/posts/the-social-contract-of-writing",
3232
description = "",
33-
commentCount = 10,
34-
commentsUrl = "https://lobste.rs/s/vvky3g/2024_state_rust_survey_results",
35-
submitter = "obsoleszenz",
36-
userIsAuthor = false,
37-
tags = listOf("rust"),
33+
commentCount = 38,
34+
commentsUrl = "https://lobste.rs/s/kgem4b/social_contract_writing",
35+
submitter = "joladev",
36+
userIsAuthor = true,
37+
tags = listOf("philosophy", "vibecoding"),
3838
),
3939
LobstersPost(
40-
shortId = "wjoric",
40+
shortId = "gydtkf",
4141
createdAt = "",
42-
title = "New hack uses prompt injection to corrupt Gemini’s long-term memory",
43-
url =
44-
"https://arstechnica.com/security/2025/02/new-hack-uses-prompt-injection-to-corrupt-geminis-long-term-memory/",
42+
title = "AI Resist List",
43+
url = "https://airesistlist.org/",
4544
description = "",
4645
commentCount = 0,
47-
commentsUrl = "https://lobste.rs/s/wjoric/new_hack_uses_prompt_injection_corrupt",
48-
submitter = "laktak",
46+
commentsUrl = "https://lobste.rs/s/gydtkf/ai_resist_list",
47+
submitter = "chobeat",
4948
userIsAuthor = false,
5049
tags = listOf("ai"),
5150
),

model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPost.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,15 @@ class LobstersPost(
5050
val commentCount: Int = 0,
5151
@Selector("> div.story_liner span.comments_label a", attr = "abs:href", defValue = "")
5252
val commentsUrl: String = "",
53-
@Selector("> div.story_liner div.byline > a.u-author")
53+
@Selector("> div.story_liner div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])")
5454
@SerialName("submitter_user")
5555
val submitter: String,
5656
@Serializable(with = UserIsAuthorSerializer::class)
57-
@Selector("> div.story_liner div.byline > a.u-author", attr = "class", defValue = "")
57+
@Selector(
58+
"> div.story_liner div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])",
59+
attr = "class",
60+
defValue = "",
61+
)
5862
@SerialName("user_is_author")
5963
val userIsAuthor: Boolean = false,
6064
@Selector("> div.story_liner span.tags > a") val tags: List<String> = emptyList(),

model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPostDetails.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,21 @@ class LobstersPostDetails(
4747
val commentCount: Int = 0,
4848
@Selector("ol.stories > li.story span.comments_label a", attr = "abs:href", defValue = "")
4949
val commentsUrl: String = "",
50-
@Selector("ol.stories > li.story div.byline > a.u-author")
50+
@Selector(
51+
"ol.stories > li.story div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])"
52+
)
5153
@SerialName("submitter_user")
5254
val submitter: String,
5355
@Selector("ol.stories > li.story span.tags > a") val tags: List<String> = emptyList(),
5456
@Serializable(with = CommentsSerializer::class)
5557
@Selector("ol.comments > li.comments_subtree")
5658
val comments: List<Comment> = emptyList(),
5759
@Serializable(with = UserIsAuthorSerializer::class)
58-
@Selector("ol.stories > li.story div.byline > a.u-author", attr = "class", defValue = "")
60+
@Selector(
61+
"ol.stories > li.story div.byline > a[href^=/~]:not([tabindex]):not([aria-hidden=true])",
62+
attr = "class",
63+
defValue = "",
64+
)
5965
@SerialName("user_is_author")
6066
val userIsAuthor: Boolean = false,
6167
)

0 commit comments

Comments
 (0)