public void ContentTypeHeaderParsingErrorTest()
        {
            var testCases = new ContentTypeTestCase[]
            {
                new ContentTypeTestCase
                {
                    ContentType       = null,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase
                {
                    ContentType       = string.Empty,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase
                {
                    ContentType       = ";foo=bar",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("HttpUtils_MediaTypeRequiresSlash", ";foo=bar")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "application/*",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "application/*")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "*/*",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "*/*")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "application/json, application/xml",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_NoOrMoreThanOneContentTypeSpecified", "application/json, application/xml")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.ReaderTestConfigurationProvider.AllFormatConfigurations.Where(tc => tc.Format != ODataFormat.Json),
                (testCase, testConfiguration) =>
            {
                // create a message reader and call GetFormat; this should fail with the expected error message
                TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(new TestStream(), testConfiguration);
                testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, testCase.ContentType);
                testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentLengthHeader, testCase.ContentLength.ToString());

                TestExceptionUtils.ExpectedException(
                    this.Assert,
                    () =>
                {
                    using (ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(testMessage, null, testConfiguration))
                    {
                        ODataFormat actualFormat = messageReader.DetectPayloadKind().Single().Format;
                    }
                },
                    testCase.ExpectedException,
                    this.ExceptionVerifier);
            });
        }
 public ContentTypeTestCase(ContentTypeTestCase other)
 {
     this.ContentType                 = other.ContentType;
     this.ExpectedException           = other.ExpectedException;
     this.ShouldSucceedForPayloadKind = other.ShouldSucceedForPayloadKind;
     this.ExpectedFormat              = other.ExpectedFormat;
     this.ContentLength               = other.ContentLength;
 }
 public ContentTypeTestCase(ContentTypeTestCase other)
 {
     this.ContentType = other.ContentType;
     this.ExpectedException = other.ExpectedException;
     this.ShouldSucceedForPayloadKind = other.ShouldSucceedForPayloadKind;
     this.ExpectedFormat = other.ExpectedFormat;
     this.ContentLength = other.ContentLength;
 }
        public void ContentTypeHeaderParsingTest()
        {
            IEnumerable<ContentTypeTestCase> testCases = new ContentTypeTestCase[]
            {
                #region Atom test cases
                new ContentTypeTestCase 
                { 
                    // only reading an entry or feed should succeed
                    ContentType = "application/atom+xml;type=feed", 
                    ExpectedFormat = ODataFormat.Atom, 
                },
                new ContentTypeTestCase 
                { 
                    // only reading an entry or feed should succeed
                    ContentType = "application/atom+xml;type=entry", 
                    ExpectedFormat = ODataFormat.Atom, 
                },
                new ContentTypeTestCase 
                { 
                    // reading a feed, an entry, and metadata should succeed
                    ContentType = "application/atom+xml", 
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase 
                { 
                    // reading a property, an entity reference link, entity reference links, a collection, a service document, and an error should succeed
                    ContentType = "application/xml", 
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase 
                { 
                    // reading a property, an entity reference link, entity reference links, and a collection should succeed
                    ContentType = "text/xml", 
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase 
                { 
                    // reading a service document should succeed
                    ContentType = "application/atomsvc+xml", 
                    ExpectedFormat = ODataFormat.Atom, 
                },
                #endregion Atom test cases

                #region RawValue test cases
                new ContentTypeTestCase 
                { 
                    // only reading a raw value will succeed
                    ContentType = "text/plain", 
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk => 
                        pk == ODataPayloadKind.Value 
                        || pk == ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase 
                { 
                    // only reading a raw value or binary value will succeed; raw values can be read as binary values when the content type is application/octet-stream
                    ContentType = "application/octet-stream", 
                    ExpectedFormat = ODataFormat.RawValue, 
                    ShouldSucceedForPayloadKind = pk => 
                        pk == ODataPayloadKind.Value 
                        || pk == ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase 
                { 
                    // only raw value / binary value will succeed
                    ContentType = "multipart/mixed",
                    ExpectedFormat = ODataFormat.RawValue, 
                    ShouldSucceedForPayloadKind = pk => false,
                },
                new ContentTypeTestCase 
                { 
                    // Test for: MimeType allows 0x7F character, but ContentType parsing doesn't
                    ContentType = "application/"+0x7F, 
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk => false,
                },

                #endregion RawValue test cases

                #region JSON Lite test cases
                new ContentTypeTestCase 
                { 
                    // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest)
                    ContentType = ApplicationJsonODataLight, 
                    ExpectedFormat = ODataFormat.Json, 
                    ShouldSucceedForPayloadKind = pk => 
                        pk != ODataPayloadKind.Value 
                        && pk != ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase 
                { 
                    // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest)
                    ContentType = ApplicationJsonODataLightStreaming, 
                    ExpectedFormat = ODataFormat.Json, 
                    ShouldSucceedForPayloadKind = pk => 
                        pk != ODataPayloadKind.Value 
                        && pk != ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase 
                { 
                    // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest)
                    ContentType = ApplicationJsonODataLightNonStreaming, 
                    ExpectedFormat = ODataFormat.Json, 
                    ShouldSucceedForPayloadKind = pk => 
                        pk != ODataPayloadKind.Value 
                        && pk != ODataPayloadKind.BinaryValue,
                },
                #endregion JSON Lite test cases

                #region Error test cases
                new ContentTypeTestCase 
                { 
                    // unsupported content type; everything will fail
                    ContentType = "application/foo", 
                    ShouldSucceedForPayloadKind = pk => false,
                },
                new ContentTypeTestCase 
                { 
                    // unsupported content type with parameters; everything will fail
                    ContentType = "abc/pqr;a=b;c=d",
                    ShouldSucceedForPayloadKind = pk => false,
                },
                new ContentTypeTestCase 
                { 
                    // "image/jpeg" is not supported, even for raw values.
                    ContentType = "image/jpeg",
                    ShouldSucceedForPayloadKind = pk => false,
                },
                #endregion Error test cases

                #region Content Type is null or empty
                new ContentTypeTestCase 
                { 
                    // null content type and zero content length should be default to Json if the payload kind is not binary value or value.
                    ContentType = null,
                    ContentLength = 0,
                    ExpectedFormat = ODataFormat.Json,
                    ShouldSucceedForPayloadKind = pk => true,
                    ShouldIgnoreTest = pk => pk == ODataPayloadKind.BinaryValue || pk == ODataPayloadKind.Value
                },
                new ContentTypeTestCase 
                { 
                    // null content type and zero content length should be default to RawValue if the payload kind is binary value or value.
                    ContentType = null,
                    ContentLength = 0,
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk => true,
                    ShouldIgnoreTest = pk => pk != ODataPayloadKind.Value
                },
                #endregion
            };

            string[] parameters = new string[] 
            {
                "foo=bar",
                "foo1=bar1;foo2=bar2"
            };

            testCases = testCases.Concat(testCases.Where(tc => tc.ContentType != null).SelectMany(tc => parameters.Select(p => new ContentTypeTestCase(tc) { ContentType = tc.ContentType + ";" + p })));

            int oDataPayloadKindCount = EnumExtensionMethods.GetValues<ODataPayloadKind>().Length;
            this.Assert.AreEqual(oDataPayloadKindCount, TestReaderUtils.ODataPayloadKinds.Length, "The number of payload kind have changed, please update this test.");

            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            // We don't support batch payloads here; we test those separately in BatchContentTypeHeaderParsingTest
            IEnumerable<ODataPayloadKind> payloadKinds =
                TestReaderUtils.ODataPayloadKinds.Where(k => k != ODataPayloadKind.Batch && k != ODataPayloadKind.Unsupported);
            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                payloadKinds,
                this.ReaderTestConfigurationProvider.AllFormatConfigurations,
                (testCase, payloadKind, testConfiguration) =>
                {
                    testConfiguration = new ReaderTestConfiguration(testConfiguration);
                    testConfiguration.MessageReaderSettings.EnableAtom = false;
                    if (IgnoreTestCase(payloadKind, testConfiguration))
                    {
                        return;
                    }

                    if (testCase.ShouldIgnoreTest != null && testCase.ShouldIgnoreTest(payloadKind))
                    {
                        return;
                    }

                    string supportedMediaTypes;

                    if (payloadKind == ODataPayloadKind.Value || payloadKind == ODataPayloadKind.BinaryValue)
                    {
                        supportedMediaTypes = TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Value) + ", " + TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.BinaryValue);
                    }
                    else
                    {
                        supportedMediaTypes = TestMediaTypeUtils.GetSupportedMediaTypes(payloadKind, /*includeAppJson*/true);
                    }

                    ExpectedException expectedException = testCase.ExpectedException == null
                         ? testCase.ShouldSucceedForPayloadKind!=null && testCase.ShouldSucceedForPayloadKind(payloadKind)
                             ? null
                             : ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", supportedMediaTypes, testCase.ContentType ?? "")
                         : testCase.ExpectedException;

                    // Make sure to run success test cases only in configurations that will work.
                    if (expectedException == null
                        && testConfiguration.Format != null
                        && testCase.ExpectedFormat != testConfiguration.Format)
                    {
                        return;
                    }

                    ODataPayloadElement payloadElement = CreatePayloadElement(model, payloadKind, testConfiguration);

                    // When we write a value with a content type different than 'text/plain', we will read it as binary.
                    // Likewise, when we write a binary value with a 'text/plain' content type, we will read it as a string.
                    Func<ReaderTestConfiguration, ODataPayloadElement> expectedResultElementFunc = null;
                    if (payloadKind == ODataPayloadKind.Value && testCase.ContentType != null && !testCase.ContentType.StartsWith("text/plain"))
                    {
                        expectedResultElementFunc = (testConfig) => ConvertToBinaryPayloadElement(payloadElement);
                    }
                    else if (payloadKind == ODataPayloadKind.BinaryValue && testCase.ContentType != null && testCase.ContentType.StartsWith("text/plain"))
                    {
                        expectedResultElementFunc = (testConfig) => ConvertToStringPayloadElement(payloadElement);
                    }

                    ODataFormat expectedFormat = testCase.ExpectedFormat;

                    ReaderContentTypeTestDescriptor testDescriptor = new ReaderContentTypeTestDescriptor(this.Settings)
                    {
                        PayloadElement = payloadElement,
                        ExpectedResultPayloadElement = expectedResultElementFunc,
                        PayloadEdmModel = model,
                        ExpectedFormat = expectedFormat,
                        ContentType = testCase.ContentType,
                        ExpectedException = expectedException
                    };

                    testDescriptor.RunTest(testConfiguration);
                    testConfiguration.MessageReaderSettings.EnableAtom = true;
                });
        }
        public void BatchContentTypeHeaderParsingTest()
        {
            IEnumerable<ContentTypeTestCase> testCases = new ContentTypeTestCase[]
            {
                // correct batch content type
                new ContentTypeTestCase 
                { 
                    ContentType = "multipart/mixed;boundary=--aa_bb_cc--", 
                    ExpectedFormat = ODataFormat.Batch, 
                },

                // missing batch boundary
                new ContentTypeTestCase 
                { 
                    ContentType = "multipart/mixed", 
                    ExpectedFormat = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataException("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed", "boundary")
                },

                // multiple batch boundary parameters
                new ContentTypeTestCase 
                { 
                    ContentType = "multipart/mixed;boundary=boundary1;boundary=boundary2", 
                    ExpectedFormat = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataException("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed;boundary=boundary1;boundary=boundary2", "boundary")
                },

                // invalid batch content types
                new ContentTypeTestCase 
                { 
                    ContentType = "multipart/bar", 
                    ExpectedFormat = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), "multipart/bar")
                },
                new ContentTypeTestCase 
                { 
                    ContentType = "foo/mixed", 
                    ExpectedFormat = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), "foo/mixed")
                },
                new ContentTypeTestCase 
                { 
                    ContentType = "abc/pqr", 
                    ExpectedFormat = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), "abc/pqr")
                },
                new ContentTypeTestCase
                {
                    ContentType = ApplicationJson,
                    ExpectedFormat = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), ApplicationJson)
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.ReaderTestConfigurationProvider.DefaultFormatConfigurations,
                (testCase, testConfiguration) =>
                {
                    // create a message reader and call GetFormat; this should fail with the expected error message
                    TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(new TestStream(), testConfiguration);
                    testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, testCase.ContentType);

                    TestExceptionUtils.ExpectedException(
                        this.Assert,
                        () =>
                        {
                            using (ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(testMessage, null, testConfiguration))
                            {
                                messageReader.CreateODataBatchReader();
                                ODataFormat actualFormat = ODataUtils.GetReadFormat(messageReader.MessageReader);
                                this.Assert.AreEqual(testCase.ExpectedFormat, actualFormat, "Formats don't match.");
                            }
                        },
                        testCase.ExpectedException,
                        this.ExceptionVerifier);
                });
        }
        public void ContentTypeHeaderParsingErrorTest()
        {
            var testCases = new ContentTypeTestCase[]
            {
                new ContentTypeTestCase 
                { 
                    ContentType = null, 
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase 
                { 
                    ContentType = string.Empty, 
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase 
                { 
                    ContentType = ";foo=bar", 
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("HttpUtils_MediaTypeRequiresSlash", ";foo=bar")
                },
                new ContentTypeTestCase 
                { 
                    ContentType = "application/*", 
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "application/*")
                },
                new ContentTypeTestCase 
                { 
                    ContentType = "*/*", 
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "*/*")
                },
                new ContentTypeTestCase 
                { 
                    ContentType = "application/json, application/xml", 
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_NoOrMoreThanOneContentTypeSpecified", "application/json, application/xml")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.ReaderTestConfigurationProvider.AllFormatConfigurations.Where(tc => tc.Format != ODataFormat.Json),
                (testCase, testConfiguration) =>
                {
                    // create a message reader and call GetFormat; this should fail with the expected error message
                    TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(new TestStream(), testConfiguration);
                    testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, testCase.ContentType);
                    testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentLengthHeader, testCase.ContentLength.ToString());

                    TestExceptionUtils.ExpectedException(
                        this.Assert,
                        () =>
                        {
                            using (ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(testMessage, null, testConfiguration))
                            {
                                ODataFormat actualFormat = messageReader.DetectPayloadKind().Single().Format;
                            }
                        },
                        testCase.ExpectedException,
                        this.ExceptionVerifier);
                });
        }
        public void ContentTypeHeaderParsingTest()
        {
            IEnumerable <ContentTypeTestCase> testCases = new ContentTypeTestCase[]
            {
                #region Atom test cases
                new ContentTypeTestCase
                {
                    // only reading an entry or feed should succeed
                    ContentType    = "application/atom+xml;type=feed",
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase
                {
                    // only reading an entry or feed should succeed
                    ContentType    = "application/atom+xml;type=entry",
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase
                {
                    // reading a feed, an entry, and metadata should succeed
                    ContentType    = "application/atom+xml",
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase
                {
                    // reading a property, an entity reference link, entity reference links, a collection, a service document, and an error should succeed
                    ContentType    = "application/xml",
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase
                {
                    // reading a property, an entity reference link, entity reference links, and a collection should succeed
                    ContentType    = "text/xml",
                    ExpectedFormat = ODataFormat.Atom,
                },
                new ContentTypeTestCase
                {
                    // reading a service document should succeed
                    ContentType    = "application/atomsvc+xml",
                    ExpectedFormat = ODataFormat.Atom,
                },
                #endregion Atom test cases

                #region RawValue test cases
                new ContentTypeTestCase
                {
                    // only reading a raw value will succeed
                    ContentType    = "text/plain",
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk =>
                                                  pk == ODataPayloadKind.Value ||
                                                  pk == ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase
                {
                    // only reading a raw value or binary value will succeed; raw values can be read as binary values when the content type is application/octet-stream
                    ContentType    = "application/octet-stream",
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk =>
                                                  pk == ODataPayloadKind.Value ||
                                                  pk == ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase
                {
                    // only raw value / binary value will succeed
                    ContentType    = "multipart/mixed",
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk => false,
                },
                new ContentTypeTestCase
                {
                    // Test for: MimeType allows 0x7F character, but ContentType parsing doesn't
                    ContentType    = "application/" + 0x7F,
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk => false,
                },

                #endregion RawValue test cases

                #region JSON Lite test cases
                new ContentTypeTestCase
                {
                    // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest)
                    ContentType    = ApplicationJsonODataLight,
                    ExpectedFormat = ODataFormat.Json,
                    ShouldSucceedForPayloadKind = pk =>
                                                  pk != ODataPayloadKind.Value &&
                                                  pk != ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase
                {
                    // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest)
                    ContentType    = ApplicationJsonODataLightStreaming,
                    ExpectedFormat = ODataFormat.Json,
                    ShouldSucceedForPayloadKind = pk =>
                                                  pk != ODataPayloadKind.Value &&
                                                  pk != ODataPayloadKind.BinaryValue,
                },
                new ContentTypeTestCase
                {
                    // only batch and raw value will fail (batch payload kind tested separately in BatchContentTypeHeaderParsingTest)
                    ContentType    = ApplicationJsonODataLightNonStreaming,
                    ExpectedFormat = ODataFormat.Json,
                    ShouldSucceedForPayloadKind = pk =>
                                                  pk != ODataPayloadKind.Value &&
                                                  pk != ODataPayloadKind.BinaryValue,
                },
                #endregion JSON Lite test cases

                #region Error test cases
                new ContentTypeTestCase
                {
                    // unsupported content type; everything will fail
                    ContentType = "application/foo",
                    ShouldSucceedForPayloadKind = pk => false,
                },
                new ContentTypeTestCase
                {
                    // unsupported content type with parameters; everything will fail
                    ContentType = "abc/pqr;a=b;c=d",
                    ShouldSucceedForPayloadKind = pk => false,
                },
                new ContentTypeTestCase
                {
                    // "image/jpeg" is not supported, even for raw values.
                    ContentType = "image/jpeg",
                    ShouldSucceedForPayloadKind = pk => false,
                },
                #endregion Error test cases

                #region Content Type is null or empty
                new ContentTypeTestCase
                {
                    // null content type and zero content length should be default to Json if the payload kind is not binary value or value.
                    ContentType    = null,
                    ContentLength  = 0,
                    ExpectedFormat = ODataFormat.Json,
                    ShouldSucceedForPayloadKind = pk => true,
                    ShouldIgnoreTest            = pk => pk == ODataPayloadKind.BinaryValue || pk == ODataPayloadKind.Value
                },
                new ContentTypeTestCase
                {
                    // null content type and zero content length should be default to RawValue if the payload kind is binary value or value.
                    ContentType    = null,
                    ContentLength  = 0,
                    ExpectedFormat = ODataFormat.RawValue,
                    ShouldSucceedForPayloadKind = pk => true,
                    ShouldIgnoreTest            = pk => pk != ODataPayloadKind.Value
                },
                #endregion
            };

            string[] parameters = new string[]
            {
                "foo=bar",
                "foo1=bar1;foo2=bar2"
            };

            testCases = testCases.Concat(testCases.Where(tc => tc.ContentType != null).SelectMany(tc => parameters.Select(p => new ContentTypeTestCase(tc)
            {
                ContentType = tc.ContentType + ";" + p
            })));

            int oDataPayloadKindCount = EnumExtensionMethods.GetValues <ODataPayloadKind>().Length;

            this.Assert.AreEqual(oDataPayloadKindCount, TestReaderUtils.ODataPayloadKinds.Length, "The number of payload kind have changed, please update this test.");

            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            // We don't support batch payloads here; we test those separately in BatchContentTypeHeaderParsingTest
            IEnumerable <ODataPayloadKind> payloadKinds =
                TestReaderUtils.ODataPayloadKinds.Where(k => k != ODataPayloadKind.Batch && k != ODataPayloadKind.Unsupported);

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                payloadKinds,
                this.ReaderTestConfigurationProvider.AllFormatConfigurations,
                (testCase, payloadKind, testConfiguration) =>
            {
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                testConfiguration.MessageReaderSettings.EnableAtom = false;
                if (IgnoreTestCase(payloadKind, testConfiguration))
                {
                    return;
                }

                if (testCase.ShouldIgnoreTest != null && testCase.ShouldIgnoreTest(payloadKind))
                {
                    return;
                }

                string supportedMediaTypes;

                if (payloadKind == ODataPayloadKind.Value || payloadKind == ODataPayloadKind.BinaryValue)
                {
                    supportedMediaTypes = TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Value) + ", " + TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.BinaryValue);
                }
                else
                {
                    supportedMediaTypes = TestMediaTypeUtils.GetSupportedMediaTypes(payloadKind, /*includeAppJson*/ true);
                }

                ExpectedException expectedException = testCase.ExpectedException == null
                         ? testCase.ShouldSucceedForPayloadKind != null && testCase.ShouldSucceedForPayloadKind(payloadKind)
                             ? null
                             : ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", supportedMediaTypes, testCase.ContentType ?? "")
                         : testCase.ExpectedException;

                // Make sure to run success test cases only in configurations that will work.
                if (expectedException == null &&
                    testConfiguration.Format != null &&
                    testCase.ExpectedFormat != testConfiguration.Format)
                {
                    return;
                }

                ODataPayloadElement payloadElement = CreatePayloadElement(model, payloadKind, testConfiguration);

                // When we write a value with a content type different than 'text/plain', we will read it as binary.
                // Likewise, when we write a binary value with a 'text/plain' content type, we will read it as a string.
                Func <ReaderTestConfiguration, ODataPayloadElement> expectedResultElementFunc = null;
                if (payloadKind == ODataPayloadKind.Value && testCase.ContentType != null && !testCase.ContentType.StartsWith("text/plain"))
                {
                    expectedResultElementFunc = (testConfig) => ConvertToBinaryPayloadElement(payloadElement);
                }
                else if (payloadKind == ODataPayloadKind.BinaryValue && testCase.ContentType != null && testCase.ContentType.StartsWith("text/plain"))
                {
                    expectedResultElementFunc = (testConfig) => ConvertToStringPayloadElement(payloadElement);
                }

                ODataFormat expectedFormat = testCase.ExpectedFormat;

                ReaderContentTypeTestDescriptor testDescriptor = new ReaderContentTypeTestDescriptor(this.Settings)
                {
                    PayloadElement = payloadElement,
                    ExpectedResultPayloadElement = expectedResultElementFunc,
                    PayloadEdmModel   = model,
                    ExpectedFormat    = expectedFormat,
                    ContentType       = testCase.ContentType,
                    ExpectedException = expectedException
                };

                testDescriptor.RunTest(testConfiguration);
                testConfiguration.MessageReaderSettings.EnableAtom = true;
            });
        }
        public void BatchContentTypeHeaderParsingTest()
        {
            IEnumerable <ContentTypeTestCase> testCases = new ContentTypeTestCase[]
            {
                // correct batch content type
                new ContentTypeTestCase
                {
                    ContentType    = "multipart/mixed;boundary=--aa_bb_cc--",
                    ExpectedFormat = ODataFormat.Batch,
                },

                // missing batch boundary
                new ContentTypeTestCase
                {
                    ContentType       = "multipart/mixed",
                    ExpectedFormat    = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataException("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed", "boundary")
                },

                // multiple batch boundary parameters
                new ContentTypeTestCase
                {
                    ContentType       = "multipart/mixed;boundary=boundary1;boundary=boundary2",
                    ExpectedFormat    = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataException("MediaTypeUtils_BoundaryMustBeSpecifiedForBatchPayloads", "multipart/mixed;boundary=boundary1;boundary=boundary2", "boundary")
                },

                // invalid batch content types
                new ContentTypeTestCase
                {
                    ContentType       = "multipart/bar",
                    ExpectedFormat    = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), "multipart/bar")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "foo/mixed",
                    ExpectedFormat    = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), "foo/mixed")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "abc/pqr",
                    ExpectedFormat    = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), "abc/pqr")
                },
                new ContentTypeTestCase
                {
                    ContentType       = ApplicationJson,
                    ExpectedFormat    = ODataFormat.Batch,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_CannotDetermineFormatFromContentType", TestMediaTypeUtils.GetSupportedMediaTypes(ODataPayloadKind.Batch), ApplicationJson)
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.ReaderTestConfigurationProvider.DefaultFormatConfigurations,
                (testCase, testConfiguration) =>
            {
                // create a message reader and call GetFormat; this should fail with the expected error message
                TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(new TestStream(), testConfiguration);
                testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, testCase.ContentType);

                TestExceptionUtils.ExpectedException(
                    this.Assert,
                    () =>
                {
                    using (ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(testMessage, null, testConfiguration))
                    {
                        messageReader.CreateODataBatchReader();
                        ODataFormat actualFormat = ODataUtils.GetReadFormat(messageReader.MessageReader);
                        this.Assert.AreEqual(testCase.ExpectedFormat, actualFormat, "Formats don't match.");
                    }
                },
                    testCase.ExpectedException,
                    this.ExceptionVerifier);
            });
        }