Пример #1
0
        /// <summary>
        /// Generates the raw test message with mixed encodings defined by the test case, as well as the expected ODataPayloadElement.
        /// </summary>
        /// <param name="testCase">The test case defining the structure and encodings of the batch payload.</param>
        /// <param name="payload">The payload to use for all generated batch operations.</param>
        /// <param name="payloadUri">The URI to use for all generated batch operations.</param>
        /// <param name="isRequest">If true, generates a batch request, otherwise a batch response.</param>
        /// <returns>The test descriptor for this test case/configuration.</returns>
        private BatchReaderMixedEncodingTestDescriptor CreateTestDescriptor(BatchReaderMixedEncodingTestCase testCase, ODataPayloadElement payload, ODataUri payloadUri, bool isRequest)
        {
            ExceptionUtilities.Assert(testCase.BatchEncoding != null, "Batch encoding has not been specified.");

            string batchBoundary    = "batch_" + Guid.NewGuid().ToString();
            string payloadUriString = this.UriConverter.ConvertToString(payloadUri);

            var batchPayload = isRequest ? (ODataPayloadElement) new BatchRequestPayload() : (ODataPayloadElement) new BatchResponsePayload();

            batchPayload.AddAnnotation(new BatchBoundaryAnnotation(batchBoundary));

            var rawMessage = new List <byte>();

            // TODO: Batch reader does not support multi codepoint encodings
            Encoding unsupportedEncoding = AsUnsupportedEncoding(testCase.BatchEncoding);

            foreach (var changeset in testCase.Changesets)
            {
                string   changesetBoundary = "change_" + Guid.NewGuid().ToString();
                Encoding changesetEncoding = changeset.ChangesetEncoding ?? testCase.BatchEncoding;

                // TODO: Batch reader does not support multi codepoint encodings
                unsupportedEncoding = unsupportedEncoding ?? AsUnsupportedEncoding(changesetEncoding);

                string changesetContentType = HttpUtilities.BuildContentType(
                    MimeTypes.MultipartMixed,
                    changeset.ChangesetEncoding == null ? string.Empty : changeset.ChangesetEncoding.WebName,
                    changesetBoundary);

                rawMessage.AddRange(
                    WriteMessagePart(
                        testCase.BatchEncoding,
                        (writer) =>
                {
                    writer.Write("--");
                    writer.WriteLine(batchBoundary);
                    writer.WriteLine(HttpHeaders.ContentType + ": " + changesetContentType);
                    writer.WriteLine();
                }));

                var mimeParts = new List <IMimePart>();
                int contentId = 0;

                foreach (var operation in changeset.Operations)
                {
                    ExceptionUtilities.Assert(operation.PayloadFormat == ODataFormat.Atom || operation.PayloadFormat == ODataFormat.Json, "Payload format must be ATOM or JSON.");
                    string   formatType         = MimeTypes.ApplicationAtomXml + ";type=entry";
                    Encoding payloadEncoding    = operation.OperationEncoding ?? changesetEncoding;
                    string   payloadContentType = HttpUtilities.BuildContentType(
                        formatType,
                        operation.OperationEncoding == null ? string.Empty : operation.OperationEncoding.WebName,
                        string.Empty);

                    string httpStatus = isRequest ? "POST " + payloadUriString + " HTTP/1.1" : "HTTP/1.1 201 Created";

                    rawMessage.AddRange(
                        WriteMessagePart(
                            changesetEncoding,
                            (writer) =>
                    {
                        writer.WriteLine();
                        writer.Write("--");
                        writer.WriteLine(changesetBoundary);
                        writer.WriteLine(HttpHeaders.ContentType + ": application/http");
                        writer.WriteLine(HttpHeaders.ContentTransferEncoding + ": binary");
                        writer.WriteLine(HttpHeaders.ContentId + ": " + (++contentId).ToString());
                        writer.WriteLine();
                        writer.WriteLine(httpStatus);
                        writer.WriteLine(HttpHeaders.ContentType + ": " + payloadContentType);
                        writer.WriteLine();
                    }));

                    IPayloadSerializer payloadSerializer =
                        operation.PayloadFormat == ODataFormat.Atom ?
                        (IPayloadSerializer) new XmlPayloadSerializer(this.PayloadElementToXmlConverter) :
                        (IPayloadSerializer) new JsonPayloadSerializer(this.PayloadElementToJsonConverter.ConvertToJson);

                    byte[] payloadBytes = payloadSerializer.SerializeToBinary(payload, payloadEncoding.WebName);
                    rawMessage.AddRange(payloadBytes.Skip(payloadEncoding.GetPreamble().Length));

                    if (isRequest)
                    {
                        var request = this.RequestManager.BuildRequest(payloadUri, HttpVerb.Post, new Dictionary <string, string> {
                            { HttpHeaders.ContentType, payloadContentType }
                        });
                        request.Body = new ODataPayloadBody(payloadBytes, payload);
                        mimeParts.Add(request);
                    }
                    else
                    {
                        var httpResponseData = new HttpResponseData {
                            StatusCode = HttpStatusCode.Created,
                        };
                        httpResponseData.Headers.Add(HttpHeaders.ContentType, payloadContentType);
                        var response = new ODataResponse(httpResponseData)
                        {
                            Body = payloadBytes, RootElement = payload
                        };
                        mimeParts.Add(response);
                    }
                }

                rawMessage.AddRange(
                    WriteMessagePart(
                        changesetEncoding,
                        (writer) =>
                {
                    writer.WriteLine();
                    writer.Write("--");
                    writer.Write(changesetBoundary);
                    writer.WriteLine("--");
                }));

                if (isRequest)
                {
                    ((BatchRequestPayload)batchPayload).Add(BatchPayloadBuilder.RequestChangeset(changesetBoundary, changesetEncoding.WebName, mimeParts.ToArray()));
                }
                else
                {
                    ((BatchResponsePayload)batchPayload).Add(BatchPayloadBuilder.ResponseChangeset(changesetBoundary, changesetEncoding.WebName, mimeParts.ToArray()));
                }
            }

            rawMessage.AddRange(
                WriteMessagePart(
                    testCase.BatchEncoding,
                    (writer) =>
            {
                writer.WriteLine();
                writer.Write("--");
                writer.Write(batchBoundary);
                writer.WriteLine("--");
            }));

            return(new BatchReaderMixedEncodingTestDescriptor(this.PayloadReaderSettings)
            {
                BatchContentTypeHeader = HttpUtilities.BuildContentType(MimeTypes.MultipartMixed, testCase.BatchEncoding.WebName, batchBoundary),
                RawMessage = rawMessage.ToArray(),
                PayloadElement = batchPayload,
                ExpectedException = unsupportedEncoding == null ? null : ODataExpectedExceptions.ODataException("ODataBatchReaderStream_MultiByteEncodingsNotSupported", unsupportedEncoding.WebName)
            });
        }
        /// <summary>
        /// Generates the raw test message with mixed encodings defined by the test case, as well as the expected ODataPayloadElement.
        /// </summary>
        /// <param name="testCase">The test case defining the structure and encodings of the batch payload.</param>
        /// <param name="payload">The payload to use for all generated batch operations.</param>
        /// <param name="payloadUri">The URI to use for all generated batch operations.</param>
        /// <param name="isRequest">If true, generates a batch request, otherwise a batch response.</param>
        /// <returns>The test descriptor for this test case/configuration.</returns>
        private BatchReaderMixedEncodingTestDescriptor CreateTestDescriptor(BatchReaderMixedEncodingTestCase testCase, ODataPayloadElement payload, ODataUri payloadUri, bool isRequest)
        {
            ExceptionUtilities.Assert(testCase.BatchEncoding != null, "Batch encoding has not been specified.");

            string batchBoundary = "batch_" + Guid.NewGuid().ToString();
            string payloadUriString = this.UriConverter.ConvertToString(payloadUri);

            var batchPayload = isRequest ? (ODataPayloadElement)new BatchRequestPayload() : (ODataPayloadElement)new BatchResponsePayload();
            batchPayload.AddAnnotation(new BatchBoundaryAnnotation(batchBoundary));

            var rawMessage = new List<byte>();

            // TODO: Batch reader does not support multi codepoint encodings
            Encoding unsupportedEncoding = AsUnsupportedEncoding(testCase.BatchEncoding);

            foreach (var changeset in testCase.Changesets)
            {
                string changesetBoundary = "change_" + Guid.NewGuid().ToString();
                Encoding changesetEncoding = changeset.ChangesetEncoding ?? testCase.BatchEncoding;

                // TODO: Batch reader does not support multi codepoint encodings
                unsupportedEncoding = unsupportedEncoding ?? AsUnsupportedEncoding(changesetEncoding);

                string changesetContentType = HttpUtilities.BuildContentType(
                    MimeTypes.MultipartMixed,
                    changeset.ChangesetEncoding == null ? string.Empty : changeset.ChangesetEncoding.WebName,
                    changesetBoundary);

                rawMessage.AddRange(
                    WriteMessagePart(
                        testCase.BatchEncoding,
                        (writer) =>
                        {
                            writer.Write("--");
                            writer.WriteLine(batchBoundary);
                            writer.WriteLine(HttpHeaders.ContentType + ": " + changesetContentType);
                            writer.WriteLine();
                        }));

                var mimeParts = new List<IMimePart>();
                int contentId = 0;

                foreach (var operation in changeset.Operations)
                {
                    ExceptionUtilities.Assert(operation.PayloadFormat == ODataFormat.Atom || operation.PayloadFormat == ODataFormat.Json, "Payload format must be ATOM or JSON.");
                    string formatType = MimeTypes.ApplicationAtomXml + ";type=entry";
                    Encoding payloadEncoding = operation.OperationEncoding ?? changesetEncoding;
                    string payloadContentType = HttpUtilities.BuildContentType(
                        formatType,
                        operation.OperationEncoding == null ? string.Empty : operation.OperationEncoding.WebName,
                        string.Empty);

                    string httpStatus = isRequest ? "POST " + payloadUriString + " HTTP/1.1" : "HTTP/1.1 201 Created";

                    rawMessage.AddRange(
                        WriteMessagePart(
                            changesetEncoding,
                            (writer) =>
                            {
                                writer.WriteLine();
                                writer.Write("--");
                                writer.WriteLine(changesetBoundary);
                                writer.WriteLine(HttpHeaders.ContentType + ": application/http");
                                writer.WriteLine(HttpHeaders.ContentTransferEncoding + ": binary");
                                writer.WriteLine(HttpHeaders.ContentId + ": " + (++contentId).ToString());
                                writer.WriteLine();
                                writer.WriteLine(httpStatus);
                                writer.WriteLine(HttpHeaders.ContentType + ": " + payloadContentType);
                                writer.WriteLine();
                            }));

                    IPayloadSerializer payloadSerializer =
                        operation.PayloadFormat == ODataFormat.Atom ?
                        (IPayloadSerializer)new XmlPayloadSerializer(this.PayloadElementToXmlConverter) :
                        (IPayloadSerializer)new JsonPayloadSerializer(this.PayloadElementToJsonConverter.ConvertToJson);

                    byte[] payloadBytes = payloadSerializer.SerializeToBinary(payload, payloadEncoding.WebName);
                    rawMessage.AddRange(payloadBytes.Skip(payloadEncoding.GetPreamble().Length));

                    if (isRequest)
                    {
                        var request = this.RequestManager.BuildRequest(payloadUri, HttpVerb.Post, new Dictionary<string, string> { { HttpHeaders.ContentType, payloadContentType } });
                        request.Body = new ODataPayloadBody(payloadBytes, payload);
                        mimeParts.Add(request);
                    }
                    else
                    {
                        var httpResponseData = new HttpResponseData { StatusCode = HttpStatusCode.Created, };
                        httpResponseData.Headers.Add(HttpHeaders.ContentType, payloadContentType);
                        var response = new ODataResponse(httpResponseData) { Body = payloadBytes, RootElement = payload };
                        mimeParts.Add(response);
                    }
                }

                rawMessage.AddRange(
                    WriteMessagePart(
                        changesetEncoding,
                        (writer) =>
                        {
                            writer.WriteLine();
                            writer.Write("--");
                            writer.Write(changesetBoundary);
                            writer.WriteLine("--");
                        }));

                if (isRequest)
                {
                    ((BatchRequestPayload)batchPayload).Add(BatchPayloadBuilder.RequestChangeset(changesetBoundary, changesetEncoding.WebName, mimeParts.ToArray()));
                }
                else
                {
                    ((BatchResponsePayload)batchPayload).Add(BatchPayloadBuilder.ResponseChangeset(changesetBoundary, changesetEncoding.WebName, mimeParts.ToArray()));
                }
            }

            rawMessage.AddRange(
                WriteMessagePart(
                    testCase.BatchEncoding,
                    (writer) =>
                    {
                        writer.WriteLine();
                        writer.Write("--");
                        writer.Write(batchBoundary);
                        writer.WriteLine("--");
                    }));

            return new BatchReaderMixedEncodingTestDescriptor(this.PayloadReaderSettings)
            {
                BatchContentTypeHeader = HttpUtilities.BuildContentType(MimeTypes.MultipartMixed, testCase.BatchEncoding.WebName, batchBoundary),
                RawMessage = rawMessage.ToArray(),
                PayloadElement = batchPayload,
                ExpectedException = unsupportedEncoding == null ? null : ODataExpectedExceptions.ODataException("ODataBatchReaderStream_MultiByteEncodingsNotSupported", unsupportedEncoding.WebName)
            };
        }