public void ThrowsWhenRepositoryThrows() { var state = new LookForChangeToPushState <IDatabaseTestModel, IThreadSafeTestModel>(dataSource); dataSource.GetAll(Arg.Any <Func <IDatabaseTestModel, bool> >()) .Returns(Observable.Throw <IEnumerable <IThreadSafeTestModel> >(new Exception())); Action callingStart = () => state.Start().SingleAsync().Wait(); callingStart.Should().Throw <Exception>(); }
public void ReturnsNothingToPushTransitionWhenTheRepositoryReturnsNoEntity() { var state = new LookForChangeToPushState <IDatabaseTestModel, IThreadSafeTestModel>(dataSource); dataSource.GetAll(Arg.Any <Func <IDatabaseTestModel, bool> >()) .Returns(Observable.Return(new IThreadSafeTestModel[0])); var transition = state.Start().SingleAsync().Wait(); transition.Result.Should().Be(state.NoMoreChanges); }
public void ReturnsPushEntityTransitionWhenTheRepositoryReturnsSomeEntity() { var state = new LookForChangeToPushState <IDatabaseTestModel, IThreadSafeTestModel>(dataSource); var entity = new TestModel(1, SyncStatus.SyncNeeded); dataSource.GetAll(Arg.Any <Func <IDatabaseTestModel, bool> >()) .Returns(Observable.Return(new[] { entity })); var transition = state.Start().SingleAsync().Wait(); var parameter = ((Transition <IThreadSafeTestModel>)transition).Parameter; transition.Result.Should().Be(state.ChangeFound); parameter.Should().BeEquivalentTo(entity, options => options.IncludingProperties()); }
private static LookForChangeToPushState <TDatabase, TThreadsafe> configureCreateOnlyPush <TModel, TDatabase, TThreadsafe>( ITransitionConfigurator transitions, IStateResult entryPoint, IDataSource <TThreadsafe, TDatabase> dataSource, IAnalyticsService analyticsService, ICreatingApiClient <TModel> creatingApi, ILeakyBucket minutesLeakyBucket, IRateLimiter rateLimiter, WaitForAWhileState waitForAWhileState, Func <TModel, TThreadsafe> toClean, Func <TThreadsafe, string, TThreadsafe> toUnsyncable) where TModel : IIdentifiable, ILastChangedDatable where TDatabase : class, TModel, IDatabaseSyncable where TThreadsafe : class, TDatabase, IThreadSafeModel { var lookForChange = new LookForChangeToPushState <TDatabase, TThreadsafe>(dataSource); var chooseOperation = new ChooseSyncOperationState <TThreadsafe>(); var create = new CreateEntityState <TModel, TDatabase, TThreadsafe>(creatingApi, dataSource, analyticsService, minutesLeakyBucket, rateLimiter, toClean); var processClientError = new ProcessClientErrorState <TThreadsafe>(); var unsyncable = new MarkEntityAsUnsyncableState <TThreadsafe>(dataSource, toUnsyncable); transitions.ConfigureTransition(entryPoint, lookForChange); transitions.ConfigureTransition(lookForChange.ChangeFound, chooseOperation); transitions.ConfigureTransition(chooseOperation.CreateEntity, create); transitions.ConfigureTransition(chooseOperation.UpdateEntity, new InvalidTransitionState($"Updating is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(chooseOperation.DeleteEntity, new InvalidTransitionState($"Deleting is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(chooseOperation.DeleteEntityLocally, new InvalidTransitionState($"Deleting locally is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(create.ClientError, processClientError); transitions.ConfigureTransition(create.ServerError, new FailureState()); transitions.ConfigureTransition(create.UnknownError, new FailureState()); transitions.ConfigureTransition(create.PreventOverloadingServer, waitForAWhileState); transitions.ConfigureTransition(processClientError.UnresolvedTooManyRequests, new FailureState()); transitions.ConfigureTransition(processClientError.Unresolved, unsyncable); transitions.ConfigureTransition(create.EntityChanged, new InvalidTransitionState($"Entity cannot have changed since updating is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(create.Done, lookForChange); transitions.ConfigureTransition(unsyncable.Done, lookForChange); return(lookForChange); }
public void ReturnsPushEntityTransitionWithTheOldestEntity() { var at = new DateTimeOffset(2017, 9, 1, 12, 34, 56, TimeSpan.Zero); var state = new LookForChangeToPushState <IDatabaseTestModel, IThreadSafeTestModel>(dataSource); var entity = new TestModel { At = at, SyncStatus = SyncStatus.SyncNeeded }; var entity2 = new TestModel { At = at.AddDays(-2), SyncStatus = SyncStatus.SyncNeeded }; var entity3 = new TestModel { At = at.AddDays(-1), SyncStatus = SyncStatus.SyncNeeded }; dataSource.GetAll(Arg.Any <Func <IDatabaseTestModel, bool> >()) .Returns(Observable.Return(new[] { entity, entity2, entity3 })); var transition = state.Start().SingleAsync().Wait(); var parameter = ((Transition <IThreadSafeTestModel>)transition).Parameter; transition.Result.Should().Be(state.ChangeFound); parameter.Should().BeEquivalentTo(entity2, options => options.IncludingProperties()); }