Trait is closer to what caldav servers provide
This commit is contained in:
parent
7af147e417
commit
86f3566532
11 changed files with 122 additions and 94 deletions
11
src/cache.rs
11
src/cache.rs
|
@ -14,7 +14,6 @@ use async_trait::async_trait;
|
|||
use chrono::{DateTime, Utc};
|
||||
|
||||
use crate::traits::CalDavSource;
|
||||
use crate::traits::SyncSlave;
|
||||
use crate::traits::PartialCalendar;
|
||||
use crate::traits::CompleteCalendar;
|
||||
use crate::calendar::cached_calendar::CachedCalendar;
|
||||
|
@ -192,16 +191,6 @@ impl CalDavSource<CachedCalendar> for Cache {
|
|||
}
|
||||
}
|
||||
|
||||
impl SyncSlave for Cache {
|
||||
fn get_last_sync(&self) -> Option<DateTime<Utc>> {
|
||||
self.data.last_sync
|
||||
}
|
||||
|
||||
fn update_last_sync(&mut self, timepoint: Option<DateTime<Utc>>) {
|
||||
self.data.last_sync = Some(timepoint.unwrap_or_else(|| Utc::now()));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::traits::{PartialCalendar, CompleteCalendar};
|
|||
use crate::calendar::{CalendarId, SupportedComponents, SearchFilter};
|
||||
use crate::Item;
|
||||
use crate::item::ItemId;
|
||||
use crate::item::VersionTag;
|
||||
|
||||
|
||||
/// A calendar used by the [`cache`](crate::cache) module
|
||||
|
@ -69,6 +70,32 @@ impl PartialCalendar for CachedCalendar {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>> {
|
||||
Ok(self.items.iter()
|
||||
.map(|(id, item)| (id.clone(), item.version_tag().clone()))
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
|
||||
async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item> {
|
||||
self.items.get_mut(id)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl CompleteCalendar for CachedCalendar {
|
||||
/// Returns the items that have been deleted after `since`
|
||||
async fn get_items_deleted_since(&self, since: DateTime<Utc>) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
||||
Ok(self.deleted_items.range(since..)
|
||||
.map(|(_key, id)| id.clone())
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Returns the list of items that this calendar contains
|
||||
async fn get_items(&self) -> Result<HashMap<ItemId, &Item>, Box<dyn Error>> {
|
||||
self.get_items_modified_since(None, None).await
|
||||
}
|
||||
|
||||
async fn get_items_modified_since(&self, since: Option<DateTime<Utc>>, filter: Option<SearchFilter>) -> Result<HashMap<ItemId, &Item>, Box<dyn Error>> {
|
||||
let filter = filter.unwrap_or_default();
|
||||
|
||||
|
@ -96,28 +123,4 @@ impl PartialCalendar for CachedCalendar {
|
|||
|
||||
Ok(map)
|
||||
}
|
||||
|
||||
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
||||
Ok(self.items.keys().cloned().collect())
|
||||
}
|
||||
|
||||
async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item> {
|
||||
self.items.get_mut(id)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl CompleteCalendar for CachedCalendar {
|
||||
/// Returns the items that have been deleted after `since`
|
||||
async fn get_items_deleted_since(&self, since: DateTime<Utc>) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
||||
Ok(self.deleted_items.range(since..)
|
||||
.map(|(_key, id)| id.clone())
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Returns the list of items that this calendar contains
|
||||
async fn get_items(&self) -> Result<HashMap<ItemId, &Item>, Box<dyn Error>> {
|
||||
self.get_items_modified_since(None, None).await
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,9 @@ use async_trait::async_trait;
|
|||
use crate::traits::PartialCalendar;
|
||||
use crate::calendar::SupportedComponents;
|
||||
use crate::calendar::CalendarId;
|
||||
use crate::item::ItemId;
|
||||
use crate::item::Item;
|
||||
use crate::item::ItemId;
|
||||
use crate::item::VersionTag;
|
||||
use crate::resource::Resource;
|
||||
|
||||
static TASKS_BODY: &str = r#"
|
||||
|
@ -51,14 +52,6 @@ impl PartialCalendar for RemoteCalendar {
|
|||
self.supported_components
|
||||
}
|
||||
|
||||
/// Returns the items that have been last-modified after `since`
|
||||
async fn get_items_modified_since(&self, since: Option<DateTime<Utc>>, _filter: Option<crate::calendar::SearchFilter>)
|
||||
-> Result<HashMap<ItemId, &Item>, Box<dyn Error>>
|
||||
{
|
||||
log::error!("Not implemented");
|
||||
Ok(HashMap::new())
|
||||
}
|
||||
|
||||
/// Get the IDs of all current items in this calendar
|
||||
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
||||
let responses = crate::client::sub_request_and_extract_elems(&self.resource, "REPORT", TASKS_BODY.to_string(), "response").await?;
|
||||
|
@ -82,6 +75,11 @@ impl PartialCalendar for RemoteCalendar {
|
|||
Ok(item_ids)
|
||||
}
|
||||
|
||||
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>> {
|
||||
log::error!("Not implemented");
|
||||
Ok(HashMap::new())
|
||||
}
|
||||
|
||||
/// Returns a particular item
|
||||
async fn get_item_by_id_mut<'a>(&'a mut self, _id: &ItemId) -> Option<&'a mut Item> {
|
||||
log::error!("Not implemented");
|
||||
|
|
|
@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||
use chrono::{Utc, DateTime};
|
||||
|
||||
use crate::item::ItemId;
|
||||
use crate::item::VersionTag;
|
||||
|
||||
/// TODO: implement Event one day.
|
||||
/// This crate currently only supports tasks, not calendar events.
|
||||
|
@ -12,6 +13,7 @@ pub struct Event {
|
|||
id: ItemId,
|
||||
name: String,
|
||||
last_modified: DateTime<Utc>,
|
||||
version_tag: VersionTag,
|
||||
}
|
||||
|
||||
impl Event {
|
||||
|
@ -26,4 +28,8 @@ impl Event {
|
|||
pub fn last_modified(&self) -> DateTime<Utc> {
|
||||
self.last_modified
|
||||
}
|
||||
|
||||
pub fn version_tag(&self) -> &VersionTag {
|
||||
&self.version_tag
|
||||
}
|
||||
}
|
||||
|
|
30
src/item.rs
30
src/item.rs
|
@ -7,6 +7,8 @@ use url::Url;
|
|||
|
||||
use crate::resource::Resource;
|
||||
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Item {
|
||||
Event(crate::event::Event),
|
||||
|
@ -35,6 +37,13 @@ impl Item {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn version_tag(&self) -> &VersionTag {
|
||||
match self {
|
||||
Item::Event(e) => e.version_tag(),
|
||||
Item::Task(t) => t.version_tag(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_event(&self) -> bool {
|
||||
match &self {
|
||||
Item::Event(_) => true,
|
||||
|
@ -109,3 +118,24 @@ impl Display for ItemId {
|
|||
write!(f, "{}", self.content)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A VersionTag is basically a CalDAV `ctag` or `etag`. Whenever it changes, this means the data has changed.
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct VersionTag {
|
||||
tag: String
|
||||
}
|
||||
|
||||
impl From<String> for VersionTag {
|
||||
fn from(tag: String) -> VersionTag {
|
||||
Self { tag }
|
||||
}
|
||||
}
|
||||
|
||||
impl VersionTag {
|
||||
/// Generate a random VesionTag. This is only useful in tests
|
||||
pub fn random() -> Self {
|
||||
let random = uuid::Uuid::new_v4().to_hyphenated().to_string();
|
||||
Self { tag: random }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ pub use calendar::cached_calendar::CachedCalendar;
|
|||
mod item;
|
||||
pub use item::Item;
|
||||
pub use item::ItemId;
|
||||
pub use item::VersionTag;
|
||||
mod task;
|
||||
pub use task::Task;
|
||||
mod event;
|
||||
|
|
|
@ -7,7 +7,6 @@ use std::marker::PhantomData;
|
|||
use chrono::{DateTime, Utc};
|
||||
|
||||
use crate::traits::{CalDavSource, CompleteCalendar};
|
||||
use crate::traits::SyncSlave;
|
||||
use crate::traits::PartialCalendar;
|
||||
use crate::Item;
|
||||
use crate::item::ItemId;
|
||||
|
@ -16,7 +15,7 @@ use crate::item::ItemId;
|
|||
/// A data source that combines two `CalDavSources` (usually a server and a local cache), which is able to sync both sources.
|
||||
pub struct Provider<L, T, S, U>
|
||||
where
|
||||
L: CalDavSource<T> + SyncSlave,
|
||||
L: CalDavSource<T>,
|
||||
T: CompleteCalendar,
|
||||
S: CalDavSource<U>,
|
||||
U: PartialCalendar + Sync + Send,
|
||||
|
@ -32,7 +31,7 @@ where
|
|||
|
||||
impl<L, T, S, U> Provider<L, T, S, U>
|
||||
where
|
||||
L: CalDavSource<T> + SyncSlave,
|
||||
L: CalDavSource<T>,
|
||||
T: CompleteCalendar,
|
||||
S: CalDavSource<U>,
|
||||
U: PartialCalendar + Sync + Send,
|
||||
|
@ -51,19 +50,14 @@ where
|
|||
pub fn server(&self) -> &S { &self.server }
|
||||
/// Returns the data source described as the `local`
|
||||
pub fn local(&self) -> &L { &self.local }
|
||||
/// Returns the last time the `local` source has been synced
|
||||
pub fn last_sync_timestamp(&self) -> Option<DateTime<Utc>> {
|
||||
self.local.get_last_sync()
|
||||
}
|
||||
|
||||
/// Performs a synchronisation between `local` and `server`.
|
||||
///
|
||||
/// This bidirectional sync applies additions/deletions made on a source to the other source.
|
||||
/// In case of conflicts (the same item has been modified on both ends since the last sync, `server` always wins)
|
||||
pub async fn sync(&mut self) -> Result<(), Box<dyn Error>> {
|
||||
let last_sync = self.local.get_last_sync();
|
||||
log::info!("Starting a sync. Last sync was at {:?}", last_sync);
|
||||
|
||||
log::info!("Starting a sync.");
|
||||
/*
|
||||
let cals_server = self.server.get_calendars().await?;
|
||||
for (id, cal_server) in cals_server {
|
||||
let mut cal_server = cal_server.lock().unwrap();
|
||||
|
@ -77,8 +71,8 @@ where
|
|||
};
|
||||
let mut cal_local = cal_local.lock().unwrap();
|
||||
|
||||
// Step 1 - "Server always wins", so a delteion from the server must be applied locally, even if it was locally modified.
|
||||
let mut local_dels = match last_sync {
|
||||
// Step 1 - "Server always wins", so a deletion from the server must be applied locally, even if it was locally modified.
|
||||
let mut local_dels = match cal_local.get_last_sync() {
|
||||
None => HashSet::new(),
|
||||
Some(date) => cal_local.get_items_deleted_since(date).await?,
|
||||
};
|
||||
|
@ -138,7 +132,7 @@ where
|
|||
}
|
||||
|
||||
self.local.update_last_sync(None);
|
||||
|
||||
*/
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use chrono::{Utc, DateTime};
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::item::ItemId;
|
||||
use crate::item::VersionTag;
|
||||
|
||||
/// A to-do task
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -11,6 +12,8 @@ pub struct Task {
|
|||
|
||||
/// The last modification date of this task
|
||||
last_modified: DateTime<Utc>,
|
||||
/// The version tag of this item
|
||||
version_tag: VersionTag,
|
||||
|
||||
/// The display name of the task
|
||||
name: String,
|
||||
|
@ -20,11 +23,12 @@ pub struct Task {
|
|||
|
||||
impl Task {
|
||||
/// Create a new Task
|
||||
pub fn new(name: String, id: ItemId, last_modified: DateTime<Utc>) -> Self {
|
||||
pub fn new(name: String, id: ItemId, last_modified: DateTime<Utc>, version_tag: VersionTag) -> Self {
|
||||
Self {
|
||||
id,
|
||||
name,
|
||||
last_modified,
|
||||
version_tag,
|
||||
completed: false,
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +37,7 @@ impl Task {
|
|||
pub fn name(&self) -> &str { &self.name }
|
||||
pub fn completed(&self) -> bool { self.completed }
|
||||
pub fn last_modified(&self) -> DateTime<Utc> { self.last_modified }
|
||||
pub fn version_tag(&self) -> &VersionTag { &self.version_tag }
|
||||
|
||||
fn update_last_modified(&mut self) {
|
||||
self.last_modified = Utc::now();
|
||||
|
|
|
@ -7,6 +7,7 @@ use chrono::{DateTime, Utc};
|
|||
|
||||
use crate::item::Item;
|
||||
use crate::item::ItemId;
|
||||
use crate::item::VersionTag;
|
||||
use crate::calendar::CalendarId;
|
||||
|
||||
#[async_trait]
|
||||
|
@ -18,14 +19,6 @@ pub trait CalDavSource<T: PartialCalendar> {
|
|||
async fn get_calendar(&self, id: &CalendarId) -> Option<Arc<Mutex<T>>>;
|
||||
}
|
||||
|
||||
pub trait SyncSlave {
|
||||
/// Returns the last time this source successfully synced from a master source (e.g. from a server)
|
||||
/// (or None in case it has never been synchronized)
|
||||
fn get_last_sync(&self) -> Option<DateTime<Utc>>;
|
||||
/// Update the last sync timestamp to now, or to a custom time in case `timepoint` is `Some`
|
||||
fn update_last_sync(&mut self, timepoint: Option<DateTime<Utc>>);
|
||||
}
|
||||
|
||||
/// A calendar we have a partial knowledge of.
|
||||
///
|
||||
/// Usually, this is a calendar from a remote source, that is synced to a CompleteCalendar
|
||||
|
@ -40,12 +33,8 @@ pub trait PartialCalendar {
|
|||
/// Returns the supported kinds of components for this calendar
|
||||
fn supported_components(&self) -> crate::calendar::SupportedComponents;
|
||||
|
||||
/// Returns the items that have been last-modified after `since`
|
||||
async fn get_items_modified_since(&self, since: Option<DateTime<Utc>>, filter: Option<crate::calendar::SearchFilter>)
|
||||
-> Result<HashMap<ItemId, &Item>, Box<dyn Error>>;
|
||||
|
||||
/// Get the IDs of all current items in this calendar
|
||||
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>>;
|
||||
/// Get the IDs and the version tags of every item in this calendar
|
||||
async fn get_item_version_tags(&self) -> Result<HashMap<ItemId, VersionTag>, Box<dyn Error>>;
|
||||
|
||||
/// Returns a particular item
|
||||
async fn get_item_by_id_mut<'a>(&'a mut self, id: &ItemId) -> Option<&'a mut Item>;
|
||||
|
@ -67,6 +56,14 @@ pub trait PartialCalendar {
|
|||
self.supported_components().contains(crate::calendar::SupportedComponents::EVENT)
|
||||
}
|
||||
|
||||
/// Get the IDs of all current items in this calendar
|
||||
async fn get_item_ids(&self) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
||||
let items = self.get_item_version_tags().await?;
|
||||
Ok(items.iter()
|
||||
.map(|(id, _tag)| id.clone())
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Finds the IDs of the items that are missing compared to a reference set
|
||||
async fn find_deletions_from(&self, reference_set: HashSet<ItemId>) -> Result<HashSet<ItemId>, Box<dyn Error>> {
|
||||
let current_items = self.get_item_ids().await?;
|
||||
|
@ -84,6 +81,10 @@ pub trait CompleteCalendar : PartialCalendar {
|
|||
/// See also [`PartialCalendar::get_items_deleted_since`]
|
||||
async fn get_items_deleted_since(&self, since: DateTime<Utc>) -> Result<HashSet<ItemId>, Box<dyn Error>>;
|
||||
|
||||
/// Returns the items that have been last-modified after `since`
|
||||
async fn get_items_modified_since(&self, since: Option<DateTime<Utc>>, filter: Option<crate::calendar::SearchFilter>)
|
||||
-> Result<HashMap<ItemId, &Item>, Box<dyn Error>>;
|
||||
|
||||
/// Returns the list of items that this calendar contains
|
||||
async fn get_items(&self) -> Result<HashMap<ItemId, &Item>, Box<dyn Error>>;
|
||||
}
|
||||
|
|
|
@ -53,9 +53,9 @@ async fn show_calendars() {
|
|||
}
|
||||
|
||||
println!(" Most recent changes:");
|
||||
for (_id, task) in cal.get_items_modified_since(None, None).await.unwrap() {
|
||||
my_tasks::utils::print_task(task);
|
||||
}
|
||||
// for (_id, task) in cal.get_item_version_tags(None, None).await.unwrap() {
|
||||
// my_tasks::utils::print_task(task);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@ use std::sync::{Arc, Mutex};
|
|||
use chrono::{Utc, TimeZone};
|
||||
use url::Url;
|
||||
|
||||
use my_tasks::traits::{CalDavSource, SyncSlave};
|
||||
use my_tasks::traits::CalDavSource;
|
||||
use my_tasks::traits::PartialCalendar;
|
||||
use my_tasks::cache::Cache;
|
||||
use my_tasks::Item;
|
||||
use my_tasks::ItemId;
|
||||
use my_tasks::VersionTag;
|
||||
use my_tasks::Task;
|
||||
use my_tasks::calendar::cached_calendar::CachedCalendar;
|
||||
use my_tasks::Provider;
|
||||
|
@ -53,23 +54,23 @@ async fn populate_test_provider() -> Provider<Cache, CachedCalendar, Cache, Cach
|
|||
|
||||
let cal_id = Url::parse("http://todo.list/cal").unwrap();
|
||||
|
||||
let task_a = Item::Task(Task::new("task A".into(), ItemId::random(), Utc.ymd(2000, 1, 1).and_hms(0, 0, 0)));
|
||||
let task_b = Item::Task(Task::new("task B".into(), ItemId::random(), Utc.ymd(2000, 1, 2).and_hms(0, 0, 0)));
|
||||
let task_c = Item::Task(Task::new("task C".into(), ItemId::random(), Utc.ymd(2000, 1, 3).and_hms(0, 0, 0)));
|
||||
let task_d = Item::Task(Task::new("task D".into(), ItemId::random(), Utc.ymd(2000, 1, 4).and_hms(0, 0, 0)));
|
||||
let task_e = Item::Task(Task::new("task E".into(), ItemId::random(), Utc.ymd(2000, 1, 5).and_hms(0, 0, 0)));
|
||||
let task_f = Item::Task(Task::new("task F".into(), ItemId::random(), Utc.ymd(2000, 1, 6).and_hms(0, 0, 0)));
|
||||
let task_g = Item::Task(Task::new("task G".into(), ItemId::random(), Utc.ymd(2000, 1, 7).and_hms(0, 0, 0)));
|
||||
let task_h = Item::Task(Task::new("task H".into(), ItemId::random(), Utc.ymd(2000, 1, 8).and_hms(0, 0, 0)));
|
||||
let task_i = Item::Task(Task::new("task I".into(), ItemId::random(), Utc.ymd(2000, 1, 9).and_hms(0, 0, 0)));
|
||||
let task_j = Item::Task(Task::new("task J".into(), ItemId::random(), Utc.ymd(2000, 1, 10).and_hms(0, 0, 0)));
|
||||
let task_k = Item::Task(Task::new("task K".into(), ItemId::random(), Utc.ymd(2000, 1, 11).and_hms(0, 0, 0)));
|
||||
let task_l = Item::Task(Task::new("task L".into(), ItemId::random(), Utc.ymd(2000, 1, 12).and_hms(0, 0, 0)));
|
||||
let task_m = Item::Task(Task::new("task M".into(), ItemId::random(), Utc.ymd(2000, 1, 12).and_hms(0, 0, 0)));
|
||||
let task_a = Item::Task(Task::new("task A".into(), ItemId::random(), Utc.ymd(2000, 1, 1).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_b = Item::Task(Task::new("task B".into(), ItemId::random(), Utc.ymd(2000, 1, 2).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_c = Item::Task(Task::new("task C".into(), ItemId::random(), Utc.ymd(2000, 1, 3).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_d = Item::Task(Task::new("task D".into(), ItemId::random(), Utc.ymd(2000, 1, 4).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_e = Item::Task(Task::new("task E".into(), ItemId::random(), Utc.ymd(2000, 1, 5).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_f = Item::Task(Task::new("task F".into(), ItemId::random(), Utc.ymd(2000, 1, 6).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_g = Item::Task(Task::new("task G".into(), ItemId::random(), Utc.ymd(2000, 1, 7).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_h = Item::Task(Task::new("task H".into(), ItemId::random(), Utc.ymd(2000, 1, 8).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_i = Item::Task(Task::new("task I".into(), ItemId::random(), Utc.ymd(2000, 1, 9).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_j = Item::Task(Task::new("task J".into(), ItemId::random(), Utc.ymd(2000, 1, 10).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_k = Item::Task(Task::new("task K".into(), ItemId::random(), Utc.ymd(2000, 1, 11).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_l = Item::Task(Task::new("task L".into(), ItemId::random(), Utc.ymd(2000, 1, 12).and_hms(0, 0, 0), VersionTag::random()));
|
||||
let task_m = Item::Task(Task::new("task M".into(), ItemId::random(), Utc.ymd(2000, 1, 12).and_hms(0, 0, 0), VersionTag::random()));
|
||||
|
||||
let last_sync = task_m.last_modified();
|
||||
local.update_last_sync(Some(last_sync));
|
||||
assert!(last_sync < Utc::now());
|
||||
// let last_sync = task_m.last_modified();
|
||||
// local.update_last_sync(Some(last_sync));
|
||||
// assert!(last_sync < Utc::now());
|
||||
|
||||
let task_b_id = task_b.id().clone();
|
||||
let task_c_id = task_c.id().clone();
|
||||
|
@ -129,7 +130,7 @@ async fn populate_test_provider() -> Provider<Cache, CachedCalendar, Cache, Cach
|
|||
|
||||
cal_server.delete_item(&task_l_id).await.unwrap();
|
||||
|
||||
let task_n = Item::Task(Task::new("task N (new from server)".into(), ItemId::random(), Utc::now()));
|
||||
let task_n = Item::Task(Task::new("task N (new from server)".into(), ItemId::random(), Utc::now(), VersionTag::random()));
|
||||
cal_server.add_item(task_n).await;
|
||||
|
||||
|
||||
|
@ -158,7 +159,7 @@ async fn populate_test_provider() -> Provider<Cache, CachedCalendar, Cache, Cach
|
|||
cal_local.delete_item(&task_k_id).await.unwrap();
|
||||
cal_local.delete_item(&task_l_id).await.unwrap();
|
||||
|
||||
let task_o = Item::Task(Task::new("task O (new from local)".into(), ItemId::random(), Utc::now()));
|
||||
let task_o = Item::Task(Task::new("task O (new from local)".into(), ItemId::random(), Utc::now(), VersionTag::random()));
|
||||
cal_local.add_item(task_o).await;
|
||||
|
||||
Provider::new(server, local)
|
||||
|
|
Loading…
Add table
Reference in a new issue