use serde_json::{Value, json};
use super::{publish, server_mode, zip_of};
use crate::adapters::chrome::testing::{self, eval, until};
fn site(text: &str) -> Vec<u8> {
zip_of(&[
(
"devpage.yml",
"kind: site\ntitle: Launch\nroot: README.md\n",
),
("README.md", &format!("# Launch\n\n{text}\n")),
])
}
#[tokio::test(flavor = "multi_thread")]
#[ignore = "drives Chrome"]
async fn a_published_documents_threads_are_its_own_across_the_page_the_api_and_a_publish() {
let base = testing::serve(server_mode("comments")).await;
let http = reqwest::Client::new();
let id = publish(
&base,
None,
site("The client retries every write until the server acknowledges it."),
)
.await;
let browser = testing::browser().await;
let page = testing::open(&browser, &format!("{base}/d/{id}/README.md")).await;
eval::<bool>(
&page,
"(document.querySelector('.comment-mode').click(), true)",
)
.await;
eval::<bool>(
&page,
"(() => { const p = document.querySelector('article p'); const t = p.firstChild;
const at = t.data.indexOf('retries every write');
const r = document.createRange(); r.setStart(t, at); r.setEnd(t, at + 19);
getSelection().removeAllRanges(); getSelection().addRange(r);
p.dispatchEvent(new MouseEvent('mouseup', { bubbles: true })); return true; })()",
)
.await;
until(&page, "!!document.querySelector('.comment-button')").await;
eval::<bool>(
&page,
"document.querySelector('.comment-button').click(), true",
)
.await;
until(
&page,
"!!document.querySelector('#devpage-comments .composer textarea')",
)
.await;
eval::<bool>(
&page,
"(() => { const box = document.querySelector('#devpage-comments .composer textarea');
box.value = 'Every write, or only the outbox?';
box.closest('form').requestSubmit(); return true; })()",
)
.await;
until(
&page,
"document.querySelector('mark.comment')?.textContent === 'retries every write'",
)
.await;
let threads: Vec<Value> = http
.get(format!("{base}/api/documents/{id}/comments"))
.send()
.await
.unwrap()
.json()
.await
.unwrap();
assert_eq!(threads.len(), 1, "{threads:?}");
assert_eq!(threads[0]["page"], "/README.md");
assert_eq!(threads[0]["version"], 1);
assert_eq!(
threads[0]["thread"][0]["text"],
"Every write, or only the outbox?"
);
let started = http
.post(format!("{base}/api/documents/{id}/comments"))
.json(&json!({
"page": "/README.md",
"anchor": { "quote": "acknowledges it", "prefix": "the server ", "suffix": "." },
"text": "Acknowledged how?",
}))
.send()
.await
.unwrap();
assert_eq!(started.status(), 201);
until(
&page,
"[...document.querySelectorAll('mark.comment')].some((m) => m.textContent === 'acknowledges it')",
)
.await;
publish(
&base,
Some(&id),
site("The client retries every write until a peer replies."),
)
.await;
page.reload().await.unwrap();
testing::loaded(&page).await;
until(&page, "!!document.querySelector('.detached-heading')").await;
let detached: String = eval(
&page,
"document.querySelector('.detached-heading').nextElementSibling.textContent",
)
.await;
assert!(detached.contains("Acknowledged how?"), "{detached}");
until(
&page,
"document.querySelector('mark.comment')?.textContent === 'retries every write'",
)
.await;
drop(browser);
}