public async Task UpdateOperationAsync_UpsertTheItemInOperation_AndDeletesTheError() { var client = new MobileServiceClient("http://www.test.com"); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; var item = new JObject() { { "id", itemId }, { "name", "unknown" } }; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary <string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 }, { "item", item.ToString() }, { "kind", (int)MobileServiceTableOperationKind.Delete } }); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item does not exist Assert.IsNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Delete, HttpStatusCode.PreconditionFailed, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var item2 = new JObject() { { "id", itemId }, { "name", "unknown" }, { "version", 2 } }; await context.UpdateOperationAsync(error, item2); var operation = await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId); // operation is updated Assert.IsNotNull(operation); // error is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); Assert.AreEqual(operation.GetValue("item").ToString(), item2.ToString(Formatting.None)); }
public async Task CancelAndUpdateItemAsync_UpsertsTheItemInLocalStore_AndDeletesTheOperationAndError() { var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary <string, JObject>() { { operationId, new JObject() } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject()); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item doesn't exist before upsert Assert.IsNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 0, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var item = new JObject() { { "id", itemId }, { "name", "unknown" } }; await context.CancelAndUpdateItemAsync(error, item); // operation is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // error is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); JObject upserted = await store.LookupAsync(tableName, itemId); // item is upserted Assert.IsNotNull(upserted); Assert.AreEqual(item, upserted); }
public async Task CancelAndDiscardItemAsync_DeletesTheItemInLocalStore_AndDeletesTheOperationAndError() { var client = new MobileServiceClient("http://www.test.com"); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary <string, JObject>() { { operationId, new JObject() } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject()); store.TableMap.Add(tableName, new Dictionary <string, JObject>() { { itemId, new JObject() } }); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item exists before upsert Assert.IsNotNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 0, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); await context.CancelAndDiscardItemAsync(error); // operation is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // error is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); // item is upserted Assert.IsNull(await store.LookupAsync(tableName, itemId)); }
public async Task UpdateOperationAsync_UpsertsTheItemInLocalStore_AndDeletesTheError_FromSyncHandler() { // Arrange string itemId = "abc"; var hijack = new TestHttpHandler(); hijack.Responses.Add(new HttpResponseMessage(HttpStatusCode.InternalServerError)); var handler = new MobileServiceSyncHandlerMock(); handler.PushCompleteAction = async pushCompletionResult => { foreach (var error in pushCompletionResult.Errors) { await error.UpdateOperationAsync(JObject.Parse("{\"id\":\"abc\",\"__version\":\"Hey\"}")); } }; var store = new MobileServiceLocalStoreMock(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", hijack); await service.SyncContext.InitializeAsync(store, handler); IMobileServiceSyncTable table = service.GetSyncTable("someTable"); await table.InsertAsync(new JObject() { { "id", "abc" }, { "__version", "Wow" } }); // Act await(service.SyncContext as MobileServiceSyncContext).PushAsync(CancellationToken.None, MobileServiceTableKind.Table); // Assert var syncError = store.TableMap[MobileServiceLocalSystemTables.SyncErrors].Values; var operation = store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Values.FirstOrDefault(); var item = JObject.Parse("{\"id\":\"abc\",\"__version\":\"Hey\"}"); JObject upserted = await store.LookupAsync("someTable", itemId); // item is upserted Assert.IsNotNull(upserted); // verify if the record was updated Assert.AreEqual(item.ToString(), upserted.ToString()); // verify if the errors were cleared Assert.AreEqual(0, syncError.Count); // Verify operation is still present Assert.AreEqual(operation.Value <string>("itemId"), itemId); }
private async Task TestOperationModifiedException(bool operationExists, Func <MobileServiceTableOperationError, MobileServiceSyncContext, Task> action, String errorMessage) { var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; if (operationExists) { store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "version", 3 } }); } else { // operation exists before cancel Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); } var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var ex = await ThrowsAsync <InvalidOperationException>(() => action(error, context)); Assert.AreEqual(ex.Message, errorMessage); }
private async Task UpdateOperationAsync_ConflictOperation_WithNotificationsEnabled_UsesTheCorrectStoreSource() { var client = new MobileServiceClient("http://www.test.com"); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store, StoreTrackingOptions.NotifyLocalConflictResolutionOperations); var manualResetEvent = new ManualResetEventSlim(); string operationId = "abc"; string itemId = "def"; string tableName = "test"; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 } }); store.TableMap.Add(tableName, new Dictionary<string, JObject>() { { itemId, new JObject() } }); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item exists before upsert Assert.IsNotNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var item = new JObject() { { "id", itemId }, { "name", "unknown" } }; bool sourceIsLocalConflict = false; IDisposable subscription = client.EventManager.Subscribe<StoreOperationCompletedEvent>(o => { sourceIsLocalConflict = o.Operation.Source == StoreOperationSource.LocalConflictResolution; manualResetEvent.Set(); }); await context.UpdateOperationAsync(error, item); bool resetEventSignaled = manualResetEvent.Wait(1000); subscription.Dispose(); Assert.IsTrue(resetEventSignaled); Assert.IsTrue(sourceIsLocalConflict); }
private async Task TestOperationModifiedException(bool operationExists, Func<MobileServiceTableOperationError, MobileServiceSyncContext, Task> action, String errorMessage) { var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; if (operationExists) { store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "version", 3 } }); } else { // operation exists before cancel Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); } var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var ex = await ThrowsAsync<InvalidOperationException>(() => action(error, context)); Assert.AreEqual(ex.Message, errorMessage); }
public async Task CancelAndDiscardItemAsync_DeletesTheItemInLocalStore_AndDeletesTheOperationAndError() { var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject()); store.TableMap.Add(tableName, new Dictionary<string, JObject>() { { itemId, new JObject() } }); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item exists before upsert Assert.IsNotNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 0, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); await context.CancelAndDiscardItemAsync(error); // operation is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // error is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); // item is upserted Assert.IsNull(await store.LookupAsync(tableName, itemId)); }
public async Task UpdateOperationAsync_UpsertTheItemInOperation_AndDeletesTheError() { var client = new MobileServiceClient("http://www.test.com"); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; var item = new JObject() { { "id", itemId }, { "name", "unknown" } }; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 }, { "item", item.ToString() }, { "kind", (int)MobileServiceTableOperationKind.Delete } }); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item does not exist Assert.IsNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Delete, HttpStatusCode.PreconditionFailed, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var item2 = new JObject() { { "id", itemId }, { "name", "unknown" }, { "version", 2 } }; await context.UpdateOperationAsync(error, item2); var operation = await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId); // operation is updated Assert.IsNotNull(operation); // error is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); Assert.AreEqual(operation.GetValue("item").ToString(), item2.ToString(Formatting.None)); }
public async Task UpdateOperationAsync_UpsertsTheItemInLocalStore_AndDeletesTheError_AndUpdatesTheOperation() { var client = new MobileServiceClient("http://www.test.com"); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store); string operationId = "abc"; string itemId = "def"; string tableName = "test"; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary<string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 } }); store.TableMap.Add(tableName, new Dictionary<string, JObject>() { { itemId, new JObject() } }); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item exists before upsert Assert.IsNotNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var item = new JObject() { { "id", itemId }, { "name", "unknown" } }; await context.UpdateOperationAsync(error, item); // operation is updated Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // error is deleted Assert.IsNull(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); JObject upserted = await store.LookupAsync(tableName, itemId); // item is upserted Assert.IsNotNull(upserted); Assert.AreEqual(item, upserted); }
public async Task UpdateOperationAsync_UpsertsTheItemInLocalStore_AndDeletesTheError_FromSyncHandler() { // Arrange string itemId = "abc"; var hijack = new TestHttpHandler(); hijack.Responses.Add(new HttpResponseMessage(HttpStatusCode.InternalServerError)); var handler = new MobileServiceSyncHandlerMock(); handler.PushCompleteAction = async pushCompletionResult => { foreach (var error in pushCompletionResult.Errors) { await error.UpdateOperationAsync(JObject.Parse("{\"id\":\"abc\",\"__version\":\"Hey\"}")); } }; var store = new MobileServiceLocalStoreMock(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", hijack); await service.SyncContext.InitializeAsync(store, handler); IMobileServiceSyncTable table = service.GetSyncTable("someTable"); await table.InsertAsync(new JObject() { { "id", "abc" }, { "__version", "Wow" } }); // Act await (service.SyncContext as MobileServiceSyncContext).PushAsync(CancellationToken.None, MobileServiceTableKind.Table); // Assert var syncError = store.TableMap[MobileServiceLocalSystemTables.SyncErrors].Values; var operation = store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Values.FirstOrDefault(); var item = JObject.Parse("{\"id\":\"abc\",\"__version\":\"Hey\"}"); JObject upserted = await store.LookupAsync("someTable", itemId); // item is upserted Assert.IsNotNull(upserted); // verify if the record was updated Assert.AreEqual(item.ToString(), upserted.ToString()); // verify if the errors were cleared Assert.AreEqual(0, syncError.Count); // Verify operation is still present Assert.AreEqual(operation.Value<string>("itemId"),itemId); }
private async Task UpdateOperationAsync_ConflictOperation_WithNotificationsEnabled_UsesTheCorrectStoreSource() { var client = new MobileServiceClient("http://www.test.com"); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); await context.InitializeAsync(store, StoreTrackingOptions.NotifyLocalConflictResolutionOperations); var manualResetEvent = new ManualResetEventSlim(); string operationId = "abc"; string itemId = "def"; string tableName = "test"; store.TableMap[MobileServiceLocalSystemTables.SyncErrors] = new Dictionary <string, JObject>() { { operationId, new JObject() { { "id", operationId }, { "version", 1 } } } }; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "id", operationId }, { "version", 1 } }); store.TableMap.Add(tableName, new Dictionary <string, JObject>() { { itemId, new JObject() } }); // operation exists before cancel Assert.IsNotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item exists before upsert Assert.IsNotNull(await store.LookupAsync(tableName, itemId)); var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); var item = new JObject() { { "id", itemId }, { "name", "unknown" } }; bool sourceIsLocalConflict = false; IDisposable subscription = client.EventManager.Subscribe <StoreOperationCompletedEvent>(o => { sourceIsLocalConflict = o.Operation.Source == StoreOperationSource.LocalConflictResolution; manualResetEvent.Set(); }); await context.UpdateOperationAsync(error, item); bool resetEventSignaled = manualResetEvent.Wait(1000); subscription.Dispose(); Assert.IsTrue(resetEventSignaled); Assert.IsTrue(sourceIsLocalConflict); }