public async Task UndeleteItemAsync_ConditionalFailure()
        {
            // Arrange
            var id   = GetRandomId();
            var item = new ClientMovie {
                Id = id, Version = "dGVzdA=="
            };
            var expected = MovieServer.GetMovieById(id);

            // Act
            var exception = await Assert.ThrowsAsync <DatasyncConflictException <ClientMovie> >(() => table.UndeleteItemAsync(item)).ConfigureAwait(false);

            // Assert
            Assert.NotNull(exception.Request);
            Assert.NotNull(exception.Response);
            Assert.Equal(HttpStatusCode.PreconditionFailed, exception.Response?.StatusCode);

            var entity = MovieServer.GetMovieById(id);

            Assert.NotNull(entity);
            Assert.Equal <IMovie>(entity, exception.Item);
            Assert.Equal <IMovie>(expected, entity);
            Assert.Equal <ITableData>(expected, entity);
            AssertEx.ResponseHasConditionalHeaders(entity, exception.Response);
        }
        public async Task DeleteItemAsync_ConditionalFailure()
        {
            await InitializeAsync();

            // Arrange
            var id       = GetRandomId();
            var expected = MovieServer.GetMovieById(id);
            var item     = ClientMovie.From(MovieServer.GetMovieById(id));

            await ModifyServerVersionAsync(id);

            // Act
            await table !.DeleteItemAsync(item);

            Assert.Equal(MovieCount, MovieServer.GetMovieCount());

            var exception = await Assert.ThrowsAsync <PushFailedException>(() => table !.PushItemsAsync());

            // Assert
            Assert.Equal(MovieCount, MovieServer.GetMovieCount());
            var entity = MovieServer.GetMovieById(id);

            // Check the PushFailedException
            Assert.Single(exception.PushResult.Errors);
            var error = exception.PushResult.Errors.First();

            AssertSystemPropertiesMatch(entity, error.Result);
        }
        public async Task DeleteItemAsync_ConditionalFailure()
        {
            // Arrange
            var id       = GetRandomId();
            var expected = MovieServer.GetMovieById(id);
            var item     = new ClientMovie {
                Id = id, Version = "dGVzdA=="
            };

            // Act
            var exception = await Assert.ThrowsAsync <DatasyncConflictException <ClientMovie> >(() => table.DeleteItemAsync(item)).ConfigureAwait(false);

            // Assert
            Assert.NotNull(exception.Request);
            Assert.NotNull(exception.Response);
            Assert.Equal(MovieCount, MovieServer.GetMovieCount());
            var entity = MovieServer.GetMovieById(id);

            Assert.NotNull(entity);
            AssertEx.SystemPropertiesSet(entity, startTime);
            AssertEx.SystemPropertiesMatch(entity, exception.Item);
            Assert.Equal <IMovie>(expected, exception.Item);
            Assert.Equal <IMovie>(expected, entity);
            Assert.Equal <ITableData>(expected, entity);
            AssertEx.ResponseHasConditionalHeaders(entity, exception.Response);
        }
Beispiel #4
0
        public async Task PushItemsAsync_SingleTable_HandlesDeleteOperation_WithoutVersion()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var item = new ClientMovie {
                Id = Guid.NewGuid().ToString()
            };
            var instance = (JObject)table.ServiceClient.Serializer.Serialize(item);

            store.Upsert("movies", new[] { instance });
            MockHandler.AddResponse(HttpStatusCode.NoContent);

            await table.DeleteItemAsync(instance);

            await table.PushItemsAsync();

            Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
            Assert.Single(MockHandler.Requests);

            var request = MockHandler.Requests[0];

            Assert.Equal(HttpMethod.Delete, request.Method);
            Assert.Equal($"/tables/movies/{item.Id}", request.RequestUri.PathAndQuery);
            Assert.Empty(request.Headers.IfMatch);
        }
Beispiel #5
0
        public async Task ReplaceItemAsync_Validation(string propName, object propValue)
        {
            await InitializeAsync();

            // Arrange
            var id       = GetRandomId();
            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);
            var entity   = expected.Clone();

            switch (propName)
            {
            case "duration": entity.Duration = (int)propValue; break;

            case "rating": entity.Rating = (string)propValue; break;

            case "title": entity.Title = (string)propValue; break;

            case "year": entity.Year = (int)propValue; break;
            }

            // Act
            await table !.ReplaceItemAsync(entity);
            var   exception = await Assert.ThrowsAsync <PushFailedException>(() => table !.PushItemsAsync());

            var stored = MovieServer.GetMovieById(id);

            // Assert
            Assert.Single(exception.PushResult.Errors);
        }
        public async Task ReplaceItemAsync_Validation(string propName, object propValue)
        {
            // Arrange
            var id       = GetRandomId();
            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);
            var entity   = expected.Clone();

            switch (propName)
            {
            case "duration": entity.Duration = (int)propValue; break;

            case "rating": entity.Rating = (string)propValue; break;

            case "title": entity.Title = (string)propValue; break;

            case "year": entity.Year = (int)propValue; break;
            }

            // Act
            var exception = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.ReplaceItemAsync(entity)).ConfigureAwait(false);

            var stored = MovieServer.GetMovieById(id);

            // Assert
            Assert.Equal(HttpStatusCode.BadRequest, exception.Response?.StatusCode);
            Assert.Equal <IMovie>(expected, stored);
            Assert.Equal <ITableData>(original, stored);
        }
Beispiel #7
0
        public async Task PushItemsAsync_SingleTable_HandlesInsertOperation()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var item = new ClientMovie {
                Id = Guid.NewGuid().ToString(), Title = "The Big Test"
            };
            var returnedItem = item.Clone();

            returnedItem.UpdatedAt = DateTimeOffset.Now;
            returnedItem.Version   = "1";
            var expectedContent = $"{{\"bestPictureWinner\":false,\"duration\":0,\"rating\":null,\"releaseDate\":\"0001-01-01T00:00:00.000Z\",\"title\":\"The Big Test\",\"year\":0,\"id\":\"{item.Id}\"}}";
            var instance        = (JObject)table.ServiceClient.Serializer.Serialize(item);

            MockHandler.AddResponse(HttpStatusCode.OK, returnedItem);

            await table.InsertItemAsync(instance);

            await table.PushItemsAsync();

            Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);
            Assert.Single(MockHandler.Requests);

            var request = MockHandler.Requests[0];

            Assert.Equal(HttpMethod.Post, request.Method);
            Assert.Equal("/tables/movies", request.RequestUri.PathAndQuery);
            Assert.Equal(expectedContent, await request.Content.ReadAsStringAsync());

            Assert.True(store.TableMap["movies"].ContainsKey(item.Id));
            var storedItem = store.TableMap["movies"][item.Id];

            Assert.Equal(storedItem.Value <DateTime>("updatedAt").Ticks, returnedItem.UpdatedAt?.Ticks);
            Assert.Equal(storedItem.Value <string>("version"), returnedItem.Version);
        }
Beispiel #8
0
        public async Task ReplaceItemAsync_SoftDeleted_ReturnsGone()
        {
            // Arrange
            var id = GetRandomId();
            await MovieServer.SoftDeleteMoviesAsync(x => x.Id == id).ConfigureAwait(false);

            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);

            expected.Title  = "Replacement Title";
            expected.Rating = "PG-13";
            var json = CreateJsonDocument(expected);

            var table = client.GetRemoteTable("soft");

            // Act
            var exception = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => soft.ReplaceItemAsync(json)).ConfigureAwait(false);

            var stored = MovieServer.GetMovieById(id).Clone();

            // Assert
            Assert.Equal(HttpStatusCode.Gone, exception.Response?.StatusCode);
            Assert.Equal <IMovie>(original, stored);
            Assert.Equal <ITableData>(original, stored);
        }
        public async Task ReplaceItemAsync_ConditionalFailure()
        {
            // Arrange
            var id       = GetRandomId();
            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);

            expected.Title   = "Replacement Title";
            expected.Rating  = "PG-13";
            expected.Version = "dGVzdA==";

            // Act
            var exception = await Assert.ThrowsAsync <DatasyncConflictException <ClientMovie> >(() => table.ReplaceItemAsync(expected)).ConfigureAwait(false);

            // Assert
            Assert.NotNull(exception.Request);
            Assert.NotNull(exception.Response);
            Assert.Equal(MovieCount, MovieServer.GetMovieCount());
            var entity = MovieServer.GetMovieById(id);

            Assert.NotNull(entity);
            AssertEx.SystemPropertiesSet(entity, startTime);
            AssertEx.SystemPropertiesMatch(entity, exception.Item);
            Assert.Equal <IMovie>(original, exception.Item);
            Assert.Equal <IMovie>(original, entity);
            Assert.Equal <ITableData>(original, entity);
            AssertEx.ResponseHasConditionalHeaders(entity, exception.Response);
        }
        public async Task ReplaceItemAsync_ThrowsOnInvalidId(string id)
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var item = new ClientMovie {
                Id = id
            };
            await Assert.ThrowsAsync <ArgumentException>(() => table.ReplaceItemAsync(item)).ConfigureAwait(false);
        }
Beispiel #11
0
        public ActionResult InsertClientMovie(int id)
        {
            var model = new ClientMovie();

            model.movie   = _context.Movies.FirstOrDefault(z => z.id == id);
            model.movieId = id;
            model.clients = _context.Clients.ToList();
            return(View(model));
        }
        public async Task RefreshItemAsync_ReturnsOnNullId()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var item = new ClientMovie {
                Id = null
            };
            await table.RefreshItemAsync(item);

            Assert.Null(item.Id);
        }
        public async Task RefreshItemAsync_MissingItem()
        {
            // Arrange
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var item = new ClientMovie {
                Id = Guid.NewGuid().ToString()
            };

            // Act
            await Assert.ThrowsAsync <InvalidOperationException>(() => table.RefreshItemAsync(item));
        }
        public async Task DeleteItemAsync_ConditionalSuccess()
        {
            // Arrange
            var id   = GetRandomId();
            var item = ClientMovie.From(MovieServer.GetMovieById(id));

            // Act
            await table.DeleteItemAsync(item).ConfigureAwait(false);

            // Assert
            Assert.Equal(MovieCount - 1, MovieServer.GetMovieCount());
            Assert.Null(MovieServer.GetMovieById(id));
        }
Beispiel #15
0
        public async Task PushItemsAsync_SingleTable_HandlesUpdateOperation_Conflict()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var itemToUpdate = new ClientMovie {
                Id = Guid.NewGuid().ToString(), Version = "1", Title = "The Big Test"
            };
            var instance = table.ServiceClient.Serializer.Serialize(itemToUpdate) as JObject;

            store.Upsert("movies", new[] { instance });

            var updatedItem = itemToUpdate.Clone();

            updatedItem.Title = "Modified";
            var mInstance = table.ServiceClient.Serializer.Serialize(updatedItem) as JObject;

            var returnedItem = itemToUpdate.Clone();

            returnedItem.Version = "2";
            var expectedInstance = table.ServiceClient.Serializer.Serialize(returnedItem) as JObject;

            MockHandler.AddResponse(HttpStatusCode.Conflict, returnedItem);

            await table.ReplaceItemAsync(mInstance);

            var ex = await Assert.ThrowsAsync <PushFailedException>(() => table.PushItemsAsync());

            Assert.Single(MockHandler.Requests);
            var request = MockHandler.Requests[0];

            Assert.Equal(HttpMethod.Put, request.Method);
            Assert.Equal($"/tables/movies/{itemToUpdate.Id}", request.RequestUri.PathAndQuery);
            Assert.Equal("\"1\"", request.Headers.IfMatch.First().Tag);
            var requestObj = JObject.Parse(await request.Content.ReadAsStringAsync());

            AssertEx.JsonEqual(mInstance, requestObj);

            Assert.Equal(PushStatus.Complete, ex.PushResult.Status);
            Assert.Single(ex.PushResult.Errors);
            Assert.Equal("movies", ex.PushResult.Errors.First().TableName);
            Assert.Equal(itemToUpdate.Id, ex.PushResult.Errors.First().Item.Value <string>("id"));

            Assert.Single(store.TableMap[SystemTables.OperationsQueue]);
            var op = TableOperation.Deserialize(store.TableMap[SystemTables.OperationsQueue].Values.First());

            Assert.Equal(TableOperationState.Failed, op.State);

            Assert.Single(store.TableMap[SystemTables.SyncErrors]);
        }
Beispiel #16
0
        /// <summary>
        /// Injects a set of items into the store.
        /// </summary>
        /// <param name="nItems"></param>
        /// <returns></returns>
        private List <ClientMovie> InjectRandomItems(int nItems = 5)
        {
            List <ClientMovie> items = new();

            for (int i = 0; i < nItems; i++)
            {
                var item = new ClientMovie {
                    Id = $"id-{i}", Title = "true"
                };
                var instance = (JObject)table.ServiceClient.Serializer.Serialize(item);
                items.Add(item);
                store.Upsert("movies", new[] { instance });
            }
            return(items);
        }
        public async Task DeleteItemAsync_Basic()
        {
            // Arrange
            var id   = GetRandomId();
            var item = new ClientMovie {
                Id = id
            };

            // Act
            await table.DeleteItemAsync(item).ConfigureAwait(false);

            // Assert
            Assert.Equal(MovieCount - 1, MovieServer.GetMovieCount());
            Assert.Null(MovieServer.GetMovieById(id));
        }
        public async Task DeleteItemAsync_SoftDelete()
        {
            // Arrange
            var id   = GetRandomId();
            var item = ClientMovie.From(MovieServer.GetMovieById(id));

            // Act
            await soft.DeleteItemAsync(item).ConfigureAwait(false);

            // Assert
            Assert.Equal(MovieCount, MovieServer.GetMovieCount());
            var entity = MovieServer.GetMovieById(id) !;

            Assert.True(entity.Deleted);
        }
        public async Task DeleteItemAsync_NotFound()
        {
            await InitializeAsync();

            // Arrange
            const string id   = "not-found";
            var          item = new ClientMovie {
                Id = id
            };

            // Act
            var exception = await Assert.ThrowsAsync <InvalidOperationException>(() => table !.DeleteItemAsync(item));

            // Assert
            Assert.Equal(MovieCount, MovieServer.GetMovieCount());
        }
        public async Task UndeleteItemAsync_NotFound()
        {
            // Arrange
            const string id   = "not-found";
            var          item = new ClientMovie {
                Id = id
            };

            // Act
            var exception = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.UndeleteItemAsync(item)).ConfigureAwait(false);

            // Assert
            Assert.NotNull(exception.Request);
            Assert.NotNull(exception.Response);
            Assert.Equal(HttpStatusCode.NotFound, exception.Response?.StatusCode);
        }
        public async Task DeleteItemAsync_Basic()
        {
            await InitializeAsync();

            // Arrange
            var id   = GetRandomId();
            var item = ClientMovie.From(MovieServer.GetMovieById(id));

            // Act
            await table !.DeleteItemAsync(item);

            Assert.Equal(MovieCount, MovieServer.GetMovieCount());

            await table !.PushItemsAsync();

            Assert.Equal(MovieCount - 1, MovieServer.GetMovieCount());
            Assert.Null(MovieServer.GetMovieById(id));
        }
        public async Task UndeleteItemAsync_SoftDelete()
        {
            // Arrange
            var id   = GetRandomId();
            var item = new ClientMovie {
                Id = id
            };

            // Act
            await soft.UndeleteItemAsync(item).ConfigureAwait(false);

            var stored = MovieServer.GetMovieById(id) !;

            // Assert
            Assert.False(stored.Deleted);
            Assert.Equal <IMovie>(stored, item);
            AssertEx.SystemPropertiesMatch(stored, item);
        }
Beispiel #23
0
        public async Task PushItemsAsync_SingleTable_HandlesUpdateOperation_WithVersion()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var itemToUpdate = new ClientMovie {
                Id = Guid.NewGuid().ToString(), Version = "1", Title = "The Big Test"
            };
            var instance = table.ServiceClient.Serializer.Serialize(itemToUpdate) as JObject;

            store.Upsert("movies", new[] { instance });

            var updatedItem = itemToUpdate.Clone();

            updatedItem.Title = "Modified";
            var mInstance = table.ServiceClient.Serializer.Serialize(updatedItem) as JObject;

            var returnedItem = itemToUpdate.Clone();

            returnedItem.Version = "2";
            MockHandler.AddResponse(HttpStatusCode.OK, returnedItem);

            await table.ReplaceItemAsync(mInstance);

            await table.PushItemsAsync();

            // Request was a PUT
            Assert.Single(MockHandler.Requests);
            var request = MockHandler.Requests[0];

            Assert.Equal(HttpMethod.Put, request.Method);
            Assert.Equal($"/tables/movies/{itemToUpdate.Id}", request.RequestUri.PathAndQuery);
            Assert.Equal("\"1\"", request.Headers.IfMatch.First().Tag);
            var requestObj = JObject.Parse(await request.Content.ReadAsStringAsync());

            AssertEx.JsonEqual(mInstance, requestObj);

            // Queue is empty
            Assert.Empty(store.TableMap[SystemTables.OperationsQueue]);

            // Item in the store has been updated.
            Assert.True(store.TableMap["movies"].ContainsKey(itemToUpdate.Id));
            Assert.Equal("2", store.TableMap["movies"][itemToUpdate.Id].Value <string>("version"));
        }
        public async Task DeleteItemAsync_GoneWhenDeleted()
        {
            // Arrange
            var id   = GetRandomId();
            var item = ClientMovie.From(MovieServer.GetMovieById(id));
            await MovieServer.SoftDeleteMoviesAsync(x => x.Id == id).ConfigureAwait(false);

            // Act
            var exception = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => soft.DeleteItemAsync(item)).ConfigureAwait(false);

            // Assert
            Assert.NotNull(exception.Request);
            Assert.NotNull(exception.Response);
            Assert.Equal(HttpStatusCode.Gone, exception.Response?.StatusCode);
            Assert.Equal(MovieCount, MovieServer.GetMovieCount());
            var entity = MovieServer.GetMovieById(id);

            Assert.True(entity.Deleted);
        }
Beispiel #25
0
        public async Task ReplaceItemAsync_ConditionalFailure()
        {
            await InitializeAsync();

            // Arrange
            var id       = GetRandomId();
            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);

            expected.Title   = "Replacement Title";
            expected.Rating  = "PG-13";
            expected.Version = "dGVzdA==";

            // Act
            await table !.ReplaceItemAsync(expected);
            var   exception = await Assert.ThrowsAsync <PushFailedException>(() => table !.PushItemsAsync());

            // Assert
            Assert.Single(exception.PushResult.Errors);
        }
Beispiel #26
0
        public async Task ReplaceItemAsync_SoftNotDeleted()
        {
            // Arrange
            var id       = GetRandomId();
            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);

            expected.Title  = "Replacement Title";
            expected.Rating = "PG-13";
            var json = CreateJsonDocument(expected);

            // Act
            var response = await soft.ReplaceItemAsync(json).ConfigureAwait(false);

            var stored = MovieServer.GetMovieById(id).Clone();

            // Assert
            Assert.Equal <IMovie>(expected, stored);
            AssertEx.SystemPropertiesChanged(original, stored);
            AssertJsonDocumentMatches(stored, response);
        }
        public async Task ReplaceItemAsync_Basic()
        {
            // Arrange
            var id       = GetRandomId();
            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);

            expected.Title  = "Replacement Title";
            expected.Rating = "PG-13";
            var response = expected.Clone();

            // Act
            await table.ReplaceItemAsync(response).ConfigureAwait(false);

            var stored = MovieServer.GetMovieById(id);

            // Assert
            Assert.Equal <IMovie>(expected, stored);
            AssertEx.SystemPropertiesChanged(original, stored);
            AssertEx.SystemPropertiesMatch(stored, response);
        }
        public async Task RefreshItemAsync_WithItem()
        {
            // Arrange
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var item = GetSampleMovie <ClientMovie>();

            item.Id        = Guid.NewGuid().ToString();
            item.UpdatedAt = DateTimeOffset.UtcNow;
            var json = (JObject)table.ServiceClient.Serializer.Serialize(item);

            store.Upsert("movies", new[] { json });

            var refresher = new ClientMovie {
                Id = item.Id
            };

            // Act
            await table.RefreshItemAsync(refresher);

            // Assert
            Assert.Equal <IMovie>(item, refresher);
        }
Beispiel #29
0
        public async Task PushItemsAsync_SingleTable_HandlesDeleteOperation_Conflict()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

            var item = new ClientMovie {
                Id = Guid.NewGuid().ToString(), Version = "1"
            };
            var conflictItem = new ClientMovie {
                Id = item.Id, Version = "2"
            };
            var instance = (JObject)table.ServiceClient.Serializer.Serialize(item);

            store.Upsert("movies", new[] { instance });
            MockHandler.AddResponse(HttpStatusCode.Conflict, conflictItem);

            await table.DeleteItemAsync(instance);

            var ex = await Assert.ThrowsAsync <PushFailedException>(() => table.PushItemsAsync());

            Assert.Single(MockHandler.Requests);
            var request = MockHandler.Requests[0];

            Assert.Equal(HttpMethod.Delete, request.Method);
            Assert.Equal($"/tables/movies/{item.Id}", request.RequestUri.PathAndQuery);

            Assert.Equal(PushStatus.Complete, ex.PushResult.Status);
            Assert.Single(ex.PushResult.Errors);
            Assert.Equal("movies", ex.PushResult.Errors.First().TableName);
            Assert.Equal(item.Id, ex.PushResult.Errors.First().Item.Value <string>("id"));

            Assert.Single(store.TableMap[SystemTables.OperationsQueue]);
            var op = TableOperation.Deserialize(store.TableMap[SystemTables.OperationsQueue].Values.First());

            Assert.Equal(TableOperationState.Failed, op.State);

            Assert.Single(store.TableMap[SystemTables.SyncErrors]);
        }
Beispiel #30
0
        public async Task ReplaceItemAsync_Basic()
        {
            await InitializeAsync();

            // Arrange
            var id       = GetRandomId();
            var original = MovieServer.GetMovieById(id) !;
            var expected = ClientMovie.From(original);

            expected.Title  = "Replacement Title";
            expected.Rating = "PG-13";

            // Act
            await table !.ReplaceItemAsync(expected);
            await table !.PushItemsAsync();
            var   response = await table !.GetItemAsync(id);

            var stored = MovieServer.GetMovieById(id);

            // Assert
            Assert.Equal <IMovie>(expected, stored);
            AssertEx.SystemPropertiesChanged(original, stored);
            AssertEx.SystemPropertiesMatch(stored, response);
        }