huskies: merge 617_story_split_gateway_into_service_and_transport
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
//! Gateway notification polling — pure event formatting.
|
||||
//!
|
||||
//! Formats pipeline events from project containers into gateway notifications
|
||||
//! with `[project-name]` prefixes. The actual I/O (HTTP polling, spawning
|
||||
//! tasks, sending messages) lives in `io.rs`.
|
||||
|
||||
use crate::service::events::StoredEvent;
|
||||
use crate::service::notifications::{
|
||||
format_blocked_notification, format_error_notification, format_stage_notification,
|
||||
stage_display_name,
|
||||
};
|
||||
|
||||
/// Format a [`StoredEvent`] from a project into a gateway notification.
|
||||
///
|
||||
/// Prefixes the message with `[project-name]` so users can distinguish which
|
||||
/// project emitted the event.
|
||||
pub fn format_gateway_event(project_name: &str, event: &StoredEvent) -> (String, String) {
|
||||
let prefix = format!("[{project_name}] ");
|
||||
|
||||
match event {
|
||||
StoredEvent::StageTransition {
|
||||
story_id,
|
||||
from_stage,
|
||||
to_stage,
|
||||
..
|
||||
} => {
|
||||
let from_display = stage_display_name(from_stage);
|
||||
let to_display = stage_display_name(to_stage);
|
||||
let (plain, html) = format_stage_notification(story_id, None, from_display, to_display);
|
||||
(format!("{prefix}{plain}"), format!("{prefix}{html}"))
|
||||
}
|
||||
StoredEvent::MergeFailure {
|
||||
story_id, reason, ..
|
||||
} => {
|
||||
let (plain, html) = format_error_notification(story_id, None, reason);
|
||||
(format!("{prefix}{plain}"), format!("{prefix}{html}"))
|
||||
}
|
||||
StoredEvent::StoryBlocked {
|
||||
story_id, reason, ..
|
||||
} => {
|
||||
let (plain, html) = format_blocked_notification(story_id, None, reason);
|
||||
(format!("{prefix}{plain}"), format!("{prefix}{html}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Tests ────────────────────────────────────────────────────────────────────
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn stage_transition_prefixes_project_name() {
|
||||
let event = StoredEvent::StageTransition {
|
||||
story_id: "42_story_my_feature".to_string(),
|
||||
from_stage: "2_current".to_string(),
|
||||
to_stage: "3_qa".to_string(),
|
||||
timestamp_ms: 1000,
|
||||
};
|
||||
let (plain, html) = format_gateway_event("huskies", &event);
|
||||
assert!(plain.starts_with("[huskies] "));
|
||||
assert!(html.starts_with("[huskies] "));
|
||||
assert!(plain.contains("Current"));
|
||||
assert!(plain.contains("QA"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_failure_prefixes_project_name() {
|
||||
let event = StoredEvent::MergeFailure {
|
||||
story_id: "42_story_my_feature".to_string(),
|
||||
reason: "merge conflict".to_string(),
|
||||
timestamp_ms: 1000,
|
||||
};
|
||||
let (plain, _html) = format_gateway_event("robot-studio", &event);
|
||||
assert!(plain.starts_with("[robot-studio] "));
|
||||
assert!(plain.contains("merge conflict"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn story_blocked_prefixes_project_name() {
|
||||
let event = StoredEvent::StoryBlocked {
|
||||
story_id: "43_story_bar".to_string(),
|
||||
reason: "retry limit exceeded".to_string(),
|
||||
timestamp_ms: 2000,
|
||||
};
|
||||
let (plain, _html) = format_gateway_event("huskies", &event);
|
||||
assert!(plain.starts_with("[huskies] "));
|
||||
assert!(plain.contains("BLOCKED"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user