johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
//! Choosing what one hears of from the pages: watching a repository, and
//! subscribing to or muting an issue, each kept by the appview for the
//! account alone, and shown back on the repository's and the issue's
//! pages.
use super::*;
/// The `name=value` of the session cookie a login set.
fn session(set: &[String]) -> String {
let found = set.iter().find(|c| c.starts_with("knotless_session="));
pair(found.unwrap()).to_string()
}
#[test]
fn watching_and_subscribing_from_the_pages() {
// Started first, so its index sees the repositories made after.
let server = gateway_with(None, true);
let owner = person(account());
let url = owner.url("watched");
let work = owner.work("w", 1);
owner.git(&work, &["push", "-q", &url, "main"]);
let (code, issue) = owner.cli(&["issue", "create", &url, "Slow", "-m", "It is."], b"");
assert_eq!(code, 0, "{issue}");
let repo = format!("at://{}/dev.knotless.repo/watched", owner.account.did);
let xrpc = |nsid: &str| format!("{}/xrpc/dev.knotless.{nsid}", server.base);
let thread = |cookie: Option<&str>| {
let url = format!("{}?repo={repo}&uri={issue}", xrpc("getThread"));
browse("GET", &url, cookie, None, None).2
};
let get_repo = |cookie: Option<&str>| {
let url = format!("{}?repo={repo}", xrpc("getRepo"));
browse("GET", &url, cookie, None, None).2
};
let put = |cookie: Option<&str>, subject: &str, level: &str| {
let body = json!({"subject": subject, "level": level});
browse("POST", &xrpc("putSubscription"), cookie, None, Some(body))
};
let list = |cookie: Option<&str>, query: &str| {
let url = format!("{}{query}", xrpc("listSubscriptions"));
browse("GET", &url, cookie, None, None)
};
wait_until(|| thread(None)["item"]["title"] == "Slow");
let watcher = person(account());
let mine = session(&log_in(&server, &watcher.account, ""));
let me = Some(mine.as_str());
let theirs = session(&log_in(&server, &owner.account, ""));
let owning = Some(theirs.as_str());
// Nothing chosen: it hears of the issue only when mentioned, and its
// author as its author.
assert_eq!(thread(me)["viewer"].get("notifiedFor"), None);
assert_eq!(thread(owning)["viewer"]["notifiedFor"], "author");
assert_eq!(get_repo(me)["viewer"].get("subscription"), None);
assert_eq!(list(me, "").2, json!({"subscriptions": []}));
// Watching the repository, it hears of the issue as watching.
let (status, _, now) = put(me, &repo, "all");
assert_eq!(status, 200, "{now}");
assert_eq!(
(&now["subject"], &now["level"]),
(&json!(repo), &json!("all"))
);
assert!(now["createdAt"].is_string());
assert_eq!(get_repo(me)["viewer"]["subscription"], "all");
assert_eq!(thread(me)["viewer"]["notifiedFor"], "watching");
// Subscribed to the issue, then muted, as it chose.
assert_eq!(put(me, &issue, "subscribed").2["level"], "subscribed");
assert_eq!(thread(me)["viewer"]["subscription"], "subscribed");
assert_eq!(put(me, &issue, "muted").2["level"], "muted");
assert_eq!(thread(me)["viewer"]["subscription"], "muted");
// Having commented, it hears of the thread as one who did.
let said = json!({"repo": repo, "subject": issue, "body": "Same here."});
let commented = browse("POST", &xrpc("createComment"), me, None, Some(said));
assert_eq!(commented.0, 200, "{}", commented.2);
assert_eq!(thread(me)["viewer"]["notifiedFor"], "commented");
// Listed, the latest choice first, a page at a time.
let all = list(me, "").2;
let subjects: Vec<&str> = all["subscriptions"]
.as_array()
.unwrap()
.iter()
.map(|s| s["subject"].as_str().unwrap())
.collect();
assert_eq!(subjects, [issue.as_str(), repo.as_str()]);
let first = list(me, "?limit=1").2;
assert_eq!(first["subscriptions"].as_array().unwrap().len(), 1);
assert_eq!(first["cursor"], "1");
let next = list(me, "?limit=1&cursor=1").2;
assert_eq!(next["subscriptions"][0]["subject"], repo.as_str());
assert_eq!(next.get("cursor"), None);
assert_eq!(list(me, "?cursor=x").0, 400);
// Forgotten, as participating.
let forgot = put(me, &repo, "participating").2;
assert_eq!(forgot, json!({"subject": repo, "level": "participating"}));
assert_eq!(get_repo(me)["viewer"].get("subscription"), None);
// Refused: a level the subject cannot take, what is no repository,
// pull or issue, a repository there is none of, no one asking, and
// from another site.
assert_eq!(put(me, &repo, "muted").0, 400);
assert_eq!(put(me, &issue, "all").0, 400);
let comment = commented.2["uri"].as_str().unwrap().to_string();
assert_eq!(put(me, &comment, "subscribed").0, 400);
assert_eq!(put(me, "nowhere", "all").0, 400);
let gone = format!("at://{}/dev.knotless.repo/none", owner.account.did);
assert_eq!(put(me, &gone, "all").0, 404);
assert_eq!(put(None, &repo, "all").0, 401);
assert_eq!(list(None, "").0, 401);
let body = Some(json!({"subject": repo, "level": "all"}));
let away = Some("https://evil.example");
assert_eq!(
browse("POST", &xrpc("putSubscription"), me, away, body).0,
403
);
}