Beispiel #1
0
        public void CollectionWithODataTypeReaderTest()
        {
            IEdmModel           model     = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            IEdmEntityContainer container = model.FindEntityContainer("DefaultContainer");
            EdmOperationImport  primitiveCollectionResultOperation = container.FindOperationImports("PrimitiveCollectionResultOperation").Single() as EdmOperationImport;
            EdmOperationImport  complexCollectionResultOperation   = container.FindOperationImports("ComplexCollectionResultOperation").Single() as EdmOperationImport;

            var primitiveCollection = PayloadBuilder.PrimitiveCollection("PrimitiveCollectionResultOperation");

            primitiveCollection.Add(PayloadBuilder.PrimitiveValue(1));
            primitiveCollection.Add(PayloadBuilder.PrimitiveValue(2));
            primitiveCollection.Add(PayloadBuilder.PrimitiveValue(3));

            var complexCollection = PayloadBuilder.ComplexCollection("ComplexCollectionResultOperation");
            var complexValue1     = PayloadBuilder.ComplexValue("TestModel.Address")
                                    .PrimitiveProperty("Street", "Am Euro Platz")
                                    .AddAnnotation(new SerializationTypeNameTestAnnotation()
            {
                TypeName = null
            });

            complexCollection.Add(complexValue1);

            // NOTE: tests to cover consistency between the expected function import and the function import
            //       in the payload exist in the ContextUriValidationJsonLightTests.
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Non-collection type specified in odata.type - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = primitiveCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.Address\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ 1, 2, 3 ]" +
                                                           "}")
                                       .ExpectedFunctionImport(primitiveCollectionResultOperation),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightCollectionDeserializer_InvalidCollectionTypeName", "TestModel.Address"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Expected primitive item type and odata.type consistent - should work.",
                    PayloadEdmModel  = model,
                    PayloadElement   = primitiveCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(Edm.Int32)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ 1, 2, 3 ]" +
                                                           "}")
                                       .ExpectedFunctionImport(primitiveCollectionResultOperation),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Context URI (primitive collection) and odata.type consistent - should work.",
                    PayloadEdmModel  = model,
                    PayloadElement   = primitiveCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(Edm.Int32)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ 1, 2, 3 ]" +
                                                           "}")
                                       .ExpectedFunctionImport(primitiveCollectionResultOperation)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Expected primitive item type and odata.type NOT consistent - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = primitiveCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(Edm.Single)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ 1, 2, 3 ]" +
                                                           "}")
                                       .ExpectedFunctionImport(primitiveCollectionResultOperation),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncompatibleType", "Edm.Single", "Edm.Int32")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Expected primitive item type and odata.type NOT consistent (2) - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = primitiveCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(TestModel.Address)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(Edm.Int32)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ 1, 2, 3 ]" +
                                                           "}")
                                       .ExpectedFunctionImport(complexCollectionResultOperation),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Edm.Int32", "Complex", "Primitive")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Expected complex item type and odata.type NOT consistent - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = complexCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(TestModel.Address)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(TestModel.OfficeType)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ { \"Street\": \"Am Euro Platz\"} ]" +
                                                           "}")
                                       .ExpectedFunctionImport(complexCollectionResultOperation),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.OfficeType", "Complex", "Entity")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Expected primitive item type and odata.type NOT consistent (2) - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = complexCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(TestModel.Address)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ { \"Street\": \"Am Euro Platz\"} ]" +
                                                           "}")
                                       .ExpectedFunctionImport(primitiveCollectionResultOperation),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.Address", "Primitive", "Complex")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Complex item type in context URI and odata.type NOT consistent - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = complexCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(TestModel.Address)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(TestModel.OfficeType)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ { \"Street\": \"Am Euro Platz\"} ]" +
                                                           "}"),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.OfficeType", "Complex", "Entity")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Primitive item type in context URI and odata.type NOT consistent - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = complexCollection.DeepCopy()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\", " +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Collection(TestModel.Address)\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ { \"Street\": \"Am Euro Platz\"} ]" +
                                                           "}"),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.Address", "Primitive", "Complex")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void StreamPropertyTest()
        {
            IEdmModel model = TestModels.BuildTestModel();

            var testCases = new[]
            {
                new StreamPropertyTestCase
                {
                    DebugDescription = "Just edit link",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/test/Cities(1)/Skyline", "http://odata.org/streamproperty/editlink", null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\""
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Just read link",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/streamproperty/readlink", "http://odata.org/test/Cities(1)/Skyline", null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/streamproperty/readlink\""
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Just content type",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/test/Cities(1)/Skyline", "http://odata.org/test/Cities(1)/Skyline", "streamproperty:contenttype", null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"streamproperty:contenttype\""
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Just ETag",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/test/Cities(1)/Skyline", "http://odata.org/test/Cities(1)/Skyline", null, "streamproperty:etag"),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"streamproperty:etag\""
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Everything",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/streamproperty/readlink", "http://odata.org/streamproperty/editlink", "streamproperty:contenttype", "streamproperty:etag"),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/streamproperty/readlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"streamproperty:contenttype\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"streamproperty:etag\""
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Just custom annotation - should report empty stream property",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/test/Cities(1)/Skyline", "http://odata.org/test/Cities(1)/Skyline", null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", "custom.value") + "\":\"value\""
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Everything with custom annotation - custom annotations should be ignored",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/streamproperty/readlink", "http://odata.org/streamproperty/editlink", "streamproperty:contenttype", "streamproperty:etag"),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", "custom.value") + "\":\"value\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/streamproperty/readlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"streamproperty:contenttype\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"streamproperty:etag\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", "custom.type") + "\":42"
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "With odata.type annotation - should fail",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.Stream\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_UnexpectedStreamPropertyAnnotation", "Skyline", JsonLightConstants.ODataTypeAnnotationName)
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Everything with navigation link URL annotation - should fail",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", "http://odata.org/streamproperty/readlink", "http://odata.org/streamproperty/editlink", "streamproperty:contenttype", "streamproperty:etag"),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/streamproperty/readlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/streamproperty/navlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"streamproperty:contenttype\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"streamproperty:etag\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_UnexpectedStreamPropertyAnnotation", "Skyline", JsonLightConstants.ODataNavigationLinkUrlAnnotationName)
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid edit link - wrong primitive",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":42",
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_CannotReadPropertyValueAsString", "42", JsonLightConstants.ODataMediaEditLinkAnnotationName),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid edit link - null",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":null",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataMediaEditLinkAnnotationName),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid read link - wrong primitive",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":true",
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_CannotReadPropertyValueAsString", "True", JsonLightConstants.ODataMediaReadLinkAnnotationName),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid read link - null",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":null",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataMediaReadLinkAnnotationName),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid ETag - non primitive",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaETagAnnotationName) + "\":[]",
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid ETag - null",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaETagAnnotationName) + "\":null",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataMediaETagAnnotationName),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid content type - non primitive",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":{}",
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Invalid content type - null",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, null, null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":null",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataMediaContentTypeAnnotationName),
                    OnlyResponse      = true,
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Open stream property",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("OpenSkyline", null, "http://odata.org/streamproperty/editlink", null, null),
                    OwningEntityType = model.FindDeclaredType("TestModel.CityOpenType").ToTypeReference(),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("OpenSkyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_OpenPropertyWithoutValue", "OpenSkyline"),
                    OnlyResponse      = true
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Undeclared stream property",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("NewSkyline", null, "http://odata.org/streamproperty/editlink", null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("NewSkyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", "NewSkyline", "TestModel.CityType"),
                    OnlyResponse      = true
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Stream property declared with non-stream type",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Name", null, "http://odata.org/streamproperty/editlink", null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithWrongType", "Name", "Edm.String"),
                    OnlyResponse      = true
                },
                new StreamPropertyTestCase
                {
                    DebugDescription = "Stream property with value",
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("Skyline", null, "http://odata.org/streamproperty/editlink", null, null),
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("Skyline", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/streamproperty/editlink\"," +
                        "\"Skyline\":\"value\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_StreamPropertyWithValue", "Skyline"),
                    OnlyResponse      = true
                },
            };

            this.RunStreamPropertyTest(model, testCases);
        }
Beispiel #3
0
        public void ParameterReaderJsonLightTest()
        {
            EdmModel model = new EdmModel();

            model.Fixup();

            EdmEntityContainer container = model.EntityContainer as EdmEntityContainer;

            EdmFunction function = new EdmFunction(container.Namespace, "f1", EdmCoreModel.Instance.GetInt32(true));

            function.AddParameter("p1", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference);
            function.AddParameter("p2", EdmCoreModel.Instance.GetString(false) as EdmTypeReference);
            model.AddElement(function);
            EdmOperationImport f1 = container.FunctionImport(function);

            ComplexInstance f1Params = PayloadBuilder.ComplexValue().PrimitiveProperty("p1", 42).PrimitiveProperty("p2", "Vienna")
                                       .ExpectedFunctionImport(f1);

            var testCases = new[]
            {
                new
                {
                    DebugDescription  = "Custom property annotation for a valid parameter property (before property) - should work.",
                    Json              = "{\"" + JsonLightUtils.GetPropertyAnnotationName("p1", "my.custom") + "\":42, \"p1\":42, \"p2\":\"Vienna\"}",
                    ExpectedException = (ExpectedException)null,
                },
                new
                {
                    DebugDescription  = "Custom property annotation for a valid parameter property (after property) - should fail.",
                    Json              = "{\"p1\":42, \"" + JsonLightUtils.GetPropertyAnnotationName("p1", "my.custom") + "\":42, \"p2\":\"Vienna\"}",
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_PropertyAnnotationAfterTheProperty", "my.custom", "p1"),
                },
                new
                {
                    DebugDescription  = "OData property annotation for a valid parameter property (before property) - should work.",
                    Json              = "{\"" + JsonLightUtils.GetPropertyAnnotationName("p1", JsonLightConstants.ODataTypeAnnotationName) + "\":42, \"p1\":42, \"p2\":\"Vienna\"}",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightParameterDeserializer_PropertyAnnotationForParameters"),
                },
                new
                {
                    DebugDescription  = "OData property annotation for a valid parameter property (after property) - should fail.",
                    Json              = "{\"p1\":42, \"" + JsonLightUtils.GetPropertyAnnotationName("p1", JsonLightConstants.ODataTypeAnnotationName) + "\":42, \"p2\":\"Vienna\"}",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightParameterDeserializer_PropertyAnnotationForParameters"),
                },
                new
                {
                    DebugDescription  = "Custom property annotation for an invalid parameter property - should fail.",
                    Json              = "{\"" + JsonLightUtils.GetPropertyAnnotationName("p0", "my.custom") + "\":42, \"p1\":42, \"p2\":\"Vienna\"}",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightParameterDeserializer_PropertyAnnotationWithoutPropertyForParameters", "p0"),
                },
                new
                {
                    DebugDescription  = "Custom instance annotation - should work.",
                    Json              = "{\"@my.custom\":42, \"p1\":42, \"p2\":\"Vienna\"}",
                    ExpectedException = (ExpectedException)null,
                },
                new
                {
                    DebugDescription  = "OData instance annotation - should fail.",
                    Json              = "{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.Int32\", \"p1\":42, \"p2\":\"Vienna\"}",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataTypeAnnotationName),
                },
            };

            var testDescriptors = testCases.Select(testCase =>
                                                   new PayloadReaderTestDescriptor(this.Settings)
            {
                DebugDescription  = testCase.DebugDescription,
                PayloadElement    = f1Params.DeepCopy().JsonRepresentation(testCase.Json),
                PayloadEdmModel   = model,
                PayloadKind       = ODataPayloadKind.Parameter,
                ExpectedException = testCase.ExpectedException,
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(c => c.IsRequest),
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.ExpectedResultNormalizers.Add(tc => ParameterReaderTests.FixupExpectedCollectionParameterPayloadElement);

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void TopLevelPropertyTest()
        {
            var injectedProperties = new[]
            {
                new
                {
                    InjectedJSON      = string.Empty,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown\": { }",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\": { }",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataContextAnnotationName)
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null, \"@custom.annotation\": 42",
                    ExpectedException = (ExpectedException)null
                },
            };

            var payloads = new[]
            {
                new
                {
                    Json = "{{ " +
                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                           "\"value\": null" +
                           "{1}{0}" +
                           "}}",
                },
                new
                {
                    Json = "{{ " +
                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                           "{0}{1}" +
                           "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                           "}}",
                },
                new
                {
                    Json = "{{ " +
                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                           "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                           "{1}{0}" +
                           "}}",
                },
            };

            EdmModel model     = new EdmModel();
            var      container = new EdmEntityContainer("TestModel", "DefaultContainer");

            model.AddElement(container);

            var owningType = new EdmEntityType("TestModel", "OwningType");

            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            owningType.AddStructuralProperty("TopLevelProperty", EdmCoreModel.Instance.GetInt32(true));
            owningType.AddStructuralProperty("TopLevelSpatialProperty", EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, false));
            owningType.AddStructuralProperty("TopLevelCollectionProperty", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(owningType);

            IEdmEntityType         edmOwningType                 = (IEdmEntityType)model.FindDeclaredType("TestModel.OwningType");
            IEdmStructuralProperty edmTopLevelProperty           = (IEdmStructuralProperty)edmOwningType.FindProperty("TopLevelProperty");
            IEdmStructuralProperty edmTopLevelSpatialProperty    = (IEdmStructuralProperty)edmOwningType.FindProperty("TopLevelSpatialProperty");
            IEdmStructuralProperty edmTopLevelCollectionProperty = (IEdmStructuralProperty)edmOwningType.FindProperty("TopLevelCollectionProperty");

            PayloadReaderTestDescriptor.ReaderMetadata readerMetadata           = new PayloadReaderTestDescriptor.ReaderMetadata(edmTopLevelProperty);
            PayloadReaderTestDescriptor.ReaderMetadata spatialReaderMetadata    = new PayloadReaderTestDescriptor.ReaderMetadata(edmTopLevelSpatialProperty);
            PayloadReaderTestDescriptor.ReaderMetadata collectionReaderMetadata = new PayloadReaderTestDescriptor.ReaderMetadata(edmTopLevelCollectionProperty);

            var testDescriptors = payloads.SelectMany(payload => injectedProperties.Select(injectedProperty =>
            {
                return(new NativeInputReaderTestDescriptor()
                {
                    PayloadKind = ODataPayloadKind.Property,
                    InputCreator = (tc) =>
                    {
                        string input = string.Format(payload.Json, injectedProperty.InjectedJSON, string.IsNullOrEmpty(injectedProperty.InjectedJSON) ? string.Empty : ",");
                        return input;
                    },
                    PayloadEdmModel = model,

                    // We use payload expected result just as a convenient way to run the reader for the Property payload kind.
                    // We validate whether the reading succeeds or fails, but not the actual read values (at least not here).
                    ExpectedResultCallback = (tc) =>
                                             new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ReaderMetadata = readerMetadata,
                        ExpectedException = injectedProperty.ExpectedException,
                    }
                });
            }));

            var explicitPayloads = new[]
            {
                new
                {
                    Description = "Custom property annotation - should be ignored.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": null," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Duplicate custom property annotation - should not fail.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": null," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": 42," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Unrecognized odata property annotation - should be ignored.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("value", JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown") + "\": null," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Custom property annotation after the property - should fail.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("value", "custom.annotation") + "\": null" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = ODataExpectedExceptions.ODataException("PropertyAnnotationAfterTheProperty", "custom.annotation", "value")
                },
                new
                {
                    Description = "OData property annotation.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.Int32\"," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Duplicate odata.type property should fail.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.Int32\"," +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.String\"," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicateAnnotationNotAllowed", JsonLightConstants.ODataTypeAnnotationName)
                },
                new
                {
                    Description = "Type information for top-level property - correct.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.Int32\"," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Type information for top-level property - different kind - should fail.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Collection(Edm.Int32)\"," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": 42" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Collection(Edm.Int32)", "Primitive", "Collection")
                },
                new
                {
                    Description = "Unknown type information for top-level null - should fail.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Unknown\"," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\": null" +
                                  "}",
                    ReaderMetadata    = readerMetadata,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Unknown", "Primitive", "Complex")
                },
                new
                {
                    Description = "Type information for top-level spatial - should work.",
                    Json        = "{ " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.GeographyPoint\", " +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"Edm.GeographyPoint\"," +
                                  "\"" + JsonLightConstants.ODataValuePropertyName + "\":" + SpatialUtils.GetSpatialStringValue(ODataFormat.Json, GeographyFactory.Point(33.1, -110.0).Build()) +
                                  "}",
                    ReaderMetadata    = spatialReaderMetadata,
                    ExpectedException = (ExpectedException)null
                },
            };

            testDescriptors = testDescriptors.Concat(explicitPayloads.Select(payload =>
            {
                return(new NativeInputReaderTestDescriptor()
                {
                    PayloadKind = ODataPayloadKind.Property,
                    InputCreator = (tc) =>
                    {
                        return payload.Json;
                    },
                    PayloadEdmModel = model,

                    // We use payload expected result just as a convenient way to run the reader for the Property payload kind
                    // since the reading should always fail, we don't need anything to compare the results to.
                    ExpectedResultCallback = (tc) =>
                                             new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ReaderMetadata = payload.ReaderMetadata,
                        ExpectedException = payload.ExpectedException,
                    },
                    DebugDescription = payload.Description
                });
            }));

            // Add a test descriptor to verify that we ignore odata.context in requests
            testDescriptors = testDescriptors.Concat(
                new NativeInputReaderTestDescriptor[]
            {
                new NativeInputReaderTestDescriptor()
                {
                    DebugDescription = "Top-level property with invalid name.",
                    PayloadKind      = ODataPayloadKind.Property,
                    InputCreator     = tc =>
                    {
                        return("{ " +
                               "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.Int32\", " +
                               "\"TopLevelProperty\": 42" +
                               "}");
                    },
                    PayloadEdmModel        = model,
                    ExpectedResultCallback = tc =>
                                             new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ReaderMetadata    = readerMetadata,
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_InvalidTopLevelPropertyName", "TopLevelProperty", "value")
                    },
                    SkipTestConfiguration = tc => !tc.IsRequest
                }
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void OpenTopLevelPropertiesErrorTest()
        {
            IEdmModel model = TestModels.BuildTestModel();

            var testCases = new OpenPropertyTestCase[]
            {
                new OpenPropertyTestCase
                {
                    DebugDescription = "String open property with property annotation type information - should fail.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value").ExpectedPropertyType(EdmCoreModel.Instance.GetString(true)),
                    Json             =
                        "{0}" +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.String\"," +
                        "\"" + JsonLightConstants.ODataValuePropertyName + "\":\"" + JsonLightConstants.ODataValuePropertyName + "\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedODataPropertyAnnotation", JsonLightConstants.ODataTypeAnnotationName)
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "String open property with complex type information - should fail.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value").ExpectedPropertyType(EdmCoreModel.Instance.GetString(true)),
                    Json             =
                        "{0}" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.Address\"," +
                        "\"" + JsonLightConstants.ODataValuePropertyName + "\":\"" + JsonLightConstants.ODataValuePropertyName + "\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.Address", "Primitive", "Complex")
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "Type property after the data property - should fail.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value").ExpectedPropertyType(EdmCoreModel.Instance.GetString(true)),
                    Json             =
                        "{0}" +
                        "\"" + JsonLightConstants.ODataValuePropertyName + "\":\"" + JsonLightConstants.ODataValuePropertyName + "\"," +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.String\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_TypePropertyAfterValueProperty", JsonLightConstants.ODataTypeAnnotationName, JsonLightConstants.ODataValuePropertyName)
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "Duplicate data property - should fail.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value").ExpectedPropertyType(EdmCoreModel.Instance.GetString(true)),
                    Json             =
                        "{0}" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.String\"," +
                        "\"" + JsonLightConstants.ODataValuePropertyName + "\":\"" + JsonLightConstants.ODataValuePropertyName + "\"," +
                        "\"" + JsonLightConstants.ODataValuePropertyName + "\":\"" + JsonLightConstants.ODataValuePropertyName + "\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesNotAllowed", JsonLightConstants.ODataValuePropertyName)
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "Duplicate odata.type property - should fail.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value").ExpectedPropertyType(EdmCoreModel.Instance.GetString(true)),
                    Json             =
                        "{0}" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.String\"," +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.String\"," +
                        "\"" + JsonLightConstants.ODataValuePropertyName + "\":\"" + JsonLightConstants.ODataValuePropertyName + "\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicateAnnotationNotAllowed", JsonLightConstants.ODataTypeAnnotationName)
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "No data property - should fail.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value").ExpectedPropertyType(EdmCoreModel.Instance.GetString(true)),
                    Json             =
                        "{0}" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.String\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_InvalidTopLevelPropertyPayload")
                },
                new OpenPropertyTestCase
                {
                    DebugDescription = "No data property (only type property) - should fail.",
                    ExpectedProperty = PayloadBuilder.PrimitiveProperty("OpenProperty", "value").ExpectedPropertyType(EdmCoreModel.Instance.GetString(true)),
                    Json             =
                        "{0}" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"Edm.String\"",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_InvalidTopLevelPropertyPayload")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testCase, testConfiguration) =>
            {
                string json = string.Format(
                    CultureInfo.InvariantCulture,
                    testCase.Json,
                    testConfiguration.IsRequest
                            ? string.Empty
                            : "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Edm.String\",");

                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = testCase.DebugDescription,
                    PayloadElement   = testCase.ExpectedProperty
                                       .JsonRepresentation("{" + json + "}"),
                    PayloadEdmModel   = model,
                    ExpectedException = testCase.ExpectedException,
                };

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void AssociationLinkOnNavigationLinkTest()
        {
            EdmModel model = new EdmModel();

            var container = new EdmEntityContainer("TestModel", "Default");

            model.AddElement(container);

            var edmEntityTypeOrderType = new EdmEntityType("TestModel", "OrderType");

            model.AddElement(edmEntityTypeOrderType);

            var edmEntityTypeCustomerType = new EdmEntityType("TestModel", "CustomerType");
            var edmNavigationPropertyAssociationLinkOne = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = "NavProp1", Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.One
            });
            var edmNavigationPropertyAssociationLinkTwo = edmEntityTypeCustomerType.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo {
                Name = "NavProp2", Target = edmEntityTypeOrderType, TargetMultiplicity = EdmMultiplicity.Many
            });

            model.AddElement(edmEntityTypeCustomerType);

            var customerSet = container.AddEntitySet("Customers", edmEntityTypeCustomerType);
            var orderSet    = container.AddEntitySet("Orders", edmEntityTypeOrderType);

            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkOne, orderSet);
            customerSet.AddNavigationTarget(edmNavigationPropertyAssociationLinkTwo, orderSet);

            var testCases = new[]
            {
                // Both nav link URL and association link URL
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = new Uri("http://odata.org/navlink"), AssociationLinkUrl = new Uri("http://odata.org/assoclink")
                    },
                    PropertyName = "NavProp1",
                    Atom         = BuildXmlNavigationLink("NavProp1", "application/atom+xml;type=entry", "http://odata.org/navlink"),
                    JsonLight    =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/assoclink\""
                },
                // Just nav link URL
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = new Uri("http://odata.org/navlink"), AssociationLinkUrl = null
                    },
                    PropertyName = "NavProp1",
                    Atom         = BuildXmlNavigationLink("NavProp1", "application/atom+xml;type=entry", "http://odata.org/navlink"),
                    JsonLight    = "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navlink\""
                },
                // Just association link URL
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = null, AssociationLinkUrl = new Uri("http://odata.org/assoclink")
                    },
                    PropertyName = "NavProp1",
                    Atom         = (string)null,
                    JsonLight    = "\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/assoclink\""
                },
                // Navigation link with both URLs null
                new {
                    NavigationLink = new ODataNavigationLink()
                    {
                        Name = "NavProp1", IsCollection = false, Url = null, AssociationLinkUrl = null
                    },
                    PropertyName = "NavProp1",
                    Atom         = (string)null,
                    JsonLight    = string.Empty
                }
            };

            IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testDescriptors = testCases.Select(testCase =>
            {
                ODataEntry entry = ObjectModelUtils.CreateDefaultEntry();
                entry.TypeName   = "TestModel.CustomerType";
                return(new PayloadWriterTestDescriptor <ODataItem>(
                           this.Settings,
                           new ODataItem[] { entry, testCase.NavigationLink, null },
                           (testConfiguration) =>
                {
                    if (testConfiguration.Format == ODataFormat.Atom)
                    {
                        return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Xml = "<Links>" + testCase.Atom + "</Links>",
                            FragmentExtractor = (result) =>
                            {
                                var links = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                                            .Where(l => l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(
                                                       TestAtomConstants.ODataNavigationPropertiesAssociationLinkRelationPrefix) ||
                                                   l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(
                                                       TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix));
                                result = new XElement("Ref", links);
                                if (result.FirstNode == null)
                                {
                                    result.Add("");
                                }

                                return result;
                            },
                            ExpectedException2 = testCase.Atom == null ? ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyUrl", testCase.PropertyName) : null
                        };
                    }
                    else if (testConfiguration.Format == ODataFormat.Json)
                    {
                        return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Json = string.Join(
                                "$(NL)",
                                "{",
                                testCase.JsonLight,
                                "}"),
                            FragmentExtractor = (result) =>
                            {
                                var links = result.Object().GetPropertyAnnotations(testCase.PropertyName).ToList();
                                var jsonResult = new JsonObject();
                                links.ForEach(l =>
                                {
                                    // NOTE we remove all annoatations here and in particular the text annotations to be able to easily compare
                                    //      against the expected results. This however means that we do not distinguish between the indented and non-indented case here.
                                    l.RemoveAllAnnotations(true);
                                    jsonResult.Add(l);
                                });
                                return jsonResult;
                            }
                        };
                    }
                    else
                    {
                        this.Settings.Assert.Fail("Unknown format '{0}'.", testConfiguration.Format);
                        return null;
                    }
                })
                {
                    Model = model,
                    PayloadEdmElementContainer = customerSet
                });
            });

            // With and without model
            testDescriptors = testDescriptors.SelectMany(td =>
                                                         new[]
            {
                td,
                new PayloadWriterTestDescriptor <ODataItem>(td)
                {
                    Model = null,
                    PayloadEdmElementContainer = null
                }
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.PayloadCases(WriterPayloads.EntryPayloads),
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent.Where(testConfiguration => !testConfiguration.IsRequest),
                (testDescriptor, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                if (testDescriptor.Model == null && testConfiguration.Format == ODataFormat.Json)
                {
                    return;
                }

                if (testDescriptor.IsGeneratedPayload && testDescriptor.Model != null)
                {
                    return;
                }

                TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
            });
        }
        public void FeedReaderErrorTest()
        {
            IEdmModel           model           = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            IEdmEntityContainer container       = model.FindEntityContainer("DefaultContainer");
            IEdmEntitySet       citiesEntitySet = container.FindEntitySet("Cities");
            IEdmType            cityType        = model.FindType("TestModel.CityType") as IEdmType;

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                #region Test cases
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Empty feed with OData property annotation before top-level feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataCountAnnotationName) + "\":\"42\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataCountAnnotationName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Empty feed with OData property annotation after top-level feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]," +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName(JsonLightConstants.ODataValuePropertyName, JsonLightConstants.ODataCountAnnotationName) + "\":\"42\"" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataCountAnnotationName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Empty feed with invalid feed property value.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":{}" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_CannotReadResourceSetContentStart", "StartObject")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed with primitive item in feed property value.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ 1 ]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_InvalidNodeTypeForItemsInResourceSet", "PrimitiveValue")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed with array item in feed property value.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[ [] ]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_InvalidNodeTypeForItemsInResourceSet", "StartArray")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed with invalid property before the feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"other\":\"42\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_InvalidPropertyInTopLevelResourceSet", "other", JsonLightConstants.ODataValuePropertyName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed with invalid property annotation before the feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName("other", JsonLightConstants.ODataCountAnnotationName) + "\":\"42\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataCountAnnotationName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed with invalid property after the feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]," +
                                                           "\"other\":\"42\"" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_InvalidPropertyInTopLevelResourceSet", "other", JsonLightConstants.ODataValuePropertyName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed with invalid property annotation after the feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]," +
                                                           "\"" + JsonLightUtils.GetPropertyAnnotationName("other", JsonLightConstants.ODataCountAnnotationName) + "\":\"42\"" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataCountAnnotationName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed with missing feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataCountAnnotationName + "\":42" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_ExpectedResourceSetPropertyNotFound", "value")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Empty feed with odata.count annotation with null value before top-level feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataCountAnnotationName + "\":null," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataCountAnnotationName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Empty feed with odata.nextLink annotation with null value before top-level feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNextLinkAnnotationName + "\":null," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataNextLinkAnnotationName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Empty feed with odata.nextLink annotation with null value after top-level feed property.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]," +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNextLinkAnnotationName + "\":null" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataNextLinkAnnotationName)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Empty feed with duplicate feed properties.",
                    PayloadElement   = PayloadBuilder.EntitySet()
                                       .JsonRepresentation("{" +
                                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities\"," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]," +
                                                           "\"" + JsonLightConstants.ODataValuePropertyName + "\":[]" +
                                                           "}")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesNotAllowed", JsonLightConstants.ODataValuePropertyName)
                },
                #endregion Test cases
            };

            // TODO: all of the above for feeds in expanded navigation links

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
Beispiel #8
0
        public void SpatialPropertiesInEntryTest()
        {
            EdmModel model     = new EdmModel();
            var      container = new EdmEntityContainer("TestModel", "TestContainer");

            model.AddElement(container);

            var customerType = new EdmEntityType("TestModel", "CustomerType");

            customerType.AddKeys(customerType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            customerType.AddStructuralProperty("Location1", EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false));
            customerType.AddStructuralProperty("Location2", EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, false));
            model.AddElement(customerType);
            var customerSet = container.AddEntitySet("CustomerSet", customerType);

            ISpatial pointValue = GeographyFactory.Point(32.0, -100.0).Build();

            IEnumerable <EntryPayloadTestCase> testCases = new[]
            {
                new EntryPayloadTestCase
                {
                    DebugDescription = "Customer instance with spatial property (expected and payload type don't match).",
                    Entry            = new ODataEntry()
                    {
                        TypeName   = "TestModel.CustomerType",
                        Properties = new ODataProperty[]
                        {
                            new ODataProperty {
                                Name = "Location1", Value = pointValue
                            }
                        }
                    },
                    Model     = model,
                    EntitySet = customerSet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{0}" +
                                            "\"" + JsonLightUtils.GetPropertyAnnotationName("Location1", JsonLightConstants.ODataTypeAnnotationName) + "\":\"GeographyPoint\"," +
                                            "\"Location1\":{{",
                                            "\"type\":\"Point\",\"coordinates\":[",
                                            "-100.0,32.0",
                                            "],\"crs\":{{",
                                            "\"type\":\"name\",\"properties\":{{",
                                            "\"name\":\"EPSG:4326\"",
                                            "}}",
                                            "}}",
                                            "}}",
                                            "}}")
                },
                new EntryPayloadTestCase
                {
                    DebugDescription = "Customer instance with spatial property (expected and payload type match).",
                    Entry            = new ODataEntry()
                    {
                        TypeName   = "TestModel.CustomerType",
                        Properties = new ODataProperty[]
                        {
                            new ODataProperty {
                                Name = "Location2", Value = pointValue
                            }
                        }
                    },
                    Model     = model,
                    EntitySet = customerSet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{0}" +
                                            "\"Location2\":{{",
                                            "\"type\":\"Point\",\"coordinates\":[",
                                            "-100.0,32.0",
                                            "],\"crs\":{{",
                                            "\"type\":\"name\",\"properties\":{{",
                                            "\"name\":\"EPSG:4326\"",
                                            "}}",
                                            "}}",
                                            "}}",
                                            "}}")
                },
            };

            IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testDescriptors = testCases.Select(testCase =>
                                                                                                      new PayloadWriterTestDescriptor <ODataItem>(
                                                                                                          this.Settings,
                                                                                                          new ODataItem[] { testCase.Entry },
                                                                                                          tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
            {
                Json = string.Format(
                    CultureInfo.InvariantCulture,
                    testCase.Json,
                    JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ","),
                FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
            })
            {
                DebugDescription           = testCase.DebugDescription,
                Model                      = testCase.Model,
                PayloadEdmElementContainer = testCase.EntitySet,
                PayloadEdmElementType      = testCase.EntityType,
                SkipTestConfiguration      = testCase.SkipTestConfiguration
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
            {
                TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
            });
        }
        public void JsonLightTaupoSerializerEntryTest()
        {
            var testCases = new JsonLightSerializerTestCase[]
            {
                // Entry with only ID
                new JsonLightSerializerTestCase
                {
                    PayloadElement = PayloadBuilder.Entity()
                                     .PrimitiveProperty("ID", (long)42)
                                     .WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          ""ID"":42
                        }"
                },
                // Entry with ID and typename
                new JsonLightSerializerTestCase
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.Customer")
                                     .PrimitiveProperty("ID", (long)42)
                                     .WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.Customer"",
                          ""ID"":42
                        }"
                },
                // Entry with all metadata expanded
                new JsonLightSerializerTestCase
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CustomerWithImage")
                                     .Id("CustomerId")
                                     .ETag("etag")
                                     .WithEditLink("http://odata.org/editlink")
                                     .WithSelfLink("http://odata.org/readlink")
                                     .WithStreamContentType("image/jpg")
                                     .WithStreamEditLink("http://odata.org/streameditlink")
                                     .WithStreamSourceLink("http://odata.org/streamreadlink")
                                     .WithStreamETag("stream-etag")
                                     .PrimitiveProperty("ID", (long)42)
                                     .Operation(new ServiceOperationDescriptor {
                        IsAction = true, Metadata = "./metadata", Target = "http://odata.org/target", Title = "ActionTitle"
                    })
                                     .Operation(new ServiceOperationDescriptor {
                        IsAction = true, Metadata = "./metadata2", Target = "http://odata.org/target2", Title = "ActionTitle2"
                    })
                                     .Operation(new ServiceOperationDescriptor {
                        IsAction = false, Metadata = "./metadata", Target = "http://odata.org/target", Title = "ActionTitle"
                    })
                                     .Operation(new ServiceOperationDescriptor {
                        IsAction = false, Metadata = "./metadata", Target = "http://odata.org/target2", Title = "ActionTitle2"
                    })
                                     .WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.CustomerWithImage"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataIdAnnotationName + @""":""CustomerId"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataETagAnnotationName + @""":""etag"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataEditLinkAnnotationName + @""":""http://odata.org/editlink"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataReadLinkAnnotationName + @""":""http://odata.org/readlink"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaEditLinkAnnotationName + @""":""http://odata.org/streameditlink"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaReadLinkAnnotationName + @""":""http://odata.org/streamreadlink"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaContentTypeAnnotationName + @""":""image/jpg"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaETagAnnotationName + @""":""stream-etag"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataActionsAnnotationName + @""":{ ""./metadata"":[{ ""title"":""ActionTitle"", ""target"":""http://odata.org/target""}], ""./metadata2"":[{ ""title"":""ActionTitle2"", ""target"":""http://odata.org/target2""}]},
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataFunctionsAnnotationName + @""":{ ""./metadata"":[{ ""title"":""ActionTitle"", ""target"":""http://odata.org/target""}, { ""title"":""ActionTitle2"", ""target"":""http://odata.org/target2""}]},
                          ""ID"":42
                        }"
                },
                // Entry with deferred navigation and association properties
                new JsonLightSerializerTestCase
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.Customer")
                                     .PrimitiveProperty("ID", (long)42)
                                     .NavigationProperty("NavProp1", "http://odata.org/NavProp1", "http://odata.org/AssocProp1")
                                     .NavigationProperty("NavProp2", "http://odata.org/NavProp2")
                                     .NavigationProperty("NavProp3", null, "http://odata.org/AssocProp3")
                                     .WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.Customer"",
                          ""ID"":42,
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + @""":""http://odata.org/NavProp1"",
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp1", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + @""":""http://odata.org/AssocProp1"",
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp2", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + @""":""http://odata.org/NavProp2"",
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp3", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + @""":""http://odata.org/AssocProp3""
                        }"
                },
                // Entry with navigation link with expanded entry
                new JsonLightSerializerTestCase
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.Customer")
                                     .PrimitiveProperty("ID", (long)42)
                                     .ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.Order").PrimitiveProperty("ID", ((long)43)))
                                     .ExpandedNavigationProperty("NavProp2", PayloadBuilder.Entity("TestModel.Order").PrimitiveProperty("ID", ((long)43)), "http://odata.org/NavProp2")
                                     .ExpandedNavigationProperty("NavProp3", PayloadBuilder.Entity("TestModel.Order").PrimitiveProperty("ID", ((long)43)), new DeferredLink {
                        UriString = "http://odata.org/AssocProp3"
                    })
                                     .WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.Customer"",
                          ""ID"":42,
                          ""NavProp1"":{ """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.Order"",""ID"":43 },
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp2", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + @""":""http://odata.org/NavProp2"",
                          ""NavProp2"":{ """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.Order"",""ID"":43 },
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp3", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + @""":""http://odata.org/AssocProp3"",
                          ""NavProp3"":{ """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.Order"",""ID"":43 }
                        }"
                },
                // Entry with navigation link with expanded feed
                new JsonLightSerializerTestCase
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.Customer")
                                     .PrimitiveProperty("ID", (long)42)
                                     .ExpandedNavigationProperty("NavProp1", PayloadBuilder.EntitySet())
                                     .ExpandedNavigationProperty("NavProp2", PayloadBuilder.EntitySet(), "http://odata.org/NavProp2")
                                     .ExpandedNavigationProperty("NavProp3", PayloadBuilder.EntitySet(), new DeferredLink {
                        UriString = "http://odata.org/AssocProp3"
                    })
                                     .WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.Customer"",
                          ""ID"":42,
                          ""NavProp1"":[],
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp2", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + @""":""http://odata.org/NavProp2"",
                          ""NavProp2"":[],
                          """ + JsonLightUtils.GetPropertyAnnotationName("NavProp3", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + @""":""http://odata.org/AssocProp3"",
                          ""NavProp3"":[]
                        }"
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                (testCase) =>
            {
                PayloadFormatVersionAnnotatingVisitor.AnnotateJsonLight(testCase.PayloadElement, DataServiceProtocolVersion.Unspecified, false);
                JsonValue actualValue   = this.JsonLightSerializer.ConvertToJsonLightValue(testCase.PayloadElement);
                JsonValue expectedValue = JsonTextPreservingParser.ParseValue(new StringReader(testCase.ExpectedJson));

                this.JsonValueComparer.Compare(expectedValue, actualValue);
            });
        }
Beispiel #10
0
        public void ActionAndFunctionPayloadOrderTest()
        {
            EdmModel model     = new EdmModel();
            var      container = new EdmEntityContainer("TestModel", "TestContainer");

            model.AddElement(container);

            var otherType = new EdmEntityType("TestModel", "OtherType");

            otherType.AddKeys(otherType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(otherType);
            container.AddEntitySet("OtherType", otherType);

            var nonMLEBaseType = new EdmEntityType("TestModel", "NonMLEBaseType");

            nonMLEBaseType.AddKeys(nonMLEBaseType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(nonMLEBaseType);
            var nonMLESet = container.AddEntitySet("NonMLESet", nonMLEBaseType);

            var nonMLEType = new EdmEntityType("TestModel", "NonMLEType", nonMLEBaseType);

            nonMLEType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
            nonMLEType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo {
                Name = "NavProp", Target = otherType, TargetMultiplicity = EdmMultiplicity.Many
            });
            model.AddElement(nonMLEType);
            container.AddEntitySet("NonMLEType", nonMLEType);

            ODataAction action = new ODataAction
            {
                Metadata = new Uri("http://odata.org/test/$metadata#defaultAction"),
                Title    = "Default Action",
                Target   = new Uri("http://www.odata.org/defaultAction"),
            };

            ODataFunction function = new ODataFunction
            {
                Metadata = new Uri("http://odata.org/test/$metadata#defaultFunction()"),
                Title    = "Default Function",
                Target   = new Uri("defaultFunctionTarget", UriKind.Relative)
            };

            string defaultJson = string.Join("$(NL)",
                                             "{{",
                                             "{1}" +
                                             "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"#TestModel.NonMLEType\"{0},\"#defaultAction\":{{",
                                             "\"title\":\"Default Action\",\"target\":\"http://www.odata.org/defaultAction\"",
                                             "}},\"#defaultFunction()\":{{",
                                             "\"title\":\"Default Function\",\"target\":\"defaultFunctionTarget\"",
                                             "}}",
                                             "}}");

            var entryWithActionAndFunction = new ODataEntry()
            {
                TypeName = "TestModel.NonMLEType",
            };

            entryWithActionAndFunction.AddAction(action);
            entryWithActionAndFunction.AddFunction(function);
            IEnumerable <EntryPayloadTestCase> testCases = new[]
            {
                new EntryPayloadTestCase
                {
                    DebugDescription = "Functions and actions available at the beginning.",
                    Entry            = entryWithActionAndFunction,
                    Model            = model,
                    EntitySet        = nonMLESet,
                    Json             = defaultJson
                },
            };

            IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testDescriptors = testCases.Select(testCase =>
                                                                                                      new PayloadWriterTestDescriptor <ODataItem>(
                                                                                                          this.Settings,
                                                                                                          new ODataItem[] { testCase.Entry },
                                                                                                          tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
            {
                Json = string.Format(CultureInfo.InvariantCulture, testCase.Json,
                                     string.Empty,
                                     tc.IsRequest ? string.Empty : (JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ",")),
                FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
            })
            {
                DebugDescription           = testCase.DebugDescription,
                Model                      = testCase.Model,
                PayloadEdmElementContainer = testCase.EntitySet,
                PayloadEdmElementType      = testCase.EntityType,
                SkipTestConfiguration      = testCase.SkipTestConfiguration
            });

            testDescriptors = testDescriptors.Concat(testCases.Select(testCase =>
                                                                      new PayloadWriterTestDescriptor <ODataItem>(
                                                                          this.Settings,
                                                                          new ODataItem[] { testCase.Entry, new ODataNavigationLink
                                                                                            {
                                                                                                Name         = "NavProp",
                                                                                                IsCollection = true,
                                                                                                Url          = new Uri("http://odata.org/navprop/uri")
                                                                                            } },
                                                                          tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
            {
                Json = string.Format(CultureInfo.InvariantCulture, testCase.Json,
                                     tc.IsRequest ?
                                     ",\"NavProp\":[$(NL){$(NL)\"__metadata\":{$(NL)\"uri\":\"http://odata.org/navprop/uri\"$(NL)}$(NL)}$(NL)]" :
                                     ",\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navprop/uri\"",
                                     tc.IsRequest ? string.Empty : (JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ",")),
                FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
            })
            {
                DebugDescription           = testCase.DebugDescription + "- with navigation property",
                Model                      = testCase.Model,
                PayloadEdmElementContainer = testCase.EntitySet,
                PayloadEdmElementType      = testCase.EntityType,
                SkipTestConfiguration      = testCase.SkipTestConfiguration
            }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                // Actions/functions are only supported in responses.
                this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent.Where(tc => !tc.IsRequest),
                (testDescriptor, testConfiguration) =>
            {
                TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor.DeferredLinksToEntityReferenceLinksInRequest(testConfiguration), testConfiguration, this.Assert, this.Logger);
            });
        }
Beispiel #11
0
        public void PayloadOrderTest()
        {
            EdmModel model     = new EdmModel();
            var      container = new EdmEntityContainer("TestModel", "DefaultContainer");

            model.AddElement(container);

            var otherType = new EdmEntityType("TestModel", "OtherType");

            otherType.AddKeys(otherType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(otherType);
            var otherset = container.AddEntitySet("OtherType", otherType);

            var nonMLEBaseType = new EdmEntityType("TestModel", "NonMLEBaseType");

            nonMLEBaseType.AddKeys(nonMLEBaseType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(nonMLEBaseType);
            var nonMLESet = container.AddEntitySet("NonMLESet", nonMLEBaseType);

            var nonMLEType = new EdmEntityType("TestModel", "NonMLEType", nonMLEBaseType);

            nonMLEType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
            nonMLEType.AddStructuralProperty("Description", EdmCoreModel.Instance.GetString(true));
            nonMLEType.AddStructuralProperty("StreamProperty", EdmPrimitiveTypeKind.Stream, isNullable: false);
            var nonMLENav = nonMLEType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo {
                Name = "NavProp", Target = otherType, TargetMultiplicity = EdmMultiplicity.Many
            });

            nonMLESet.AddNavigationTarget(nonMLENav, otherset);
            model.AddElement(nonMLEType);

            var mleBaseType = new EdmEntityType("TestModel", "MLEBaseType");

            mleBaseType.AddKeys(mleBaseType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(mleBaseType);
            var mleSet = container.AddEntitySet("MLESet", mleBaseType);

            var mleType = new EdmEntityType("TestModel", "MLEType", mleBaseType, false, false, true);

            mleType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
            mleType.AddStructuralProperty("Description", EdmCoreModel.Instance.GetString(true));
            mleType.AddStructuralProperty("StreamProperty", EdmPrimitiveTypeKind.Stream, isNullable: false);
            var mleNav = mleType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo {
                Name = "NavProp", Target = otherType, TargetMultiplicity = EdmMultiplicity.Many
            });

            mleSet.AddNavigationTarget(mleNav, otherset);
            model.AddElement(mleType);

            IEnumerable <EntryPayloadTestCase> testCases = new[]
            {
                new EntryPayloadTestCase
                {
                    DebugDescription = "TypeName at the beginning, nothing else",
                    Entry            = new ODataEntry()
                    {
                        TypeName = "TestModel.NonMLEType"
                    },
                    Model     = model,
                    EntitySet = nonMLESet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{1}" +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.NonMLEType\"{0}",
                                            "}}")
                },
                new EntryPayloadTestCase
                {
                    DebugDescription = "TypeName at the beginning, changes at the end - the one from the beginning is used (also for validation).",
                    Entry            = new ODataEntry()
                    {
                        MediaResource = new ODataStreamReferenceValue(),
                        Properties    = new []
                        {
                            new ODataProperty {
                                Name = "ID", Value = (int)42
                            },
                            new ODataProperty {
                                Name = "Name", Value = "test"
                            },
                        }
                    }
                    .WithAnnotation(new WriteEntryCallbacksAnnotation
                    {
                        BeforeWriteStartCallback = (entry) => { entry.TypeName = "TestModel.MLEType"; },
                        BeforeWriteEndCallback   = (entry) => { entry.TypeName = "NonExistingType"; }
                    }),
                    Model     = model,
                    EntitySet = mleSet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{1}" +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.MLEType\"{0},\"ID\":\"42\",\"Name\":\"test\"",
                                            "}}")
                },
                new EntryPayloadTestCase
                {
                    DebugDescription = "TypeName, ID and ETag at the beginning, nothing else",
                    Entry            = new ODataEntry()
                    {
                        TypeName = "TestModel.NonMLEType", Id = new Uri("urn:id"), ETag = "etag"
                    },
                    Model     = model,
                    EntitySet = nonMLESet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{1}" +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.NonMLEType\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataIdAnnotationName + "\":\"urn:id\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataETagAnnotationName + "\":\"etag\"{0}",
                                            "}}")
                },
                new EntryPayloadTestCase
                {
                    DebugDescription = "TypeName at the beginning, ID and ETag at the end, ID and ETag are not written and are ignored at the end",
                    Entry            = new ODataEntry()
                    {
                        TypeName = "TestModel.NonMLEType"
                    }
                    .WithAnnotation(new WriteEntryCallbacksAnnotation
                    {
                        BeforeWriteStartCallback = (entry) => { entry.Id = null; entry.ETag = null; },
                        BeforeWriteEndCallback   = (entry) => { entry.Id = new Uri("urn:id"); entry.ETag = "etag"; }
                    }),
                    Model     = model,
                    EntitySet = nonMLESet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{1}" +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.NonMLEType\"{0}",
                                            "}}")
                },
                new EntryPayloadTestCase
                {
                    DebugDescription = "Everything at the beginning",
                    Entry            = new ODataEntry()
                    {
                        TypeName      = "TestModel.MLEType",
                        Id            = new Uri("urn:id"),
                        ETag          = "etag",
                        EditLink      = new Uri("http://odata.org/editlink"),
                        ReadLink      = new Uri("http://odata.org/readlink"),
                        MediaResource = new ODataStreamReferenceValue()
                        {
                            EditLink    = new Uri("http://odata.org/mediaeditlink"),
                            ReadLink    = new Uri("http://odata.org/mediareadlink"),
                            ETag        = "mediaetag",
                            ContentType = "media/contenttype"
                        },
                        Properties = new []
                        {
                            new ODataProperty {
                                Name = "ID", Value = (int)42
                            },
                            new ODataProperty {
                                Name = "Name", Value = "test"
                            },
                        }
                    },
                    Model     = model,
                    EntitySet = mleSet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{1}" +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.MLEType\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataIdAnnotationName + "\":\"urn:id\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataETagAnnotationName + "\":\"etag\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataEditLinkAnnotationName + "\":\"http://odata.org/editlink\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataReadLinkAnnotationName + "\":\"http://odata.org/readlink\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaEditLinkAnnotationName + "\":\"http://odata.org/mediaeditlink\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaReadLinkAnnotationName + "\":\"http://odata.org/mediareadlink\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaContentTypeAnnotationName + "\":\"media/contenttype\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaETagAnnotationName + "\":\"mediaetag\"{0}," +
                                            "\"ID\":\"42\"," +
                                            "\"Name\":\"test\"",
                                            "}}")
                },
                new EntryPayloadTestCase
                {
                    DebugDescription = "TypeName, Id, ETag and ReadLinks at the beginning, the rest at the end",
                    Entry            = new ODataEntry()
                    {
                        TypeName      = "TestModel.MLEType",
                        Id            = new Uri("urn:id"),
                        ETag          = "etag",
                        ReadLink      = new Uri("http://odata.org/readlink"),
                        MediaResource = new ODataStreamReferenceValue()
                        {
                            ReadLink = new Uri("http://odata.org/mediareadlink")
                        },
                        Properties = new []
                        {
                            new ODataProperty {
                                Name = "ID", Value = (int)42
                            },
                            new ODataProperty {
                                Name = "Name", Value = "test"
                            },
                        }
                    }.WithAnnotation(new WriteEntryCallbacksAnnotation
                    {
                        BeforeWriteStartCallback = (entry) =>
                        {
                            entry.EditLink = null;
                            entry.MediaResource.EditLink    = null;
                            entry.MediaResource.ETag        = null;
                            entry.MediaResource.ContentType = null;
                        },
                        BeforeWriteEndCallback = (entry) =>
                        {
                            entry.EditLink = new Uri("http://odata.org/editlink");
                            entry.MediaResource.EditLink    = new Uri("http://odata.org/mediaeditlink");
                            entry.MediaResource.ETag        = "mediaetag";
                            entry.MediaResource.ContentType = "media/contenttype";
                        }
                    }),
                    Model     = model,
                    EntitySet = mleSet,
                    Json      = string.Join("$(NL)",
                                            "{{",
                                            "{1}" +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.MLEType\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataIdAnnotationName + "\":\"urn:id\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataETagAnnotationName + "\":\"etag\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataReadLinkAnnotationName + "\":\"http://odata.org/readlink\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaReadLinkAnnotationName + "\":\"http://odata.org/mediareadlink\"{0}," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataEditLinkAnnotationName + "\":\"http://odata.org/editlink\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaEditLinkAnnotationName + "\":\"http://odata.org/mediaeditlink\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaContentTypeAnnotationName + "\":\"media/contenttype\"," +
                                            "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataMediaETagAnnotationName + "\":\"mediaetag\"," +
                                            "\"ID\":\"42\"," +
                                            "\"Name\":\"test\"",
                                            "}}")
                },
            };

            IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testDescriptors = testCases.Select(testCase =>
                                                                                                      new PayloadWriterTestDescriptor <ODataItem>(
                                                                                                          this.Settings,
                                                                                                          new ODataItem[] { testCase.Entry },
                                                                                                          tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
            {
                Json = string.Format(CultureInfo.InvariantCulture, testCase.Json,
                                     string.Empty,
                                     JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ","),
                FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
            })
            {
                DebugDescription           = testCase.DebugDescription,
                Model                      = testCase.Model,
                PayloadEdmElementContainer = testCase.EntitySet,
                PayloadEdmElementType      = testCase.EntityType,
                SkipTestConfiguration      = testCase.SkipTestConfiguration
            });

            testDescriptors = testDescriptors.Concat(testCases.Select(testCase =>
                                                                      new PayloadWriterTestDescriptor <ODataItem>(
                                                                          this.Settings,
                                                                          new ODataItem[] { testCase.Entry, new ODataNavigationLink
                                                                                            {
                                                                                                Name         = "NavProp",
                                                                                                IsCollection = true,
                                                                                                Url          = new Uri("http://odata.org/navprop/uri")
                                                                                            } },
                                                                          tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
            {
                Json = string.Format(CultureInfo.InvariantCulture, testCase.Json,
                                     tc.IsRequest ?
                                     ",\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp", JsonLightConstants.ODataBindAnnotationName) + "\":[$(NL)\"http://odata.org/navprop/uri\"$(NL)]" :
                                     ",\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navprop/uri\"",
                                     JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ","),
                FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
            })
            {
                DebugDescription           = testCase.DebugDescription + "- with navigation property",
                Model                      = testCase.Model,
                PayloadEdmElementContainer = testCase.EntitySet,
                PayloadEdmElementType      = testCase.EntityType,
                SkipTestConfiguration      = testCase.SkipTestConfiguration
            }))
                              .Concat(testCases.Select(testCase =>
                                                       new PayloadWriterTestDescriptor <ODataItem>(
                                                           this.Settings,
                                                           new ODataItem[] { testCase.Entry, new ODataNavigationLink
                                                                             {
                                                                                 Name               = "NavProp",
                                                                                 IsCollection       = true,
                                                                                 Url                = new Uri("http://odata.org/navprop/uri"),
                                                                                 AssociationLinkUrl = new Uri("http://odata.org/assoclink")
                                                                             } },
                                                           tc => new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
            {
                Json = string.Format(CultureInfo.InvariantCulture, testCase.Json,
                                     tc.IsRequest ?
                                     ",\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp", JsonLightConstants.ODataBindAnnotationName) + "\":[$(NL)\"http://odata.org/navprop/uri\"$(NL)]" :
                                     ",\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navprop/uri\"" +
                                     ",\"" + JsonLightUtils.GetPropertyAnnotationName("NavProp", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/assoclink\"",
                                     JsonLightWriterUtils.GetMetadataUrlPropertyForEntry(testCase.EntitySet.Name) + ","),
                FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
            })
            {
                DebugDescription           = testCase.DebugDescription + "- with navigation property",
                Model                      = testCase.Model,
                PayloadEdmElementContainer = testCase.EntitySet,
                PayloadEdmElementType      = testCase.EntityType,
                SkipTestConfiguration      = testCase.SkipTestConfiguration
            }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
            {
                TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor.DeferredLinksToEntityReferenceLinksInRequest(testConfiguration), testConfiguration, this.Assert, this.Logger);
            });
        }
Beispiel #12
0
        public void UndeclaredNavigationLinkTests()
        {
            IEdmModel model = TestModels.BuildTestModel();

            IEnumerable <UndeclaredPropertyTestCase> testCases = new[]
            {
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just navigation link",
                    Json             = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"",
                    IsLink           = true,
                    ExpectedEntity   = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just association link",
                    Json             = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink           = true,
                    ExpectedEntity   = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", null, "http://odata.org/associationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Navigation and association link",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink         = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink", "http://odata.org/associationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Navigation and association link with custom annotation",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation") + "\":null," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink         = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink", "http://odata.org/associationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Navigation link with another odata.type annotation - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.OfficeType\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"",
                    IsLink            = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_UnexpectedDeferredLinkPropertyAnnotation", "UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Association link with another odata.mediaEditLink annotation - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink            = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_UnexpectedDeferredLinkPropertyAnnotation", "UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded feed navigation link",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"UndeclaredProperty\":[]",
                    IsLink         = true,
                    IsValue        = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink"),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded entry navigation link",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"," +
                        "\"UndeclaredProperty\":{}",
                    IsLink         = true,
                    IsValue        = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", null, "http://odata.org/associationlink"),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded null entry navigation link",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"," +
                        "\"UndeclaredProperty\":null",
                    IsLink         = true,
                    IsValue        = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink", "http://odata.org/associationlink"),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded navigation link with wrong value",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"UndeclaredProperty\":42",
                    IsLink            = true,
                    IsValue           = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_CannotReadNestedResource", "UndeclaredProperty")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                new[] { false, true },
                // Undeclared properties are only allowed in responses
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                (testCase, throwOnUndeclaredPropertyForNonOpenType, testConfiguration) =>
            {
                PayloadReaderTestDescriptor testDescriptor = testCase.ToTestDescriptor(this.Settings, model, throwOnUndeclaredPropertyForNonOpenType);
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                if (!throwOnUndeclaredPropertyForNonOpenType)
                {
                    testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;
                }

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
Beispiel #13
0
        public void UndeclaredStreamPropertyTests()
        {
            IEdmModel model = TestModels.BuildTestModel();

            IEnumerable <UndeclaredPropertyTestCase> testCases = new[]
            {
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just edit link",
                    Json             = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"",
                    IsLink           = true,
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", null, "http://odata.org/mediaeditlink", null, null)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just read link",
                    Json             = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/mediareadlink\"",
                    IsLink           = true,
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", "http://odata.org/mediareadlink", null, null, null)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just content type",
                    Json             = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"media/contenttype\"",
                    IsLink           = true,
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", null, null, "media/contenttype", null)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just ETag",
                    Json             = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"etag\"",
                    IsLink           = true,
                    ExpectedEntity   = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", null, null, null, "etag")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Everything",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/mediareadlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"media/contenttype\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"etag\"",
                    IsLink         = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", "http://odata.org/mediareadlink", "http://odata.org/mediaeditlink", "media/contenttype", "etag")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Everything with custom annotations",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/mediareadlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation") + "\":\"value\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"media/contenttype\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"etag\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation2") + "\":42",
                    IsLink         = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", "http://odata.org/mediareadlink", "http://odata.org/mediaeditlink", "media/contenttype", "etag")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Stream property with odata.type annotation",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.Stream\"",
                    IsLink            = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_UnexpectedStreamPropertyAnnotation", "UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Stream property with a value",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"UndeclaredProperty\":null",
                    IsLink            = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_StreamPropertyWithValue", "UndeclaredProperty")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                new[] { false, true },
                // Undeclared properties are only allowed in responses
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                (testCase, throwOnUndeclaredPropertyForNonOpenType, testConfiguration) =>
            {
                var settings = testConfiguration.Format == ODataFormat.Json ? this.JsonLightSettings : this.Settings;
                PayloadReaderTestDescriptor testDescriptor = testCase.ToTestDescriptor(settings, model, throwOnUndeclaredPropertyForNonOpenType);
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                if (!throwOnUndeclaredPropertyForNonOpenType)
                {
                    testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;
                }

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
Beispiel #14
0
        public void ComplexValueTest()
        {
            var injectedProperties = new[]
            {
                new
                {
                    InjectedJSON      = string.Empty,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown\": { }",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\": { }",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataContextAnnotationName)
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null, \"@custom.annotation\": 42",
                    ExpectedException = (ExpectedException)null
                },
            };

            var payloads = new[]
            {
                new
                {
                    Json          = "{0}",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true)
                },
                new
                {
                    Json          = "{0}{1} \"Name\": \"Value\"",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType")
                                    .PrimitiveProperty("Name", "Value").IsComplex(true)
                },
                new
                {
                    Json          = "\"Name\": \"Value\"{1}{0}",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType")
                                    .PrimitiveProperty("Name", "Value").IsComplex(true)
                },
                new
                {
                    Json          = "\"Name\":\"Value\",{0}{1}\"City\":\"Redmond\"",
                    ExpectedValue = PayloadBuilder.Entity("TestModel.ComplexType")
                                    .PrimitiveProperty("Name", "Value")
                                    .PrimitiveProperty("City", "Redmond")
                                    .IsComplex(true)
                },
            };

            EdmModel model = new EdmModel();

            var addressType = new EdmComplexType("TestModel", "Address");

            addressType.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(isNullable: false));

            var complexType = new EdmComplexType("TestModel", "ComplexType");

            complexType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(isNullable: false));
            complexType.AddStructuralProperty("City", EdmCoreModel.Instance.GetString(isNullable: false));
            complexType.AddStructuralProperty("Address", new EdmComplexTypeReference(addressType, isNullable: false));
            complexType.AddStructuralProperty("Location", EdmPrimitiveTypeKind.GeographyPoint);

            var owningType = new EdmEntityType("TestModel", "OwningType");

            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(isNullable: false)));
            owningType.AddStructuralProperty("TopLevelProperty", new EdmComplexTypeReference(complexType, isNullable: true));
            model.AddElement(owningType);
            model.AddElement(addressType);
            model.AddElement(complexType);

            var container = new EdmEntityContainer("TestModel", "DefaultContainer");

            container.AddEntitySet("OwningType", owningType);
            model.AddElement(container);

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = payloads.SelectMany(payload => injectedProperties.Select(injectedProperty =>
            {
                var json = string.Format(payload.Json, injectedProperty.InjectedJSON, string.IsNullOrEmpty(injectedProperty.InjectedJSON) ? string.Empty : ",");
                json     = string.Format("{{{0}{1}{2}}}",
                                         "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.ComplexType\"",
                                         string.IsNullOrEmpty(json) ? string.Empty : ",", json);
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadKind = ODataPayloadKind.Resource,
                    PayloadElement = payload.ExpectedValue.DeepCopy()
                                     .JsonRepresentation(json)
                                     // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                     .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                                     .ExpectedEntityType(complexType),
                    PayloadEdmModel = model,
                    ExpectedException = injectedProperty.ExpectedException,
                    ExpectedResultPayloadElement = tc => tc.IsRequest
                        ? payload.ExpectedValue
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }).IsComplex(true)
                        : payload.ExpectedValue
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }).IsComplex(true)
                });
            }));

            var explicitPayloadsForPrimitiveAndArray = new[]
            {
                new
                {
                    Description       = "Primitive value as complex - should fail.",
                    Json              = "42",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "PrimitiveValue")
                },
                new
                {
                    Description       = "Array value as complex - should fail.",
                    Json              = "[]",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "StartArray")
                },
            };

            testDescriptors = testDescriptors.Concat(explicitPayloadsForPrimitiveAndArray.Select(payload =>
            {
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = payload.ExpectedPayload.DeepCopy()
                                     .JsonRepresentation(payload.Json)
                                     // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                     .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                                     .ExpectedEntityType(complexType),
                    PayloadEdmModel = model,
                    ExpectedException = payload.ExpectedException,
                    DebugDescription = payload.Description,
                    ExpectedResultPayloadElement = tc => payload.ExpectedPayload.DeepCopy()
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                });
            }));

            var explicitPayloads = new[]
            {
                new
                {
                    Description = "Type annotation preceded by custom annotation - should fail",
                    Json        = "\"@custom.annotation\": null," +
                                  "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\": \"TestModel.ComplexType\"," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_ResourceTypeAnnotationNotFirst")
                },
                new
                {
                    Description = "Custom property annotation - should be ignored.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": null," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload = PayloadBuilder.Entity("TestModel.ComplexType")
                                      .PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Duplicate custom property annotation - should not fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": null," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": 42," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload = PayloadBuilder.Entity("TestModel.ComplexType")
                                      .PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Unrecognized odata property annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown") + "\": null," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Custom property annotation after the property - should fail.",
                    Json        = "\"Name\": \"Value\"," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", "custom.annotation") + "\": null",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("PropertyAnnotationAfterTheProperty", "custom.annotation", "Name")
                },
                new
                {
                    Description = "OData property annotation.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\": \"Edm.String\"," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload = PayloadBuilder.Entity("TestModel.ComplexType")
                                      .PrimitiveProperty("Name", "Value").IsComplex(true),
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    Description = "Duplicate odata property annotation.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\": \"Edm.Int32\"," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\": \"Edm.String\"," +
                                  "\"Name\": \"Value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicateAnnotationForPropertyNotAllowed", JsonLightConstants.ODataTypeAnnotationName, "Name")
                },
                new
                {
                    Description = "Property with object value and type name annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Address", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.Address\"," +
                                  "\"Address\":{}",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ComplexValueWithPropertyTypeAnnotation", JsonLightConstants.ODataTypeAnnotationName)
                },
                new
                {
                    Description = "String property with type annotation after the property - should fail.",
                    Json        = "\"Name\":\"value\"," +
                                  "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.String\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("PropertyAnnotationAfterTheProperty", JsonLightConstants.ODataTypeAnnotationName, "Name")
                },
                new
                {
                    Description = "String property with null type annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\":null," +
                                  "\"Name\":\"value\"",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_InvalidTypeName", string.Empty)
                },
                new
                {
                    Description = "null property with unknown type annotation - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Name", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Unknown\"," +
                                  "\"Name\":null",
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Unknown", "Primitive", "Complex"),
                },
                new
                {
                    Description       = "Spatial property with odata.type annotation inside the GeoJson object - should fail.",
                    Json              = "\"Location\":" + SpatialUtils.GetSpatialStringValue(ODataFormat.Json, GeographyFactory.Point(33.1, -110.0).Build(), "Edm.GeographyPoint"),
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ODataTypeAnnotationInPrimitiveValue", JsonLightConstants.ODataTypeAnnotationName),
                },
                new
                {
                    Description = "Spatial property with odata.type annotation inside and outside the GeoJson object - should fail.",
                    Json        = "\"" + JsonLightUtils.GetPropertyAnnotationName("Location", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.GeographyPoint\"," +
                                  "\"Location\":" + SpatialUtils.GetSpatialStringValue(ODataFormat.Json, GeographyFactory.Point(33.1, -110.0).Build(), "Edm.GeographyPoint"),
                    ExpectedPayload   = PayloadBuilder.Entity("TestModel.ComplexType").IsComplex(true),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_ODataTypeAnnotationInPrimitiveValue", JsonLightConstants.ODataTypeAnnotationName),
                },
            };

            testDescriptors = testDescriptors.Concat(explicitPayloads.Select(payload =>
            {
                var json = string.Format("{{{0}{1}{2}}}",
                                         "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.ComplexType\"",
                                         string.IsNullOrEmpty(payload.Json) ? string.Empty : ",", payload.Json);
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = payload.ExpectedPayload.DeepCopy()
                                     .JsonRepresentation(json)
                                     // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                     .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                                     .ExpectedEntityType(complexType),
                    PayloadEdmModel = model,
                    ExpectedException = payload.ExpectedException,
                    DebugDescription = payload.Description,
                    ExpectedResultPayloadElement = tc => payload.ExpectedPayload.DeepCopy()
                                                   .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })
                });
            }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
Beispiel #15
0
        public void CollectionNavigationLinkInRequestTest()
        {
            IEnumerable <NavigationLinkTestCase> testCases = new[]
            {
                new NavigationLinkTestCase
                {
                    DebugDescription           = "Just binding links - one",
                    Json                       = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[\"http://odata.org/referencelink1\"]",
                    ExpectedEntity             = PayloadBuilder.Entity().NavigationProperty("CityHall", "http://odata.org/referencelink1"),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Just binding links - multiple",
                    Json             = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[" +
                                       "\"http://odata.org/referencelink1\"," +
                                       "\"http://odata.org/referencelink2\"," +
                                       "\"http://odata.org/referencelink3\"]",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new LinkCollection(
                                                                                                         PayloadBuilder.DeferredLink("http://odata.org/referencelink1"),
                                                                                                         PayloadBuilder.DeferredLink("http://odata.org/referencelink2"),
                                                                                                         PayloadBuilder.DeferredLink("http://odata.org/referencelink3")))),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Empty binding array - invalid",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[]",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_EmptyBindArray", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding annotation value - object",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":{}",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding annotation value - null",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":null",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding annotation value - number",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":42",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_CannotReadPropertyValueAsString", "42", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding annotation value - string - we need array for collection nav. prop.",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/referencelink1\"",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_StringValueForCollectionBindPropertyAnnotation", "CityHall", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding item value - object",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[{}]",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding item value - array",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[[]]",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding item value - null",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[null]",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Invalid binding item value - number",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[42]",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_CannotReadPropertyValueAsString", "42", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Binding links with custom annotation before",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", "custom.annotation") + "\":null," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[\"http://odata.org/referencelink1\"]",
                    ExpectedEntity             = PayloadBuilder.Entity().NavigationProperty("CityHall", "http://odata.org/referencelink1"),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Binding links with custom annotation after",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[\"http://odata.org/referencelink1\"]," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", "custom.annotation") + "\":null",
                    ExpectedEntity             = PayloadBuilder.Entity().NavigationProperty("CityHall", "http://odata.org/referencelink1"),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Collection navigation property with just custom annotation - invalid",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", "custom.annotation") + "\":null",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException(
                        "ODataJsonLightEntryAndFeedDeserializer_NavigationPropertyWithoutValueAndEntityReferenceLink",
                        "CityHall",
                        JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded feed - empty",
                    Json             = "\"CityHall\":[]",
                    ExpectedEntity   = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.EntitySet()
                    })),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded feed - one entry",
                    Json             = "\"CityHall\":[{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}]",
                    ExpectedEntity   = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.EntitySet()
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                    })),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded feed - multiple entries",
                    Json             =
                        "\"CityHall\":[" +
                        "{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}," +
                        "{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}," +
                        "{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}" +
                        "]",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.EntitySet()
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                    })),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded feed with custom annotation",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", "custom.annotation") + "\":null," +
                        "\"CityHall\":[{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}]",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.EntitySet()
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                    })),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded feed with next link before - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataNextLinkAnnotationName) + "\":\"http://odata.org/nextlink\"," +
                        "\"CityHall\":[{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}]",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException(
                        "ODataJsonLightEntryAndFeedDeserializer_UnexpectedNavigationLinkInRequestPropertyAnnotation",
                        "CityHall",
                        JsonLightConstants.ODataNextLinkAnnotationName,
                        JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded feed with next link after - should fail",
                    Json             =
                        "\"CityHall\":[{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}]," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataNextLinkAnnotationName) + "\":\"http://odata.org/nextlink\"",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedPropertyAnnotation", "CityHall", JsonLightConstants.ODataNextLinkAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded empty feed with binding link",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[\"http://odata.org/referencelink1\"]," +
                        "\"CityHall\":[]",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new LinkCollection(
                                                                                                         new DeferredLink()
                    {
                        UriString = "http://odata.org/referencelink1"
                    },
                                                                                                         new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.EntitySet()
                    }))),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded empty feed with binding links",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[" +
                        "\"http://odata.org/referencelink1\"," +
                        "\"http://odata.org/referencelink2\"," +
                        "\"http://odata.org/referencelink3\"" +
                        "]," +
                        "\"CityHall\":[]",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new LinkCollection(
                                                                                                         new DeferredLink()
                    {
                        UriString = "http://odata.org/referencelink1"
                    },
                                                                                                         new DeferredLink()
                    {
                        UriString = "http://odata.org/referencelink2"
                    },
                                                                                                         new DeferredLink()
                    {
                        UriString = "http://odata.org/referencelink3"
                    },
                                                                                                         new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.EntitySet()
                    }))),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded feed with multiple entries and multiple binding links",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("CityHall", JsonLightConstants.ODataBindAnnotationName) + "\":[" +
                        "\"http://odata.org/referencelink1\"," +
                        "\"http://odata.org/referencelink2\"," +
                        "\"http://odata.org/referencelink3\"" +
                        "]," +
                        "\"CityHall\":[" +
                        "{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}," +
                        "{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}," +
                        "{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}" +
                        "]",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("CityHall", new LinkCollection(
                                                                                                         new DeferredLink()
                    {
                        UriString = "http://odata.org/referencelink1"
                    },
                                                                                                         new DeferredLink()
                    {
                        UriString = "http://odata.org/referencelink2"
                    },
                                                                                                         new DeferredLink()
                    {
                        UriString = "http://odata.org/referencelink3"
                    },
                                                                                                         new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.EntitySet()
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                                          .Append(PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1))
                    }))),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "CityHall", true }
                    },
                },
            };

            this.RunNavigationLinkInRequestTest(testCases);
        }
        public void WriterStreamPropertiesTests()
        {
            Uri baseUri             = new Uri("http://www.odata.org/", UriKind.Absolute);
            Uri relativeReadLinkUri = new Uri("readlink", UriKind.RelativeOrAbsolute);
            Uri relativeEditLinkUri = new Uri("editlink", UriKind.RelativeOrAbsolute);
            Uri absoluteReadLinkUri = new Uri(baseUri, relativeReadLinkUri.OriginalString);
            Uri absoluteEditLinkUri = new Uri(baseUri, relativeEditLinkUri.OriginalString);

            string contentType        = "application/binary";
            string etag               = "\"myetagvalue\"";
            string streamPropertyName = "stream1";

            var namedStreamProperties = new[]
            {
                // with only read link
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = relativeReadLinkUri
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = relativeReadLinkUri, ContentType = contentType
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = absoluteReadLinkUri
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = absoluteReadLinkUri, ContentType = contentType
                    }
                },
                // with only edit link
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        EditLink = relativeEditLinkUri
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        EditLink = relativeEditLinkUri, ContentType = contentType
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        EditLink = relativeEditLinkUri, ContentType = contentType, ETag = etag
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        EditLink = absoluteEditLinkUri
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        EditLink = absoluteEditLinkUri, ContentType = contentType
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        EditLink = absoluteEditLinkUri, ContentType = contentType, ETag = etag
                    }
                },
                // with both edit and read link
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = relativeReadLinkUri, EditLink = relativeEditLinkUri
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = relativeReadLinkUri, EditLink = relativeEditLinkUri, ContentType = contentType
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = relativeReadLinkUri, EditLink = relativeEditLinkUri, ContentType = contentType, ETag = etag
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = absoluteReadLinkUri, EditLink = relativeEditLinkUri
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = absoluteReadLinkUri, EditLink = relativeEditLinkUri, ContentType = contentType
                    }
                },
                new ODataProperty {
                    Name = streamPropertyName, Value = new ODataStreamReferenceValue {
                        ReadLink = absoluteReadLinkUri, EditLink = relativeEditLinkUri, ContentType = contentType, ETag = etag
                    }
                },
            };

            var testCases = namedStreamProperties.Select(property =>
            {
                var propertyName         = property.Name;
                var streamReferenceValue = (ODataStreamReferenceValue)property.Value;
                return(new StreamPropertyTestCase
                {
                    NamedStreamProperty = property,
                    GetExpectedAtomPayload = (testConfiguration) =>
                    {
                        return
                        (streamReferenceValue.ReadLink == null
                                    ? string.Empty
                                    : (
                             "<link rel=\"http://docs.oasis-open.org/odata/ns/mediaresource/" + property.Name + "\" " +
                             (streamReferenceValue.ContentType == null ? string.Empty : "type=\"" + streamReferenceValue.ContentType + "\" ") +
                             "title=\"" + property.Name + "\" " +
                             "href=\"" + (((ODataStreamReferenceValue)property.Value).ReadLink.IsAbsoluteUri ? absoluteReadLinkUri.OriginalString : relativeReadLinkUri.OriginalString) + "\" " +
                             "xmlns=\"" + TestAtomConstants.AtomNamespace + "\" />")) +

                        (streamReferenceValue.EditLink == null
                                    ? string.Empty
                                    : (
                             "<link rel=\"http://docs.oasis-open.org/odata/ns/edit-media/" + property.Name + "\" " +
                             (streamReferenceValue.ContentType == null ? string.Empty : "type=\"" + streamReferenceValue.ContentType + "\" ") +
                             "title=\"" + property.Name + "\" " +
                             "href=\"" + (((ODataStreamReferenceValue)property.Value).EditLink.IsAbsoluteUri ? absoluteEditLinkUri.OriginalString : relativeEditLinkUri.OriginalString) + "\" " +
                             (streamReferenceValue.ETag == null ? string.Empty : "m:etag=\"" + streamReferenceValue.ETag.Replace("\"", "&quot;") + "\" xmlns:m=\"" + TestAtomConstants.ODataMetadataNamespace + "\" ") +
                             "xmlns=\"" + TestAtomConstants.AtomNamespace + "\" />"));
                    },
                    GetExpectedJsonLightPayload = (testConfiguration) =>
                    {
                        return JsonLightWriterUtils.CombineProperties(
                            (streamReferenceValue.EditLink == null ? string.Empty : ("\"" + JsonLightUtils.GetPropertyAnnotationName(propertyName, JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"" + absoluteEditLinkUri.OriginalString + "\"")),
                            (streamReferenceValue.ReadLink == null ? string.Empty : ("\"" + JsonLightUtils.GetPropertyAnnotationName(propertyName, JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"" + absoluteReadLinkUri.OriginalString + "\"")),
                            (streamReferenceValue.ContentType == null ? string.Empty : ("\"" + JsonLightUtils.GetPropertyAnnotationName(propertyName, JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"" + streamReferenceValue.ContentType + "\"")),
                            (streamReferenceValue.ETag == null ? string.Empty : ("\"" + JsonLightUtils.GetPropertyAnnotationName(propertyName, JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"" + streamReferenceValue.ETag.Replace("\"", "\\\"") + "\"")));
                    },
                });
            });

            var testDescriptors = testCases.SelectMany(testCase =>
            {
                EdmModel model = new EdmModel();

                EdmEntityType edmEntityType = new EdmEntityType("TestModel", "StreamPropertyEntityType");
                EdmStructuralProperty edmStructuralProperty = edmEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, false);
                edmEntityType.AddKeys(new IEdmStructuralProperty[] { edmStructuralProperty });
                model.AddElement(edmEntityType);

                EdmEntityContainer edmEntityContainer = new EdmEntityContainer("TestModel", "DefaultContainer");
                model.AddElement(edmEntityContainer);

                EdmEntitySet edmEntitySet = new EdmEntitySet(edmEntityContainer, "StreamPropertyEntitySet", edmEntityType);
                edmEntityContainer.AddElement(edmEntitySet);

                ODataEntry entry = new ODataEntry()
                {
                    Id       = ObjectModelUtils.DefaultEntryId,
                    ReadLink = ObjectModelUtils.DefaultEntryReadLink,
                    TypeName = edmEntityType.FullName()
                };

                var streamReference = (ODataStreamReferenceValue)testCase.NamedStreamProperty.Value;
                bool needBaseUri    = (streamReference.ReadLink != null && !streamReference.ReadLink.IsAbsoluteUri) || (streamReference.EditLink != null && !streamReference.EditLink.IsAbsoluteUri);
                entry.Properties    = new ODataProperty[] { testCase.NamedStreamProperty };

                var resultDescriptor = new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    entry,
                    (testConfiguration) =>
                {
                    if (testConfiguration.Format == ODataFormat.Atom)
                    {
                        return(new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Xml = "<NamedStream>" + testCase.GetExpectedAtomPayload(testConfiguration) + "</NamedStream>",
                            FragmentExtractor = result => result,
                        });
                    }
                    else if (testConfiguration.Format == ODataFormat.Json)
                    {
                        return(new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Json = string.Join(
                                "$(NL)",
                                "{",
                                testCase.GetExpectedJsonLightPayload(testConfiguration),
                                "}"),
                            FragmentExtractor = result => result.RemoveAllAnnotations(true),
                        });
                    }
                    else
                    {
                        throw new NotSupportedException("Unsupported ODataFormat found: " + testConfiguration.Format.ToString());
                    }
                })
                {
                    Model = model,
                    PayloadEdmElementContainer = edmEntityContainer,
                    PayloadEdmElementType      = edmEntityType,
                };

                var resultTestCases = new List <StreamPropertyTestDescriptor>();
                if (needBaseUri)
                {
                    resultTestCases.Add(new StreamPropertyTestDescriptor {
                        BaseUri = baseUri, TestDescriptor = resultDescriptor
                    });
                }
                else
                {
                    resultTestCases.Add(new StreamPropertyTestDescriptor {
                        BaseUri = null, TestDescriptor = resultDescriptor
                    });
                    resultTestCases.Add(new StreamPropertyTestDescriptor {
                        BaseUri = baseUri, TestDescriptor = resultDescriptor
                    });
                    resultTestCases.Add(new StreamPropertyTestDescriptor {
                        BaseUri = new Uri("http://mybaseuri/", UriKind.Absolute), TestDescriptor = resultDescriptor
                    });
                }

                return(resultTestCases);
            });

            var testDescriptorBaseUriPairSet = testDescriptors.SelectMany(descriptor =>
                                                                          WriterPayloads.NamedStreamPayloads(descriptor.TestDescriptor).Select(namedStreamPayload =>
                                                                                                                                               new Tuple <PayloadWriterTestDescriptor <ODataItem>, Uri>(namedStreamPayload, descriptor.BaseUri)));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptorBaseUriPairSet,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent,
                (testDescriptorBaseUriPair, testConfiguration) =>
            {
                var testDescriptor = testDescriptorBaseUriPair.Item1;

                if (testDescriptor.IsGeneratedPayload && testConfiguration.Format == ODataFormat.Json)
                {
                    return;
                }

                ODataMessageWriterSettings settings = testConfiguration.MessageWriterSettings.Clone();
                settings.PayloadBaseUri             = testDescriptorBaseUriPair.Item2;
                settings.SetServiceDocumentUri(ServiceDocumentUri);

                WriterTestConfiguration config =
                    new WriterTestConfiguration(testConfiguration.Format, settings, testConfiguration.IsRequest, testConfiguration.Synchronous);

                if (testConfiguration.IsRequest)
                {
                    ODataEntry payloadEntry           = (ODataEntry)testDescriptor.PayloadItems[0];
                    ODataProperty firstStreamProperty = payloadEntry.Properties.Where(p => p.Value is ODataStreamReferenceValue).FirstOrDefault();
                    this.Assert.IsNotNull(firstStreamProperty, "firstStreamProperty != null");

                    testDescriptor = new PayloadWriterTestDescriptor <ODataItem>(testDescriptor)
                    {
                        ExpectedResultCallback = tc => new WriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            ExpectedException2 = ODataExpectedExceptions.ODataException("WriterValidationUtils_StreamPropertyInRequest", firstStreamProperty.Name)
                        }
                    };
                }

                TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, config, this.Assert, this.Logger);
            });
        }
Beispiel #17
0
        public void SingletonNavigationLinkInRequestTest()
        {
            IEnumerable <NavigationLinkTestCase> testCases = new[]
            {
                new NavigationLinkTestCase
                {
                    DebugDescription           = "Just binding link",
                    Json                       = "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/referencelink1\"",
                    ExpectedEntity             = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "PoliceStation", false }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Binding link with invalid value - null",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":null",
                    ExpectedEntity    = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightReaderUtils_AnnotationWithNullValue", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Binding link with invalid value - number",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":42",
                    ExpectedEntity    = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_CannotReadPropertyValueAsString", "42", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Binding link with invalid value - array",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":[]",
                    ExpectedEntity    = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_EmptyBindArray", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Binding link with invalid value - array of strings",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":[\"http://odata.org/referencelink1\"]",
                    ExpectedEntity    = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_ArrayValueForSingletonBindPropertyAnnotation", "PoliceStation", JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Binding link with invalid value - object",
                    Json              = "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":{}",
                    ExpectedEntity    = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Binding link with custom annotation before",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", "custom.annotation") + "\":\"value\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/referencelink1\"",
                    ExpectedEntity             = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "PoliceStation", false }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Binding link with custom annotation after",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/referencelink1\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", "custom.annotation") + "\":\"value\"",
                    ExpectedEntity             = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "PoliceStation", false }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Just custom annotation - should fail - we need either expanded value or binding",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", "custom.annotation") + "\":\"value\"",
                    ExpectedEntity    = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedException = ODataExpectedExceptions.ODataException(
                        "ODataJsonLightEntryAndFeedDeserializer_NavigationPropertyWithoutValueAndEntityReferenceLink",
                        "PoliceStation",
                        JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Non-binding OData annotation on nav. prop - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.OfficeType\"",
                    ExpectedEntity    = PayloadBuilder.Entity().NavigationProperty("PoliceStation", "http://odata.org/referencelink1"),
                    ExpectedException = ODataExpectedExceptions.ODataException(
                        "ODataJsonLightEntryAndFeedDeserializer_UnexpectedNavigationLinkInRequestPropertyAnnotation",
                        "PoliceStation",
                        JsonLightConstants.ODataTypeAnnotationName,
                        JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded entry",
                    Json             = "\"PoliceStation\":{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}",
                    ExpectedEntity   = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("PoliceStation", new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1)
                    }, null)),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "PoliceStation", false }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded null entry",
                    Json             = "\"PoliceStation\":null",
                    ExpectedEntity   = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("PoliceStation", new ExpandedLink()
                    {
                        ExpandedElement = new EntityInstance(null, true)
                    }, null)),
                    ExpectedIsCollectionValues = new Dictionary <string, bool?> {
                        { "PoliceStation", false }
                    },
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Expanded singleton link with array value - invalid",
                    Json              = "\"PoliceStation\":[]",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_CannotReadSingletonNavigationPropertyValue", "StartArray", "PoliceStation"),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription  = "Expanded singleton link with number value - invalid",
                    Json              = "\"PoliceStation\":42",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_CannotReadNavigationPropertyValue", "PoliceStation"),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded entry with binding - invalid",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/referencelink1\"," +
                        "\"PoliceStation\":{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("PoliceStation", new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1)
                    }, null)),
                    ExpectedException = ODataExpectedExceptions.ODataException(
                        "ODataJsonLightEntryAndFeedDeserializer_SingletonNavigationPropertyWithBindingAndValue",
                        "PoliceStation",
                        JsonLightConstants.ODataBindAnnotationName),
                },
                new NavigationLinkTestCase
                {
                    DebugDescription = "Expanded entry with non-binding annotation - invalid",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("PoliceStation", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.OfficeType\"," +
                        "\"PoliceStation\":{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.OfficeType\", \"Id\":1}",
                    ExpectedEntity = PayloadBuilder.Entity().Property(new NavigationPropertyInstance("PoliceStation", new ExpandedLink()
                    {
                        ExpandedElement = PayloadBuilder.Entity("TestModel.OfficeType").PrimitiveProperty("Id", 1)
                    }, null)),
                    ExpectedException = ODataExpectedExceptions.ODataException(
                        "ODataJsonLightEntryAndFeedDeserializer_UnexpectedNavigationLinkInRequestPropertyAnnotation",
                        "PoliceStation",
                        JsonLightConstants.ODataTypeAnnotationName,
                        JsonLightConstants.ODataBindAnnotationName),
                },
            };

            this.RunNavigationLinkInRequestTest(testCases);
        }
        public void UndeclaredValuePropertyTests()
        {
            IEdmModel model = TestModels.BuildTestModel();

            IEnumerable <UndeclaredPropertyTestCase> testCases = new[]
            {
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number without type",
                    Json             = "\"UndeclaredProperty\":42",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity().PrimitiveProperty("UndeclaredProperty", 42),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "String without type",
                    Json             = "\"UndeclaredProperty\":\"value\"",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity().PrimitiveProperty("UndeclaredProperty", "value"),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "null without type",
                    Json             = "\"UndeclaredProperty\":null",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity().PrimitiveProperty("UndeclaredProperty", null),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Boolean without type",
                    Json             = "\"UndeclaredProperty\":false",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity().PrimitiveProperty("UndeclaredProperty", false),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number with type",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.Int16\"," +
                        "\"UndeclaredProperty\":42",
                    IsValue        = true,
                    ExpectedEntity = PayloadBuilder.Entity().PrimitiveProperty("UndeclaredProperty", (short)42),
                },

                // TODO read: Microsoft.OData.Core.ODataException: A type named 'TestModel.Unknown' could not be resolved by the model. When a model is available, each type name must resolve to a valid type.
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number with invalid type - should work, the type is ignored",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.Unknown\"," +
                        "\"UndeclaredProperty\":42",
                    IsValue           = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "TestModel.Unknown")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number with another odata annotation - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/reference\"," +
                        "\"UndeclaredProperty\":42",
                    IsValue           = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedDataPropertyAnnotation", "UndeclaredProperty", JsonLightConstants.ODataBindAnnotationName)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Property without value and with no recognized annotations - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation") + "\":\"value\"",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithUnknownType", "UndeclaredProperty")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Property without value and with known annotation - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/reference\"",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithUnknownType", "UndeclaredProperty")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                TestReaderUtils.ODataUndeclaredPropertyBehaviorKindsCombinations,
                // Undeclared properties are only allowed in responses
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                (testCase, undeclaredPropertyBehaviorKinds, testConfiguration) =>
            {
                PayloadReaderTestDescriptor testDescriptor = testCase.ToTestDescriptor(this.Settings, model, undeclaredPropertyBehaviorKinds);
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                testConfiguration.MessageReaderSettings.UndeclaredPropertyBehaviorKinds = undeclaredPropertyBehaviorKinds;

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }