chadtmiller.com/knotless
git that lives in your Atmosphere account
1
10
knotless-serve: A new repository is found while its name is still checked
crates/knotless-serve/src/lib.rs+13−7
| @@ -475,13 +475,19 @@ impl App { | ||
let delegated = delegated.filter(|_| gateway); | ||
let viewer = private::viewer().filter(|_| gateway); | ||
let viewer = viewer.or_else(|| delegated.as_ref().map(|d| d.did.clone())); | ||
// One the viewer was shown as private is read as theirs again. | ||
if let Some(viewer) = &viewer | ||
&& self.shown_private(viewer, &did, &url.name) | ||
{ | ||
return self | ||
.as_viewer(viewer, &did, &url, None, delegated.as_ref()) | ||
.await; | ||
// One the viewer was shown as private is read as theirs again. Not | ||
// found so, it is looked for as anyone looks: shown here may be only | ||
// a look under way, such as the new repository form's check of a | ||
// name, which a repository made public meanwhile is not in. | ||
let shown = viewer | ||
.as_ref() | ||
.filter(|v| self.shown_private(v, &did, &url.name)); | ||
if let Some(viewer) = shown { | ||
let read = self.as_viewer(viewer, &did, &url, None, delegated.as_ref()); | ||
let read = read.await; | ||
if !read.as_ref().is_err_and(|e| e.0 == StatusCode::NOT_FOUND) { | ||
return read; | ||
} | ||
} | ||
let missing = match self.public(remote, &url).await { | ||
Err(e) if e.0 == StatusCode::NOT_FOUND => e, | ||
crates/knotless-serve/tests/pages.rs+36−0
| @@ -177,6 +177,42 @@ impl Server { | ||
} | ||
} | ||
| ||
/// A name the form checks as it is typed, still being looked for when the | ||
/// repository it names is made, keeps no one from the repository after: | ||
/// the reads its page asks for at once find it. | ||
#[test] | ||
fn a_name_checked_as_its_repository_is_made() { | ||
let server = server(); | ||
let maker = person(account()); | ||
let cookie = log_in(&server, &maker.account); | ||
let me = Some(cookie.as_str()); | ||
let handle = maker.account.handle.clone(); | ||
for i in 0..20u64 { | ||
let name = format!("raced{i}"); | ||
let repo = format!("at://{handle}/dev.knotless.repo/{name}"); | ||
let read = |nsid: &str| { | ||
let url = format!("{}?repo={repo}", server.xrpc(nsid)); | ||
browse("GET", &url, me, None).0 | ||
}; | ||
let read = &read; | ||
std::thread::scope(|s| { | ||
let made = s.spawn(|| server.call("createRepo", me, json!({ "name": name })).0); | ||
// The check, a moment into the making. | ||
std::thread::sleep(Duration::from_millis(i * 3)); | ||
let checked = s.spawn(|| read("getRepo")); | ||
assert_eq!(made.join().unwrap(), 200); | ||
let page = ["getRepo", "getTree", "listBranches", "listTags"]; | ||
let page = page.map(|nsid| s.spawn(move || (nsid, read(nsid)))); | ||
let found = page.map(|asked| asked.join().unwrap()); | ||
assert!( | ||
found.iter().all(|(_, status)| *status == 200), | ||
"{name}: {found:?}" | ||
); | ||
checked.join().unwrap(); | ||
}); | ||
} | ||
} | ||
| ||
/// An account taken down cannot log in, and the cookie it holds names no | ||
/// one until it is restored. | ||
#[test] | ||