public void ThrowsWhenRepositoryThrows() { var state = new PushSingleState <IThreadSafeTestModel>(dataSource); dataSource.Get().Returns(Observable.Throw <IThreadSafeTestModel>(new Exception())); Action callingStart = () => state.Start().SingleAsync().Wait(); callingStart.Should().Throw <Exception>(); }
public void ReturnsNothingToPushTransitionWhenTheSingleEntityDoesNotNeedSyncing(SyncStatus syncStatus) { var entity = new TestModel(1, syncStatus); var state = new PushSingleState <IThreadSafeTestModel>(dataSource); dataSource.Get().Returns(Observable.Return(entity)); var transition = state.Start().SingleAsync().Wait(); transition.Result.Should().Be(state.NothingToPush); }
public void ReturnsPushEntityTransitionWhenTheRepositoryReturnsSomeEntity() { var state = new PushSingleState <IThreadSafeTestModel>(dataSource); var entity = new TestModel(1, SyncStatus.SyncNeeded); dataSource.Get().Returns(Observable.Return(entity)); var transition = state.Start().SingleAsync().Wait(); var parameter = ((Transition <IThreadSafeTestModel>)transition).Parameter; transition.Result.Should().Be(state.PushEntity); parameter.Should().BeEquivalentTo(entity, options => options.IncludingProperties()); }
private static IStateResult configurePushSingleton <TModel, TThreadsafe>( ITransitionConfigurator transitions, IStateResult entryPoint, ISingletonDataSource <TThreadsafe> dataSource, IAnalyticsService analyticsService, IUpdatingApiClient <TModel> updatingApi, Func <TModel, TThreadsafe> toClean, Func <TThreadsafe, string, TThreadsafe> toUnsyncable, ITogglApi api, IScheduler scheduler, IObservable <Unit> delayCancellation) where TModel : class where TThreadsafe : class, TModel, IThreadSafeModel, IDatabaseSyncable { var rnd = new Random(); var apiDelay = new RetryDelayService(rnd); var statusDelay = new RetryDelayService(rnd); var push = new PushSingleState <TThreadsafe>(dataSource); var pushOne = new PushOneEntityState <TThreadsafe>(); var update = new UpdateEntityState <TModel, TThreadsafe>(updatingApi, dataSource, analyticsService, toClean); var tryResolveClientError = new TryResolveClientErrorState <TThreadsafe>(); var unsyncable = new UnsyncableEntityState <TThreadsafe>(dataSource, toUnsyncable); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); transitions.ConfigureTransition(entryPoint, push); transitions.ConfigureTransition(push.PushEntity, pushOne); transitions.ConfigureTransition(pushOne.UpdateEntity, update); transitions.ConfigureTransition(pushOne.CreateEntity, new InvalidTransitionState($"Creating is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(pushOne.DeleteEntity, new InvalidTransitionState($"Deleting is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(pushOne.DeleteEntityLocally, new InvalidTransitionState($"Deleting locally is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(update.ClientError, tryResolveClientError); transitions.ConfigureTransition(update.ServerError, checkServerStatus); transitions.ConfigureTransition(update.UnknownError, checkServerStatus); transitions.ConfigureTransition(tryResolveClientError.UnresolvedTooManyRequests, checkServerStatus); transitions.ConfigureTransition(tryResolveClientError.Unresolved, unsyncable); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, push); transitions.ConfigureTransition(update.UpdatingSucceeded, finished); transitions.ConfigureTransition(finished.Continue, push); return(push.NothingToPush); }