예제 #1
0
        public async Task PushItemsAsync_SingleTable_HandlesInsertOperation()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

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

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

            MockHandler.AddResponse(HttpStatusCode.OK, returnedItem);

            await table.InsertItemAsync(instance);

            await table.PushItemsAsync();

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

            var request = MockHandler.Requests[0];

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

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

            Assert.Equal(storedItem.Value <DateTime>("updatedAt").Ticks, returnedItem.UpdatedAt?.Ticks);
            Assert.Equal(storedItem.Value <string>("version"), returnedItem.Version);
        }
예제 #2
0
        public async Task PushItemsAsync_SingleTable_HandlesDeleteOperation_WithoutVersion()
        {
            await table.ServiceClient.InitializeOfflineStoreAsync();

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

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

            await table.DeleteItemAsync(instance);

            await table.PushItemsAsync();

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

            var request = MockHandler.Requests[0];

            Assert.Equal(HttpMethod.Delete, request.Method);
            Assert.Equal($"/tables/movies/{item.Id}", request.RequestUri.PathAndQuery);
            Assert.Empty(request.Headers.IfMatch);
        }
        public async Task ExecuteRemote_CallsRemoteServer_WithFailure(HttpStatusCode statusCode)
        {
            var client = GetMockClient();

            if (statusCode == HttpStatusCode.Conflict || statusCode == HttpStatusCode.PreconditionFailed)
            {
                MockHandler.AddResponse(statusCode, new IdEntity {
                    Id = "1234", StringValue = "movie"
                });
            }
            else
            {
                MockHandler.AddResponse(statusCode);
            }

            var sut = new UpdateOperation("test", "1234")
            {
                Item = testObject
            };
            var exception = await Assert.ThrowsAnyAsync <DatasyncInvalidOperationException>(() => sut.ExecuteOperationOnRemoteServiceAsync(client));

            if (statusCode == HttpStatusCode.Conflict || statusCode == HttpStatusCode.PreconditionFailed)
            {
                Assert.IsAssignableFrom <DatasyncConflictException>(exception);
                Assert.NotNull(exception.Value);
            }
            Assert.NotNull(exception.Request);
            Assert.NotNull(exception.Response);
            Assert.Equal(statusCode, exception.Response?.StatusCode);
        }
        public async Task ReplaceItemAsync_Success_FormulatesCorrectResponse_WithAuth(bool hasPrecondition)
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, payload);
            var obj = new IdEntity {
                Id = sId, Version = hasPrecondition ? "etag" : null
            };
            var original = new IdEntity {
                Id = sId, Version = hasPrecondition ? "etag" : null
            };

            // Act
            await authTable.ReplaceItemAsync(obj).ConfigureAwait(false);

            // Assert
            var request = AssertSingleRequest(HttpMethod.Put, expectedEndpoint);

            await AssertRequestContentMatchesAsync(request, original);

            AssertEx.HasHeader(request.Headers, "X-ZUMO-AUTH", ValidAuthenticationToken.Token);
            if (hasPrecondition)
            {
                AssertEx.HasHeader(request.Headers, "If-Match", "\"etag\"");
            }
            else
            {
                Assert.False(request.Headers.Contains("If-Match"));
            }
            Assert.Equal(payload, obj);
        }
        public async Task UndeleteItemAsync_SuccessNoContent()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK);

            // Act
            await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.UndeleteItemAsync(jIdEntity)).ConfigureAwait(false);
        }
        public async Task ReplaceItemAsync_ConflictNoContent(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);

            // Act
            var ex = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.ReplaceItemAsync(payload)).ConfigureAwait(false);
        }
        public async Task InsertItemAsync_SuccessNoContent(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);

            // Act
            await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.InsertItemAsync(sut)).ConfigureAwait(false);
        }
        public async Task GetPageOfItems_ConstructsRequest_WithRequestUri(string requestUri)
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, new Page <IdEntity>());

            // Act
            await(table as RemoteTable <IdEntity>) !.GetNextPageAsync <IdEntity>("", requestUri).ConfigureAwait(false);

            // Assert
            AssertSingleRequest(HttpMethod.Get, requestUri);
        }
        public async Task InsertItemAsync_RequestFailed_Throws(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);

            // Act
            var ex = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.InsertItemAsync(sut)).ConfigureAwait(false);

            // Assert
            Assert.Equal(statusCode, ex.Response?.StatusCode);
        }
예제 #10
0
        public async Task RefreshItemAsync_SuccessNoContent()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK);
            var item = new IdEntity {
                Id = sId
            };

            // Act
            await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.RefreshItemAsync(item));
        }
        public async Task ReplaceItemAsync_SuccessNoContent()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK);
            var obj = new IdEntity {
                Id = sId
            };

            // Act
            await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.ReplaceItemAsync(obj)).ConfigureAwait(false);
        }
        public async Task DeleteItemAsync_ConflictNoContent_FormulatesCorrectResponse(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);

            // Act
            var ex = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.DeleteItemAsync(jIdEntity)).ConfigureAwait(false);

            // Assert
            Assert.Equal(statusCode, ex.Response.StatusCode);
        }
        public async Task UndeleteItemAsync_ConflictNoContent(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);
            var obj = new IdEntity {
                Id = sId
            };

            // Act
            await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.UndeleteItemAsync(obj)).ConfigureAwait(false);
        }
        public async Task GetPageOfItemAsync_BadResponse_ThrowsRequestFailed(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);
            var t = table as RemoteTable <IdEntity>;

            // Act
            var ex = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => t.GetNextPageAsync <IdEntity>("", null)).ConfigureAwait(false);

            // Assert
            Assert.Equal(statusCode, ex.Response?.StatusCode);
        }
        public async Task GetItemAsync_FormulatesCorrectRequest()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, payload);

            // Act
            var actual = await table.GetItemAsync(sId).ConfigureAwait(false);

            // Assert
            AssertSingleRequest(HttpMethod.Get, expectedEndpoint);
            Assert.Equal(payload, actual);
        }
        public async Task GetPageOfItems_ConstructsRequest_WithQuery(string query)
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, new Page <IdEntity>());
            var expectedUri = string.IsNullOrEmpty(query) ? tableEndpoint : $"{tableEndpoint}?{query}";

            // Act
            await(table as RemoteTable <IdEntity>) !.GetNextPageAsync <IdEntity>(query, null).ConfigureAwait(false);

            // Assert
            AssertSingleRequest(HttpMethod.Get, expectedUri);
        }
        public async Task GetPageOfItems_ConstructsRequest_PrefersRequestUri(string query)
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, new Page <IdEntity>());
            const string requestUri = "https://localhost/tables/foo?$count=true&$skip=5&$top=10&__includedeleted=true";

            // Act
            _ = await(table as RemoteTable <IdEntity>) !.GetNextPageAsync <IdEntity>(query, requestUri).ConfigureAwait(false);

            // Assert
            AssertSingleRequest(HttpMethod.Get, requestUri);
        }
        public async Task DeleteItemAsync_Conflict_FormulatesCorrectResponse(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode, payload);

            // Act
            var ex = await Assert.ThrowsAsync <DatasyncConflictException>(() => table.DeleteItemAsync(jIdEntity)).ConfigureAwait(false);

            // Assert
            Assert.Equal(statusCode, ex.Response.StatusCode);
            AssertJsonMatches(ex.Value);
        }
        public async Task ExecuteRemote_ThrowsError_WithNoItem()
        {
            var client = GetMockClient();

            MockHandler.AddResponse(HttpStatusCode.OK);

            var sut       = new UpdateOperation("test", "1234");
            var exception = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => sut.ExecuteOperationOnRemoteServiceAsync(client));

            Assert.Empty(MockHandler.Requests);
            Assert.Contains("must have an item", exception.Message);
        }
예제 #20
0
        public async Task GetAsyncItems_NoItems_WhenNullResponse()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK);

            // Act
            var pageable   = table.GetAsyncItems("") as AsyncPageable <JToken>;
            var enumerator = pageable.AsPages().GetAsyncEnumerator();

            // Assert
            await Assert.ThrowsAsync <DatasyncInvalidOperationException>(async() => await enumerator.MoveNextAsync());
        }
        public async Task ExecuteRemote_CallsRemoteServer_ThrowsWhenInvalidResponse()
        {
            var client = GetMockClient();

            MockHandler.AddResponse(HttpStatusCode.OK, new string[] { "test" });

            var sut = new UpdateOperation("test", "1234")
            {
                Item = testObject
            };
            await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => sut.ExecuteOperationOnRemoteServiceAsync(client));
        }
예제 #22
0
        public async Task GetAsyncItems_Throws_OnBadRequest(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);

            // Act
            var enumerator = table.GetAsyncItems("").GetAsyncEnumerator();

            // Assert
            var ex = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(async() => await enumerator.MoveNextAsync().ConfigureAwait(false)).ConfigureAwait(false);

            Assert.Equal(statusCode, ex.Response.StatusCode);
        }
예제 #23
0
        public async Task GetAsyncItems_NoItems()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, new Page <IdEntity>());

            // Act
            var enumerator = table.GetAsyncItems("").GetAsyncEnumerator();
            var hasMore    = await enumerator.MoveNextAsync().ConfigureAwait(false);

            // Assert
            _ = AssertSingleRequest(HttpMethod.Get, tableEndpoint);
            Assert.False(hasMore);
        }
        public async Task DeleteItemAsync_FormsCorrectResponse_NoPrecondition()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.NoContent);

            // Act
            _ = await table.DeleteItemAsync(jIdOnly).ConfigureAwait(false);

            // Assert
            var request = AssertSingleRequest(HttpMethod.Delete, expectedEndpoint);

            Assert.False(request.Headers.Contains("If-Match"));
        }
        public async Task DeleteItemAsync_FormsCorrectResponse_WithPrecondition()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.NoContent);

            // Act
            _ = await table.DeleteItemAsync(jIdEntity).ConfigureAwait(false);

            // Check Request
            var request = AssertSingleRequest(HttpMethod.Delete, expectedEndpoint);

            AssertEx.HasHeader(request.Headers, "If-Match", "\"etag\"");
        }
        public async Task GetPageOfItems_ConstructsRequest_WithRequestUriAndAuth(string requestUri)
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, new Page <IdEntity>());

            // Act
            await(authTable as RemoteTable <IdEntity>) !.GetNextPageAsync <IdEntity>("", requestUri).ConfigureAwait(false);

            // Assert
            var request = AssertSingleRequest(HttpMethod.Get, requestUri);

            AssertEx.HasHeader(request.Headers, "X-ZUMO-AUTH", ValidAuthenticationToken.Token);
        }
        public async Task UndeleteItemAsync_ConflictNoContent(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);

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

            // Assert
            Assert.NotNull(ex.Request);
            Assert.NotNull(ex.Response);
            Assert.Null(ex.Value);
        }
예제 #28
0
        public async Task RefreshItemAsync_RequestFailed_Throws(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode);
            var item = new IdEntity {
                Id = sId
            };

            // Act
            var ex = await Assert.ThrowsAsync <DatasyncInvalidOperationException>(() => table.RefreshItemAsync(item));

            // Assert
            Assert.Equal(statusCode, ex.Response?.StatusCode);
        }
예제 #29
0
        public async Task GetItemAsync_FormulatesCorrectRequest()
        {
            // Arrange
            MockHandler.AddResponse(HttpStatusCode.OK, payload);

            // Act
            var response = await table.GetItemAsync(sId).ConfigureAwait(false);

            // Assert
            var request = AssertSingleRequest(HttpMethod.Get, expectedEndpoint);

            Assert.False(request.Headers.Contains("If-None-Match"));
            AssertJsonMatches(response);
        }
        public async Task ReplaceItemAsync_Conflict_FormulatesCorrectResponse(HttpStatusCode statusCode)
        {
            // Arrange
            MockHandler.AddResponse(statusCode, payload);
            var obj = new IdEntity {
                Id = sId
            };

            // Act
            var ex = await Assert.ThrowsAsync <DatasyncConflictException <IdEntity> >(() => table.ReplaceItemAsync(obj)).ConfigureAwait(false);

            // Assert
            Assert.Equal(payload, ex.Item);
        }