fix(forge,claw): forge keys separate the issue from the pull

The watch key encoded source, repo, and number but not the thread
kind, and on GitLab an issue and a merge request share one number
space: iid 7 twice produced one key, one snapshot, and comments on
the merge request landing in the issue (or a 404 fallback that
misrouted the other way). The key carries the kind now —
{source}:{kind}:{owner}/{name}#{number}, with GitLab spelling the
pull variant mr — comment and snapshot route outright by kind, and a
kind-less payload parses to the unparsable key instead of guessing
issue. The claw's callers thread the kind from the payload and strip
the segment where the bare repo is wanted; pre-kind stored keys parse
as None rather than misroute. Four route-pinning wiremock tests cover
the GitLab split, and the GitHub/Gitea clients take the kind without
using it (their issues and PRs share the same REST space).
This commit is contained in:
vhaudiquet committed 2026-11-05 19:03:52 +01:00
1 parent 10efe85f38
commit 00adf092ff
15 files changed
+478 -178

No files matched your search

@@ -2,7 +2,8 @@
//! wiremock server. Zero network.
use rhema_forge_integration::{
EventKind, Forge, ForgeError, GiteaForge, NotificationReason, RepoRef, Timestamp,
EventKind, Forge, ForgeError, ForgeThreadKind, GiteaForge, NotificationReason, RepoRef,
Timestamp,
};
use serde_json::{Value, json};
use wiremock::matchers::{header, method, path, query_param};
@@ -311,7 +312,12 @@ async fn posting_a_comment_uses_the_token_header_and_the_issues_endpoint() {
.await;
forge(&server)
.comment(&RepoRef::new("acme", "widgets"), 4, "on it")
.comment(
&RepoRef::new("acme", "widgets"),
ForgeThreadKind::Issue,
4,
"on it",
)
.await
.expect("comment posts");
@@ -360,7 +366,7 @@ async fn snapshot_reads_prs_through_the_pulls_row() {
let repo = RepoRef::new("acme", "widgets");
let issue = forge(&server)
.snapshot(&repo, 7)
.snapshot(&repo, ForgeThreadKind::Issue, 7)
.await
.expect("issue snapshot");
assert_eq!(issue.state, rhema_forge_integration::ThreadState::Open);
@@ -368,7 +374,7 @@ async fn snapshot_reads_prs_through_the_pulls_row() {
assert_eq!(issue.labels, vec!["bug".to_owned()]);
let pull = forge(&server)
.snapshot(&repo, 3)
.snapshot(&repo, ForgeThreadKind::PullRequest, 3)
.await
.expect("pull snapshot");
assert_eq!(pull.state, rhema_forge_integration::ThreadState::Merged);
@@ -387,7 +393,7 @@ async fn trailing_slashes_in_the_base_url_are_trimmed() {
let forge = GiteaForge::new(format!("{}/", server.uri()), "tok");
forge
.snapshot(&RepoRef::new("acme", "widgets"), 7)
.snapshot(&RepoRef::new("acme", "widgets"), ForgeThreadKind::Issue, 7)
.await
.expect("the trimmed base reaches the same path");
}