diff --git a/src/forge/gitea/api_tests.rs b/src/forge/gitea/api_tests.rs
index 6adcefb9..1011af20 100644
--- a/src/forge/gitea/api_tests.rs
+++ b/src/forge/gitea/api_tests.rs
@@ -111,22 +111,44 @@ fn publish_release_patches_draft_false() {
}
#[test]
-fn find_comment_matches_the_marker_on_the_issue_thread() {
- let server = FakeServer::start(vec![Reply::json(
- 200,
- json!([
- { "id": 1, "body": "hello" },
- { "id": 2, "body": " preview" },
- ]),
- )]);
+fn find_comment_only_matches_the_tokens_own_comments() {
+ let server = FakeServer::start(vec![
+ Reply::json(
+ 200,
+ json!([
+ { "id": 1, "body": "hello", "user": { "login": "me" } },
+ { "id": 2, "body": " preview", "user": { "login": "me" } },
+ { "id": 3, "body": " quoted", "user": { "login": "someone" } },
+ ]),
+ ),
+ Reply::json(200, json!({ "login": "me" })),
+ ]);
let found = forge(&server).find_comment(8, "").unwrap();
assert_eq!(found, Some(2));
+ let requests = server.requests();
assert_eq!(
- server.only_request().path,
+ requests[0].path,
"/repos/owner/repo/issues/8/comments?limit=50&page=1"
);
+ assert_eq!(requests[1].path, "/user");
+}
+
+#[test]
+fn find_comment_matches_nothing_when_the_token_cannot_read_its_user() {
+ let server = FakeServer::start(vec![
+ Reply::json(
+ 200,
+ json!([{ "id": 2, "body": "", "user": { "login": "me", "type": "Bot" } }]),
+ ),
+ Reply::json(403, json!({})),
+ ]);
+
+ assert_eq!(
+ forge(&server).find_comment(8, "").unwrap(),
+ None
+ );
}
#[test]
diff --git a/src/forge/github/api_tests.rs b/src/forge/github/api_tests.rs
index 3130a194..5f485546 100644
--- a/src/forge/github/api_tests.rs
+++ b/src/forge/github/api_tests.rs
@@ -284,24 +284,86 @@ fn a_transport_failure_on_auto_merge_uses_the_request_code() {
assert_eq!(code(&err).as_deref(), Some("E3008"));
}
+fn marked_comment(id: u64, login: &str, kind: &str) -> serde_json::Value {
+ json!({
+ "id": id,
+ "body": "\npreview",
+ "user": { "login": login, "type": kind },
+ })
+}
+
#[test]
-fn find_comment_returns_the_first_comment_carrying_the_marker() {
- let server = FakeServer::start(vec![Reply::json(
- 200,
- json!([
- { "id": 1, "body": "looks good" },
- { "id": 2, "body": "\npreview" },
- { "id": 3, "body": " again" },
- ]),
- )]);
+fn find_comment_skips_a_foreign_comment_and_prefers_the_most_recent_own_one() {
+ let server = FakeServer::start(vec![
+ Reply::json(
+ 200,
+ json!([
+ { "id": 1, "body": "looks good", "user": { "login": "me", "type": "User" } },
+ marked_comment(2, "me", "User"),
+ marked_comment(3, "me", "User"),
+ marked_comment(4, "someone", "User"),
+ ]),
+ ),
+ Reply::json(200, json!({ "login": "me" })),
+ ]);
let found = forge(&server).find_comment(5, "").unwrap();
- assert_eq!(found, Some(2));
+ assert_eq!(found, Some(3));
+ let requests = server.requests();
assert_eq!(
- server.only_request().path,
+ requests[0].path,
"/repos/owner/repo/issues/5/comments?per_page=100&page=1"
);
+ assert_eq!(requests[1].path, "/user");
+}
+
+#[test]
+fn find_comment_is_none_when_only_someone_else_carries_the_marker() {
+ let server = FakeServer::start(vec![
+ Reply::json(200, json!([marked_comment(4, "someone", "User")])),
+ Reply::json(200, json!({ "login": "me" })),
+ ]);
+
+ assert_eq!(
+ forge(&server).find_comment(5, "").unwrap(),
+ None
+ );
+}
+
+#[test]
+fn find_comment_with_an_integration_token_only_matches_bots() {
+ let server = FakeServer::start(vec![
+ Reply::json(
+ 200,
+ json!([
+ marked_comment(2, "github-actions[bot]", "Bot"),
+ marked_comment(4, "someone", "User"),
+ ]),
+ ),
+ Reply::json(
+ 403,
+ json!({ "message": "Resource not accessible by integration" }),
+ ),
+ ]);
+
+ let found = forge(&server).find_comment(5, "").unwrap();
+
+ assert_eq!(found, Some(2));
+}
+
+#[test]
+fn find_comment_propagates_a_server_error_from_the_identity_lookup() {
+ let server = FakeServer::start(vec![
+ Reply::json(200, json!([marked_comment(2, "me", "User")])),
+ Reply::json(500, json!({})),
+ ]);
+
+ let err = forge(&server)
+ .find_comment(5, "")
+ .unwrap_err();
+
+ assert!(format!("{err:#}").contains("token's user"), "{err:#}");
}
#[test]
diff --git a/src/forge/gitlab.rs b/src/forge/gitlab.rs
index db1f37df..83e158b0 100644
--- a/src/forge/gitlab.rs
+++ b/src/forge/gitlab.rs
@@ -64,6 +64,29 @@ impl GitLabForge {
what,
)
}
+
+ fn token_username(&self) -> Result