File: update-and-delete-sync.rs

package info (click to toggle)
rust-taskchampion 2.0.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 812 kB
  • sloc: python: 49; makefile: 2
file content (81 lines) | stat: -rw-r--r-- 2,670 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use taskchampion::chrono::{TimeZone, Utc};
use taskchampion::{Operations, Replica, ServerConfig, Status, StorageConfig, Uuid};
use tempfile::TempDir;

#[test]
fn update_and_delete_sync_delete_first() -> anyhow::Result<()> {
    update_and_delete_sync(true)
}

#[test]
fn update_and_delete_sync_update_first() -> anyhow::Result<()> {
    update_and_delete_sync(false)
}

/// Test what happens when an update is sync'd into a repo after a task is deleted.
/// If delete_first, then the deletion is sync'd to the server first; otherwise
/// the update is sync'd first.  Either way, the task is gone.
fn update_and_delete_sync(delete_first: bool) -> anyhow::Result<()> {
    // set up two replicas, and demonstrate replication between them
    let mut rep1 = Replica::new(StorageConfig::InMemory.into_storage()?);
    let mut rep2 = Replica::new(StorageConfig::InMemory.into_storage()?);

    let tmp_dir = TempDir::new().expect("TempDir failed");
    let mut server = ServerConfig::Local {
        server_dir: tmp_dir.path().to_path_buf(),
    }
    .into_server()?;

    // add a task on rep1, and sync it to rep2
    let mut ops = Operations::new();
    let u = Uuid::new_v4();
    let mut t = rep1.create_task(u, &mut ops)?;
    t.set_description("test task".into(), &mut ops)?;
    t.set_status(Status::Pending, &mut ops)?;
    t.set_entry(Some(Utc::now()), &mut ops)?;
    rep1.commit_operations(ops)?;

    rep1.sync(&mut server, false)?;
    rep2.sync(&mut server, false)?;

    // mark the task as deleted, long in the past, on rep2
    {
        let mut ops = Operations::new();
        let mut t = rep2.get_task(u)?.unwrap();
        t.set_status(Status::Deleted, &mut ops)?;
        t.set_modified(Utc.with_ymd_and_hms(1980, 1, 1, 0, 0, 0).unwrap(), &mut ops)?;
        rep2.commit_operations(ops)?;
    }

    // sync it back to rep1
    rep2.sync(&mut server, false)?;
    rep1.sync(&mut server, false)?;

    // expire the task on rep1 and check that it is gone locally
    rep1.expire_tasks()?;
    assert!(rep1.get_task(u)?.is_none());

    // modify the task on rep2
    {
        let mut ops = Operations::new();
        let mut t = rep2.get_task(u)?.unwrap();
        t.set_description("modified".to_string(), &mut ops)?;
        rep2.commit_operations(ops)?;
    }

    // sync back and forth
    if delete_first {
        rep1.sync(&mut server, false)?;
    }
    rep2.sync(&mut server, false)?;
    rep1.sync(&mut server, false)?;
    if !delete_first {
        rep2.sync(&mut server, false)?;
    }

    // check that the task is gone on both replicas
    assert!(rep1.get_task(u)?.is_none());
    assert!(rep2.get_task(u)?.is_none());

    Ok(())
}