public void CollectionWithHeterogenousItemsErrorTest()
        {
            EdmModel model = new EdmModel();

            var complexType1 = model.ComplexType("ComplexTypeWithStringAndInteger32")
                               .Property("Property1", EdmCoreModel.Instance.GetString(true) as EdmTypeReference)
                               .Property("Property2", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference);

            var complexType2 = model.ComplexType("ComplexTypeWithStringAndDateTime")
                               .Property("Property1", EdmCoreModel.Instance.GetString(true) as EdmTypeReference)
                               .Property("Property2", EdmPrimitiveTypeKind.DateTimeOffset);

            model.Fixup();

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Primitive collection containing items of different primitive types
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement         = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32")).Item(1).Item(true).Item(2).WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false))),
                    PayloadEdmModel        = model,
                    ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_CannotConvertPrimitiveValue", "True", "Edm.Int32")
                    }
                },
                // Complex collection containing items of different complex type (correct type attribute value)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName(complexType1.FullName()))
                                     .Item(PayloadBuilder.ComplexValue(complexType1.FullName()).PrimitiveProperty("Property1", "Foo").PrimitiveProperty("Property2", -1))
                                     .Item(PayloadBuilder.ComplexValue(complexType2.FullName()).PrimitiveProperty("Property1", "Foo").PrimitiveProperty("Property2", DateTimeOffset.Now))
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(complexType1.ToTypeReference())),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncompatibleType", "TestModel.ComplexTypeWithStringAndDateTime", "TestModel.ComplexTypeWithStringAndInteger32"),
                },
                // Complex collection containing items of different complex type (incorrect type attribute value)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName(complexType2.FullName()))
                                     .Item(PayloadBuilder.ComplexValue(complexType2.FullName()).PrimitiveProperty("Property1", "Foo").PrimitiveProperty("Property2", -1))
                                     .Item(PayloadBuilder.ComplexValue(complexType2.FullName()).PrimitiveProperty("Property1", "Foo").PrimitiveProperty("Property2", DateTimeOffset.Now))
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(complexType2.ToTypeReference())),
                    PayloadEdmModel        = model,
                    ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_CannotConvertPrimitiveValue", "-1", "Edm.DateTimeOffset")
                    }
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor = testDescriptor.InProperty("RootProperty");
                testDescriptor.RunTest(testConfiguration);
            });
        }
Exemple #2
0
        public void CollectionOfComplexInstanceTest()
        {
            EdmModel model       = new EdmModel();
            var      complexType = new EdmComplexType("TestModel", "ComplexType").Property("Name", EdmPrimitiveTypeKind.String, true);

            model.AddElement(complexType);
            var owningType = new EdmEntityType("TestModel", "OwningType");

            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            owningType.AddStructuralProperty("PrimitiveCollection", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)));
            owningType.AddStructuralProperty("ComplexCollection", EdmCoreModel.GetCollection(complexType.ToTypeReference()));
            model.AddElement(owningType);
            model.Fixup();

            var primitiveMultiValue = PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)").Item(42).Item(43);
            var complexMultiValue   = PayloadBuilder.EntitySet(new EntityInstance[]
            {
                PayloadBuilder.Entity("TestModel.ComplexType")
                .PrimitiveProperty("Name", "Value")
                .AddAnnotation(new SerializationTypeNameTestAnnotation()
                {
                    TypeName = null
                })
                .IsComplex(true)
            })
                                      .JsonRepresentation("[{\"Name\":\"Value\"}]")
                                      .AddAnnotation(new SerializationTypeNameTestAnnotation()
            {
                TypeName = null
            });

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Simple complex collection.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("ComplexCollection", complexMultiValue)
                                       .ExpectedProperty(owningType, "ComplexCollection"),
                    ExpectedResultPayloadElement = tc => tc.IsRequest
                        ? PayloadBuilder.Property(string.Empty, complexMultiValue)
                        : PayloadBuilder.Property("ComplexCollection", complexMultiValue)
                },
            };

            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);
            });
        }
        private IEnumerable <PayloadReaderTestDescriptor> CreateCollectionPayloadsWithMetadata(bool withTypeNames)
        {
            // Start with the standard set of collections
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreateCollectionTestDescriptors(this.Settings, withTypeNames);

            // Add collections with all of the primitive values (except null)
            testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreatePrimitiveValueTestDescriptors(this.Settings, false)
                                                     .Where(primitivePayload => ((PrimitiveValue)primitivePayload.PayloadElement).ClrValue != null)
                                                     .Select(primitivePayload =>
            {
                IEdmTypeReference edmType = primitivePayload.PayloadElement.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType;
                var primitiveCollection   = PayloadBuilder.PrimitiveMultiValue(withTypeNames ? EntityModelUtils.GetCollectionTypeName(edmType.FullName()) : null)
                                            .Item(((PrimitiveValue)primitivePayload.PayloadElement).ClrValue)
                                            .WithTypeAnnotation(EdmCoreModel.GetCollection(edmType));
                if (!withTypeNames)
                {
                    primitiveCollection.AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    });
                }
                return(new PayloadReaderTestDescriptor(primitivePayload)
                {
                    PayloadElement = primitiveCollection,
                });
            }));

            // Add collections with all of the complex values (except null)
            testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, withTypeNames, false)
                                                     .Where(complexPayload => !((ComplexInstance)complexPayload.PayloadElement).IsNull)
                                                     .Select(complexPayload =>
            {
                IEdmTypeReference edmComplexType = complexPayload.PayloadElement.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType;
                var complexCollection            = PayloadBuilder.ComplexMultiValue(withTypeNames ? EntityModelUtils.GetCollectionTypeName(edmComplexType.FullName()) : null)
                                                   .Item((ComplexInstance)complexPayload.PayloadElement)
                                                   .WithTypeAnnotation(EdmCoreModel.GetCollection(edmComplexType));
                if (!withTypeNames)
                {
                    complexCollection.AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    });
                }
                return(new PayloadReaderTestDescriptor(complexPayload)
                {
                    PayloadElement = complexCollection,
                });
            }));

            return(testDescriptors);
        }
        public void JsonLightTaupoSerializerCollectionPropertyTest()
        {
            var testCases = new JsonLightSerializerTestCase[]
            {
                // Primitive collection property
                new JsonLightSerializerTestCase
                {
                    PayloadElement = new PrimitiveMultiValueProperty("Prop", PayloadBuilder.PrimitiveMultiValue().Item((long)1).Item((long)2)).WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson   = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          """ + JsonLightConstants.ODataValuePropertyName + @""":[1,2]
                        }"
                },
                // Complex collection property
                new JsonLightSerializerTestCase
                {
                    PayloadElement = new ComplexMultiValueProperty("Prop",
                                                                   PayloadBuilder.ComplexMultiValue()
                                                                   .Item(PayloadBuilder.ComplexValue("TestModel.City")
                                                                         .PrimitiveProperty("City", "Vienna")))
                                     .WithContextUri("http://odata.org/metadatauri"),
                    ExpectedJson = @"
                        {
                          """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + @""":""http://odata.org/metadatauri"",
                          """ + JsonLightConstants.ODataValuePropertyName + @""":[{ """ + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.City"", ""City"":""Vienna"" }]
                        }"
                },
            };

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

                this.JsonValueComparer.Compare(expectedValue, actualValue);
            });
        }
Exemple #5
0
            /// <summary>
            /// Visits a collection of parameters.
            /// </summary>
            /// <param name="parameters">The parameters to visit.</param>
            protected override ODataPayloadElement VisitParameters(ODataParameters parameters)
            {
                ExceptionUtilities.CheckArgumentNotNull(parameters, "parameters");
                ComplexInstance result = new ComplexInstance();

                result.IsNull = parameters.Count == 0;
                foreach (var parameter in parameters)
                {
                    if (parameter.Value == null)
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, null));
                        continue;
                    }

                    ODataCollectionStart odataCollectionStart = parameter.Value as ODataCollectionStart;

                    if (odataCollectionStart != null)
                    {
                        ODataCollectionItemsObjectModelAnnotation annotation = odataCollectionStart.GetAnnotation <ODataCollectionItemsObjectModelAnnotation>();

                        PrimitiveMultiValue primitiveCollection = PayloadBuilder.PrimitiveMultiValue();
                        foreach (var value in annotation)
                        {
                            primitiveCollection.Item(value);
                        }

                        PrimitiveMultiValueProperty primitiveCollectionProperty = new PrimitiveMultiValueProperty(parameter.Key, primitiveCollection);
                        result.Add(primitiveCollectionProperty);
                    }
                    else
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, PayloadBuilder.PrimitiveValue(parameter.Value).ClrValue));
                    }
                }

                return(result);
            }
        public void JsonLightTaupoSerializerParameterTest()
        {
            var testCases = new JsonLightSerializerTestCase[]
            {
                // Parameter payload with null, primitive, complex and collection parameters
                new JsonLightSerializerTestCase
                {
                    PayloadElement = PayloadBuilder.ComplexValue()
                                     .PrimitiveProperty("NullProp", null)
                                     .PrimitiveProperty("LongProp", (long)42)
                                     .Property("ComplexProp", PayloadBuilder.ComplexValue("TestModel.CityType").PrimitiveProperty("Name", "Vienna"))
                                     .Property("PrimitiveColl", PayloadBuilder.PrimitiveMultiValue().Item((long)1).Item((long)2))
                                     .Property("ComplexColl", PayloadBuilder.ComplexMultiValue()
                                               .Item(PayloadBuilder.ComplexValue().PrimitiveProperty("Name", "Vienna"))
                                               .Item(PayloadBuilder.ComplexValue().PrimitiveProperty("Name", "Prague"))),
                    ExpectedJson = @"
                        {
                          ""NullProp"":null,
                          ""LongProp"":42,
                          ""ComplexProp"":{""" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + @""":""TestModel.CityType"", ""Name"":""Vienna""},
                          ""PrimitiveColl"":[1,2],
                          ""ComplexColl"":[{""Name"":""Vienna""}, {""Name"":""Prague""}]
                        }"
                },
            };

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

                this.JsonValueComparer.Compare(expectedValue, actualValue);
            });
        }
        public void CollectionValueTest()
        {
            EdmModel       edmModel = new EdmModel();
            EdmComplexType edmComplexTypeMyComplexType = edmModel.ComplexType("MyComplexType", ModelNamespace);

            edmComplexTypeMyComplexType.Property("P1", EdmPrimitiveTypeKind.Int32, false).Property("P2", EdmPrimitiveTypeKind.String, true);
            edmModel.Fixup();

            var edmCollectionTypeOfIntegerType   = new EdmCollectionType(EdmCoreModel.Instance.GetInt32(false));
            var edmCollectionTypeOfMyComplexType = new EdmCollectionType(new EdmComplexTypeReference(edmComplexTypeMyComplexType, true));
            // Create payloads of the collection properties
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Empty element collection
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .XmlValueRepresentation(new XNode[0])
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType),
                    PayloadEdmModel = edmModel,
                },
                // Collections containing collections are not supported
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .XmlValueRepresentation("<m:element />", EntityModelUtils.GetCollectionTypeName(EntityModelUtils.GetCollectionTypeName("Edm.String")), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_NestedCollectionsAreNotSupported"),
                },
            };

            var primitivePayloadsWithPadding = new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>[]
            {
                new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>
                {
                    XmlValue       = "{0}",
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType)
                },
                new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>
                {
                    XmlValue       = "{0}<m:element>42</m:element>",
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .Item(42)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType)
                },
                new CollectionPaddingPayloadTextCase <PrimitiveMultiValue>
                {
                    XmlValue       = "<m:element>42</m:element>{0}",
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .Item(42)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType)
                },
            };

            var complexPayloadsWithPadding = new CollectionPaddingPayloadTextCase <ComplexMultiValue>[]
            {
                new CollectionPaddingPayloadTextCase <ComplexMultiValue>
                {
                    XmlValue       = "<m:element><d:P1>42</d:P1></m:element>{0}<m:element><d:P2>test</d:P2></m:element>",
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.MyComplexType"))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P1", 42).AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P2", "test").AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .WithTypeAnnotation(edmCollectionTypeOfMyComplexType)
                },
            };

            var xmlPadding = new CollectionXmlPadding[]
            {
                // Nothing
                new CollectionXmlPadding
                {
                    Padding = string.Empty,
                },
                // Whitespace only
                new CollectionXmlPadding
                {
                    Padding = "  \r\n\t",
                },
                // Insignificant nodes
                new CollectionXmlPadding
                {
                    Padding = "<!--s--> <?value?>",
                },
                // Element in no namespace
                new CollectionXmlPadding
                {
                    Padding = "<foo xmlns=''/>",
                },
                // Element in custom namespace
                new CollectionXmlPadding
                {
                    Padding = "<c:foo xmlns:c='uri' attr='1'><c:child/>text</c:foo>",
                },
                // Element in metadata namespace (should be ignored as well)
                new CollectionXmlPadding
                {
                    Padding = "<m:properties/>",
                },
                // Element in atom namespace (should also be ignored)
                new CollectionXmlPadding
                {
                    Padding = "<entry/>",
                },
                // Significant nodes - will be ignored
                new CollectionXmlPadding
                {
                    Padding = "some text <![CDATA[cdata]]>",
                },
                // Element in the d namespace should fail
                new CollectionXmlPadding
                {
                    Padding           = "<d:foo/>",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement", "foo", "http://docs.oasis-open.org/odata/ns/metadata"),
                },
                // Element in the d namespace should fail (wrong name)
                new CollectionXmlPadding
                {
                    Padding           = "<d:Element/>",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement", "Element", "http://docs.oasis-open.org/odata/ns/metadata"),
                },
            };

            testDescriptors = testDescriptors.Concat(this.CreatePayloadWithPaddingTestDescriptor(
                                                         primitivePayloadsWithPadding, xmlPadding, edmModel));

            testDescriptors = testDescriptors.Concat(this.CreatePayloadWithPaddingTestDescriptor(
                                                         complexPayloadsWithPadding, xmlPadding, edmModel));

            testDescriptors = testDescriptors.Select(td => td.InProperty());

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void CollectionNoMetadataTest()
        {
            string collectionOfStringTypeName = EntityModelUtils.GetCollectionTypeName("Edm.String");
            string collectionOfInt32TypeName  = EntityModelUtils.GetCollectionTypeName("Edm.Int32");
            string collectionOfComplexType    = EntityModelUtils.GetCollectionTypeName("TestModel.ComplexType");

            // Create payloads of the collection properties
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Single empty m:element in >=V3
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .XmlValueRepresentation("<m:element/>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Single m:element with no content in >= V3
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .XmlValueRepresentation("<m:element></m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Two m:element items in >= V3
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .Item("foo")
                                     .XmlValueRepresentation("<m:element></m:element><m:element>foo</m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Two m:element items with insiginificant nodes >= V3
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .Item("foo")
                                     .XmlValueRepresentation("  <m:element></m:element>\r\n<?value?><m:element>foo</m:element><!--some-->", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Two m:element items with text nodes >= V3
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .Item("foo")
                                     .XmlValueRepresentation("foo<m:element></m:element>bar<m:element>foo</m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Two m:element items with custom element >= V3
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .Item("foo")
                                     .XmlValueRepresentation("<m:foo/><m:element></m:element><m:bar>some</m:bar><m:element>foo</m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Two m:element items with custom element with m:element in it (which is to be ignored)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .Item("foo")
                                     .XmlValueRepresentation("<m:foo/><m:element></m:element><m:bar><m:element/></m:bar><m:element>foo</m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Two m:element items with custom element with d:prop in it (which is to be ignored)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .Item(string.Empty)
                                     .Item("foo")
                                     .XmlValueRepresentation("<m:foo/><m:element></m:element><m:bar><d:prop/></m:bar><m:element>foo</m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Nested m:element items (error)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .XmlValueRepresentation("<m:element><m:element>0</m:element><m:element>1</m:element></m:element>", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_InvalidItemTypeKind", "Collection"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },

                #region No collection type name tests
                // No collection type name and string items (with and without type names)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue().Item("foo").Item(new PrimitiveValue(/*fullTypeName*/ null, "bar"))
                                     .XmlValueRepresentation("<m:element m:type='Edm.String'>foo</m:element><m:element>bar</m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and Int32 items
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue().Item(1).Item(2)
                                     .XmlValueRepresentation("<m:element m:type='Edm.Int32'>1</m:element><m:element m:type='Edm.Int32'>2</m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and complex items
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("StringProperty", "abc"))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("StringProperty", "123"))
                                     .XmlValueRepresentation("<m:element m:type='TestModel.ComplexType'><d:StringProperty>abc</d:StringProperty></m:element><m:element m:type='TestModel.ComplexType'><d:StringProperty>123</d:StringProperty></m:element>", null, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and different item type kinds (complex instead of primitive)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue()
                                     .XmlValueRepresentation("<m:element>0</m:element><m:element><d:bar>2</d:bar></m:element>", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeKind", "Complex", "Primitive"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and item type kind does not match item type name (primitive and complex items)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .XmlValueRepresentation("<m:element></m:element><m:element><d:bar>2</d:bar></m:element>", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeKind", "Complex", "Primitive"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and item type names don't match (Edm.String and Edm.Int32)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .XmlValueRepresentation("<m:element></m:element><m:element m:type='Edm.Int32'>2</m:element>", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "Edm.Int32", "Edm.String"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and item type names don't match (Edm.String and Edm.Int32); including some null items
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .XmlValueRepresentation("<m:element m:null='true' /><m:element></m:element><m:element m:null='true' /><m:element m:type='Edm.Int32'>2</m:element><m:element m:null='true' />", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "Edm.Int32", "Edm.String"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and item type names don't match (TestModel.SomeComplexType and TestModel.OtherComplexType)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .XmlValueRepresentation("<m:element m:type='TestModel.SomeComplexType'><d:SomeProperty /></m:element><m:element m:type='TestModel.OtherComplexType'><d:OtherProperty /></m:element>", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "TestModel.OtherComplexType", "TestModel.SomeComplexType"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and item type names don't match (TestModel.SomeComplexType and TestModel.OtherComplexType); including some null items
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .XmlValueRepresentation("<m:element m:null='true' /><m:element m:type='TestModel.SomeComplexType'></m:element><m:element m:null='true' /><m:element m:type='TestModel.OtherComplexType'></m:element><m:element m:null='true' />", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "TestModel.OtherComplexType", "TestModel.SomeComplexType"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // No collection type name and different item type kinds (primitive instead of complex)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .XmlValueRepresentation("<m:element m:type='TestModel.SomeComplexType'><m:bar>2</m:bar></m:element><m:element>0</m:element>", null, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeKind", "Primitive", "Complex"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },

                #endregion No collection type name tests

                #region Collection with type name tests
                // Collection with type name and string items (without type names) >= V3
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(collectionOfStringTypeName).Item("test")
                                     .XmlValueRepresentation("<m:element>test</m:element>", collectionOfStringTypeName, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Collection with type name and string items (with and without type names)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(collectionOfStringTypeName).Item("foo").Item(new PrimitiveValue(/*fullTypeName*/ null, "bar"))
                                     .XmlValueRepresentation("<m:element m:type='Edm.String'>foo</m:element><m:element>bar</m:element>", collectionOfStringTypeName, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Collection with type name and Int32 items (with type names)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(collectionOfInt32TypeName).Item(1).Item(2)
                                     .XmlValueRepresentation("<m:element m:type='Edm.Int32'>1</m:element><m:element m:type='Edm.Int32'>2</m:element>", collectionOfInt32TypeName, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Collection with type name and Int32 items (without type names)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(collectionOfInt32TypeName)
                                     .Item(new PrimitiveValue(/*fullTypeName*/ null, 1))
                                     .Item(new PrimitiveValue(/*fullTypeName*/ null, 2))
                                     .XmlValueRepresentation("<m:element>1</m:element><m:element>2</m:element>", collectionOfInt32TypeName, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Collection with type name and complex items (with type names)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(collectionOfComplexType)
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("bar", "1"))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("bar", "2"))
                                     .XmlValueRepresentation("<m:element m:type='TestModel.ComplexType'><d:bar>1</d:bar></m:element><m:element m:type='TestModel.ComplexType'><d:bar>2</d:bar></m:element>", collectionOfComplexType, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Collection with type name and complex items (without type names)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(collectionOfComplexType)
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("bar", "1").AddAnnotation(new SerializationTypeNameTestAnnotation {
                        TypeName = null
                    }))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("bar", "2").AddAnnotation(new SerializationTypeNameTestAnnotation {
                        TypeName = null
                    }))
                                     .XmlValueRepresentation("<m:element><d:bar>1</d:bar></m:element><m:element><d:bar>2</d:bar></m:element>", collectionOfComplexType, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Primitive collection with type name and different item type kinds (complex instead of primitive)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(collectionOfInt32TypeName)
                                     .XmlValueRepresentation("<m:element m:type='Edm.Int32'>0</m:element><m:element m:type='TestModel.SomeComplexType'><d:bar>2</d:bar></m:element>", collectionOfInt32TypeName, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeKind", "Complex", "Primitive"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Primitive collection with type name and different item type kinds (invalid element in primitive)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(collectionOfInt32TypeName)
                                     .XmlValueRepresentation("<m:element m:type='Edm.Int32'>0</m:element><m:element><d:bar>2</d:bar></m:element>", collectionOfInt32TypeName, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Complex collection type with type name and different item type kinds (primitive instead of complex)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(collectionOfComplexType)
                                     .XmlValueRepresentation("<m:element m:type='TestModel.ComplexType'><d:bar>2</d:bar></m:element><m:element m:type='Edm.Int32'>0</m:element>", collectionOfComplexType, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeKind", "Primitive", "Complex"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Complex collection type with type name and mixed content - primitive value at the same level as complex value
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(collectionOfComplexType)
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("bar", "2").AddAnnotation(new SerializationTypeNameTestAnnotation {
                        TypeName = null
                    }))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ComplexType").PrimitiveProperty("bar", "3").AddAnnotation(new SerializationTypeNameTestAnnotation {
                        TypeName = null
                    }))
                                     .XmlValueRepresentation("<m:element><d:bar>2</d:bar></m:element><m:element>0<d:bar>3</d:bar></m:element>", collectionOfComplexType, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Primitive collection with type name and inconsistent item type names
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(collectionOfInt32TypeName).Item(new PrimitiveValue(/*fullTypeName*/ null, 0)).Item(1)
                                     .XmlValueRepresentation("<m:element>0</m:element><m:element m:type='Edm.Int32'>1</m:element>", collectionOfInt32TypeName, null),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                // Complex collection type with type name and inconsistent item type names
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(collectionOfComplexType)
                                     .XmlValueRepresentation("<m:element m:type='TestModel.SomeComplexType'><d:foo>1</d:foo></m:element><m:element><d:bar>2</d:bar></m:element>", collectionOfComplexType, null),
                    ExpectedException     = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "TestModel.SomeComplexType", "TestModel.ComplexType"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                },
                #endregion Collection with type name and inconsistent payload items
            };

            // Wrap it in property (manually to prevent any type annotations)
            testDescriptors = testDescriptors.Select(td => td.InProperty());

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Exemple #9
0
        public void TopLevelPropertiesWithMetadataTest()
        {
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreatePrimitiveValueTestDescriptors(this.Settings);

            testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, true));
            testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateCollectionTestDescriptors(this.Settings, true));

            testDescriptors = testDescriptors.Select(collectionTestDescriptor => collectionTestDescriptor.InProperty("propertyName"));
            testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            // Limit to only top-level property payloads
            testDescriptors = testDescriptors.Where(td => td.PayloadElement is PropertyInstance);

            // Add a couple of invalid cases which use a standard model
            EdmModel model = new EdmModel();

            model.ComplexType("UnusedComplexType");

            EdmEntityType unusedEntityType = model.EntityType("UnusedEntityType");

            unusedEntityType.AddKeys(unusedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false));
            unusedEntityType.Property("Name", EdmPrimitiveTypeKind.String, isNullable: false);

            EdmEntityType streamPropertyEntityType = model.EntityType("EntityTypeWithStreamProperty");

            streamPropertyEntityType.AddKeys(streamPropertyEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false));
            streamPropertyEntityType.AddStructuralProperty("Video", EdmPrimitiveTypeKind.Stream, isNullable: false);
            streamPropertyEntityType.Property("NonStreamProperty", EdmPrimitiveTypeKind.Boolean, isNullable: false);

            EdmEntityType navigationPropertyEntityType = model.EntityType("EntityTypeWithNavigationProperty");

            navigationPropertyEntityType.AddKeys(navigationPropertyEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false));
            navigationPropertyEntityType.NavigationProperty("Navigation", streamPropertyEntityType);

            model.Fixup();

            EdmEntityContainer container = model.EntityContainer as EdmEntityContainer;

            EdmFunction nameFunction = new EdmFunction(container.Namespace, "NameFunctionImport", EdmCoreModel.Instance.GetInt32(false), false /*isBound*/, null, false /*isComposable*/);

            model.AddElement(nameFunction);
            container.AddFunctionImport("NameFunctionImport", nameFunction);
            model.Fixup();

            var videoPropertyType = model.GetEntityType("TestModel.EntityTypeWithStreamProperty").Properties().Single(p => p.Name == "Video").Type;

            var explicitTestDescriptors = new[]
            {
                // Non existant type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("TestModel.NonExistantType")),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "TestModel.NonExistantType"),
                    // This test has different meaning in JSON-L (no expected type + non-existent typename)
                    SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json,
                },
                // Existing type name without namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("UnusedComplexType")),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "UnusedComplexType"),
                    // This test has different meaning in JSON-L (no expected type + non-existent typename)
                    SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json,
                },
                // Existing type of wrong kind
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("TestModel.UnusedEntityType")),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectValueTypeKind", "TestModel.UnusedEntityType", "Entity"),
                    // This test has different meaning in JSON-L
                    SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json,
                },
                // A stream is not allowed in a property with a non-stream property kind.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement         = PayloadBuilder.Entity("TestModel.EntityTypeWithStreamProperty").StreamProperty("NonStreamProperty", "http://readlink", "http://editlink"),
                    PayloadEdmModel        = model,
                    ExpectedResultCallback = tc =>
                                             new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = tc.Format == ODataFormat.Atom
                                    ? tc.IsRequest
                                        ? null
                                        : ODataExpectedExceptions.ODataException("ValidationUtils_MismatchPropertyKindForStreamProperty", "NonStreamProperty")
                                    : tc.Format == ODataFormat.Json
                                        ? ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithWrongType", "NonStreamProperty", "Edm.Boolean")
                                        : ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject")
                    },
                },
                // Top-level property of stream type is not allowed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(videoPropertyType),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeStream"),
                },
                // Top-level deferred navigation property is not allowed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(streamPropertyEntityType),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeEntityKind"),
                },
                // Top-level expanded navigation property is not allowed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(streamPropertyEntityType),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeEntityKind"),
                },
                // Top-level collection without expected type and without type name is not allowed (when metadata is specified)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.Property("propertyName2", PayloadBuilder.PrimitiveMultiValue(null).Item(42)),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ValueWithoutType"),
                    // This test has different meaning in JSON-L (no expected type + non-existent typename)
                    SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json,
                },
                // Top-level complex property without expected type and without type name is not allowed (when metadata is specified)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue(null).PrimitiveProperty("foo", "bar")),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ValueWithoutType"),
                    // This test has different meaning in JSON-L (no expected type + non-existent typename)
                    SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json,
                },
            };

            testDescriptors = testDescriptors.Concat(explicitTestDescriptors);

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                var property = testDescriptor.PayloadElement as PropertyInstance;
                if (property != null && testConfiguration.Format == ODataFormat.Atom)
                {
                    property.Name = null;
                }
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void CollectionWithoutExpectedTypeAndWithoutMetadataTest()
        {
            const string complexType1Name = "TestModel.TestComplexType1";
            const string complexType2Name = "TestModel.TestComplexType2";

            #region Test cases where the collection does not specify a type name
            IEnumerable <PayloadReaderTestDescriptor> noCollectionTypeNameTestDescriptors = new[]
            {
                // Primitive collection containing items of the same primitive type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue().Item(1).Item(2).Item(3)
                },
                // Primitive collection containing string items where some don't specify the type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue().Item("One").Item(new PrimitiveValue(/*fullTypeName*/ null, "Two")).Item("Three")
                },
                // Primitive collection containing string items where the first doesn't specify the type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue().Item(new PrimitiveValue(/*fullTypeName*/ null, "One")).Item("Two").Item("Three")
                },

                // Primitive collection containing items of different primitive types
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement         = PayloadBuilder.PrimitiveMultiValue().Item(1).Item(true).Item(2),
                    ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "Edm.Boolean", "Edm.Int32")
                    }
                },
                // Complex collection containing items of different complex type (correct type attribute value)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .Item(PayloadBuilder.ComplexValue(complexType1Name).PrimitiveProperty("Property1", "Foo"))
                                     .Item(PayloadBuilder.ComplexValue(complexType2Name).PrimitiveProperty("Property1", "Foo")),
                    ExpectedException = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", complexType2Name, complexType1Name),
                },
                // Primitive collection containing items of different primitive types (including one not specifying the type name)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement         = PayloadBuilder.PrimitiveMultiValue().Item(new PrimitiveValue(/*fullTypeName*/ null, "One")).Item("Two").Item(3),
                    ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "Edm.Int32", "Edm.String")
                    }
                },
                // Complex collection containing complex items without type names
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue()
                                     .Item(PayloadBuilder.ComplexValue().PrimitiveProperty("Property1", "Foo"))
                                     .Item(PayloadBuilder.ComplexValue().PrimitiveProperty("Property2", "Bar")),
                },
            };
            #endregion Test cases where the collection does not specify a type name

            #region Test cases where the collection does specify a type name
            IEnumerable <PayloadReaderTestDescriptor> collectionTypeNameTestDescriptors = new[]
            {
                // Primitive collection containing items of the same primitive type and the items have type names as well
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32")).Item(1).Item(2).Item(3)
                },
                // Primitive collection containing string items where some don't specify the type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String")).Item("One").Item(new PrimitiveValue(/*fullTypeName*/ null, "Two")).Item("Three")
                },
                // Primitive collection containing string items where the first doesn't specify the type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String")).Item(new PrimitiveValue(/*fullTypeName*/ null, "One")).Item("Two").Item("Three")
                },

                // Primitive collection containing some items of a different primitive type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement         = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String")).Item(new PrimitiveValue(/*fullTypeName*/ null, "One")).Item("Two").Item(3),
                    ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "Edm.Int32", "Edm.String")
                    }
                },
                // Primitive collection containing items of the same primitive type where some specify type names
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32")).Item(1).Item(new PrimitiveValue(/*fullTypeName*/ null, 2)).Item(3),
                },
                // Primitive collection containing items of different primitive types
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement         = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String")).Item(1).Item(true).Item(2),
                    ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", "Edm.Int32", "Edm.String")
                    }
                },
                // Complex collection containing items of different complex type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName(complexType1Name))
                                     .Item(PayloadBuilder.ComplexValue(complexType2Name).PrimitiveProperty("Property1", "Foo")),
                    ExpectedException = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", complexType2Name, complexType1Name),
                },
                // Complex collection containing items of different complex type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName(complexType1Name))
                                     .Item(PayloadBuilder.ComplexValue(complexType1Name).PrimitiveProperty("Property1", "Foo"))
                                     .Item(PayloadBuilder.ComplexValue(complexType2Name).PrimitiveProperty("Property1", "Foo")),
                    ExpectedException = ODataExpectedExceptions.ODataException("CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName", complexType2Name, complexType1Name),
                },
            };
            #endregion

            noCollectionTypeNameTestDescriptors = noCollectionTypeNameTestDescriptors.Select(td => td.InProperty());
            collectionTypeNameTestDescriptors   = collectionTypeNameTestDescriptors.Select(td => td.InProperty());

            this.CombinatorialEngineProvider.RunCombinations(
                noCollectionTypeNameTestDescriptors.Concat(collectionTypeNameTestDescriptors),
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Exemple #11
0
        public void DuplicatePropertyNamesTest()
        {
            PropertyInstance primitiveProperty = PayloadBuilder.PrimitiveProperty("DuplicateProperty", 42);
            PropertyInstance complexProperty   = PayloadBuilder.Property("DuplicateProperty",
                                                                         PayloadBuilder.ComplexValue("TestModel.DuplicateComplexType").PrimitiveProperty("Name", "foo"));
            PropertyInstance collectionProperty = PayloadBuilder.Property("DuplicateProperty",
                                                                          PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String")).WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetString(false))));

            PropertyInstance[] allProperties = new[] { primitiveProperty, complexProperty, collectionProperty };
            PropertyInstance[] propertiesWithPossibleDuplication = new[] { primitiveProperty, complexProperty };
            PropertyInstance[] propertiesWithNoDuplication       = new[] { collectionProperty };

            IEnumerable <DuplicatePropertySet> duplicatePropertySets;

            // Those which may allow duplication
            duplicatePropertySets = propertiesWithPossibleDuplication
                                    .Variations(2).Select(properties => new DuplicatePropertySet {
                Properties = properties, DuplicationPotentiallyAllowed = true
            });

            // Then for each in those which don't allow duplication try it against all the others
            duplicatePropertySets = duplicatePropertySets.Concat(propertiesWithNoDuplication.SelectMany(
                                                                     propertyWithNoDuplication => allProperties.SelectMany(otherProperty =>
                                                                                                                           new[]
            {
                new DuplicatePropertySet {
                    Properties = new [] { propertyWithNoDuplication, otherProperty }, DuplicationPotentiallyAllowed = false
                },
                new DuplicatePropertySet {
                    Properties = new [] { otherProperty, propertyWithNoDuplication }, DuplicationPotentiallyAllowed = false
                },
            })));

            this.CombinatorialEngineProvider.RunCombinations(
                duplicatePropertySets,
                new bool[] { false, true },
                new bool[] { true, false },
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (duplicatePropertySet, allowDuplicateProperties, useMetadata, testConfiguration) =>
            {
                EdmModel model  = new EdmModel();
                var complexType = model.ComplexType("DuplicateComplexType");
                complexType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
                model.Fixup();

                PropertyInstance firstProperty  = duplicatePropertySet.Properties.ElementAt(0);
                PropertyInstance secondProperty = duplicatePropertySet.Properties.ElementAt(1);

                // Non-metadata reading is not possible in JSON
                if (!useMetadata && (testConfiguration.Format == ODataFormat.Json))
                {
                    return;
                }

                // If we will have metadata then we can only allow combinations of the same kind
                if (useMetadata)
                {
                    if (firstProperty.ElementType != secondProperty.ElementType)
                    {
                        return;
                    }
                }

                // Copy the test config
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                if (allowDuplicateProperties)
                {
                    testConfiguration.MessageReaderSettings.EnableODataServerBehavior();
                }

                // Create a descriptor with the first property
                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement  = firstProperty,
                    PayloadEdmModel = useMetadata ? model : null
                };

                // Now generate entity around it
                testDescriptor = testDescriptor.InComplexValue(5, 5);

                // Now add the second property to it
                ((ComplexInstance)testDescriptor.PayloadElement).Add(secondProperty);

                // [Astoria-ODataLib-Integration] Parsing of URLs on OData recognized places may fail, but Astoria server doesn't
                // Server does not read named stream links for Atom payload therefore the expected payload needs to be normalized
                if (testConfiguration.Format == ODataFormat.Atom)
                {
                    testDescriptor.ExpectedResultNormalizers.Add(config => (payloadElement => WcfDsServerPayloadElementNormalizer.Normalize(payloadElement, ODataFormat.Atom, testDescriptor.PayloadEdmModel as EdmModel)));
                }

                // We expect failure only if we don't allow duplicates or if the property kind doesn't allow duplicates ever
                if ((!duplicatePropertySet.DuplicationPotentiallyAllowed || !allowDuplicateProperties))
                {
                    testDescriptor.ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "DuplicateProperty");
                }

                IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
                {
                    testDescriptor.InProperty("TopLevelProperty"),
                    testDescriptor.InProperty("ComplexProperty").InEntity(2, 2),
                    testDescriptor.InCollection(5, 5).InProperty("TopLevelCollection"),
                };

                this.CombinatorialEngineProvider.RunCombinations(
                    testDescriptors,
                    td =>
                {
                    var property = td.PayloadElement as PropertyInstance;
                    if (property != null && testConfiguration.Format == ODataFormat.Atom)
                    {
                        property.Name = null;
                    }
                    td.RunTest(testConfiguration);
                });
            });
        }
Exemple #12
0
            /// <summary>
            /// Visits a collection of parameters.
            /// </summary>
            /// <param name="parameters">The parameters to visit.</param>
            protected override ODataPayloadElement VisitParameters(ODataParameters parameters)
            {
                ExceptionUtilities.CheckArgumentNotNull(parameters, "parameters");
                ComplexInstance result = new ComplexInstance();

                result.IsNull = parameters.Count == 0;
                foreach (var parameter in parameters)
                {
                    if (parameter.Value == null)
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, null));
                        continue;
                    }

                    ODataComplexValue    odataComplexValue    = parameter.Value as ODataComplexValue;
                    ODataCollectionStart odataCollectionStart = parameter.Value as ODataCollectionStart;

                    if (odataCollectionStart != null)
                    {
                        ODataCollectionItemsObjectModelAnnotation annotation = odataCollectionStart.GetAnnotation <ODataCollectionItemsObjectModelAnnotation>();
                        if (annotation.OfType <ODataComplexValue>().FirstOrDefault() != null)
                        {
                            ComplexMultiValue complexCollection = PayloadBuilder.ComplexMultiValue();
                            foreach (var value in annotation)
                            {
                                complexCollection.Item(this.VisitComplexValue(value as ODataComplexValue) as ComplexInstance);
                            }

                            ComplexMultiValueProperty complexCollectionProperty = new ComplexMultiValueProperty(parameter.Key, complexCollection);
                            result.Add(complexCollectionProperty);
                        }
                        else
                        {
                            PrimitiveMultiValue primitiveCollection = PayloadBuilder.PrimitiveMultiValue();
                            foreach (var value in annotation)
                            {
                                primitiveCollection.Item(value);
                            }

                            PrimitiveMultiValueProperty primitiveCollectionProperty = new PrimitiveMultiValueProperty(parameter.Key, primitiveCollection);
                            result.Add(primitiveCollectionProperty);
                        }
                    }
                    else if (odataComplexValue != null)
                    {
                        ComplexInstance complexInstance = PayloadBuilder.ComplexValue(odataComplexValue.TypeName);
                        complexInstance.IsNull = false;
                        foreach (ODataProperty odataProperty in odataComplexValue.Properties)
                        {
                            complexInstance.Property(odataProperty.Name, this.Visit(odataProperty.Value));
                        }

                        result.Add(new ComplexProperty(parameter.Key, complexInstance));
                    }
                    else
                    {
                        result.Add(new PrimitiveProperty(parameter.Key, null, PayloadBuilder.PrimitiveValue(parameter.Value).ClrValue));
                    }
                }

                return(result);
            }
        public void CollectionWithoutExpectedTypeAndWithMetadataTest()
        {
            // For now only top-level property can do this.
            // TODO: Once we have open properties, these test cases apply to those as well, then probably move these to the top-level property
            // tests and share them from the open properties test, or possible keep both here.

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = this.CreateCollectionPayloadsWithMetadata(true);

            testDescriptors = testDescriptors.Concat(this.CreateInvalidCollectionsWithTypeNames(false));

            EdmModel       model           = new EdmModel();
            EdmComplexType itemComplexType = model.ComplexType("ItemComplexType").Property("stringProperty", EdmPrimitiveTypeKind.String);

            model = model.Fixup();

            testDescriptors = testDescriptors.Concat(new[]
            {
                // No expected type specified, the one in the payload should be enough
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement  = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String")),
                    PayloadEdmModel = model,
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement  = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.ItemComplexType")),
                    PayloadEdmModel = model,
                },

                // Verify that the item type is inherited from the collection to its items if the item doesn't specify the type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.ItemComplexType"))
                                     .Item(PayloadBuilder
                                           .ComplexValue()
                                           .PrimitiveProperty("stringProperty", "test")
                                           .WithTypeAnnotation(itemComplexType)
                                           .AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })),                                                                                             // Add item which does not have the type name
                    PayloadEdmModel = model
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.ItemComplexType"))
                                     .Item(PayloadBuilder
                                           .ComplexValue("TestModel.ItemComplexType")
                                           .PrimitiveProperty("stringProperty", "test")
                                           .WithTypeAnnotation(itemComplexType)) // Add an item which does have the type name
                                     .Item(PayloadBuilder
                                           .ComplexValue()
                                           .PrimitiveProperty("stringProperty", "test")
                                           .WithTypeAnnotation(itemComplexType)
                                           .AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })),                                                                                             // Add item which does not have the type name
                    PayloadEdmModel = model
                }
            });

            // Wrap the value in a top-level property without expected type (can't use the .InProperty here, since that would put the expected type on it)
            testDescriptors = testDescriptors.Select(td =>
                                                     new PayloadReaderTestDescriptor(td)
            {
                PayloadElement = PayloadBuilder.Property("propertyName", td.PayloadElement)
            });

            // Fill in type names for expected result from the type annotations
            testDescriptors = testDescriptors.Select(td =>
            {
                td.ExpectedResultNormalizers.Add(tc => FillTypeNamesFromTypeAnnotationsPayloadElementVisitor.Visit);
                return(td);
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                // The version dependent behavior tests are implemented in the format specific tests.
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.PayloadNormalizers.Add((tc) => tc.Format == ODataFormat.Json ? ReplaceExpectedTypeWithContextUriVisitor.VisitPayload : (Func <ODataPayloadElement, ODataPayloadElement>)null);

                var property = testDescriptor.PayloadElement as PropertyInstance;
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public IEnumerable <PayloadReaderTestDescriptor> CreateInvalidCollectionsWithTypeNames(bool expectedTypeWillBeUsed)
        {
            EdmModel       model           = new EdmModel();
            EdmComplexType itemComplexType = model.ComplexType("ItemComplexType");

            model.ComplexType("ExtraComplexType");
            model = model.Fixup();

            // Add invalid cases
            var testDescriptors = new[]
            {
                // Invalid collection type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue("")
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false))),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", string.Empty),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName(""))
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false))),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", EntityModelUtils.GetCollectionTypeName("")),
                },
                // Invalid collection type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue("collection(Edm.Int32)")
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false))),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "collection(Edm.Int32)"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue("foo")
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false))),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "foo"),
                },

                // Non existant type name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.NonExistant"))
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false))),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", EntityModelUtils.GetCollectionTypeName("TestModel.NonExistant")),
                },

                // Type of the item differs from the type of the collection
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String"))
                                     .Item(-42)
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetString(true))),
                    PayloadEdmModel        = model,
                    ExpectedResultCallback = tc =>
                                             new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_CannotConvertPrimitiveValue", "-42", "Edm.String")
                    },
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.ItemComplexType"))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.ExtraComplexType"))
                                     .WithTypeAnnotation(EdmCoreModel.GetCollection(itemComplexType.ToTypeReference())),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncompatibleType", "TestModel.ExtraComplexType", "TestModel.ItemComplexType"),
                }
            };

            if (expectedTypeWillBeUsed)
            {
                testDescriptors = testDescriptors.Concat(new[]
                {
                    // Type differs from the declared/expected type
                    new PayloadReaderTestDescriptor(this.Settings)
                    {
                        PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String"))
                                         .WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false))),
                        PayloadEdmModel   = model,
                        ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncompatibleType", EntityModelUtils.GetCollectionTypeName("Edm.String"), EntityModelUtils.GetCollectionTypeName("Edm.Int32")),
                    },
                }).ToArray();
            }

            foreach (var testDescriptor in testDescriptors)
            {
                testDescriptor.PayloadNormalizers.Add((tc) => tc.Format == ODataFormat.Json ? AddJsonLightTypeAnnotationToCollectionsVisitor.Normalize : (Func <ODataPayloadElement, ODataPayloadElement>)null);
            }

            return(testDescriptors);
        }
        public void CollectionWithHeterogenousItemsTest()
        {
            EdmModel       edmModel = new EdmModel();
            EdmComplexType edmComplexTypeMyComplexType = edmModel.ComplexType("MyComplexType", ModelNamespace);

            edmComplexTypeMyComplexType.Property("P1", EdmPrimitiveTypeKind.Int32, false).Property("P2", EdmPrimitiveTypeKind.String, true);
            edmModel.Fixup();

            var edmCollectionTypeOfIntegerType = new EdmCollectionType(EdmCoreModel.Instance.GetInt32(false));
            var edmCollectionTypeOfStringType  = new EdmCollectionType(EdmCoreModel.Instance.GetString(true));

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Primitive collection with complex item
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String"))
                                     .XmlValueRepresentation("<m:element><d:P1>0</d:P1><d:P2>Foo</d:P2></m:element>", EntityModelUtils.GetCollectionTypeName("Edm.String"), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfStringType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))
                                     .XmlValueRepresentation("<m:element>0</m:element><m:element><d:P1>0</d:P1><d:P2>Foo</d:P2></m:element>", EntityModelUtils.GetCollectionTypeName("Edm.Int32"), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfIntegerType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                // Complex collection with primitive item
                // Note - the text nodes (of the primitive items) are ignored in complex values - leaving empty complex values
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.MyComplexType"))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P1", 987).AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .Item(PayloadBuilder.ComplexValue("TestModel.MyComplexType").PrimitiveProperty("P1", 123).AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .XmlValueRepresentation("<m:element>Foo<d:P1>987</d:P1></m:element><m:element><d:P1>123</d:P1>Bar</m:element>", EntityModelUtils.GetCollectionTypeName("TestModel.MyComplexType"), null),
                    PayloadEdmModel = edmModel,
                },
                // Primitive collection containing a primitive and a nested collection
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String"))
                                     .XmlValueRepresentation("<m:element>Foo</m:element><m:element><m:element>0</m:element><m:element>1</m:element></m:element>", EntityModelUtils.GetCollectionTypeName("Edm.String"), null)
                                     .WithTypeAnnotation(edmCollectionTypeOfStringType),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
            };

            testDescriptors = testDescriptors.Select(td => td.InProperty());

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void NoMetadataTest()
        {
            EdmModel model     = new EdmModel();
            var      container = new EdmEntityContainer("TestModel", "DefaultContainer");

            model.AddElement(container);

            var testDescriptors = new[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.EntitySet(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.EntitySet(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.EntitySet(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_NoEntitySetForRequest"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Entity(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Entity(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Entity(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_NoEntitySetForRequest"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.PrimitiveProperty("propertyName", 42),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue()),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.Property("propertyName", PayloadBuilder.PrimitiveMultiValue()),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.PrimitiveCollection(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.PrimitiveCollection(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveCollection(),
                    //PayloadModel = model,
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ItemTypeRequiredForCollectionReaderInRequests"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexCollection(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexCollection(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexCollection(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ItemTypeRequiredForCollectionReaderInRequests"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ServiceDocument().Workspace(PayloadBuilder.Workspace()),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.DeferredLink("http://odata.org/deferred"),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.DeferredLink("http://odata.org/deferred"),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.LinkCollection(),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexValue(),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ODataJsonLightInputContext_ModelRequiredForReading"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement        = PayloadBuilder.ComplexValue(),
                    PayloadEdmModel       = model,
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ArgumentNullException("ODataJsonLightInputContext_OperationCannotBeNullForCreateParameterReader", "operation")
                },
            };

            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);
            });
        }
Exemple #17
0
        public void ComplexValueIgnorePropertyNullValuesTest()
        {
            var versions = new Version[] {
                null,
                new Version(4, 0),
            };

            EdmModel        edmModel          = new EdmModel();
            IEdmComplexType countryRegionType = edmModel.ComplexType("CountryRegion")
                                                .Property("Name", EdmPrimitiveTypeKind.String)
                                                .Property("CountryRegionCode", EdmPrimitiveTypeKind.String);
            IEdmComplexType countryRegionNullType = edmModel.ComplexType("CountryRegionNull")
                                                    .Property("Name", EdmPrimitiveTypeKind.String)
                                                    .Property("CountryRegionCode", EdmPrimitiveTypeKind.String);
            IEdmComplexType addressType = edmModel.ComplexType("Address")
                                          .Property("Street", EdmPrimitiveTypeKind.String)
                                          .Property("StreetNull", EdmCoreModel.Instance.GetString(true) as EdmTypeReference)
                                          .Property("Numbers", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)) as EdmTypeReference)
                                          .Property("CountryRegion", new EdmComplexTypeReference(countryRegionType, false))
                                          .Property("CountryRegionNull", new EdmComplexTypeReference(countryRegionNullType, true));

            edmModel.EntityType("Customer")
            .KeyProperty("ID", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference)
            .Property("Address", new EdmComplexTypeReference(addressType, false));
            edmModel.Fixup();

            this.CombinatorialEngineProvider.RunCombinations(
                new ODataNullValueBehaviorKind[] { ODataNullValueBehaviorKind.Default, ODataNullValueBehaviorKind.DisableValidation, ODataNullValueBehaviorKind.IgnoreValue },
                versions,
                versions,
                TestReaderUtils.ODataBehaviorKinds,
                (nullPropertyValueReaderBehavior, dataServiceVersion, edmVersion, behaviorKind) =>
            {
                edmModel.SetEdmVersion(edmVersion);

                // Now we set the 'IgnoreNullValues' annotation on all properties
                IEdmComplexType edmAddressType = (IEdmComplexType)edmModel.FindType("TestModel.Address");
                foreach (IEdmStructuralProperty edmProperty in edmAddressType.StructuralProperties())
                {
                    edmModel.SetNullValueReaderBehavior(edmProperty, nullPropertyValueReaderBehavior);
                }

                EntityInstance customerPayload = PayloadBuilder.Entity("TestModel.Customer")
                                                 .PrimitiveProperty("ID", 1)
                                                 .Property("Address", PayloadBuilder.ComplexValue("TestModel.Address")
                                                           .PrimitiveProperty("Street", "One Microsoft Way")
                                                           .PrimitiveProperty("StreetNull", "One Microsoft Way")
                                                           .Property("Numbers", PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)").Item(1).Item(2))
                                                           .Property("CountryRegion", PayloadBuilder.ComplexValue("TestModel.CountryRegion")
                                                                     .PrimitiveProperty("Name", "Austria")
                                                                     .PrimitiveProperty("CountryRegionCode", "AUT"))
                                                           .Property("CountryRegionNull", PayloadBuilder.ComplexValue("TestModel.CountryRegionNull")
                                                                     .PrimitiveProperty("Name", "Austria")
                                                                     .PrimitiveProperty("CountryRegionCode", "AUT")));

                var testCases = new[]
                {
                    // Complex types that are not nullable should not allow null values.
                    // Null primitive property in the payload and non-nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "Street",
                        ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "Street", "Edm.String"),
                    },
                    // Null complex property in the payload and non-nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "CountryRegion",
                        ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "CountryRegion", "TestModel.CountryRegion"),
                    },
                    // Null collection property in the payload and non-nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "Numbers",
                        ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "Numbers", "Collection(Edm.Int32)"),
                    },
                    // Complex types that are nullable should allow null values.
                    // Null primitive property in the payload and nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "StreetNull",
                    },
                    // Null complex property in the payload and nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "CountryRegionNull",
                    },
                };

                Func <IgnoreNullValueTestCase, ReaderTestConfiguration, PayloadReaderTestDescriptor> createTestDescriptor =
                    (testCase, testConfig) =>
                {
                    EntityInstance payloadValue         = customerPayload.DeepCopy();
                    ComplexInstance payloadAddressValue = ((ComplexProperty)payloadValue.GetProperty("Address")).Value;
                    SetToNull(payloadAddressValue, testCase.PropertyName);

                    ComplexInstance resultValue = payloadValue;
                    if (testConfig.IsRequest && nullPropertyValueReaderBehavior == ODataNullValueBehaviorKind.IgnoreValue)
                    {
                        resultValue = customerPayload.DeepCopy();
                        ComplexInstance resultAddressValue = ((ComplexProperty)resultValue.GetProperty("Address")).Value;
                        resultAddressValue.Remove(resultAddressValue.GetProperty(testCase.PropertyName));
                    }

                    return(new PayloadReaderTestDescriptor(this.Settings)
                    {
                        PayloadElement = payloadValue,
                        PayloadEdmModel = edmModel,
                        ExpectedResultPayloadElement =
                            tc =>
                        {
                            if (tc.Format == ODataFormat.Json)
                            {
                                // under the client knob ODL will compute edit links, ids, etc
                                // so we need to update the expected payload
                                if (tc.RunBehaviorKind == TestODataBehaviorKind.WcfDataServicesClient)
                                {
                                    var entity = resultValue as EntityInstance;
                                    if (entity != null)
                                    {
                                        if (!tc.IsRequest)
                                        {
                                            entity.Id = "http://odata.org/test/Customer(1)";
                                            entity.EditLink = "http://odata.org/test/Customer(1)";
                                            entity.WithSelfLink("http://odata.org/test/Customer(1)");
                                        }
                                    }
                                }

                                var tempDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                                {
                                    PayloadElement = resultValue,
                                    PayloadEdmModel = edmModel,
                                };

                                JsonLightPayloadElementFixup.Fixup(tempDescriptor);
                                return tempDescriptor.PayloadElement;
                            }

                            return resultValue;
                        },
                        ExpectedException = (testConfig.IsRequest && nullPropertyValueReaderBehavior != ODataNullValueBehaviorKind.Default) ? null : testCase.ExpectedResponseException
                    });
                };

                this.CombinatorialEngineProvider.RunCombinations(
                    testCases,
                    this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                    (testCase, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.CloneAndApplyBehavior(behaviorKind);
                    testConfiguration.MessageReaderSettings.BaseUri = null;

                    PayloadReaderTestDescriptor testDescriptor = createTestDescriptor(testCase, testConfiguration);
                    testDescriptor.RunTest(testConfiguration);
                });
            });
        }
        public void CollectionValueTest()
        {
            EdmModel model       = new EdmModel();
            var      complexType = new EdmComplexType("TestModel", "ComplexType").Property("Name", EdmPrimitiveTypeKind.String, true);

            model.AddElement(complexType);
            var owningType = new EdmEntityType("TestModel", "OwningType");

            owningType.AddKeys(owningType.AddStructuralProperty("ID", EdmCoreModel.Instance.GetInt32(false)));
            owningType.AddStructuralProperty("PrimitiveCollection", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)));
            model.AddElement(owningType);
            model.Fixup();

            var primitiveMultiValue = PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)").Item(42).Item(43);

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "null collection in request - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)"))
                                       .JsonRepresentation("{\"value\":null }")
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "value", "Collection(Edm.Int32)")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "null collection in response - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)"))
                                       .JsonRepresentation(
                        "{" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#Collection(Edm.Int32)\"," +
                        "\"value\":null" +
                        "}")
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNullableType", "value", "Collection(Edm.Int32)")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Primitive value for collection - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)")
                                                               .JsonRepresentation("42"))
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartArray", "PrimitiveValue")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Object value for collection - should fail.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)")
                                                               .JsonRepresentation("{}"))
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetectedWithPropertyName", "StartArray", "StartObject", "value")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Simple primitive collection.",
                    PayloadEdmModel  = model,
                    PayloadElement   = PayloadBuilder.Property("PrimitiveCollection",
                                                               primitiveMultiValue
                                                               .JsonRepresentation("[42,43]")
                                                               .AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    ExpectedResultPayloadElement = tc => tc.IsRequest
                        ? PayloadBuilder.Property(string.Empty, primitiveMultiValue)
                        : PayloadBuilder.Property("PrimitiveCollection", primitiveMultiValue)
                },
            };

            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);
            });
        }
Exemple #19
0
        public void ComplexValueWithMetadataTest()
        {
            // Use some standard complex value payloads first
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, true);

            // Add metadata validation tests
            EdmModel model            = new EdmModel();
            var      innerComplexType = model.ComplexType("InnerComplexType");

            innerComplexType.AddStructuralProperty("name", EdmCoreModel.Instance.GetString(true));

            var complexType = model.ComplexType("ComplexType");

            complexType.AddStructuralProperty("number", EdmPrimitiveTypeKind.Int32);
            complexType.AddStructuralProperty("string", EdmCoreModel.Instance.GetString(true));
            complexType.AddStructuralProperty("complex", MetadataUtils.ToTypeReference(innerComplexType, true));

            var entityType = model.EntityType("EntityType");

            entityType.KeyProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            model.Fixup();

            // Test that different types of properties not present in the metadata all fail
            IEnumerable <PropertyInstance> undeclaredPropertyTestCases = new PropertyInstance[]
            {
                PayloadBuilder.PrimitiveProperty("undeclared", 42),
                PayloadBuilder.Property("undeclared", PayloadBuilder.ComplexValue(innerComplexType.FullName())),
                PayloadBuilder.Property("undeclared", PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))),
                PayloadBuilder.Property("undeclared", PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.InnerComplexType"))),
            };

            testDescriptors = testDescriptors.Concat(
                undeclaredPropertyTestCases.Select(tc =>
            {
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType)
                                     .Property(tc),
                    PayloadEdmModel = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", "undeclared", "TestModel.ComplexType"),
                });
            }));

            testDescriptors = testDescriptors.Concat(new[]
            {
                // Property which should take typename not from value but from the parent metadata
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType)
                                     .Property("complex", PayloadBuilder.ComplexValue(innerComplexType.FullName()).PrimitiveProperty("name", null)
                                               .JsonRepresentation("{ \"name\" : null }").XmlRepresentation("<d:name m:null=\"true\" />")
                                               .AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })),
                    PayloadEdmModel = model,
                },
                // Property which is declared in the metadata but with a different type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType)
                                     .Property("complex", PayloadBuilder.ComplexValue(complexType.FullName())),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncompatibleType", "TestModel.ComplexType", "TestModel.InnerComplexType"),
                },
                // Property which is declared in the metadata but with a wrong kind
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType)
                                     .Property("complex", PayloadBuilder.ComplexValue(entityType.FullName())),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.EntityType", "Complex", "Entity"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.ComplexValue("").WithTypeAnnotation(complexType),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", string.Empty)
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.ComplexValue("TestModel.NonExistant").WithTypeAnnotation(complexType),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "TestModel.NonExistant"),
                },
            });

            // Wrap the complex type in a property
            testDescriptors = testDescriptors
                              .Select((td, index) => new PayloadReaderTestDescriptor(td)
            {
                PayloadDescriptor = td.PayloadDescriptor.InProperty("propertyName" + index)
            })
                              .SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            // Handcrafted cases
            testDescriptors = testDescriptors.Concat(new[]
            {
                // Top-level complex property without expected type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement  = PayloadBuilder.Property("property", PayloadBuilder.ComplexValue(complexType.FullName()).PrimitiveProperty("number", 42)),
                    PayloadEdmModel = model
                },
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                var property = testDescriptor.PayloadElement as PropertyInstance;
                if (property != null && testConfiguration.Format == ODataFormat.Atom)
                {
                    property.Name = null;
                }
                testDescriptor.RunTest(testConfiguration);
            });
        }