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); }
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); }
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); }
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); }
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); }
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)); }
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]); }
/// <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); }
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); }
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); }
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); }
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]); }
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); }