use super::*;
use wsb::peer::identity::{Fingerprint, PairedPeer};
fn store() -> (tempfile::TempDir, MachineStore) {
let dir = tempfile::tempdir().expect("tempdir");
let store = MachineStore::open(dir.path()).expect("a machine store");
(dir, store)
}
fn peer_id() -> PeerId {
PeerId::parse("aaaa1111bbbb2222").expect("a peer id")
}
fn workspace_id() -> WorkspaceId {
WorkspaceId::parse("cccc3333@main").expect("a workspace id")
}
fn pair(store: &MachineStore) -> PeerId {
let id = peer_id();
store
.add_peer(&PairedPeer {
id: id.clone(),
name: "laptop".to_string(),
public_key: "key".to_string(),
fingerprint: Fingerprint::from_stored("ff".to_string()),
address: "127.0.0.1:7420".to_string(),
paired_at: 1,
})
.expect("the peer is paired");
id
}
#[test]
fn test10147_services_default_on_and_switch_both_ways() {
let (_dir, store) = store();
let peer = pair(&store);
for service in Service::BUILT_IN {
assert_eq!(
store.service(&peer, service.clone()).expect("a switch"),
Switch::On,
"{service} must be available to a machine somebody paired"
);
}
store
.set_service(&peer, Service::Files, Switch::Off, 10)
.expect("files off");
assert_eq!(store.service(&peer, Service::Files).expect("files"), Switch::Off);
store
.set_service(&peer, Service::Files, Switch::On, 11)
.expect("files on");
assert_eq!(store.service(&peer, Service::Files).expect("files"), Switch::On);
}
#[test]
fn test10148_the_mode_defaults_to_manual_and_persists() {
let (dir, store) = store();
let peer = pair(&store);
let workspace = workspace_id();
assert_eq!(
store.mode(&peer, &workspace).expect("a mode"),
SyncMode::Manual,
"a relationship nobody has configured must not carry files by itself"
);
store
.set_desired(&peer, &workspace, Desired::Enabled, 10)
.expect("enabled");
assert_eq!(store.mode(&peer, &workspace).expect("a mode"), SyncMode::Manual);
store
.set_mode(&peer, &workspace, SyncMode::Auto, 11)
.expect("auto");
assert_eq!(store.mode(&peer, &workspace).expect("a mode"), SyncMode::Auto);
assert_eq!(
store.desired(&peer, &workspace).expect("desired"),
Desired::Enabled,
"setting the mode must not disturb whether the workspace is carried"
);
drop(store);
let store = MachineStore::open(dir.path()).expect("reopened");
assert_eq!(store.mode(&peer, &workspace).expect("a mode"), SyncMode::Auto);
}
#[test]
fn test10149_a_mode_can_be_set_before_the_workspace_is_carried() {
let (_dir, store) = store();
let peer = pair(&store);
let workspace = workspace_id();
store
.set_mode(&peer, &workspace, SyncMode::Auto, 10)
.expect("auto before enabled");
assert_eq!(store.mode(&peer, &workspace).expect("a mode"), SyncMode::Auto);
assert_eq!(
store.desired(&peer, &workspace).expect("desired"),
Desired::Disabled,
"choosing how it would be carried must not start carrying it"
);
store
.set_desired(&peer, &workspace, Desired::Enabled, 11)
.expect("enabled");
assert_eq!(
store.mode(&peer, &workspace).expect("a mode"),
SyncMode::Auto,
"enabling the workspace must keep the mode already chosen"
);
}
#[test]
fn test10150_a_dismissal_records_the_versions_it_was_about() {
let (_dir, store) = store();
let peer = pair(&store);
let workspace = workspace_id();
let repository = RepositoryId::root();
store
.dismiss(&peer, &workspace, &repository, "notes.md", Some("aaa"), None, 10)
.expect("dismissed");
let held = store
.dismissals(&peer, &workspace, &repository)
.expect("dismissals");
assert_eq!(
held.get("notes.md"),
Some(&(Some("aaa".to_string()), None)),
"the absent side must come back absent rather than as an empty string"
);
store
.dismiss(&peer, &workspace, &repository, "notes.md", Some("bbb"), Some("ccc"), 11)
.expect("dismissed again");
let held = store
.dismissals(&peer, &workspace, &repository)
.expect("dismissals");
assert_eq!(
held.get("notes.md"),
Some(&(Some("bbb".to_string()), Some("ccc".to_string())))
);
store
.clear_dismissal(&peer, &workspace, &repository, "notes.md")
.expect("cleared");
assert!(store
.dismissals(&peer, &workspace, &repository)
.expect("dismissals")
.is_empty());
}
#[test]
fn test10151_forgetting_a_peer_forgets_what_it_was_allowed_to_do() {
let (_dir, store) = store();
let peer = pair(&store);
store
.set_service(&peer, Service::Files, Switch::Off, 10)
.expect("files off");
assert!(store.remove_peer(&peer).expect("removed"));
let peer = pair(&store);
assert_eq!(
store.service(&peer, Service::Files).expect("files"),
Switch::On,
"a re-paired machine must start from the defaults"
);
}
#[test]
fn test10152_a_database_from_before_the_mode_upgrades_in_place() {
let dir = tempfile::tempdir().expect("tempdir");
{
let connection =
rusqlite::Connection::open(dir.path().join("machine.db")).expect("the old database");
connection
.execute_batch(
r#"
CREATE TABLE peers (
peer_id TEXT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
public_key TEXT NOT NULL,
fingerprint TEXT NOT NULL,
address TEXT NOT NULL,
paired_at INTEGER NOT NULL,
last_seen INTEGER
);
CREATE TABLE relationships (
peer_id TEXT NOT NULL REFERENCES peers(peer_id) ON DELETE CASCADE,
workspace_id TEXT NOT NULL,
desired TEXT NOT NULL,
enabled_at INTEGER NOT NULL,
PRIMARY KEY (peer_id, workspace_id)
);
INSERT INTO peers VALUES
('aaaa1111bbbb2222', 'laptop', 'key', 'ff', '127.0.0.1:7420', 1, NULL);
INSERT INTO relationships VALUES
('aaaa1111bbbb2222', 'cccc3333@main', 'enabled', 2);
"#,
)
.expect("the old schema");
}
let store = MachineStore::open(dir.path()).expect("the store opens an older database");
let peer = peer_id();
let workspace = workspace_id();
let peers = store.peers().expect("peers");
assert_eq!(peers.len(), 1, "the upgrade must not lose a pinned identity");
assert_eq!(peers[0].public_key, "key", "the pinned key must survive");
assert_eq!(
store.desired(&peer, &workspace).expect("desired"),
Desired::Enabled,
"what the operator asked for must survive the upgrade"
);
assert_eq!(
store.mode(&peer, &workspace).expect("a mode"),
SyncMode::Manual,
"a relationship that predates the column must not start carrying files by itself"
);
store
.set_mode(&peer, &workspace, SyncMode::Auto, 10)
.expect("auto");
assert_eq!(store.mode(&peer, &workspace).expect("a mode"), SyncMode::Auto);
drop(store);
let store = MachineStore::open(dir.path()).expect("reopened");
assert_eq!(store.mode(&peer, &workspace).expect("a mode"), SyncMode::Auto);
}