Example #1
0
        [Ignore] // Remove Atom
        // [TestMethod, TestCategory("Partition1")]
        public void CanOverrideAcceptHeaderToBatchRequestWithQueryItem()
        {
            StringBuilder batchQueryOperation = new StringBuilder();

            batchQueryOperation.AppendLine("GET Customers(1)/Address?Override-Accept=" + UnitTestsUtil.JsonLightMimeType + " HTTP/1.1");
            batchQueryOperation.AppendLine("Host: host");
            batchQueryOperation.AppendLine("Accept: " + UnitTestsUtil.MimeApplicationXml);

            var test = new SimpleBatchTestCase
            {
                RequestPayload               = new BatchInfo(new BatchQuery(new Operation(batchQueryOperation.ToString()))),
                ResponseStatusCode           = 202,
                ResponseETag                 = default(string),
                ResponseVersion              = V4,
                RequestDataServiceVersion    = V4,
                RequestMaxDataServiceVersion = V4,
            };

            foreach (var serviceType in Services)
            {
                using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf())
                {
                    request.HttpMethod         = "POST";
                    request.RequestUriString   = "/$batch?Override-Batch-Accept=" + UnitTestsUtil.JsonLightMimeType;
                    request.DataServiceType    = serviceType;
                    request.Accept             = UnitTestsUtil.MimeMultipartMixed;
                    request.RequestVersion     = test.RequestDataServiceVersion.ToString();
                    request.RequestMaxVersion  = test.RequestMaxDataServiceVersion.ToString();
                    request.ForceVerboseErrors = true;
                    if (test.RequestPayload == null)
                    {
                        request.RequestContentLength = 0;
                    }
                    else
                    {
                        const string boundary = "batch-set";
                        request.RequestContentType = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);
                        request.SetRequestStreamAsText(BatchRequestWritingUtils.GetBatchText(test.RequestPayload, boundary));
                    }

                    TestUtil.RunCatching(request.SendRequest);

                    // expect 202 as $batch request does not honor query string Accept header
                    Assert.AreEqual(test.ResponseStatusCode, request.ResponseStatusCode);
                    // The following response header is written in ProcessingRequest/OnStartProcessingRequest
                    Assert.AreEqual(UnitTestsUtil.JsonLightMimeType, request.ResponseHeaders["Override-Batch-Accept"]);

                    string response = request.GetResponseStreamAsText();
                    if (serviceType == typeof(ModifyHeaderOnStartProcessingRequestTestService))
                    {
                        Assert.IsTrue(response.Contains("Content-Type: application/json;odata.metadata=minimal;"));
                    }
                    else
                    {
                        // ProcessingRequest which sets the Aceept header is not called for inner requests
                        Assert.IsTrue(response.Contains("Content-Type: application/xml;charset=utf-8"));
                    }
                }
            }
        }
Example #2
0
        public void CallBackInBatchRequestTest()
        {
            StringBuilder batchQueryOperation = new StringBuilder();

            batchQueryOperation.AppendLine("GET Customers(1)/Address?$callback=foo HTTP/1.1");
            batchQueryOperation.AppendLine("Host: host");
            batchQueryOperation.AppendLine("Accept: " + UnitTestsUtil.JsonMimeType);
            batchQueryOperation.AppendLine("Override-Accept: " + UnitTestsUtil.JsonLightMimeType);

            var testCase = new SimpleBatchTestCase
            {
                RequestPayload = new BatchInfo(new BatchQuery(new Operation(batchQueryOperation.ToString()))),
                ExpectedResponsePayloadContains = new[]
                {
                    "Content-Type: text/javascript;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8",
                    "foo({\"@odata.context\":",
                    "\"StreetAddress\":\"Line1\",\"City\":\"Redmond\",\"State\":\"WA\",\"PostalCode\":\"98052\"})",
                },
                ResponseStatusCode = 202,
                ResponseETag       = default(string),
            };

            using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf())
            {
                request.HttpMethod         = "POST";
                request.RequestUriString   = "/$batch";
                request.DataServiceType    = typeof(CustomDataContext);
                request.Accept             = UnitTestsUtil.MimeMultipartMixed;
                request.ForceVerboseErrors = true;

                const string boundary = "batch-set";
                request.RequestContentType = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);
                request.SetRequestStreamAsText(BatchRequestWritingUtils.GetBatchText(testCase.RequestPayload, boundary));

                // callback in inner GET request should succeed
                request.SendRequest();
                string response = request.GetResponseStreamAsText();
                Assert.AreEqual(testCase.ResponseStatusCode, request.ResponseStatusCode);
                Assert.IsTrue(request.ResponseContentType.StartsWith("multipart/mixed; boundary=batchresponse_"));
                foreach (string str in testCase.ExpectedResponsePayloadContains)
                {
                    Assert.IsTrue(response.Contains(str), String.Format("The response:\r\n{0}\r\nDoes not contain the string:\r\n{1}.", response, str));
                }

                // callback with $batch should fail
                try
                {
                    request.RequestUriString = "/$batch?$callback=bar";
                    request.SendRequest();
                    Assert.Fail("Request should have failed because it was not a GET request.");
                }
                catch (WebException)
                {
                    Assert.IsTrue(request.GetResponseStreamAsText().Contains("$callback can only be specified on GET requests."));
                    Assert.IsTrue(request.ResponseHeaders["content-type"].StartsWith("application/xml"));
                    Assert.AreEqual(400, request.ResponseStatusCode);
                }
            }
        }
        public void BadCustomAnnotationOnErrorWithBatchRequestCausesInStreamErrorInErrorPayload()
        {
            StringBuilder batchQueryOperation = new StringBuilder();

            batchQueryOperation.AppendLine("GET Customers(1)/Addresssss?Override-Accept=" + UnitTestsUtil.JsonLightMimeType + " HTTP/1.1");
            batchQueryOperation.AppendLine("Host: host");
            batchQueryOperation.AppendLine("Accept: " + "application/json;odata.metadata=minimal");

            var test = new SimpleBatchTestCase
            {
                RequestPayload               = new BatchInfo(new BatchQuery(new Operation(batchQueryOperation.ToString()))),
                ResponseStatusCode           = 202,
                ResponseETag                 = default(string),
                ResponseVersion              = V4,
                RequestDataServiceVersion    = V4,
                RequestMaxDataServiceVersion = V4,
            };

            using (TestWebRequest webRequest = this.SetupRequest())
            {
                webRequest.HttpMethod       = "POST";
                webRequest.RequestUriString = "/$batch";

                webRequest.Accept             = UnitTestsUtil.MimeMultipartMixed;
                webRequest.RequestVersion     = "4.0;";
                webRequest.RequestMaxVersion  = "4.0;";
                webRequest.ForceVerboseErrors = true;

                const string boundary = "batch-set";
                webRequest.RequestContentType = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);
                webRequest.SetRequestStreamAsText(BatchRequestWritingUtils.GetBatchText(test.RequestPayload, boundary));

                AnnotationValue = new ODataComplexValue
                {
                    TypeName   = "AstoriaUnitTests.Stubs.Address",
                    Properties = new[]
                    {
                        new ODataProperty {
                            Name = "CityCity", Value = "404"
                        },
                        new ODataProperty {
                            Name = "State", Value = (new DateTimeOffset(2012, 10, 10, 1, 2, 3, new TimeSpan())).ToString()
                        },
                        new ODataProperty {
                            Name = "Foo", Value = new ODataCollectionValue {
                                Items = new Object[] { 123, new Object() }
                            }
                        }                                                                                                          // collection value is wrong so error payload fails to write
                    }
                };

                TestUtil.RunCatching(webRequest.SendRequest);

                // For batch request if ODL fails when writing error, HandleException is called twice and ODataError annotation cannot be be written correctly
                webRequest.ResponseStatusCode.Should().Be(202);
                webRequest.GetResponseStreamAsText().Should().Contain("{\"error\":{\"code\":\"\",\"message\":\"Resource not found for the segment 'Addresssss'.\",\"@location.error\":{\"@odata.type\":\"#AstoriaUnitTests.Stubs.Address\",\"CityCity\":\"404\",\"State\":\"10/10/2012 1:02:03 AM +00:00\",\"Foo\":[123<?xml");
                HandleExceptionCalls.Should().Be(2);
            }
        }
        public void BatchCustomAnnotationOnInnerRequestErrorShouldGetWrittenInJsonLight()
        {
            StringBuilder batchQueryOperation = new StringBuilder();

            batchQueryOperation.AppendLine("GET Customers(1)/Addresssss?Override-Accept=" + UnitTestsUtil.JsonLightMimeType + " HTTP/1.1");
            batchQueryOperation.AppendLine("Host: host");
            batchQueryOperation.AppendLine("Accept: " + "application/json;odata.metadata=minimal");

            var test = new SimpleBatchTestCase
            {
                RequestPayload               = new BatchInfo(new BatchQuery(new Operation(batchQueryOperation.ToString()))),
                ResponseStatusCode           = 202,
                ResponseETag                 = default(string),
                ResponseVersion              = V4,
                RequestDataServiceVersion    = V4,
                RequestMaxDataServiceVersion = V4,
            };

            using (TestWebRequest webRequest = this.SetupRequest())
            {
                webRequest.HttpMethod       = "POST";
                webRequest.RequestUriString = "/$batch";

                webRequest.Accept             = UnitTestsUtil.MimeMultipartMixed;
                webRequest.RequestVersion     = "4.0;";
                webRequest.RequestMaxVersion  = "4.0;";
                webRequest.ForceVerboseErrors = true;

                const string boundary = "batch-set";
                webRequest.RequestContentType = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);
                webRequest.SetRequestStreamAsText(BatchRequestWritingUtils.GetBatchText(test.RequestPayload, boundary));

                AnnotationValue = new ODataCollectionValue
                {
                    TypeName = "Collection(Edm.String)",
                    Items    = new []
                    {
                        "404",
                        new DateTimeOffset(2012, 10, 10, 1, 2, 3, new TimeSpan()).ToString()
                    }
                };

                TestUtil.RunCatching(webRequest.SendRequest);
                webRequest.ResponseStatusCode.Should().Be(202);
                webRequest.GetResponseStreamAsText().Should().Contain("{\"error\":{\"code\":\"\",\"message\":\"Resource not found for the segment 'Addresssss'.\",\"[email protected]\":\"#Collection(String)\",\"@location.error\":[\"404\",\"10/10/2012 1:02:03 AM +00:00\"]}}");
                HandleExceptionCalls.Should().Be(1);
            }
        }
Example #5
0
        [Ignore] // Remove Atom
        // [TestMethod, TestCategory("Partition1")]
        public void DollarFormatShouldFailOnTopLevelBatch()
        {
            StringBuilder batchQueryOperation = new StringBuilder();

            batchQueryOperation.AppendLine("GET Customers(1)/Address HTTP/1.1");
            batchQueryOperation.AppendLine("Host: host");

            var test = new SimpleBatchTestCase
            {
                RequestPayload = new BatchInfo(new BatchQuery(new Operation(batchQueryOperation.ToString()))),
                ExpectedResponsePayloadContains = new[] { "batch" },
                ResponseStatusCode           = 400,
                ResponseETag                 = default(string),
                ResponseVersion              = V4,
                RequestDataServiceVersion    = V4,
                RequestMaxDataServiceVersion = V4,
            };

            RunBatchTest(test, typeof(ModifyHeaderOnStartProcessingRequestTestService), "/$batch?$format=multipart/mixed", () => DataServicesResourceUtil.GetString("RequestQueryProcessor_FormatNotApplicable"));
        }
Example #6
0
        public void OnStartProcessingRequestCanOverrideAcceptHeaderInBatchOperationWithQueryItem()
        {
            StringBuilder batchQueryOperation = new StringBuilder();

            batchQueryOperation.AppendLine("GET Customers(1)/Address?Override-Accept=" + UnitTestsUtil.JsonLightMimeType + " HTTP/1.1");
            batchQueryOperation.AppendLine("Host: host");
            batchQueryOperation.AppendLine("Accept: " + UnitTestsUtil.MimeApplicationXml);

            var test = new SimpleBatchTestCase
            {
                RequestPayload = new BatchInfo(new BatchQuery(new Operation(batchQueryOperation.ToString()))),
                ExpectedResponsePayloadContains = new[] { "Content-Type: application/json;odata.metadata=minimal" },
                ResponseStatusCode           = 202,
                ResponseETag                 = default(string),
                ResponseVersion              = V4,
                RequestDataServiceVersion    = V4,
                RequestMaxDataServiceVersion = V4,
            };

            RunBatchTest(test, typeof(ModifyHeaderOnStartProcessingRequestTestService));
        }
        public void FailedTopLevelBatchRequestShouldBeXmlRegardlessOfCustomAnnotation()
        {
            StringBuilder batchQueryOperation = new StringBuilder();

            batchQueryOperation.AppendLine("GET Customers(1)/Address?Override-Accept=" + UnitTestsUtil.JsonLightMimeType + " HTTP/1.1");
            batchQueryOperation.AppendLine("Host: host");
            batchQueryOperation.AppendLine("Accept: " + "application/json;odata.metadata=minimal");

            var test = new SimpleBatchTestCase
            {
                RequestPayload     = new BatchInfo(new BatchQuery(new Operation(batchQueryOperation.ToString()))),
                ResponseStatusCode = 400,
            };

            using (TestWebRequest webRequest = this.SetupRequest())
            {
                webRequest.HttpMethod       = "POST";
                webRequest.RequestUriString = "/$batch";

                webRequest.Accept             = UnitTestsUtil.MimeMultipartMixed;
                webRequest.RequestVersion     = "4.0;";
                webRequest.RequestMaxVersion  = "4.0;";
                webRequest.ForceVerboseErrors = true;
                const string boundary = "batch-set";

                // set content type to json so the batch request fails with 400
                webRequest.RequestContentType = String.Format("{0}; boundary={1}", "application/json;odata.metadata=minimal", boundary);
                webRequest.SetRequestStreamAsText(BatchRequestWritingUtils.GetBatchText(test.RequestPayload, boundary));

                AnnotationValue = new ODataPrimitiveValue("This is a custom value message");

                TestUtil.RunCatching(webRequest.SendRequest);

                // Since the error response of top level batch request is xml, the custom error annotation will be ignored
                webRequest.ResponseStatusCode.Should().Be(test.ResponseStatusCode);
                webRequest.GetResponseStreamAsText().Should().NotContain("custom value message");
                HandleExceptionCalls.Should().Be(1);
            }
        }
Example #8
0
        /// <summary>
        /// Runs a batch test. For the purposes of exact baselining, this will strip off the guids from the boundary markers
        /// in the batch response. Also replaces the string BASE_URI with the service's base URI in any expected response text,
        /// so metadata in the response can be properly compared. Ignore the action-specific fields on the SimpleBatchTestCase.
        /// </summary>
        /// <param name="testCase">Description of the test.</param>
        /// <param name="serviceType">The DataServiceType to use.</param>
        private static void RunBatchTest(SimpleBatchTestCase testCase, Type serviceType, string requestUriString, Func <string> exceptionMessageFunc)
        {
            using (TestWebRequest request = TestWebRequest.CreateForInProcessWcf())
            {
                request.HttpMethod         = "POST";
                request.RequestUriString   = requestUriString;
                request.DataServiceType    = serviceType;
                request.Accept             = UnitTestsUtil.MimeMultipartMixed;
                request.RequestVersion     = testCase.RequestDataServiceVersion.ToString();
                request.RequestMaxVersion  = testCase.RequestMaxDataServiceVersion.ToString();
                request.ForceVerboseErrors = true;
                if (testCase.RequestPayload == null)
                {
                    request.RequestContentLength = 0;
                }
                else
                {
                    const string boundary = "batch-set";
                    request.RequestContentType = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);
                    request.SetRequestStreamAsText(BatchRequestWritingUtils.GetBatchText(testCase.RequestPayload, boundary));
                }

                Exception e        = TestUtil.RunCatching(request.SendRequest);
                string    response = request.GetResponseStreamAsText();

                // Top level status code / response version / etag comparisons
                Assert.AreEqual(testCase.ResponseStatusCode, request.ResponseStatusCode);
                Assert.AreEqual(testCase.ResponseVersion.ToString(), request.ResponseVersion);
                Assert.AreEqual(testCase.ResponseETag, request.ResponseETag);

                // strip off the guid from the boundries and etag for comparison purposes
                Regex regex1 = new Regex(@"batchresponse_\w{8}-\w{4}-\w{4}-\w{4}-\w{12}");
                response = regex1.Replace(response, "batchresponse");
                Regex regex2 = new Regex(@"changesetresponse_\w{8}-\w{4}-\w{4}-\w{4}-\w{12}");
                response = regex2.Replace(response, "changesetresponse");
                Regex regex3 = new Regex(@"ETag: W/""\w{8}-\w{4}-\w{4}-\w{4}-\w{12}""");
                response = regex3.Replace(response, "ETag");

                var expectedMessage = exceptionMessageFunc();
                if (expectedMessage != null)
                {
                    Assert.IsNotNull(expectedMessage, "Expected an exception");
                    Assert.IsTrue(response.Contains(expectedMessage));
                }
                else
                {
                    // Make exact comparision if given that, or otherwise do a series of str contains
                    if (testCase.ExpectedResponsePayloadExact != null)
                    {
                        Assert.AreEqual(testCase.ExpectedResponsePayloadExact.Replace("BASE_URI", request.BaseUri + "/"), response);
                    }
                    else
                    {
                        foreach (string str in testCase.ExpectedResponsePayloadContains)
                        {
                            Assert.IsTrue(response.Contains(str.Replace("BASE_URI", request.BaseUri + "/")), String.Format("The response:\r\n{0}\r\nDoes not contain the string:\r\n{1}.", response, str));
                        }
                    }

                    Assert.IsNull(e, "No exception expected but received one.");
                }
            }
        }
Example #9
0
 private static void RunBatchTest(SimpleBatchTestCase testCase, Type serviceType)
 {
     RunBatchTest(testCase, serviceType, "/$batch", () => null);
 }