mod support;
use anyhow::Result;
use assert_fs::prelude::*;
use reqwest::blocking::Client;
use reqwest::blocking::get;
use serde_json::Value;
use crate::support::RepoFixture;
use crate::support::TestServer;
use crate::support::{PijulEnv, pijul_env::run_pijul};
#[test]
fn serves_response_for_library_initialized_repo() -> Result<()> {
let repo = RepoFixture::new().expect("failed to create repo fixture");
let server = TestServer::start(repo).expect("failed to start server");
let resp = dbg!(get(&format!("{}/.pijul", server.base_url()))?);
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Content-Type")
.is_some_and(|t| t == "application/json")
);
let body: Value = serde_json::from_str(&resp.text()?)?;
let channels = body
.get("channels")
.and_then(|c| c.as_array())
.expect("expected channels array");
assert!(channels.iter().any(|c| c == "main"));
assert!(body.get("head").is_some());
Ok(())
}
#[test]
fn test_all_endpoints() -> Result<()> {
let repo = RepoFixture::new()?;
repo.write_file(".pijul/changes/ab/cdef123.change", "change data")?;
repo.write_file(".pijul/changes/ab/cdef123.tag", "tag data")?;
let server = TestServer::start(repo)?;
let url = format!("{}/.pijul", server.base_url());
let client = &Client::builder().user_agent("pijul-1.0.0-beta9").build()?;
{
let resp = client.get(&url).query(&[("log", "")]).send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Content-Type")
.is_some_and(|t| t == "application/json")
);
}
{
let resp = client.get(&url).query(&[("identities", "")]).send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Content-Type")
.is_some_and(|t| t == "application/json")
);
let body = resp.text()?;
assert_eq!(body, r#"{"id":[],"rev":0}"#);
}
{
let resp = client
.get(&url)
.query(&[("channel", "main"), ("id", "")])
.send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Content-Type")
.is_some_and(|t| t == "application/octet-stream")
);
let bytes = resp.bytes()?;
assert_eq!(bytes.len(), 16);
}
{
let resp = client.get(&url).query(&[("channel", "main")]).send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Content-Type")
.is_some_and(|t| t == "application/json")
);
let body: Value = serde_json::from_str(&resp.text()?)?;
assert!(body.get("position").and_then(|v| v.as_u64()).is_some());
assert!(body.get("merkle").and_then(|v| v.as_str()).is_some());
assert!(body.get("tag_merkle").and_then(|v| v.as_str()).is_some());
}
{
let resp = client
.get(&url)
.query(&[("state", "0"), ("channel", "main")])
.send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Content-Type")
.is_some_and(|t| t == "text/plain")
);
let body = resp.text()?;
let parts: Vec<&str> = body.split_whitespace().collect();
assert_eq!(parts.len(), 3);
assert!(parts[0].parse::<u64>().is_ok());
}
{
let resp = client
.get(&url)
.query(&[("changelist", "0"), ("channel", "main")])
.send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Content-Type")
.is_some_and(|t| t == "text/plain")
);
assert_eq!(resp.text()?, "");
}
{
let resp = client.get(&url).query(&[("change", "abcdef123")]).send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Cache-Control")
.is_some_and(|v| v == "public, max-age=31536000, immutable")
);
let bytes = resp.bytes()?.to_vec();
assert_eq!(bytes, b"change data");
}
{
let resp = client.get(&url).query(&[("tag", "abcdef123")]).send()?;
assert_eq!(resp.status(), 200);
assert!(
resp.headers()
.get("Cache-Control")
.is_some_and(|v| v == "public, max-age=31536000, immutable")
);
let bytes = resp.bytes()?.to_vec();
assert_eq!(bytes, b"tag data");
}
{
let resp = client.get(&url).query(&[("changelist", "0")]).send()?;
assert_eq!(resp.status(), 400);
}
Ok(())
}
#[test]
fn pijul_cli_clone_and_pull_over_http() -> Result<()> {
let remote = RepoFixture::new()?;
remote.write_file("hello.txt", "v1\n")?;
{
let mut cmd = std::process::Command::new("pijul");
cmd.current_dir(remote.repo_root())
.arg("add")
.arg("hello.txt");
remote.apply_env(&mut cmd);
run_pijul(cmd)?;
}
{
let mut cmd = std::process::Command::new("pijul");
cmd.current_dir(remote.repo_root())
.arg("record")
.arg("--all")
.arg("--message")
.arg("init")
.arg("--identity")
.arg("test")
.arg("--no-prompt");
remote.apply_env(&mut cmd);
run_pijul(cmd)?;
}
let server = TestServer::start(remote)?;
let env = PijulEnv::new()?;
let clone_parent = assert_fs::TempDir::new()?;
let clone_dir = clone_parent.child("clone");
{
let mut cmd = std::process::Command::new("pijul");
cmd.current_dir(clone_parent.path())
.arg("clone")
.arg(server.base_url())
.arg(clone_dir.path())
.arg("--no-prompt");
env.apply_env(&mut cmd);
run_pijul(cmd)?;
}
clone_dir.child("hello.txt").assert("v1\n");
std::fs::write(server.repo_root().join("hello.txt"), "v2\n")?;
{
let mut cmd = std::process::Command::new("pijul");
cmd.current_dir(server.repo_root())
.arg("record")
.arg("--all")
.arg("--message")
.arg("update")
.arg("--identity")
.arg("test")
.arg("--no-prompt");
server.apply_repo_env(&mut cmd);
run_pijul(cmd)?;
}
{
let mut cmd = std::process::Command::new("pijul");
cmd.current_dir(clone_dir.path())
.arg("pull")
.arg(server.base_url())
.arg("--all")
.arg("--no-prompt");
env.apply_env(&mut cmd);
run_pijul(cmd)?;
}
clone_dir.child("hello.txt").assert("v2\n");
Ok(())
}