use std::time::Duration;
use crate::types::ApiRuntimeConfig;
const NOTIFY_TIMEOUT: Duration = Duration::from_millis(250);
pub fn notify_task_changed(api: &ApiRuntimeConfig) -> Result<(), ureq::Error> {
let url = format!("http://127.0.0.1:{}/api/events/tasks-changed", api.port);
let agent: ureq::Agent = ureq::Agent::config_builder()
.timeout_global(Some(NOTIFY_TIMEOUT))
.build()
.into();
agent.post(&url).send_empty()?;
Ok(())
}
#[cfg(test)]
mod tests {
use std::io::{Read, Write};
use std::net::TcpListener;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use crate::types::ApiRuntimeConfig;
use super::notify_task_changed;
#[test]
fn posts_task_change_notification_to_the_local_api() {
let listener = TcpListener::bind("127.0.0.1:0").expect("listener should bind");
let port = listener
.local_addr()
.expect("listener should expose local address")
.port();
let (sender, receiver) = mpsc::channel();
let server = thread::spawn(move || {
let (mut stream, _) = listener.accept().expect("listener should accept");
let mut buffer = [0u8; 1024];
let bytes_read = stream
.read(&mut buffer)
.expect("request should be readable");
stream
.write_all(
b"HTTP/1.1 204 No Content\r\nContent-Length: 0\r\nConnection: close\r\n\r\n",
)
.expect("response should be writable");
sender
.send(String::from_utf8_lossy(&buffer[..bytes_read]).into_owned())
.expect("request should reach the test thread");
});
notify_task_changed(&ApiRuntimeConfig { port }).expect("notification should succeed");
let request = receiver
.recv_timeout(Duration::from_secs(1))
.expect("notification should be received");
assert!(request.starts_with("POST /api/events/tasks-changed HTTP/1.1"));
server.join().expect("server thread should exit cleanly");
}
}