refactor(server): tidy webhook wiring and test-helper context

- Distinguish the two GitHub webhook auth-failure warn messages (missing
  signature header vs. HMAC mismatch) so logs can tell them apart.
- Route update_github_app_webhook through fabro_github::github_api_base_url()
  so GITHUB_BASE_URL overrides the webhook config endpoint too.
- Drop a narrative shutdown comment that restated the next two lines.
- Replace concat!(file!(), ":", line!()) inside local test-helper wrappers;
  those macros expand at the wrapper definition site, so every panic
  reported the same phantom location. Pass the wrapper name instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-04-20 08:27:50 -04:00
parent 6829935649
commit 86bb88cdca
No known key found for this signature in database
6 changed files with 14 additions and 14 deletions

View file

@ -151,8 +151,9 @@ pub(crate) async fn update_github_app_webhook(
"content_type": "json",
});
let url = format!("{}/app/hook/config", fabro_github::github_api_base_url());
let resp = client
.patch("https://api.github.com/app/hook/config")
.patch(&url)
.header("Authorization", format!("Bearer {jwt}"))
.header("Accept", "application/vnd.github+json")
.header("User-Agent", "fabro")

View file

@ -345,7 +345,7 @@ mod tests {
}
async fn assert_status(response: axum::response::Response, expected: StatusCode) {
assert_axum_status(response, expected, concat!(file!(), ":", line!())).await;
assert_axum_status(response, expected, "assert_status").await;
}
#[test]

View file

@ -299,11 +299,11 @@ mod tests {
}
async fn response_json(response: axum::response::Response) -> serde_json::Value {
expect_axum_json(response, StatusCode::OK, concat!(file!(), ":", line!())).await
expect_axum_json(response, StatusCode::OK, "response_json").await
}
async fn assert_status(response: axum::response::Response, expected: StatusCode) {
assert_axum_status(response, expected, concat!(file!(), ":", line!())).await;
assert_axum_status(response, expected, "assert_status").await;
}
fn dev_token_mode() -> AuthMode {

View file

@ -649,7 +649,6 @@ where
let _ = child.wait();
}
// Clean up webhook listener on shutdown
if let Some(manager) = webhook_manager {
manager.shutdown().await;
}

View file

@ -1250,12 +1250,12 @@ async fn github_webhook(
.get("x-hub-signature-256")
.and_then(|value| value.to_str().ok())
else {
warn!(delivery = %delivery_id, "Webhook signature verification failed");
warn!(delivery = %delivery_id, "Webhook missing X-Hub-Signature-256 header");
return StatusCode::UNAUTHORIZED;
};
if !verify_signature(&secret, &body, signature) {
warn!(delivery = %delivery_id, "Webhook signature verification failed");
warn!(delivery = %delivery_id, "Webhook HMAC signature mismatch");
return StatusCode::UNAUTHORIZED;
}
@ -7416,25 +7416,25 @@ mod tests {
}
async fn assert_status(response: axum::response::Response, expected: StatusCode) {
assert_axum_status(response, expected, concat!(file!(), ":", line!())).await;
assert_axum_status(response, expected, "assert_status").await;
}
async fn checked_response(
response: axum::response::Response,
expected: StatusCode,
) -> axum::response::Response {
expect_axum_status(response, expected, concat!(file!(), ":", line!())).await
expect_axum_status(response, expected, "checked_response").await
}
async fn response_json(
response: axum::response::Response,
expected: StatusCode,
) -> serde_json::Value {
expect_axum_json(response, expected, concat!(file!(), ":", line!())).await
expect_axum_json(response, expected, "response_json").await
}
async fn response_bytes(response: axum::response::Response, expected: StatusCode) -> Vec<u8> {
expect_axum_bytes(response, expected, concat!(file!(), ":", line!())).await
expect_axum_bytes(response, expected, "response_bytes").await
}
fn api(path: &str) -> String {

View file

@ -740,18 +740,18 @@ mod tests {
}
async fn response_json(response: axum::response::Response) -> Value {
expect_axum_json(response, StatusCode::OK, concat!(file!(), ":", line!())).await
expect_axum_json(response, StatusCode::OK, "response_json").await
}
async fn assert_status(response: axum::response::Response, expected: StatusCode) {
assert_axum_status(response, expected, concat!(file!(), ":", line!())).await;
assert_axum_status(response, expected, "assert_status").await;
}
async fn checked_response(
response: axum::response::Response,
expected: StatusCode,
) -> axum::response::Response {
fabro_test::expect_axum_status(response, expected, concat!(file!(), ":", line!())).await
fabro_test::expect_axum_status(response, expected, "checked_response").await
}
#[tokio::test]