public async Task ReadAsyncWithStringIdTypeAndStringIdResponseContent() { string[] testIdData = IdTestData.ValidStringIds.Concat( IdTestData.EmptyStringIds).Concat( IdTestData.InvalidStringIds).ToArray(); foreach (string testId in testIdData) { TestHttpHandler hijack = new TestHttpHandler(); // Make the testId JSON safe string jsonTestId = testId.Replace("\\", "\\\\").Replace("\"", "\\\""); hijack.SetResponseContent("[{\"id\":\"" + jsonTestId + "\",\"String\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<StringIdType> table = service.GetTable<StringIdType>(); IEnumerable<StringIdType> results = await table.ReadAsync(); StringIdType[] items = results.ToArray(); Assert.AreEqual(1, items.Count()); Assert.AreEqual(testId, items[0].Id); Assert.AreEqual("Hey", items[0].String); } }
public async Task ReadAsync_WithRelativeUri_Generic() { var data = new[] { new { ServiceUri = "http://www.test.com", QueryUri = "/about?$filter=a eq b&$orderby=c", RequestUri = "http://www.test.com/about?$filter=a eq b&$orderby=c" }, new { ServiceUri = "http://www.test.com/", QueryUri = "/about?$filter=a eq b&$orderby=c", RequestUri = "http://www.test.com/about?$filter=a eq b&$orderby=c" } }; foreach (var item in data) { var hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"col1\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient(item.ServiceUri, "secret...", hijack); IMobileServiceTable<ToDo> table = service.GetTable<ToDo>(); await table.ReadAsync<ToDo>(item.QueryUri); Assert.AreEqual("TT", hijack.Request.Headers.GetValues("X-ZUMO-FEATURES").First()); Assert.AreEqual(item.RequestUri, hijack.Request.RequestUri.ToString()); } }
public async Task PullAsync_Cancels_WhenCancellationTokenIsCancelled() { var store = new MobileServiceLocalStoreMock(); var handler = new MobileServiceSyncHandlerMock(); handler.TableOperationAction = op => Task.Delay(TimeSpan.MaxValue).ContinueWith<JObject>(t => null); // long slow operation var hijack = new TestHttpHandler(); hijack.OnSendingRequest = async req => { await Task.Delay(1000); return req; }; IMobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); await service.SyncContext.InitializeAsync(store, handler); IMobileServiceSyncTable table = service.GetSyncTable("someTable"); using (var cts = new CancellationTokenSource()) { Task pullTask = table.PullAsync(null, null, null, cancellationToken: cts.Token); cts.Cancel(); var ex = await ThrowsAsync<Exception>(() => pullTask); Assert.IsTrue((ex is OperationCanceledException || ex is TaskCanceledException)); Assert.AreEqual(pullTask.Status, TaskStatus.Canceled); } }
public void DoesNotRewireSingleWiredDelegatingHandler() { string appUrl = MobileAppUriValidator.DummyMobileApp; TestHttpHandler innerHandler = new TestHttpHandler(); DelegatingHandler wiredHandler = new TestHttpHandler(); wiredHandler.InnerHandler = innerHandler; IMobileServiceClient service = new MobileServiceClient(appUrl, handlers: wiredHandler); Assert.AreEqual(wiredHandler.InnerHandler, innerHandler, "The prewired handler passed in should not have been rewired"); }
public async Task DateOffsetUri() { TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient client = new MobileServiceClient("http://www.test.com", null, hijack); IMobileServiceTable<DateOffsetExample> table = client.GetTable<DateOffsetExample>(); hijack.Response.StatusCode = HttpStatusCode.OK; hijack.SetResponseContent("[]"); DateTimeOffset date = new DateTimeOffset(2009, 11, 21, 14, 22, 59, 860, TimeSpan.FromHours(-8)); await table.Where(b => b.Date == date).ToEnumerableAsync(); Assert.EndsWith(hijack.Request.RequestUri.ToString(), "$filter=(DateOffsetExampleDate eq datetimeoffset'2009-11-21T14:22:59.8600000-08:00')"); }
public async Task ReadAsync_WithAbsoluteUri_Generic() { var hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"col1\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<ToDo> table = service.GetTable<ToDo>(); await table.ReadAsync<ToDo>("http://www.test.com/about?$filter=a eq b&$orderby=c"); Assert.AreEqual("TT,LH", hijack.Request.Headers.GetValues("X-ZUMO-FEATURES").First()); Assert.AreEqual("http://www.test.com/about?$filter=a eq b&$orderby=c", hijack.Request.RequestUri.ToString()); }
public async Task DateOffsetUri() { TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient client = new MobileServiceClient("http://www.test.com", null, hijack); IMobileServiceTable<DateOffsetExample> table = client.GetTable<DateOffsetExample>(); hijack.Response = new HttpResponseMessage(HttpStatusCode.OK); hijack.SetResponseContent("[]"); var date = DateTimeOffset.Parse("2009-11-21T06:22:59.8600000-08:00"); await table.Where(b => b.Date == date).ToEnumerableAsync(); Assert.EndsWith(hijack.Request.RequestUri.ToString(), "$filter=(DateOffsetExampleDate eq datetimeoffset'2009-11-21T06:22:59.8600000-08:00')"); }
public async Task LookupAsyncGeneric() { TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<StringType> table = service.GetTable<StringType>(); hijack.SetResponseContent("{\"id\":12,\"String\":\"Hello\"}"); StringType expected = await table.LookupAsync(12); Assert.Contains(hijack.Request.RequestUri.ToString(), "12"); Assert.AreEqual(12, expected.Id); Assert.AreEqual("Hello", expected.String); }
public async Task ReadAsyncWithStringIdTypeAndNullIdResponseContent() { TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"id\":null,\"String\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<StringIdType> table = service.GetTable<StringIdType>(); IEnumerable<StringIdType> results = await table.ReadAsync(); StringIdType[] items = results.ToArray(); Assert.AreEqual(1, items.Count()); Assert.AreEqual(null, items[0].Id); Assert.AreEqual("Hey", items[0].String); }
public async Task PushAsync_FeatureHeaderPresent() { var hijack = new TestHttpHandler(); hijack.AddResponseContent("{\"id\":\"abc\",\"String\":\"Hey\"}"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", 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); await service.SyncContext.PushAsync(); Assert.AreEqual(hijack.Requests[0].Headers.GetValues("X-ZUMO-FEATURES").First(), "TU,OL"); }
public async Task LookupAsyncGenericWithUserParameters() { var userDefinedParameters = new Dictionary<string, string>() { { "state", "CA" } }; TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<StringType> table = service.GetTable<StringType>(); hijack.SetResponseContent("{\"id\":12,\"String\":\"Hello\"}"); StringType expected = await table.LookupAsync(12, userDefinedParameters); Assert.Contains(hijack.Request.RequestUri.ToString(), "12"); Assert.Contains(hijack.Request.RequestUri.Query, "state=CA"); Assert.AreEqual(12, expected.Id); Assert.AreEqual("Hello", expected.String); }
[AsyncTestMethod] // this is the default buggy behavior that we've already shipped public async Task ReadAsync_ModifiesStringId_IfItContainsIsoDateValue() { var hijack = new TestHttpHandler(); hijack.SetResponseContent(@"[{ ""id"": ""2014-01-29T23:01:33.444Z"", ""__createdAt"": ""2014-01-29T23:01:33.444Z"" }]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<ToDoWithSystemPropertiesType> table = service.GetTable<ToDoWithSystemPropertiesType>(); IEnumerable<ToDoWithSystemPropertiesType> results = await table.ReadAsync(); ToDoWithSystemPropertiesType item = results.First(); Assert.AreEqual(item.Id, "01/29/2014 23:01:33"); Assert.AreEqual(item.CreatedAt, DateTime.Parse("2014-01-29T23:01:33.444Z")); }
public async Task ReadAsync() { TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("{\"Count\":1, People: [{\"Id\":\"12\", \"String\":\"Hey\"}] }"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable table = service.GetTable("tests"); JToken people = await table.ReadAsync("$filter=id eq 12"); Assert.Contains(hijack.Request.RequestUri.ToString(), "tests"); Assert.Contains(hijack.Request.RequestUri.ToString(), "$filter=id eq 12"); Assert.AreEqual(1, (int)people["Count"]); Assert.AreEqual(12, (int)people["People"][0]["Id"]); Assert.AreEqual("Hey", (string)people["People"][0]["String"]); }
public async Task ReadAsyncGeneric() { TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"id\":12,\"String\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<StringType> table = service.GetTable<StringType>(); IEnumerable<StringType> results = await table.ReadAsync(); StringType[] people = results.Cast<StringType>().ToArray(); Assert.Contains(hijack.Request.RequestUri.ToString(), "StringType"); Assert.AreEqual(1, people.Count()); Assert.AreEqual(12, people[0].Id); Assert.AreEqual("Hey", people[0].String); }
public async Task SingleHttpHandlerConstructor() { TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, handlers: hijack); MobileAppUriValidator mobileAppUriValidator = new MobileAppUriValidator(service); // Ensure properties are copied over Assert.AreEqual(MobileAppUriValidator.DummyMobileApp, service.MobileAppUri.ToString()); // Set the handler to return an empty array hijack.SetResponseContent("[]"); JToken response = await service.GetTable("foo").ReadAsync("bar"); // Verify the handler was in the loop Assert.StartsWith(hijack.Request.RequestUri.ToString(), mobileAppUriValidator.TableBaseUri); }
[AsyncTestMethod] // user has to set the serializer setting to round trip dates in string fields correctly public async Task ReadAsync_DoesNotModifyStringId_IfItContainsIsoDateValueAndSerializerIsConfiguredToNotParseDates() { var hijack = new TestHttpHandler(); hijack.SetResponseContent(@"[{ ""id"": ""2014-01-29T23:01:33.444Z"", ""__createdAt"": ""2014-01-29T23:01:33.444Z"" }]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); service.SerializerSettings.DateParseHandling = DateParseHandling.None; IMobileServiceTable<ToDoWithSystemPropertiesType> table = service.GetTable<ToDoWithSystemPropertiesType>(); IEnumerable<ToDoWithSystemPropertiesType> results = await table.ReadAsync(); ToDoWithSystemPropertiesType item = results.First(); Assert.AreEqual(item.Id, "2014-01-29T23:01:33.444Z"); Assert.AreEqual(item.CreatedAt, DateTime.Parse("2014-01-29T23:01:33.444Z")); }
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.AreEqual(hijack.Requests.Count, 0); // 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.AreEqual(hijack.Requests.Count, 0); await service.SyncContext.PushAsync(); Assert.AreEqual(hijack.Requests.Count, 2); Assert.AreEqual(hijack.RequestContents[0], item1.ToString(Formatting.None)); Assert.AreEqual(hijack.Requests[0].Headers.GetValues("X-ZUMO-FEATURES").First(), "TU,OL"); Assert.AreEqual(hijack.RequestContents[1], item2.ToString(Formatting.None)); Assert.AreEqual(hijack.Requests[1].Headers.GetValues("X-ZUMO-FEATURES").First(), "TU,OL"); // 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.AreEqual(hijack.Requests.Count, 0); await service.SyncContext.PushAsync(); Assert.AreEqual(hijack.Requests.Count, 0); }
public async Task SingleHttpHandlerConstructor() { string appUrl = "http://www.test.com/"; string appKey = "secret..."; TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient(new Uri(appUrl), appKey, hijack); // Ensure properties are copied over Assert.AreEqual(appUrl, service.ApplicationUri.ToString()); Assert.AreEqual(appKey, service.ApplicationKey); // Set the handler to return an empty array hijack.SetResponseContent("[]"); JToken response = await service.GetTable("foo").ReadAsync("bar"); // Verify the handler was in the loop Assert.StartsWith(hijack.Request.RequestUri.ToString(), appUrl); }
public async Task ReadAsyncWithUserParameters() { TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("{\"Count\":1, People: [{\"Id\":\"12\", \"String\":\"Hey\"}] }"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); var userDefinedParameters = new Dictionary<string, string>() { { "tags", "#pizza #beer" } }; IMobileServiceTable table = service.GetTable("tests"); JToken people = await table.ReadAsync("$filter=id eq 12", userDefinedParameters); Assert.Contains(hijack.Request.RequestUri.ToString(), "tests"); Assert.Contains(hijack.Request.RequestUri.AbsoluteUri, "tags=%23pizza%20%23beer"); Assert.Contains(hijack.Request.RequestUri.ToString(), "$filter=id eq 12"); Assert.AreEqual(1, (int)people["Count"]); Assert.AreEqual(12, (int)people["People"][0]["Id"]); Assert.AreEqual("Hey", (string)people["People"][0]["String"]); }
public async Task ReadAsync_WithAbsoluteUri_Generic() { var data = new[] { new { ServiceUri = MobileAppUriValidator.DummyMobileApp, Result = MobileAppUriValidator.DummyMobileApp + "about?$filter=a eq b&$orderby=c" }, new { ServiceUri = MobileAppUriValidator.DummyMobileAppWithoutTralingSlash, Result = MobileAppUriValidator.DummyMobileAppWithoutTralingSlash + "/about?$filter=a eq b&$orderby=c" }, new { ServiceUri = MobileAppUriValidator.DummyMobileAppUriWithFolder, Result = MobileAppUriValidator.DummyMobileAppUriWithFolder + "about?$filter=a eq b&$orderby=c" }, new { ServiceUri = MobileAppUriValidator.DummyMobileAppUriWithFolderWithoutTralingSlash, Result = MobileAppUriValidator.DummyMobileAppUriWithFolderWithoutTralingSlash + "/about?$filter=a eq b&$orderby=c" }, }; foreach (var item in data) { var hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"col1\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient(item.ServiceUri, hijack); MobileAppUriValidator mobileAppUriValidator = new MobileAppUriValidator(service); IMobileServiceTable<ToDo> table = service.GetTable<ToDo>(); await table.ReadAsync<ToDo>(item.Result); Assert.AreEqual("TT,LH", hijack.Request.Headers.GetValues("X-ZUMO-FEATURES").First()); Assert.AreEqual(item.Result, hijack.Request.RequestUri.ToString()); } }
public async Task InvokeCustomAPI_ErrorStringAndNoContentType() { TestHttpHandler hijack = new TestHttpHandler(); hijack.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); hijack.Response.Content = new StringContent("message", Encoding.UTF8, null); hijack.Response.Content.Headers.ContentType = null; MobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); try { await service.InvokeApiAsync("testapi"); Assert.Fail("Invoke API should have thrown"); } catch (Exception e) { Assert.AreEqual(e.Message, "The request could not be completed. (Bad Request)"); } }
public async Task DateUri() { TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient client = new MobileServiceClient("http://www.test.com", null, hijack); IMobileServiceTable<DateExample> table = client.GetTable<DateExample>(); hijack.Response = new HttpResponseMessage(HttpStatusCode.OK); hijack.SetResponseContent("[]"); // Verify a full UTC date DateTime date = new DateTime(2009, 11, 21, 14, 22, 59, 860, DateTimeKind.Utc); await table.Where(b => b.Date == date).ToEnumerableAsync(); Assert.EndsWith(hijack.Request.RequestUri.ToString(), "$filter=(DateExampleDate eq datetime'2009-11-21T14:22:59.860Z')"); // Local date is converted to UTC hijack.Response = new HttpResponseMessage(HttpStatusCode.OK); hijack.SetResponseContent("[]"); date = new DateTime(2009, 11, 21, 14, 22, 59, 860, DateTimeKind.Local); await table.Where(b => b.Date == date).ToEnumerableAsync(); Assert.EndsWith(hijack.Request.RequestUri.ToString(), "Z')"); }
public async Task InvokeCustomAPIResponseWithParams() { TestHttpHandler hijack = new TestHttpHandler(); hijack.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Accepted); hijack.Response.Content = new StringContent("{\"id\":\"2\"}", Encoding.UTF8, "application/json"); var myParams = new Dictionary <string, string>() { { "a", "1" }, { "b", "2" } }; MobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); MobileAppUriValidator mobileAppUriValidator = new MobileAppUriValidator(service); HttpResponseMessage response = await service.InvokeApiAsync("calculator/add", null, HttpMethod.Post, null, myParams); Assert.AreEqual(hijack.Request.RequestUri.LocalPath, mobileAppUriValidator.GetApiUriPath("calculator/add")); Assert.AreEqual(hijack.Request.RequestUri.Query, "?a=1&b=2"); Assert.IsNull(hijack.Request.Content); Assert.Contains(response.Content.ReadAsStringAsync().Result, "{\"id\":\"2\"}"); }
public static DelegatingHandler CreateTestHttpHandler(string expectedUri, HttpMethod expectedMethod, string responseContent, HttpStatusCode?httpStatusCode = null, Uri location = null, string expectedRequestContent = null) { var handler = new TestHttpHandler { OnSendingRequest = message => { Assert.AreEqual(expectedUri, message.RequestUri.OriginalString, "The Http Uri used to send the request is different than expected."); Assert.AreEqual(expectedMethod, message.Method, "The Http Method used to send the request is different than expected."); if (expectedRequestContent != null) { var messageContent = Regex.Replace(message.Content.ReadAsStringAsync().Result, @"\s+", String.Empty); expectedRequestContent = Regex.Replace(expectedRequestContent, @"\s+", String.Empty); Assert.AreEqual(expectedRequestContent, messageContent, "The Http request content is different than expected."); } return(Task.FromResult(message)); } }; if (responseContent != null) { handler.SetResponseContent(responseContent); } else { handler.Response = new HttpResponseMessage(HttpStatusCode.OK); } if (location != null) { handler.Response.Headers.Location = location; } if (httpStatusCode.HasValue) { handler.Response.StatusCode = httpStatusCode.Value; } return(handler); }
public static DelegatingHandler CreateTestHttpHandler(string expectedUri, HttpMethod expectedMethod, string responseContent, HttpStatusCode? httpStatusCode = null, Uri location = null, string expectedRequestContent = null) { var handler = new TestHttpHandler { OnSendingRequest = message => { Assert.AreEqual(expectedUri, message.RequestUri.OriginalString, "The Http Uri used to send the request is different than expected."); Assert.AreEqual(expectedMethod, message.Method, "The Http Method used to send the request is different than expected."); if (expectedRequestContent != null) { var messageContent = Regex.Replace(message.Content.ReadAsStringAsync().Result, @"\s+", String.Empty); expectedRequestContent = Regex.Replace(expectedRequestContent, @"\s+", String.Empty); Assert.AreEqual(expectedRequestContent, messageContent, "The Http request content is different than expected."); } return Task.FromResult(message); } }; if (responseContent != null) { handler.SetResponseContent(responseContent); } else { handler.Response = new HttpResponseMessage(HttpStatusCode.OK); } if (location != null) { handler.Response.Headers.Location = location; } if (httpStatusCode.HasValue) { handler.Response.StatusCode = httpStatusCode.Value; } return handler; }
public async Task PushAsync_Succeeds_WithClientWinsPolicy() { var hijack = new TestHttpHandler(); hijack.Responses.Add(new HttpResponseMessage(HttpStatusCode.PreconditionFailed) { Content = new StringContent("{\"id\":\"abc\",\"version\":\"Hey\"}") }); hijack.AddResponseContent(@"{""id"": ""abc""}"); var handler = new MobileServiceSyncHandlerMock(); handler.TableOperationAction = async op => { for (int i = 0; i < 2; i++) { try { return(await op.ExecuteAsync()); } catch (MobileServicePreconditionFailedException ex) { op.Item[MobileServiceSystemColumns.Version] = ex.Value[MobileServiceSystemColumns.Version]; } } return(null); }; IMobileServiceClient service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); await service.SyncContext.InitializeAsync(new MobileServiceLocalStoreMock(), handler); IMobileServiceSyncTable table = service.GetSyncTable("someTable"); await table.UpdateAsync(new JObject() { { "id", "abc" }, { "version", "Wow" } }); await service.SyncContext.PushAsync(); }
private static async Task RefreshUserAsync_Setup(string alternateLoginUri = null) { string appUrl = MobileAppUriValidator.DummyMobileApp; string newAuthToken = "new-auth-token"; string userId = "sid:xxxxxxxxxxxxxxxxx"; string responseContent = "{\"authenticationToken\":\"" + newAuthToken + "\",\"user\":{\"userId\":\"" + userId + "\"}}"; TestHttpHandler hijack = new TestHttpHandler(); hijack.Response = new HttpResponseMessage(HttpStatusCode.OK); hijack.Response.Content = new StringContent(responseContent); MobileServiceHttpClient.DefaultHandlerFactory = () => hijack; MobileServiceClient client = new MobileServiceClient(appUrl, hijack); client.CurrentUser = new MobileServiceUser(userId) { MobileServiceAuthenticationToken = "auth-token" }; string refreshUrl; if (!string.IsNullOrEmpty(alternateLoginUri)) { refreshUrl = alternateLoginUri + ".auth/refresh"; client.AlternateLoginHost = new Uri(alternateLoginUri); } else { refreshUrl = appUrl + ".auth/refresh"; } MobileServiceUser user = await client.RefreshUserAsync(); Assert.AreEqual(EnumValueAttribute.GetValue(MobileServiceFeatures.RefreshToken), hijack.Request.Headers.GetValues(MobileServiceHttpClient.ZumoFeaturesHeader).FirstOrDefault()); Assert.AreEqual(hijack.Request.RequestUri.OriginalString, refreshUrl); Assert.AreEqual(newAuthToken, user.MobileServiceAuthenticationToken); Assert.AreEqual(userId, user.UserId); }
public async Task WithParametersAsyncGeneric() { var userDefinedParameters = new Dictionary <string, string>() { { "state", "WY" } }; TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"id\":12,\"String\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable <StringType> table = service.GetTable <StringType>(); List <StringType> people = await table.WithParameters(userDefinedParameters).ToListAsync(); Assert.Contains(hijack.Request.RequestUri.ToString(), "StringType"); Assert.Contains(hijack.Request.RequestUri.Query, "state=WY"); Assert.AreEqual(1, people.Count); Assert.AreEqual(12, people[0].Id); Assert.AreEqual("Hey", people[0].String); }
public async Task ReadAsyncWithNonStringAndNonIntIdResponseContent() { object[] testIdData = IdTestData.NonStringNonIntValidJsonIds; foreach (object testId in testIdData) { string stringTestId = testId.ToString().ToLower(); TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"id\":" + stringTestId + ",\"String\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable table = service.GetTable("someTable"); JToken results = await table.ReadAsync(""); JToken[] items = results.ToArray(); Assert.AreEqual(1, items.Count()); Assert.AreEqual(testId, items[0]["id"].ToObject(testId.GetType())); Assert.AreEqual("Hey", (string)items[0]["String"]); } }
public async Task InsertAsyncGenericWithUserParameters() { var userDefinedParameters = new Dictionary <string, string>() { { "state", "CA" } }; TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable <StringType> table = service.GetTable <StringType>(); StringType obj = new StringType(); obj.String = "new"; hijack.SetResponseContent("{\"id\":12,\"value\":\"new\"}"); await table.InsertAsync(obj, userDefinedParameters); Assert.AreEqual(12, obj.Id); Assert.Contains(hijack.Request.RequestUri.ToString(), "StringType"); Assert.Contains(hijack.Request.RequestUri.Query, "state=CA"); }
public async Task ReadAsyncWithIntIdResponseContent() { long[] testIdData = IdTestData.ValidIntIds.Concat( IdTestData.InvalidIntIds).ToArray(); foreach (long testId in testIdData) { string stringTestId = testId.ToString(); TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"id\":" + stringTestId + ",\"String\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable table = service.GetTable("someTable"); JToken results = await table.ReadAsync(""); JToken[] items = results.ToArray(); Assert.AreEqual(1, items.Count()); Assert.AreEqual(testId, (long)items[0]["id"]); Assert.AreEqual("Hey", (string)items[0]["String"]); } }
public async Task DateUri() { TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient client = new MobileServiceClient("http://www.test.com", null, hijack); IMobileServiceTable <DateExample> table = client.GetTable <DateExample>(); hijack.Response.StatusCode = HttpStatusCode.OK; hijack.SetResponseContent("[]"); // Verify a full UTC date DateTime date = new DateTime(2009, 11, 21, 14, 22, 59, 860, DateTimeKind.Utc); await table.Where(b => b.Date == date).ToEnumerableAsync(); Assert.EndsWith(hijack.Request.RequestUri.ToString(), "$filter=(DateExampleDate eq datetime'2009-11-21T14:22:59.860Z')"); // Local date is converted to UTC hijack.Response = new HttpResponseMessage(HttpStatusCode.OK); hijack.SetResponseContent("[]"); date = new DateTime(2009, 11, 21, 14, 22, 59, 860, DateTimeKind.Local); await table.Where(b => b.Date == date).ToEnumerableAsync(); Assert.EndsWith(hijack.Request.RequestUri.ToString(), "Z')"); }
public async Task RefreshAsyncGenericWithUserParameters() { var userDefinedParameters = new Dictionary <string, string>() { { "state", "CA" } }; TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable <StringType> table = service.GetTable <StringType>(); StringType expected = new StringType(); expected.Id = 12; hijack.SetResponseContent("{\"id\":12,\"String\":\"Goodbye\"}"); await table.RefreshAsync(expected, userDefinedParameters); Assert.Contains(hijack.Request.RequestUri.ToString(), "$filter=id eq 12"); Assert.Contains(hijack.Request.RequestUri.Query, "state=CA"); Assert.AreEqual(12, expected.Id); Assert.AreEqual("Goodbye", expected.String); }
public async Task DeleteAsyncGenericWithParameters() { var userDefinedParameters = new Dictionary <string, string>() { { "state", "WY" } }; TestHttpHandler hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable <StringType> table = service.GetTable <StringType>(); StringType obj = new StringType(); obj.Id = 12; obj.String = "new"; await table.DeleteAsync(obj, userDefinedParameters); Assert.AreEqual(0, obj.Id); Assert.Contains(hijack.Request.RequestUri.ToString(), "StringType"); Assert.IsNull(hijack.Request.Content); Assert.Contains(hijack.Request.RequestUri.Query, "state=WY"); }
public async Task MultipleHttpHandlerConstructor() { string appUrl = "http://www.test.com/"; string appKey = "secret..."; TestHttpHandler hijack = new TestHttpHandler(); string firstBeforeMessage = "Message before 1"; string firstAfterMessage = "Message after 1"; string secondBeforeMessage = "Message before 2"; string secondAfterMessage = "Message after 2"; ComplexDelegatingHandler firstHandler = new ComplexDelegatingHandler(firstBeforeMessage, firstAfterMessage); ComplexDelegatingHandler secondHandler = new ComplexDelegatingHandler(secondBeforeMessage, secondAfterMessage); IMobileServiceClient service = new MobileServiceClient(new Uri(appUrl), appKey, firstHandler, secondHandler, hijack); // Validate that handlers are properly chained Assert.AreSame(hijack, secondHandler.InnerHandler); Assert.AreSame(secondHandler, firstHandler.InnerHandler); // Clears the messages on the handler ComplexDelegatingHandler.ClearStoredMessages(); // Set the handler to return an empty array hijack.SetResponseContent("[]"); JToken response = await service.GetTable("foo").ReadAsync("bar"); var storedMessages = new List <string>(ComplexDelegatingHandler.AllMessages); Assert.AreEqual(4, storedMessages.Count); Assert.AreEqual(firstBeforeMessage, storedMessages[0]); Assert.AreEqual(secondBeforeMessage, storedMessages[1]); Assert.AreEqual(secondAfterMessage, storedMessages[2]); Assert.AreEqual(firstAfterMessage, storedMessages[3]); }
public async Task ReadAsyncWithStringIdTypeAndNonStringIdResponseContent() { object[] testIdData = IdTestData.ValidIntIds.Concat( IdTestData.InvalidIntIds).Cast<object>().Concat( IdTestData.NonStringNonIntValidJsonIds).ToArray(); foreach (object testId in testIdData) { string stringTestId = testId.ToString().ToLower(); TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("[{\"id\":" + stringTestId + ",\"String\":\"Hey\"}]"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); IMobileServiceTable<StringIdType> table = service.GetTable<StringIdType>(); IEnumerable<StringIdType> results = await table.ReadAsync(); StringIdType[] items = results.ToArray(); Assert.AreEqual(1, items.Count()); Assert.AreEqual(testId.ToString(), items[0].Id); Assert.AreEqual("Hey", items[0].String); } }
public async Task ReadAsyncWithUserParameters() { TestHttpHandler hijack = new TestHttpHandler(); hijack.SetResponseContent("{\"Count\":1, People: [{\"Id\":\"12\", \"String\":\"Hey\"}] }"); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); var userDefinedParameters = new Dictionary <string, string>() { { "tags", "#pizza #beer" } }; IMobileServiceTable table = service.GetTable("tests"); JToken people = await table.ReadAsync("$filter=id eq 12", userDefinedParameters); Assert.Contains(hijack.Request.RequestUri.ToString(), "tests"); Assert.Contains(hijack.Request.RequestUri.AbsoluteUri, "tags=%23pizza%20%23beer"); Assert.Contains(hijack.Request.RequestUri.ToString(), "$filter=id eq 12"); Assert.AreEqual(1, (int)people["Count"]); Assert.AreEqual(12, (int)people["People"][0]["Id"]); Assert.AreEqual("Hey", (string)people["People"][0]["String"]); }
public async Task MultipleHttpHandlerConstructor() { string appUrl = "http://www.test.com/"; string appKey = "secret..."; TestHttpHandler hijack = new TestHttpHandler(); string firstBeforeMessage = "Message before 1"; string firstAfterMessage = "Message after 1"; string secondBeforeMessage = "Message before 2"; string secondAfterMessage = "Message after 2"; ComplexDelegatingHandler firstHandler = new ComplexDelegatingHandler(firstBeforeMessage, firstAfterMessage); ComplexDelegatingHandler secondHandler = new ComplexDelegatingHandler(secondBeforeMessage, secondAfterMessage); IMobileServiceClient service = new MobileServiceClient(new Uri(appUrl), appKey, firstHandler, secondHandler, hijack); // Validate that handlers are properly chained Assert.AreSame(hijack, secondHandler.InnerHandler); Assert.AreSame(secondHandler, firstHandler.InnerHandler); // Clears the messages on the handler ComplexDelegatingHandler.ClearStoredMessages(); // Set the handler to return an empty array hijack.SetResponseContent("[]"); JToken response = await service.GetTable("foo").ReadAsync("bar"); var storedMessages = new List<string>(ComplexDelegatingHandler.AllMessages); Assert.AreEqual(4, storedMessages.Count); Assert.AreEqual(firstBeforeMessage, storedMessages[0]); Assert.AreEqual(secondBeforeMessage, storedMessages[1]); Assert.AreEqual(secondAfterMessage, storedMessages[2]); Assert.AreEqual(firstAfterMessage, storedMessages[3]); }
private async Task ValidateFeaturesHeader(string expectedFeaturesHeader, Func<IMobileServiceClient, Task> operation) { TestHttpHandler hijack = new TestHttpHandler(); bool validationDone = false; hijack.OnSendingRequest = (request) => { Assert.AreEqual(expectedFeaturesHeader, request.Headers.GetValues("X-ZUMO-FEATURES").First()); validationDone = true; return Task.FromResult(request); }; IMobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); hijack.SetResponseContent("{\"id\":3}"); await operation(service); Assert.IsTrue(validationDone); }
public async Task InvokeApiTypedOverloads_HasCorrectFeaturesHeader() { TestHttpHandler hijack = new TestHttpHandler(); hijack.OnSendingRequest = (request) => { Assert.AreEqual("AT", request.Headers.GetValues("X-ZUMO-FEATURES").First()); return Task.FromResult(request); }; MobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); hijack.SetResponseContent("{\"id\":3}"); await service.InvokeApiAsync<IntType>("apiName"); hijack.SetResponseContent("{\"id\":3}"); await service.InvokeApiAsync<IntType, IntType>("apiName", new IntType { Id = 1 }); hijack.OnSendingRequest = (request) => { Assert.AreEqual("AT,QS", request.Headers.GetValues("X-ZUMO-FEATURES").First()); return Task.FromResult(request); }; var dic = new Dictionary<string, string> { { "a", "b" } }; hijack.SetResponseContent("{\"id\":3}"); await service.InvokeApiAsync<IntType>("apiName", HttpMethod.Get, dic); hijack.SetResponseContent("{\"hello\":\"world\"}"); await service.InvokeApiAsync<IntType, IntType>("apiName", new IntType { Id = 1 }, HttpMethod.Put, dic); }
public async Task InvokeCustomAPI_ErrorStringAndNoContentType() { TestHttpHandler hijack = new TestHttpHandler(); hijack.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); hijack.Response.Content = new StringContent("message", Encoding.UTF8, null); hijack.Response.Content.Headers.ContentType = null; MobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); try { await service.InvokeApiAsync("testapi"); Assert.Fail("Invoke API should have thrown"); } catch (Exception e) { Assert.AreEqual(e.Message, "The request could not be completed. (Bad Request)"); } }
public async Task InvokeCustomAPI_ErrorWithString() { TestHttpHandler hijack = new TestHttpHandler(); hijack.Response = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest); hijack.Response.Content = new StringContent("message", Encoding.UTF8, "text/html"); MobileServiceClient service = new MobileServiceClient("http://www.test.com", "secret...", hijack); try { await service.InvokeApiAsync("testapi"); Assert.Fail("Invoke API should have thrown"); } catch (Exception e) { Assert.AreEqual(e.Message, "message"); } }
public async Task PushAsync_ExecutesThePendingOperations_InOrder_BatchedOne() { 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.AreEqual(hijack.Requests.Count, 0); // create a new service to test that operations are loaded from store hijack = new TestHttpHandler(); var content = new MultipartContent("mixed", "6f078995-ef2a-4617-a4c9-5d8746b26d32"); var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{\"id\":\"abc\",\"String\":\"Hey\"}", Encoding.UTF8, "application/json") }; content.Add(new HttpMessageContent(response)); hijack.AddResponseContent(content); content = new MultipartContent("mixed", "6f078995-ef2a-4617-a4c9-5d8746b26d32"); response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{\"id\":\"def\",\"String\":\"What\"}", Encoding.UTF8, "application/json") }; content.Add(new HttpMessageContent(response)); hijack.AddResponseContent(content); service = new MobileServiceClient(MobileAppUriValidator.DummyMobileApp, hijack); await service.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler()); service.SyncContext.BatchApiEndpoint = "batch"; service.SyncContext.BatchSize = 1; Assert.AreEqual(hijack.Requests.Count, 0); await service.SyncContext.PushAsync(); Assert.AreEqual(hijack.Requests.Count, 2); Assert.IsTrue(hijack.RequestContents[0].Contains(item1.ToString(Formatting.None))); Assert.IsTrue(hijack.RequestContents[0].Contains("X-ZUMO-FEATURES: TU,OL")); Assert.IsTrue(hijack.RequestContents[1].Contains(item2.ToString(Formatting.None))); Assert.IsTrue(hijack.RequestContents[1].Contains("X-ZUMO-FEATURES: TU,OL")); // 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.AreEqual(hijack.Requests.Count, 0); await service.SyncContext.PushAsync(); Assert.AreEqual(hijack.Requests.Count, 0); }
public async Task PushAsync_Succeeds_WithPendingOperations_AndOpQueueIsConsistent() { // Essentially async ManualResetEvents SemaphoreSlim untilPendingOpsCreated = new SemaphoreSlim(0, 1); SemaphoreSlim untilAboutToExecuteOp = new SemaphoreSlim(0, 1); int pushState = 0; var handler = new MobileServiceSyncHandlerMock(); handler.TableOperationAction = async op => { try { untilAboutToExecuteOp.Release(); await untilPendingOpsCreated.WaitAsync(); JObject result = await op.ExecuteAsync(); if (0 == pushState) { Assert.AreEqual(MobileServiceTableOperationKind.Insert, op.Kind); Assert.AreEqual(0, op.Item.Value <int>("value")); } else { Assert.AreEqual(MobileServiceTableOperationKind.Update, op.Kind); Assert.AreEqual(2, op.Item.Value <int>("value")); // We shouldn't see the value == 1, since it should have been collapsed } // We don't care what the server actually returned, as long as there was no exception raised in our Push logic return(result); } catch (Exception ex) { Assert.Fail("Things are bad: " + ex.Message); } return(null); }; var hijack = new TestHttpHandler(); IMobileServiceClient service = new MobileServiceClient("http://www.test.com", hijack); LocalStoreWithDelay mockLocalStore = new LocalStoreWithDelay(); await service.SyncContext.InitializeAsync(mockLocalStore, handler); JObject item = null; // Add the initial operation and perform a push IMobileServiceSyncTable table = service.GetSyncTable("someTable"); string responseContent = @"{ ""id"": ""abc"", ""value"": ""0"", ""version"": ""v0"" }"; // Whatever is fine, since we won't use it or look at it // Do this Insert/Push/Update+Update/Push cycle several times fast to try to hit any race conditions that would cause an error for (int id = 0; id < 10; id++) { hijack.SetResponseContent(responseContent); string idStr = "id" + id; // Generate a new Id each time in case the mock objects ever care that we insert an item that already exists // The Operations and PushAction don't necessarily clone the JObject, so we need a fresh one for each operation or else we'll change // the in-memory representation of the JObject stored in all operations, as well as in the "batch" the PushAction owns. This is problematic. item = new JObject() { { "id", idStr }, { "value", 0 } }; await table.InsertAsync(item); Task pushComplete = service.SyncContext.PushAsync(); // Make sure the PushAction has actually called into our SyncHandler, otherwise the two UpdateOperations could collapse onto it, and // there won't necessarily even be a second PushAction await untilAboutToExecuteOp.WaitAsync(); // Add some more operations while that push is in flight. Since these operations affect the same item in someTable, the operations // will be stuck awaiting the PushAction since it locks on the row. item = new JObject() { { "id", idStr }, { "value", 1 } }; Task updateOnce = table.UpdateAsync(item); item = new JObject() { { "id", idStr }, { "value", 2 } }; Task updateTwice = table.UpdateAsync(item); // Before we let the push finish, let's inject a delay that will cause it to take a long time deleting the operation from the queue. // This will give the other operations, if there's an unaddressed race condition, a chance to wreak havoc on the op queue. mockLocalStore.SetLookupDelay(500); // Let the first push finish untilPendingOpsCreated.Release(); await pushComplete; mockLocalStore.SetLookupDelay(0); await updateOnce; await updateTwice; // Push again, but now the operation condensed from the two updates should be executed remotely pushState = (pushState + 1) % 2; hijack.SetResponseContent(responseContent); pushComplete = service.SyncContext.PushAsync(); await untilAboutToExecuteOp.WaitAsync(); // not strictly necessary other than to keep the semaphore count at 0 untilPendingOpsCreated.Release(); await pushComplete; pushState = (pushState + 1) % 2; } }