public async Task BatchNotification_ReportsOperationCount() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.ServerPull, string.Empty); var eventManager = new MobileServiceEventManagerMock<IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); EnqueueSimpleObjectResponse(store, "123", "XXX", "789"); await changeTracker.UpsertAsync("test", new JObject() { { "id", "123" }, { "version", "2" } }, true); // Update await changeTracker.UpsertAsync("test", new JObject() { { "id", "456" }, { "version", "2" } }, true); // Insert await changeTracker.DeleteAsync("test", "789"); // Delete StoreOperationsBatchCompletedEvent batchEvent = null; eventManager.PublishAsyncFunc = e => { batchEvent = e as StoreOperationsBatchCompletedEvent; return Task.FromResult(0); }; changeTracker.Dispose(); Assert.IsNotNull(batchEvent); Assert.AreEqual(batchEvent.Batch.OperationCount, 3); Assert.AreEqual(batchEvent.Batch.GetOperationCountByKind(LocalStoreOperationKind.Update), 1); Assert.AreEqual(batchEvent.Batch.GetOperationCountByKind(LocalStoreOperationKind.Insert), 1); Assert.AreEqual(batchEvent.Batch.GetOperationCountByKind(LocalStoreOperationKind.Delete), 1); }
public async Task DeleteAsync_WithTableNameAndRecordIds_SendsNotification() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty); var eventManager = new MobileServiceEventManagerMock <IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); JObject item = EnqueueSimpleObjectResponse(store); StoreOperationCompletedEvent operationEvent = null; eventManager.PublishAsyncFunc = t => { operationEvent = t as StoreOperationCompletedEvent; return(Task.FromResult(0)); }; await changeTracker.DeleteAsync("test", "123"); Assert.IsNotNull(operationEvent); Assert.AreEqual(operationEvent.Operation.Kind, LocalStoreOperationKind.Delete); Assert.AreEqual(operationEvent.Operation.RecordId, "123"); Assert.AreEqual(operationEvent.Operation.TableName, "test"); }
public async Task DeleteAsync_WithQuery_SendsNotification() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty); var eventManager = new MobileServiceEventManagerMock <IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); JObject item = EnqueueSimpleObjectResponse(store); StoreOperationCompletedEvent operationEvent = null; eventManager.PublishAsyncFunc = t => { operationEvent = t as StoreOperationCompletedEvent; return(Task.FromResult(0)); }; MobileServiceTableQueryDescription query = new MobileServiceTableQueryDescription("test"); query.Filter = new BinaryOperatorNode(BinaryOperatorKind.Equal, new MemberAccessNode(null, MobileServiceSystemColumns.Id), new ConstantNode("123")); await changeTracker.DeleteAsync(query); Assert.IsNotNull(operationEvent); Assert.AreEqual(operationEvent.Operation.Kind, LocalStoreOperationKind.Delete); Assert.AreEqual(operationEvent.Operation.RecordId, "123"); Assert.AreEqual(operationEvent.Operation.TableName, "test"); }
public async Task PushAsync_FeatureHeaderPresentWhenRehydrated() { var hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); var store = new MobileServiceLocalStoreMock(); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); IMobileServiceSyncTable table = service.GetSyncTable("someTable"); JObject item1 = new JObject() { { "id", "abc" } }; await table.InsertAsync(item1); // create a new service to test that operations are loaded from store hijack = new TestHttpHandler(); hijack.AddResponseContent("{\"id\":\"abc\",\"String\":\"Hey\"}"); service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); await service.SyncContext.PushAsync(); Assert.Equal("TU,OL", hijack.Requests[0].Headers.GetValues("X-ZUMO-FEATURES").First()); }
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.NotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item does not exist Assert.Null(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.NotNull(operation); // error is deleted Assert.Null(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); Assert.Equal(operation.GetValue("item").ToString(), item2.ToString(Formatting.None)); }
public void Constructor_Throws_WhenTrackingOptionsAreInvalid() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty, StoreTrackingOptions.None); var eventManager = new MobileServiceEventManager(); var settings = new MobileServiceSyncSettingsManager(store); AssertEx.Throws<InvalidOperationException>(() => new LocalStoreChangeTracker(store, trackingContext, eventManager, settings)); }
public void Constructor_Throws_WhenTrackingOptionsAreInvalid() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty, StoreTrackingOptions.None); var eventManager = new MobileServiceEventManager(); var settings = new MobileServiceSyncSettingsManager(store); AssertEx.Throws <InvalidOperationException>(() => new LocalStoreChangeTracker(store, trackingContext, eventManager, settings)); }
private void AssertUntrackedStoreForSourceWithOptions(StoreOperationSource source, StoreTrackingOptions trackingOptions) { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty, StoreTrackingOptions.None); var eventManager = new MobileServiceEventManager(); var settings = new MobileServiceSyncSettingsManager(store); IMobileServiceLocalStore trackedStore = StoreChangeTrackerFactory.CreateTrackedStore(store, source, trackingOptions, eventManager, settings); Assert.IsNotNull(trackedStore); Assert.IsTrue(trackedStore is LocalStoreProxy); }
private void AssertUntrackedStoreForSourceWithOptions(StoreOperationSource source, StoreTrackingOptions trackingOptions) { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty, StoreTrackingOptions.None); var eventManager = new MobileServiceEventManager(); var settings = new MobileServiceSyncSettingsManager(store); IMobileServiceLocalStore trackedStore = StoreChangeTrackerFactory.CreateTrackedStore(store, source, trackingOptions, eventManager, settings); Assert.NotNull(trackedStore); Assert.IsType <LocalStoreProxy>(trackedStore); }
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.NotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item doesn't exist before upsert Assert.Null(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.Null(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // error is deleted Assert.Null(await store.LookupAsync(MobileServiceLocalSystemTables.SyncErrors, operationId)); JObject upserted = await store.LookupAsync(tableName, itemId); // item is upserted Assert.NotNull(upserted); Assert.Equal(item, upserted); }
public async Task PushAsync_ExecutesThePendingOperations_InOrder() { var hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); var store = new MobileServiceLocalStoreMock(); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); IMobileServiceSyncTable table = service.GetSyncTable("someTable"); JObject item1 = new JObject() { { "id", "abc" } }, item2 = new JObject() { { "id", "def" } }; await table.InsertAsync(item1); await table.InsertAsync(item2); Assert.Empty(hijack.Requests); // create a new service to test that operations are loaded from store hijack = new TestHttpHandler(); hijack.AddResponseContent("{\"id\":\"abc\",\"String\":\"Hey\"}"); hijack.AddResponseContent("{\"id\":\"def\",\"String\":\"What\"}"); service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); Assert.Empty(hijack.Requests); await service.SyncContext.PushAsync(); Assert.Equal(2, hijack.Requests.Count); Assert.Equal(item1.ToString(Formatting.None), hijack.RequestContents[0]); Assert.Equal("TU,OL", hijack.Requests[0].Headers.GetValues("X-ZUMO-FEATURES").First()); Assert.Equal(item2.ToString(Formatting.None), hijack.RequestContents[1]); Assert.Equal("TU,OL", hijack.Requests[1].Headers.GetValues("X-ZUMO-FEATURES").First()); // create yet another service to make sure the old items were purged from queue hijack = new TestHttpHandler(); hijack.AddResponseContent("{\"id\":\"abc\",\"String\":\"Hey\"}"); service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); Assert.Empty(hijack.Requests); await service.SyncContext.PushAsync(); Assert.Empty(hijack.Requests); }
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.NotNull(upserted); // verify if the record was updated Assert.Equal(item.ToString(), upserted.ToString()); // verify if the errors were cleared Assert.Empty(syncError); // Verify operation is still present Assert.Equal(operation.Value <string>("itemId"), itemId); }
private async Task ConflictOperation_WithNotificationsEnabled_UsesTheCorrectStoreOperationSource(Func <MobileServiceSyncContext, MobileServiceTableOperationError, Task> handler) { var client = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp); var store = new MobileServiceLocalStoreMock(); var context = new MobileServiceSyncContext(client); var manualResetEvent = new ManualResetEventSlim(); await context.InitializeAsync(store, StoreTrackingOptions.NotifyLocalConflictResolutionOperations); string operationId = "abc"; string itemId = string.Empty; string tableName = "test"; store.TableMap[MobileServiceLocalSystemTables.OperationQueue].Add(operationId, new JObject() { { "version", 1 } }); var error = new MobileServiceTableOperationError(operationId, 1, MobileServiceTableOperationKind.Update, HttpStatusCode.Conflict, tableName, item: new JObject() { { "id", itemId } }, rawResult: "{}", result: new JObject()); bool sourceIsLocalConflict = false; IDisposable subscription = client.EventManager.Subscribe <StoreOperationCompletedEvent>(o => { sourceIsLocalConflict = o.Operation.Source == StoreOperationSource.LocalConflictResolution; manualResetEvent.Set(); }); await handler(context, error); bool resetEventSignaled = manualResetEvent.Wait(1000); subscription.Dispose(); Assert.True(resetEventSignaled); Assert.True(sourceIsLocalConflict); }
private IEnumerable <JObject> EnqueueSimpleObjectResponse(MobileServiceLocalStoreMock store, params string[] ids) { var results = new List <JObject>(); foreach (var id in ids) { var item = new JObject() { { "id", id }, { "version", "1" } }; store.ReadResponses.Enqueue(string.Format("[{0}]", item.ToString())); results.Add(item); } return(results); }
public void Disposing_CompletesBatch() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.ServerPull, string.Empty); var eventManager = new MobileServiceEventManagerMock<IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); StoreOperationsBatchCompletedEvent batchEvent = null; eventManager.PublishAsyncFunc = e => { batchEvent = e as StoreOperationsBatchCompletedEvent; return Task.FromResult(0); }; var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); changeTracker.Dispose(); Assert.IsNotNull(batchEvent); }
public async Task PushAsync_ReplaysStoredErrors_IfTheyAreInStore() { var error = new MobileServiceTableOperationError("abc", 1, MobileServiceTableOperationKind.Update, HttpStatusCode.PreconditionFailed, "test", new JObject(), "{}", new JObject()); var store = new MobileServiceLocalStoreMock(); await store.UpsertAsync(MobileServiceLocalSystemTables.SyncErrors, error.Serialize(), fromServer : false); var hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); await Assert.ThrowsAsync <MobileServicePushFailedException>(() => service.SyncContext.PushAsync()); }
public void Disposing_CompletesBatch() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.ServerPull, string.Empty); var eventManager = new MobileServiceEventManagerMock <IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); StoreOperationsBatchCompletedEvent batchEvent = null; eventManager.PublishAsyncFunc = e => { batchEvent = e as StoreOperationsBatchCompletedEvent; return(Task.FromResult(0)); }; var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); changeTracker.Dispose(); Assert.IsNotNull(batchEvent); }
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.Null(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()); InvalidOperationException ex = await Assert.ThrowsAsync <InvalidOperationException>(() => action(error, context)); Assert.Equal(errorMessage, ex.Message); }
public async Task BatchNotification_ReportsOperationCount() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.ServerPull, string.Empty); var eventManager = new MobileServiceEventManagerMock <IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); EnqueueSimpleObjectResponse(store, "123", "XXX", "789"); await changeTracker.UpsertAsync("test", new JObject() { { "id", "123" }, { "version", "2" } }, true); // Update await changeTracker.UpsertAsync("test", new JObject() { { "id", "456" }, { "version", "2" } }, true); // Insert await changeTracker.DeleteAsync("test", "789"); // Delete StoreOperationsBatchCompletedEvent batchEvent = null; eventManager.PublishAsyncFunc = e => { batchEvent = e as StoreOperationsBatchCompletedEvent; return(Task.FromResult(0)); }; changeTracker.Dispose(); Assert.IsNotNull(batchEvent); Assert.AreEqual(batchEvent.Batch.OperationCount, 3); Assert.AreEqual(batchEvent.Batch.GetOperationCountByKind(LocalStoreOperationKind.Update), 1); Assert.AreEqual(batchEvent.Batch.GetOperationCountByKind(LocalStoreOperationKind.Insert), 1); Assert.AreEqual(batchEvent.Batch.GetOperationCountByKind(LocalStoreOperationKind.Delete), 1); }
private async Task AssertNotificationResultWithMatchingLocalRecordVersion(StoreOperationSource[] operationSources, bool shouldNotify) { foreach (var operationSource in operationSources) { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(operationSource, string.Empty); var eventManager = new MobileServiceEventManagerMock <IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); JObject item = EnqueueSimpleObjectResponse(store); bool notificationSent = false; eventManager.PublishAsyncFunc = t => { notificationSent = true; return(Task.FromResult(0)); }; await changeTracker.UpsertAsync("test", item, true); Assert.AreEqual(notificationSent, shouldNotify, string.Format("Incorrect notification result with source {0}", operationSource)); } }
public async Task DeleteAsync_WithTableNameAndRecordIds_SendsNotification() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty); var eventManager = new MobileServiceEventManagerMock<IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); JObject item = EnqueueSimpleObjectResponse(store); StoreOperationCompletedEvent operationEvent = null; eventManager.PublishAsyncFunc = t => { operationEvent = t as StoreOperationCompletedEvent; return Task.FromResult(0); }; await changeTracker.DeleteAsync("test", "123"); Assert.IsNotNull(operationEvent); Assert.AreEqual(operationEvent.Operation.Kind, LocalStoreOperationKind.Delete); Assert.AreEqual(operationEvent.Operation.RecordId, "123"); Assert.AreEqual(operationEvent.Operation.TableName, "test"); }
public async Task DeleteAsync_WithQuery_SendsNotification() { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(StoreOperationSource.Local, string.Empty); var eventManager = new MobileServiceEventManagerMock<IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); JObject item = EnqueueSimpleObjectResponse(store); StoreOperationCompletedEvent operationEvent = null; eventManager.PublishAsyncFunc = t => { operationEvent = t as StoreOperationCompletedEvent; return Task.FromResult(0); }; MobileServiceTableQueryDescription query = new MobileServiceTableQueryDescription("test"); query.Filter = new BinaryOperatorNode(BinaryOperatorKind.Equal, new MemberAccessNode(null, MobileServiceSystemColumns.Id), new ConstantNode("123")); await changeTracker.DeleteAsync(query); Assert.IsNotNull(operationEvent); Assert.AreEqual(operationEvent.Operation.Kind, LocalStoreOperationKind.Delete); Assert.AreEqual(operationEvent.Operation.RecordId, "123"); Assert.AreEqual(operationEvent.Operation.TableName, "test"); }
private async Task AssertNotificationResultWithMatchingLocalRecordVersion(StoreOperationSource[] operationSources, bool shouldNotify) { foreach (var operationSource in operationSources) { var store = new MobileServiceLocalStoreMock(); var trackingContext = new StoreTrackingContext(operationSource, string.Empty); var eventManager = new MobileServiceEventManagerMock<IMobileServiceEvent>(); var settings = new MobileServiceSyncSettingsManager(store); var changeTracker = new LocalStoreChangeTracker(store, trackingContext, eventManager, settings); JObject item = EnqueueSimpleObjectResponse(store); bool notificationSent = false; eventManager.PublishAsyncFunc = t => { notificationSent = true; return Task.FromResult(0); }; await changeTracker.UpsertAsync("test", item, true); Assert.AreEqual(notificationSent, shouldNotify, string.Format("Incorrect notification result with source {0}", operationSource)); } }
private JObject EnqueueSimpleObjectResponse(MobileServiceLocalStoreMock store) { return EnqueueSimpleObjectResponse(store, "123").First(); }
private IEnumerable<JObject> EnqueueSimpleObjectResponse(MobileServiceLocalStoreMock store, params string[] ids) { var results = new List<JObject>(); foreach (var id in ids) { var item = new JObject() { { "id", id }, { "version", "1" } }; store.ReadResponses.Enqueue(string.Format("[{0}]", item.ToString())); results.Add(item); } return results; }
private JObject EnqueueSimpleObjectResponse(MobileServiceLocalStoreMock store) { return(EnqueueSimpleObjectResponse(store, "123").First()); }
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.NotNull(await store.LookupAsync(MobileServiceLocalSystemTables.OperationQueue, operationId)); // item exists before upsert Assert.NotNull(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.True(resetEventSignaled); Assert.True(sourceIsLocalConflict); }