@ -11,6 +11,7 @@
use std ::path ::PathBuf ;
use std ::sync ::{ Arc , Mutex } ;
use std ::error ::Error ;
use url ::Url ;
use chrono ::Utc ;
@ -22,13 +23,13 @@ use kitchen_fridge::traits::CompleteCalendar;
use kitchen_fridge ::traits ::DavCalendar ;
use kitchen_fridge ::cache ::Cache ;
use kitchen_fridge ::Item ;
use kitchen_fridge ::item ::ItemId ;
use kitchen_fridge ::item ::SyncStatus ;
use kitchen_fridge ::Task ;
use kitchen_fridge ::task ::CompletionStatus ;
use kitchen_fridge ::calendar ::cached_calendar ::CachedCalendar ;
use kitchen_fridge ::provider ::Provider ;
use kitchen_fridge ::mock_behaviour ::MockBehaviour ;
use kitchen_fridge ::utils ::random_url ;
pub enum LocatedState {
/// Item does not exist yet or does not exist anymore
@ -62,7 +63,7 @@ pub enum ChangeToApply {
pub struct ItemScenario {
id : ItemId ,
url : Url ,
initial_state : LocatedState ,
local_changes_to_apply : Vec < ChangeToApply > ,
remote_changes_to_apply : Vec < ChangeToApply > ,
@ -93,7 +94,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & first_cal ) ,
url : random_url ( & first_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : first_cal . clone ( ) ,
name : String ::from ( "Task A" ) ,
@ -111,7 +112,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & first_cal ) ,
url : random_url ( & first_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : first_cal . clone ( ) ,
name : String ::from ( "Task B" ) ,
@ -125,7 +126,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & first_cal ) ,
url : random_url ( & first_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : first_cal . clone ( ) ,
name : String ::from ( "Task C" ) ,
@ -139,7 +140,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & first_cal ) ,
url : random_url ( & first_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : first_cal . clone ( ) ,
name : String ::from ( "Task D" ) ,
@ -157,7 +158,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & first_cal ) ,
url : random_url ( & first_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : first_cal . clone ( ) ,
name : String ::from ( "Task E" ) ,
@ -175,7 +176,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & first_cal ) ,
url : random_url ( & first_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : first_cal . clone ( ) ,
name : String ::from ( "Task F" ) ,
@ -194,7 +195,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & second_cal ) ,
url : random_url ( & second_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : second_cal . clone ( ) ,
name : String ::from ( "Task G" ) ,
@ -212,7 +213,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & second_cal ) ,
url : random_url ( & second_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : second_cal . clone ( ) ,
name : String ::from ( "Task H" ) ,
@ -230,7 +231,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & second_cal ) ,
url : random_url ( & second_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : second_cal . clone ( ) ,
name : String ::from ( "Task I" ) ,
@ -249,7 +250,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & second_cal ) ,
url : random_url ( & second_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : second_cal . clone ( ) ,
name : String ::from ( "Task J" ) ,
@ -263,7 +264,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & second_cal ) ,
url : random_url ( & second_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : second_cal . clone ( ) ,
name : String ::from ( "Task K" ) ,
@ -281,7 +282,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & second_cal ) ,
url : random_url ( & second_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : second_cal . clone ( ) ,
name : String ::from ( "Task L" ) ,
@ -295,7 +296,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & second_cal ) ,
url : random_url ( & second_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : second_cal . clone ( ) ,
name : String ::from ( "Task M" ) ,
@ -313,7 +314,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & third_cal ) ,
url : random_url ( & third_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : third_cal . clone ( ) ,
name : String ::from ( "Task N" ) ,
@ -331,7 +332,7 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & third_cal ) ,
url : random_url ( & third_cal ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : third_cal . clone ( ) ,
name : String ::from ( "Task O" ) ,
@ -347,10 +348,10 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
}
) ;
let id _p = ItemId ::random ( & third_cal ) ;
let url _p = random_url ( & third_cal ) ;
tasks . push (
ItemScenario {
id : id _p. clone ( ) ,
url : url _p. clone ( ) ,
initial_state : LocatedState ::BothSynced ( ItemState {
calendar : third_cal . clone ( ) ,
name : String ::from ( "Task P" ) ,
@ -369,16 +370,16 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
}
) ;
let id _q = ItemId ::random ( & third_cal ) ;
let url _q = random_url ( & third_cal ) ;
tasks . push (
ItemScenario {
id : id _q. clone ( ) ,
url : url _q. clone ( ) ,
initial_state : LocatedState ::None ,
local_changes_to_apply : Vec ::new ( ) ,
remote_changes_to_apply : vec ! [ ChangeToApply ::Create ( third_cal . clone ( ) , Item ::Task (
Task ::new_with_parameters (
String ::from ( "Task Q, created on the server" ) ,
id _q. to_string ( ) , id _q,
url _q. to_string ( ) , url _q,
CompletionStatus ::Uncompleted ,
SyncStatus ::random_synced ( ) , Some ( Utc ::now ( ) ) , Utc ::now ( ) , "prod_id" . to_string ( ) , Vec ::new ( ) )
) ) ] ,
@ -390,15 +391,15 @@ pub fn scenarii_basic() -> Vec<ItemScenario> {
}
) ;
let id _r = ItemId ::random ( & third_cal ) ;
let url _r = random_url ( & third_cal ) ;
tasks . push (
ItemScenario {
id : id _r. clone ( ) ,
url : url _r. clone ( ) ,
initial_state : LocatedState ::None ,
local_changes_to_apply : vec ! [ ChangeToApply ::Create ( third_cal . clone ( ) , Item ::Task (
Task ::new_with_parameters (
String ::from ( "Task R, created locally" ) ,
id _r. to_string ( ) , id _r,
url _r. to_string ( ) , url _r,
CompletionStatus ::Uncompleted ,
SyncStatus ::NotSynced , Some ( Utc ::now ( ) ) , Utc ::now ( ) , "prod_id" . to_string ( ) , Vec ::new ( ) )
) ) ] ,
@ -423,7 +424,7 @@ pub fn scenarii_first_sync_to_local() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & cal1 ) ,
url : random_url ( & cal1 ) ,
initial_state : LocatedState ::Remote ( ItemState {
calendar : cal1 . clone ( ) ,
name : String ::from ( "Task A1" ) ,
@ -441,7 +442,7 @@ pub fn scenarii_first_sync_to_local() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & cal2 ) ,
url : random_url ( & cal2 ) ,
initial_state : LocatedState ::Remote ( ItemState {
calendar : cal2 . clone ( ) ,
name : String ::from ( "Task A2" ) ,
@ -459,7 +460,7 @@ pub fn scenarii_first_sync_to_local() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & cal1 ) ,
url : random_url ( & cal1 ) ,
initial_state : LocatedState ::Remote ( ItemState {
calendar : cal1 . clone ( ) ,
name : String ::from ( "Task B1" ) ,
@ -487,7 +488,7 @@ pub fn scenarii_first_sync_to_server() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & cal3 ) ,
url : random_url ( & cal3 ) ,
initial_state : LocatedState ::Local ( ItemState {
calendar : cal3 . clone ( ) ,
name : String ::from ( "Task A3" ) ,
@ -505,7 +506,7 @@ pub fn scenarii_first_sync_to_server() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & cal4 ) ,
url : random_url ( & cal4 ) ,
initial_state : LocatedState ::Local ( ItemState {
calendar : cal4 . clone ( ) ,
name : String ::from ( "Task A4" ) ,
@ -523,7 +524,7 @@ pub fn scenarii_first_sync_to_server() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & cal3 ) ,
url : random_url ( & cal3 ) ,
initial_state : LocatedState ::Local ( ItemState {
calendar : cal3 . clone ( ) ,
name : String ::from ( "Task B3" ) ,
@ -551,7 +552,7 @@ pub fn scenarii_transient_task() -> Vec<ItemScenario> {
tasks . push (
ItemScenario {
id : ItemId ::random ( & cal ) ,
url : random_url ( & cal ) ,
initial_state : LocatedState ::Local ( ItemState {
calendar : cal . clone ( ) ,
name : String ::from ( "A task, so that the calendar actually exists" ) ,
@ -567,16 +568,16 @@ pub fn scenarii_transient_task() -> Vec<ItemScenario> {
}
) ;
let id _transient = ItemId ::random ( & cal ) ;
let url _transient = random_url ( & cal ) ;
tasks . push (
ItemScenario {
id : id _transient. clone ( ) ,
url : url _transient. clone ( ) ,
initial_state : LocatedState ::None ,
local_changes_to_apply : vec ! [
ChangeToApply ::Create ( cal , Item ::Task (
Task ::new_with_parameters (
String ::from ( "A transient task that will be deleted before the sync" ) ,
id _transient. to_string ( ) , id _transient,
url _transient. to_string ( ) , url _transient,
CompletionStatus ::Uncompleted ,
SyncStatus ::NotSynced , Some ( Utc ::now ( ) ) , Utc ::now ( ) ,
"prod_id" . to_string ( ) , Vec ::new ( ) )
@ -637,8 +638,8 @@ async fn populate_test_provider(scenarii: &[ItemScenario], mock_behaviour: Arc<M
let new_item = Item ::Task (
Task ::new_with_parameters (
state . name . clone ( ) ,
item . id . to_string ( ) ,
item . id . clone ( ) ,
item . url . to_string ( ) ,
item . url . clone ( ) ,
completion_status ,
sync_status ,
Some ( now ) ,
@ -676,12 +677,12 @@ async fn apply_changes_on_provider(provider: &mut Provider<Cache, CachedCalendar
let mut calendar_id = initial_calendar_id . clone ( ) ;
for local_change in & item . local_changes_to_apply {
calendar_id = Some ( apply_change ( provider . local ( ) , calendar_id , & item . id , local_change , false ) . await ) ;
calendar_id = Some ( apply_change ( provider . local ( ) , calendar_id , & item . url , local_change , false ) . await ) ;
}
let mut calendar_id = initial_calendar_id ;
for remote_change in & item . remote_changes_to_apply {
calendar_id = Some ( apply_change ( provider . remote ( ) , calendar_id , & item . id , remote_change , true ) . await ) ;
calendar_id = Some ( apply_change ( provider . remote ( ) , calendar_id , & item . url , remote_change , true ) . await ) ;
}
}
}
@ -707,14 +708,14 @@ async fn get_or_insert_calendar(source: &mut Cache, id: &CalendarId)
}
/// Apply a single change on a given source, and returns the calendar ID that was modified
async fn apply_change < S , C > ( source : & S , calendar_id : Option < CalendarId > , item_id : & ItemId , change : & ChangeToApply , is_remote : bool ) -> CalendarId
async fn apply_change < S , C > ( source : & S , calendar_id : Option < CalendarId > , item_url : & Url , change : & ChangeToApply , is_remote : bool ) -> CalendarId
where
S : CalDavSource < C > ,
C : CompleteCalendar + DavCalendar , // in this test, we're using a calendar that mocks both kinds
{
match calendar_id {
Some ( cal ) = > {
apply_changes_on_an_existing_item ( source , & cal , item_id , change , is_remote ) . await ;
apply_changes_on_an_existing_item ( source , & cal , item_url , change , is_remote ) . await ;
cal
} ,
None = > {
@ -723,14 +724,14 @@ where
}
}
async fn apply_changes_on_an_existing_item < S , C > ( source : & S , calendar_id : & CalendarId , item_id : & ItemId , change : & ChangeToApply , is_remote : bool )
async fn apply_changes_on_an_existing_item < S , C > ( source : & S , calendar_id : & CalendarId , item_url : & Url , change : & ChangeToApply , is_remote : bool )
where
S : CalDavSource < C > ,
C : CompleteCalendar + DavCalendar , // in this test, we're using a calendar that mocks both kinds
{
let cal = source . get_calendar ( calendar_id ) . await . unwrap ( ) ;
let mut cal = cal . lock ( ) . unwrap ( ) ;
let task = cal . get_item_by_id_mut ( item_id ) . await . unwrap ( ) . unwrap_task_mut ( ) ;
let task = cal . get_item_by_id_mut ( item_url ) . await . unwrap ( ) . unwrap_task_mut ( ) ;
match change {
ChangeToApply ::Rename ( new_name ) = > {
@ -753,8 +754,8 @@ where
} ,
ChangeToApply ::Remove = > {
match is_remote {
false = > cal . mark_for_deletion ( item_id ) . await . unwrap ( ) ,
true = > cal . delete_item ( item_id ) . await . unwrap ( ) ,
false = > cal . mark_for_deletion ( item_url ) . await . unwrap ( ) ,
true = > cal . delete_item ( item_url ) . await . unwrap ( ) ,
} ;
} ,
ChangeToApply ::Create ( _calendar_id , _item ) = > {