Skeletons for new files only; existing files change by exact edits, so no task overwrites an earlier one's work. Each task's tests were run against a reference built in order from master, with the gate at each step and mutations checked; each skeleton compiles and fails its tests, and every todo!() comment was read beside its signature. The reference is kept off this machine. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
130 lines
3.7 KiB
Rust
130 lines
3.7 KiB
Rust
//! Editing a post and looking up a username, against a scripted server (M4b spec, sections 6 and
|
|
//! 7). Do not edit.
|
|
|
|
#[path = "support/http_server.rs"]
|
|
mod http_server;
|
|
#[path = "support/tls_server.rs"]
|
|
mod tls_server;
|
|
|
|
use std::net::SocketAddr;
|
|
use std::time::Duration;
|
|
|
|
use gatewayd::config::ServerUrl;
|
|
use gatewayd::mm::MmError;
|
|
use gatewayd::mm::rest::Client;
|
|
use gatewayd::net::Connector;
|
|
use gatewayd::secrets::Secret;
|
|
use http_server::{reply, serve_http};
|
|
use serde_json::json;
|
|
|
|
const BOT: &str = "b0000000000000000000000000";
|
|
const KYLE: &str = "k0000000000000000000000000";
|
|
const DM: &str = "d0000000000000000000000000";
|
|
const POST: &str = "p0000000000000000000000001";
|
|
const WAIT: Duration = Duration::from_secs(5);
|
|
|
|
fn client(addr: SocketAddr) -> Client {
|
|
let url = ServerUrl {
|
|
tls: false,
|
|
host: "localhost".to_string(),
|
|
port: addr.port(),
|
|
};
|
|
Client::new(
|
|
Connector::new(url, None).unwrap(),
|
|
Secret::new("TOKEN".to_string()),
|
|
WAIT,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn a_post_is_patched_with_its_new_text() {
|
|
let (addr, rx) = serve_http(None, |_, r| {
|
|
let text = r.json()["message"].as_str().unwrap().to_string();
|
|
let post = json!({"id": POST, "user_id": BOT, "channel_id": DM, "root_id": "", "message": text, "create_at": 5, "is_pinned": false});
|
|
reply(200, "", &post.to_string())
|
|
});
|
|
client(addr)
|
|
.patch_post(
|
|
POST,
|
|
"**Approval 42**\n✅ Approved by @kyle: the call runs.",
|
|
)
|
|
.unwrap();
|
|
let r = rx.recv_timeout(WAIT).unwrap();
|
|
assert_eq!(
|
|
(r.method.as_str(), r.path.as_str()),
|
|
("PUT", format!("/api/v4/posts/{POST}/patch").as_str())
|
|
);
|
|
assert!(
|
|
r.head.contains("Authorization: Bearer TOKEN\r\n"),
|
|
"{}",
|
|
r.head
|
|
);
|
|
assert_eq!(
|
|
r.json(),
|
|
json!({"message": "**Approval 42**\n✅ Approved by @kyle: the call runs."})
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn a_post_that_is_not_an_id_is_never_sent() {
|
|
let (addr, rx) = serve_http(None, |_, _| reply(200, "", "{}"));
|
|
for bad in ["../users/me", "", "P0000000000000000000000001"] {
|
|
assert!(
|
|
matches!(client(addr).patch_post(bad, "x"), Err(MmError::Json(_))),
|
|
"{bad:?}"
|
|
);
|
|
assert!(
|
|
matches!(client(addr).username(bad), Err(MmError::Json(_))),
|
|
"{bad:?}"
|
|
);
|
|
}
|
|
std::thread::sleep(Duration::from_millis(100));
|
|
assert!(rx.try_recv().is_err(), "nothing was sent");
|
|
}
|
|
|
|
#[test]
|
|
fn a_refused_edit_is_an_error() {
|
|
let (addr, _rx) = serve_http(None, |_, _| {
|
|
reply(
|
|
403,
|
|
"",
|
|
r#"{"id":"api.post.update_post.permissions_details.app_error"}"#,
|
|
)
|
|
});
|
|
assert!(matches!(
|
|
client(addr).patch_post(POST, "x"),
|
|
Err(MmError::Auth(403))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn the_username_of_a_user() {
|
|
let (addr, rx) = serve_http(None, |_, _| {
|
|
reply(
|
|
200,
|
|
"",
|
|
&json!({"id": KYLE, "username": "kyle", "first_name": "K", "roles": "system_user"})
|
|
.to_string(),
|
|
)
|
|
});
|
|
assert_eq!(client(addr).username(KYLE).unwrap(), "kyle");
|
|
let r = rx.recv_timeout(WAIT).unwrap();
|
|
assert_eq!(
|
|
(r.method.as_str(), r.path.as_str()),
|
|
("GET", format!("/api/v4/users/{KYLE}").as_str())
|
|
);
|
|
for bad in [
|
|
json!({"id": KYLE}),
|
|
json!({"id": KYLE, "username": ""}),
|
|
json!({"id": KYLE, "username": "Kyle\n@channel"}),
|
|
json!({"id": KYLE, "username": "x".repeat(65)}),
|
|
] {
|
|
let body = bad.to_string();
|
|
let (addr, _rx) = serve_http(None, move |_, _| reply(200, "", &body));
|
|
assert!(
|
|
matches!(client(addr).username(KYLE), Err(MmError::Json(_))),
|
|
"{bad}"
|
|
);
|
|
}
|
|
}
|