Ejemplo n.º 1
0
        /// <summary>Writes the batch as a response into an in-memory request (sets up properties and such).</summary>
        /// <param name="request">The request to apply the batch as a response to.</param>
        public void WriteResponse(InMemoryWebRequest request)
        {
            request.SetResponseStatusCode(200);
            string boundary = "boundary_" + Guid.NewGuid().ToString();

            request.ResponseHeaders["Content-Type"] = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);

            request.SetResponseStream(this.CreateBatchContent(true, boundary));
        }
Ejemplo n.º 2
0
 /// <summary>Creates the in-memory response from another TestWebRequest, copying its reponse.</summary>
 /// <param name="sourceResponse">The request to read the response from.</param>
 /// <returns>The newly create request object with the response proeprties filled with the data from the request response.</returns>
 public static InMemoryWebRequest FromResponse(TestWebRequest sourceResponse)
 {
     InMemoryWebRequest response = new InMemoryWebRequest();
     response.SetResponseStatusCode(sourceResponse.ResponseStatusCode);
     foreach (var header in GetAllResponseHeaders(sourceResponse))
     {
         response.ResponseHeaders[header.Key] = header.Value;
     }
     using (Stream responseStream = sourceResponse.GetResponseStream())
     {
         response.SetResponseStream(responseStream);
     }
     return response;
 }
Ejemplo n.º 3
0
        /// <summary>Creates the in-memory response from another TestWebRequest, copying its reponse.</summary>
        /// <param name="sourceResponse">The request to read the response from.</param>
        /// <returns>The newly create request object with the response proeprties filled with the data from the request response.</returns>
        public static InMemoryWebRequest FromResponse(TestWebRequest sourceResponse)
        {
            InMemoryWebRequest response = new InMemoryWebRequest();

            response.SetResponseStatusCode(sourceResponse.ResponseStatusCode);
            foreach (var header in GetAllResponseHeaders(sourceResponse))
            {
                response.ResponseHeaders[header.Key] = header.Value;
            }
            using (Stream responseStream = sourceResponse.GetResponseStream())
            {
                response.SetResponseStream(responseStream);
            }
            return(response);
        }
Ejemplo n.º 4
0
            public InMemoryWebRequest ProcessRequestOverride(InMemoryWebRequest request)
            {
                if (IsTextPayloadType(request.RequestContentType))
                {
                    string payload =
                        ReplaceUriOccurences(
                            this.playbackServiceBaseUri,
                            this.underlyingServiceBaseUri,
                            new StreamReader(request.GetRequestStream()).ReadToEnd());
                    // Remove all Content-Length headers (if it's a batch since we just changed the length of the requests by replacing strings)
                    StringBuilder sb     = new StringBuilder();
                    TextReader    reader = new StringReader(payload);
                    string        line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (!line.StartsWith("Content-Length"))
                        {
                            sb.AppendLine(line);
                        }
                    }
                    request.SetRequestStreamAsText(sb.ToString());
                }

                // Copy the request to the server request
                request.WriteRequest(this.underlyingService);
                // Send the request
                try
                {
                    this.underlyingService.SendRequest();

                    // Copy the response to our in-memory representation
                    var response = InMemoryWebRequest.FromResponse(this.underlyingService);
                    if (IsTextPayloadType(response.ResponseContentType))
                    {
                        response.SetResponseStreamAsText(
                            ReplaceUriOccurences(
                                this.underlyingServiceBaseUri,
                                this.playbackServiceBaseUri,
                                response.GetResponseStreamAsText()));
                    }
                    var headersToReplace = new string[] { "Location", "OData-EntityId" };
                    foreach (var headerName in headersToReplace)
                    {
                        string value;
                        if (response.ResponseHeaders.TryGetValue(headerName, out value))
                        {
                            response.ResponseHeaders[headerName] =
                                ReplaceUriOccurences(
                                    this.underlyingServiceBaseUri,
                                    this.playbackServiceBaseUri,
                                    value);
                        }
                    }
                    return(response);
                }
                catch (Exception exception)
                {
                    // Translate everything into a 500, it's easier and we don't need correct error reporting on the client anyway (for versioning tests)
                    var response = new InMemoryWebRequest();
                    response.SetResponseStatusCode(500);
                    response.ResponseHeaders["Content-Type"] = UnitTestsUtil.MimeTextPlain;
                    response.SetResponseStreamAsText(exception.ToString());
                    return(response);
                }
            }
Ejemplo n.º 5
0
            public InMemoryWebRequest ProcessRequestOverride(InMemoryWebRequest request)
            {
                if (IsTextPayloadType(request.RequestContentType))
                {
                    string payload = 
                        ReplaceUriOccurences(
                            this.playbackServiceBaseUri,
                            this.underlyingServiceBaseUri,
                            new StreamReader(request.GetRequestStream()).ReadToEnd());
                    // Remove all Content-Length headers (if it's a batch since we just changed the length of the requests by replacing strings)
                    StringBuilder sb = new StringBuilder();
                    TextReader reader = new StringReader(payload);
                    string line;
                    while((line = reader.ReadLine()) != null)
                    {
                        if (!line.StartsWith("Content-Length")) sb.AppendLine(line);
                    }
                    request.SetRequestStreamAsText(sb.ToString());
                }

                // Copy the request to the server request
                request.WriteRequest(this.underlyingService);
                // Send the request
                try
                {
                    this.underlyingService.SendRequest();

                    // Copy the response to our in-memory representation
                    var response = InMemoryWebRequest.FromResponse(this.underlyingService);
                    if (IsTextPayloadType(response.ResponseContentType))
                    {
                        response.SetResponseStreamAsText(
                            ReplaceUriOccurences(
                                this.underlyingServiceBaseUri,
                                this.playbackServiceBaseUri,
                                response.GetResponseStreamAsText()));
                    }
                    var headersToReplace = new string[] { "Location", "OData-EntityId" };
                    foreach (var headerName in headersToReplace)
                    {
                        string value;
                        if (response.ResponseHeaders.TryGetValue(headerName, out value))
                        {
                            response.ResponseHeaders[headerName] = 
                                ReplaceUriOccurences(
                                    this.underlyingServiceBaseUri, 
                                    this.playbackServiceBaseUri, 
                                    value);
                        }
                    }
                    return response;
                }
                catch (Exception exception)
                {
                    // Translate everything into a 500, it's easier and we don't need correct error reporting on the client anyway (for versioning tests)
                    var response = new InMemoryWebRequest();
                    response.SetResponseStatusCode(500);
                    response.ResponseHeaders["Content-Type"] = UnitTestsUtil.MimeTextPlain;
                    response.SetResponseStreamAsText(exception.ToString());
                    return response;
                }
            }
Ejemplo n.º 6
0
            public void BatchContentTypeTest()
            {
                var testCases = new BatchContentTypeTestCase[]
                {
                    // Completely wrong content type
                    new BatchContentTypeTestCase
                    {
                        ContentType = "text/plain",
                        ExpectedErrorStatusCode = 400,
                        ExpectedClientErrorMessage = DataServicesClientResourceUtil.GetString("Batch_ExpectedContentType", "text/plain")
                    },
                    // Just type is correct, subtype is wrong
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/text",
                        ExpectedErrorStatusCode = 400,
                        ExpectedClientErrorMessage = DataServicesClientResourceUtil.GetString("Batch_ExpectedContentType", "multipart/text")
                    },
                    // No boundary - still wrong
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/mixed",
                        ExpectedErrorStatusCode = 400,
                        ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed", "boundary")
                    },
                    // Some other parameter but no boundary
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/mixed;param=value",
                        ExpectedErrorStatusCode = 400,
                        ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed;param=value", "boundary")
                    },
                    // Empty boundary - fails
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/mixed;boundary=",
                        ExpectedErrorStatusCode = 400,
                        ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("ValidationUtils_InvalidBatchBoundaryDelimiterLength", string.Empty, "70")
                    },
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/mixed;boundary=;param=value",
                        ExpectedErrorStatusCode = 400,
                        ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("ValidationUtils_InvalidBatchBoundaryDelimiterLength", string.Empty, "70")
                    },
                    // Two boundary parameters - wrong
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/mixed;boundary=one;boundary=two",
                        ExpectedErrorStatusCode = 400,
                        ExpectedClientErrorMessage = ODataLibResourceUtil.GetString("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed;boundary=one;boundary=two", "boundary")
                    },
                    // Valid simple boundary
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/mixed;boundary=batchboundary",
                        PayloadBatchBoundary = "batchboundary"
                    },
                    // Valid simple boundary - mimetype using different casing
                    new BatchContentTypeTestCase
                    {
                        ContentType = "MultiPart/mIxed;boundary=batchboundary",
                        PayloadBatchBoundary = "batchboundary"
                    },
                    // Valid simple boundary - boundary parameter name different casing
                    new BatchContentTypeTestCase
                    {
                        ContentType = "multipart/mixed;BounDary=batchboundary",
                        PayloadBatchBoundary = "batchboundary"
                    },
                };

                OpenWebDataServiceDefinition serverService = new OpenWebDataServiceDefinition()
                {
                    DataServiceType = typeof(CustomDataContext)
                };

                PlaybackServiceDefinition clientService = new PlaybackServiceDefinition();

                TestUtil.RunCombinations(
                    testCases,
                    (testCase) =>
                    {
                        using (TestWebRequest request = serverService.CreateForInProcess())
                        {
                            request.RequestContentType = testCase.ContentType;
                            request.SetRequestStreamAsText(string.Format(
                                "--{0}\r\n" +
                                "Content-Type: multipart/mixed; boundary=changesetresponse_00000001-0000-0000-0000-000000000000\r\n\r\n" +
                                "--changesetresponse_00000001-0000-0000-0000-000000000000\r\n" +
                                "--changesetresponse_00000001-0000-0000-0000-000000000000--\r\n" +
                                "--{0}--\r\n", testCase.PayloadBatchBoundary));
                            request.RequestUriString = "/$batch";
                            request.HttpMethod = "POST";

                            Exception exception = TestUtil.RunCatching(request.SendRequest);

                            int actualStatusCode = 0;
                            if (exception != null)
                            {
                                actualStatusCode = request.ResponseStatusCode;
                            }
                            else
                            {
                                Assert.AreEqual(202, request.ResponseStatusCode, "Wrong response code for no-exception request.");
                                BatchWebRequest batchResponse = BatchWebRequest.FromResponse(InMemoryWebRequest.FromResponse(request));
                                if (batchResponse.Parts.Count > 0)
                                {
                                    actualStatusCode = batchResponse.Parts[0].ResponseStatusCode;
                                    if (actualStatusCode == 200) actualStatusCode = 0;
                                }
                            }

                            Assert.AreEqual(testCase.ExpectedErrorStatusCode, actualStatusCode, "Wrong status code.");
                        }

                        using (TestWebRequest request = clientService.CreateForInProcessWcf())
                        {
                            request.StartService();

                            clientService.ProcessRequestOverride = clientRequest =>
                            {
                                var clientResponse = new InMemoryWebRequest();
                                clientResponse.SetResponseStatusCode(202);
                                clientResponse.ResponseHeaders["Content-Type"] = testCase.ContentType;
                                clientResponse.SetResponseStreamAsText(string.Format(
                                    "--{0}\r\n" +
                                    "Content-Type: application/http\r\n" +
                                    "Content-Transfer-Encoding: binary\r\n" +
                                    "\r\n" +
                                    "200 OK\r\n" +
                                    "<feed xmlns='http://www.w3.org/2005/Atom'/>\r\n" +
                                    "--{0}--\r\n",
                                    testCase.PayloadBatchBoundary));
                                return clientResponse;
                            };

                            DataServiceContext ctx = new DataServiceContext(request.ServiceRoot);
                            Exception exception = TestUtil.RunCatching(() => ctx.ExecuteBatch(ctx.CreateQuery<Customer>("/Customers")));

                            if (exception != null)
                            {
                                exception = ((DataServiceRequestException)exception).InnerException;
                                Assert.AreEqual(testCase.ExpectedClientErrorMessage, exception.Message, "Unexpected error message.");
                            }
                            else
                            {
                                Assert.IsNull(testCase.ExpectedClientErrorMessage, "Expected exception, but none was thrown.");
                            }
                        }
                    });
            }
Ejemplo n.º 7
0
        /// <summary>Writes the batch as a response into an in-memory request (sets up properties and such).</summary>
        /// <param name="request">The request to apply the batch as a response to.</param>
        public void WriteResponse(InMemoryWebRequest request)
        {
            request.SetResponseStatusCode(200);
            string boundary = "boundary_" + Guid.NewGuid().ToString();
            request.ResponseHeaders["Content-Type"] = String.Format("{0}; boundary={1}", UnitTestsUtil.MimeMultipartMixed, boundary);

            request.SetResponseStream(this.CreateBatchContent(true, boundary));
        }