mod common;
use std::process::Command;
use common::{
TestEnv, TestServer, contains_all, contains_none, extract_ref, fail, meta_value, ok, scalar_i64,
};
fn sync(env: &TestEnv, db: &std::path::Path, server: &TestServer) -> String {
ok(env.aven(db, ["sync", "--server", &server.url]))
}
#[test]
fn sync_server_url_is_pinned_and_normalized() {
let env = TestEnv::new();
let server_a = TestServer::start_with_data(&env, "server-a.sqlite");
let server_b = TestServer::start_with_data(&env, "server-b.sqlite");
let db = env.db("pinned.sqlite");
ok(env.aven(&db, ["sync", "--server", &format!("{}/", server_a.url)]));
assert_eq!(
meta_value(&db, "sync_server_url"),
Some(server_a.url.clone())
);
ok(env.aven(&db, ["sync", "--server", &server_a.url]));
let error = fail(env.aven(&db, ["sync", "--server", &server_b.url]));
contains_all(
&error,
&["error sync-server-changed", "use a fresh database"],
);
}
#[test]
fn repeated_sync_is_idempotent_and_acknowledges_changes() {
let env = TestEnv::new();
let server = TestServer::start(&env);
let a = env.db("client-a.sqlite");
let b = env.db("client-b.sqlite");
ok(env.aven(&a, ["label", "create", "sync"]));
let task_ref = extract_ref(&ok(env.aven(
&a,
[
"add",
"idempotent sync",
"--project",
"app",
"--label",
"sync",
],
)));
ok(env.aven_stdin(&a, ["note", &task_ref, "--stdin"], "only once\n"));
let first = sync(&env, &a, &server);
contains_all(&first, &["pushed=4", "pulled=0", "cursor="]);
assert_eq!(
scalar_i64(&a, "SELECT count(*) FROM changes WHERE server_seq IS NULL"),
0
);
let first_cursor = meta_value(&a, "sync_cursor").expect("first cursor");
sync(&env, &b, &server);
let repeat_b = sync(&env, &b, &server);
contains_all(&repeat_b, &["pushed=0", "pulled=0"]);
assert_eq!(scalar_i64(&b, "SELECT count(*) FROM tasks"), 1);
assert_eq!(scalar_i64(&b, "SELECT count(*) FROM notes"), 1);
assert_eq!(scalar_i64(&b, "SELECT count(*) FROM task_labels"), 1);
let repeat_a = sync(&env, &a, &server);
contains_all(&repeat_a, &["pushed=0", "pulled=0"]);
assert_eq!(meta_value(&a, "sync_cursor"), Some(first_cursor));
}
#[test]
fn config_env_and_flag_precedence_for_sync_server() {
let env = TestEnv::new();
let server_config = TestServer::start_with_data(&env, "server-config.sqlite");
let server_env = TestServer::start_with_data(&env, "server-env.sqlite");
let server_flag = TestServer::start_with_data(&env, "server-flag.sqlite");
let db = env.db("precedence.sqlite");
env.write_config(&format!(
r#"
local:
db_path: "{}"
sync:
enabled: true
server_url: "{}"
"#,
db.display(),
server_config.url
));
ok(env.aven_config(["sync"]));
assert_eq!(
meta_value(&db, "sync_server_url"),
Some(server_config.url.clone())
);
let env_db = env.db("env.sqlite");
let env_output = Command::new(common::bin())
.env("AVEN_CONFIG_DIR", env.config_dir().join("aven"))
.env("AVEN_DB", &env_db)
.env("AVEN_SYNC_SERVER", &server_env.url)
.arg("sync")
.output()
.expect("run aven with env server");
ok(env_output);
assert_eq!(
meta_value(&env_db, "sync_server_url"),
Some(server_env.url.clone())
);
let flag_db = env.db("flag.sqlite");
ok(env.aven_config([
"--db",
flag_db.to_str().expect("utf8 db path"),
"sync",
"--server",
&server_flag.url,
]));
assert_eq!(
meta_value(&flag_db, "sync_server_url"),
Some(server_flag.url.clone())
);
}
#[test]
fn db_flag_bypasses_config_except_for_sync_settings() {
let server_env = TestEnv::new();
server_env.write_config(
r#"
sync:
auth_token: "secret"
"#,
);
let server = TestServer::start_configured(&server_env, "server.sqlite");
let env = TestEnv::new();
let config_db = env.db("config.sqlite");
let flag_db = env.db("flag.sqlite");
env.write_config(&format!(
r#"
local:
db_path: "{}"
sync:
enabled: true
server_url: "{}"
auth_token: "secret"
"#,
config_db.display(),
server.url
));
let task_ref = extract_ref(&ok(env.aven_config([
"--db",
flag_db.to_str().expect("utf8 db path"),
"add",
"flag task",
"--project",
"app",
])));
let config_list = ok(env.aven_config(["list", "--all"]));
contains_none(&config_list, &["flag task"]);
let flag_list = ok(env.aven(&flag_db, ["list", "--all"]));
contains_all(&flag_list, &[&task_ref, "flag task"]);
let sync = ok(env.aven_config(["--db", flag_db.to_str().expect("utf8 db path"), "sync"]));
contains_all(&sync, &["synced", "pushed="]);
assert_eq!(
meta_value(&flag_db, "sync_server_url"),
Some(server.url.clone())
);
}