Exemple #1
0
        public void ComplexValueNoMetadataTest()
        {
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Single property with string value
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", "foo")
                                     .XmlValueRepresentation("<d:prop>foo</d:prop>", null, null)
                },
                // Single property - empty element
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", string.Empty)
                                     .XmlValueRepresentation("<d:prop/>", null, null)
                },
                // Two properties
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", "foo")
                                     .PrimitiveProperty("prop2", 42)
                                     .XmlValueRepresentation("<d:prop m:type='Edm.String'>foo</d:prop><d:prop2 m:type='Edm.Int32'>42</d:prop2>", null, null)
                },
                // Elements in non-OData namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", "foo")
                                     .XmlValueRepresentation("<m:foo/><!----><?value?><bar>some</bar><nested><d:ignored/></nested><d:prop>foo</d:prop>", null, null)
                },
                // Two properties - first called "element"
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("element", "foo")
                                     .PrimitiveProperty("prop2", 42)
                                     .XmlValueRepresentation("<d:element>foo</d:element><d:prop2 m:type='Edm.Int32'>42</d:prop2>", null, null)
                },
                // Two properties - second called "element"
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", "foo")
                                     .PrimitiveProperty("element", 42)
                                     .XmlValueRepresentation("<d:prop>foo</d:prop><d:element m:type='Edm.Int32'>42</d:element>", null, null)
                },
                // Single property - element in non-OData metadata namespace with OData element in it
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", string.Empty)
                                     .XmlValueRepresentation("<d:prop/><bar><d:prop/></bar>", null, null)
                },
                // Single property - element in non-OData metadata namespace with OData element called "element" in it
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", string.Empty)
                                     .XmlValueRepresentation("<d:prop/><bar><d:element/></bar>", null, null)
                },
                // Single property - element in OData metadata namespace with OData element in it
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", string.Empty)
                                     .XmlValueRepresentation("<d:prop/><m:bar><d:prop/></m:bar>", null, null)
                },
                // Single property - element in OData metadata namespace with OData element called "element" in it
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue(null)
                                     .PrimitiveProperty("prop", string.Empty)
                                     .XmlValueRepresentation("<d:prop/><m:bar><d:element/></m:bar>", null, null)
                },
                // Complex with type name, but no model
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue("MyTypeName")
                                     .PrimitiveProperty("prop", "foo")
                                     .XmlValueRepresentation("<d:prop>foo</d:prop>", "MyTypeName", null)
                },
                // Empty complex with type name, but no model - still should recognize that the type name is not primitive and read as complex
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ComplexValue("MyTypeName")
                                     .XmlValueRepresentation(null, "MyTypeName", null)
                },
            };

            // Wrap it in property (manually to prevent any type annotations)
            testDescriptors = testDescriptors.Select(td =>
                                                     new PayloadReaderTestDescriptor(td)
            {
                PayloadElement = PayloadBuilder.Property(null, td.PayloadElement)
            });

            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 #3
0
        /// <summary>
        /// Creates several PayloadTestDescriptors containing Batch Responses
        /// </summary>
        /// <param name="requestManager">Used for building the requests/responses.</param>
        /// <param name="model">The model to use for adding additional types.</param>
        /// <param name="withTypeNames">Whether or not to use full type names.</param>
        /// <returns>PayloadTestDescriptors</returns>
        public static IEnumerable <PayloadTestDescriptor> CreateBatchResponseTestDescriptors(
            IODataRequestManager requestManager,
            EdmModel model,
            bool withTypeNames = false)
        {
            EdmEntityType  personType = null;
            EdmComplexType carType    = null;

            if (model != null)
            {
                //TODO: CLONE for EdmModel
                //model = model.Clone();

                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType    = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;

                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    model.AddElement(carType);
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true);
                }

                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    model.AddElement(personType);
                    personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());

                    EdmEntityContainer container = (EdmEntityContainer)model.EntityContainer;
                    if (container == null)
                    {
                        container = new EdmEntityContainer("TestModel", "DefaultContainer");
                        model.AddElement(container);
                        container.AddEntitySet("Customers", personType);
                        container.AddEntitySet("TFPerson", personType);
                    }
                }
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                                          .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                                          .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));
            ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance)
                                          .WithTypeAnnotation(carType);

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                                            .Property("Id", PayloadBuilder.PrimitiveValue(1))
                                            .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                                            .Property("Car", carInstance)
                                            .WithTypeAnnotation(personType);

            ODataErrorPayload errorInstance = PayloadBuilder.Error("ErrorCode")
                                              .Message("ErrorValue")
                                              .InnerError(
                PayloadBuilder.InnerError().Message("InnerErrorMessage").StackTrace("InnerErrorStackTrace").TypeName("InnerErrorTypeName"));

            var carPropertyPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = carProperty,
                PayloadEdmModel = model
            };

            var emptyPayload = new PayloadTestDescriptor()
            {
                PayloadEdmModel = CreateEmptyEdmModel()
            };

            var personPayload = new PayloadTestDescriptor()
            {
                // This payload will be serialised to JSON so we need the annotation to mark it as a response.
                PayloadElement = personInstance.AddAnnotation(new PayloadFormatVersionAnnotation()
                {
                    Response = true, ResponseWrapper = true
                }),
                PayloadEdmModel = model
            };

            var errorPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = errorInstance,
                PayloadEdmModel = model,
            };

            // response operation with a status code of 5 containing a complex instance
            var carPropertyPayloadOperation = carPropertyPayload.InResponseOperation(5, requestManager);
            // response operation with no payload and a status code of 200
            var emptyPayloadOperation = emptyPayload.InResponseOperation(200, requestManager);
            // response operation with a status code of 418 containing an entity instance
            var personPayloadOperation = personPayload.InResponseOperation(418, requestManager, MimeTypes.ApplicationJsonLight);
            // response operation with a status code of 404 containing an error instance
            var errorPayloadOperation = errorPayload.InResponseOperation(404, requestManager);

            // changeset with multiple operations
            var twoOperationsChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation }, requestManager);
            // changesets with a single operation
            var oneOperationChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { personPayloadOperation }, requestManager);
            var oneErrorChangeset     = BatchUtils.GetResponseChangeset(new IMimePart[] { errorPayloadOperation }, requestManager);
            // empty changeset
            var emptyChangeset = BatchUtils.GetResponseChangeset(new IMimePart[] { }, requestManager);

            // Empty Batch
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] {  })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")),
                PayloadEdmModel = emptyPayload.PayloadEdmModel,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Single Operation
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Multiple Operations
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, emptyPayloadOperation, errorPayloadOperation, personPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Single Changeset
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Multiple Changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            // Operations and changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { twoOperationsChangeset, carPropertyPayloadOperation, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { carPropertyPayloadOperation, oneOperationChangeset, emptyPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(new IMimePart[] { errorPayloadOperation, carPropertyPayloadOperation, emptyPayloadOperation, twoOperationsChangeset, oneOperationChangeset })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchResponsePayload(
                    new IMimePart[] { oneErrorChangeset, carPropertyPayloadOperation, emptyChangeset, emptyPayloadOperation, twoOperationsChangeset, personPayloadOperation, oneOperationChangeset, errorPayloadOperation })
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => tc.IsRequest,
            });
        }
Exemple #4
0
        /// <summary>
        /// Creates several PayloadTestDescriptors containing Batch Requests
        /// </summary>
        /// <param name="requestManager">Used for building the requests</param>
        /// <param name="model">The model to use for adding additional types.</param>
        /// <param name="withTypeNames">Whether or not to use full type names.</param>
        /// <returns>PayloadTestDescriptors</returns>
        public static IEnumerable <PayloadTestDescriptor> CreateBatchRequestTestDescriptors(
            IODataRequestManager requestManager,
            EdmModel model,
            bool withTypeNames = false)
        {
            ExceptionUtilities.CheckArgumentNotNull(requestManager, "requestManager");
            EdmEntityType      personType       = null;
            EdmComplexType     carType          = null;
            EdmEntitySet       personsEntitySet = null;
            EdmEntityContainer container        = model.EntityContainer as EdmEntityContainer;

            if (model != null)
            {
                //TODO: Clone EdmModel
                //model = model.Clone();

                if (container == null)
                {
                    container = new EdmEntityContainer("TestModel", "DefaultContainer");
                    model.AddElement(container);
                }

                personType = model.FindDeclaredType("TestModel.TFPerson") as EdmEntityType;
                carType    = model.FindDeclaredType("TestModel.TFCar") as EdmComplexType;

                // Create the metadata types for the entity instance used in the entity set
                if (carType == null)
                {
                    carType = new EdmComplexType("TestModel", "TFCar");
                    model.AddElement(carType);
                    carType.AddStructuralProperty("Make", EdmPrimitiveTypeKind.String, true);
                    carType.AddStructuralProperty("Color", EdmPrimitiveTypeKind.String, true);
                }

                if (personType == null)
                {
                    personType = new EdmEntityType("TestModel", "TFPerson");
                    model.AddElement(personType);
                    personType.AddKeys(personType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    personType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String, true);
                    personType.AddStructuralProperty("Car", carType.ToTypeReference());
                    container.AddEntitySet("Customers", personType);
                }

                personsEntitySet = container.AddEntitySet("People", personType);
            }

            ComplexInstance carInstance = PayloadBuilder.ComplexValue(withTypeNames ? "TestModel.TFCar" : null)
                                          .Property("Make", PayloadBuilder.PrimitiveValue("Ford"))
                                          .Property("Color", PayloadBuilder.PrimitiveValue("Blue"));
            ComplexProperty carProperty = (ComplexProperty)PayloadBuilder.Property("Car", carInstance)
                                          .WithTypeAnnotation(personType);

            EntityInstance personInstance = PayloadBuilder.Entity(withTypeNames ? "TestModel.TFPerson" : null)
                                            .Property("Id", PayloadBuilder.PrimitiveValue(1))
                                            .Property("Name", PayloadBuilder.PrimitiveValue("John Doe"))
                                            .Property("Car", carInstance)
                                            .WithTypeAnnotation(personType);

            var carPropertyPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = carProperty,
                PayloadEdmModel = model
            };

            var emptyPayload = new PayloadTestDescriptor()
            {
                PayloadEdmModel = CreateEmptyEdmModel()
            };

            var personPayload = new PayloadTestDescriptor()
            {
                PayloadElement  = personInstance,
                PayloadEdmModel = model
            };

            var root      = ODataUriBuilder.Root(new Uri("http://www.odata.org/service.svc"));
            var entityset = ODataUriBuilder.EntitySet(personsEntitySet);

            // Get operations
            var queryOperation1 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager);
            var queryOperation2 = emptyPayload.InRequestOperation(HttpVerb.Get, new ODataUri(new ODataUriSegment[] { root }), requestManager);

            // Post operation containing a complex property
            var postOperation = carPropertyPayload.InRequestOperation(HttpVerb.Post, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager, MimeTypes.ApplicationJsonLight);
            // Delete operation with no payload
            var deleteOperation = emptyPayload.InRequestOperation(HttpVerb.Delete, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager);
            // Put operation where the payload is an EntityInstance
            var putOperation = personPayload.InRequestOperation(HttpVerb.Put, new ODataUri(new ODataUriSegment[] { root, entityset }), requestManager);

            // A changeset containing a delete with no payload and a put
            var twoOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { postOperation, deleteOperation }, requestManager);
            // A changeset containing a delete with no payload
            var oneOperationChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { deleteOperation }, requestManager);
            // A changeset containing a put, post and delete
            var threeOperationsChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { putOperation, postOperation, deleteOperation }, requestManager);
            // A changeset containing no operations
            var emptyChangeset = BatchUtils.GetRequestChangeset(new IMimePart[] { }, requestManager);

            // Empty Batch
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload()
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_emptybatch")),
                PayloadEdmModel = emptyPayload.PayloadEdmModel,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Single Operation
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singleoperation")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Multiple Operations
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multipleoperations")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Single Changeset
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_singlechangeset")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Multiple Changesets (different content types)
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, oneOperationChangeset, emptyChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_multiplechangesets")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            // Operations and changesets
            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(twoOperationsChangeset, queryOperation1, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_1")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, oneOperationChangeset, queryOperation2)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_2")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, queryOperation2, twoOperationsChangeset, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_3")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, threeOperationsChangeset, queryOperation2, twoOperationsChangeset, queryOperation1, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_4")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });

            yield return(new PayloadTestDescriptor()
            {
                PayloadElement = PayloadBuilder.BatchRequestPayload(queryOperation1, emptyChangeset, queryOperation1, threeOperationsChangeset, queryOperation2, oneOperationChangeset)
                                 .AddAnnotation(new BatchBoundaryAnnotation("bb_operationsandchangesets_5")),
                PayloadEdmModel = model,
                SkipTestConfiguration = (tc) => !tc.IsRequest,
            });
        }
Exemple #5
0
        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)));
            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.ComplexMultiValue("Collection(TestModel.ComplexType)").Item(
                PayloadBuilder.ComplexValue("TestModel.ComplexType")
                .PrimitiveProperty("Name", "Value")
                .AddAnnotation(new SerializationTypeNameTestAnnotation()
            {
                TypeName = null
            }))
                                      .JsonRepresentation("[{\"Name\":\"Value\"}]")
                                      .AddAnnotation(new SerializationTypeNameTestAnnotation()
            {
                TypeName = null
            });

            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("{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\":true }")
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    SkipTestConfiguration = tc => !tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullValueForNonNullableType", "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)\"," +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\":true" +
                        "}")
                                       .ExpectedProperty(owningType, "PrimitiveCollection"),
                    SkipTestConfiguration = tc => tc.IsRequest,
                    ExpectedException     = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullValueForNonNullableType", "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)
                },
                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);
            });
        }
        public void OpenComplexTopLevelPropertiesTest()
        {
            IEdmModel model = TestModels.BuildTestModel();

            var addressType = model.FindDeclaredType("TestModel.Address");

            var testCases = new OpenPropertyTestCase[]
            {
                new OpenPropertyTestCase
                {
                    DebugDescription     = "Empty complex open property with type information.",
                    ExpectedProperty     = PayloadBuilder.Property("OpenProperty", PayloadBuilder.ComplexValue("TestModel.Address")),
                    ExpectedPropertyType = addressType.ToTypeReference(),
                    JsonTypeInformation  = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.Address\"",
                    Json = "{0}{1}",
                },
                new OpenPropertyTestCase
                {
                    DebugDescription     = "Complex property with data.",
                    ExpectedProperty     = PayloadBuilder.Property("OpenProperty", PayloadBuilder.ComplexValue("TestModel.Address").PrimitiveProperty("Street", "First")),
                    ExpectedPropertyType = addressType.ToTypeReference(),
                    JsonTypeInformation  = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.Address\",",
                    Json = "{0}{1}\"Street\":\"First\"",
                },

                new OpenPropertyTestCase
                {
                    DebugDescription     = "Complex property with data.",
                    ExpectedProperty     = PayloadBuilder.Property("OpenProperty", PayloadBuilder.ComplexValue("TestModel.Address").PrimitiveProperty("Street", "First")),
                    ExpectedPropertyType = addressType.ToTypeReference(),
                    JsonTypeInformation  = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.Address\",",
                    Json = "{0}{1}\"Street\":\"First\"",
                },
            };

            bool[] withExpectedTypes = new bool[] { true, false };
            bool[] withPayloadTypes  = new bool[] { true, false };
            bool[] includeContextUri = new bool[] { true, false };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                withExpectedTypes,
                withPayloadTypes,
                includeContextUri,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testCase, withExpectedType, withPayloadType, withContextUri, testConfiguration) =>
            {
                if (withContextUri && testConfiguration.IsRequest)
                {
                    return;
                }

                PropertyInstance property       = testCase.ExpectedProperty.DeepCopy();
                ComplexProperty complexProperty = (ComplexProperty)property;
                ComplexInstance complexValue    = complexProperty.Value;
                bool isEmpty = !complexValue.Properties.Any();

                string contextUri = withContextUri ? "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.Address\"," : string.Empty;
                string json       = string.Format(
                    CultureInfo.InvariantCulture,
                    testCase.Json,
                    contextUri,
                    withPayloadType ? testCase.JsonTypeInformation : string.Empty);

                if (isEmpty && json.EndsWith(","))
                {
                    json = json.Substring(0, json.Length - 1);
                }

                if (withExpectedType)
                {
                    property = property.ExpectedPropertyType(testCase.ExpectedPropertyType);
                }

                if (!withPayloadType)
                {
                    complexProperty.Value.AddAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    });
                }

                ExpectedException expectedException = testCase.ExpectedException;
                if (!withContextUri && !testConfiguration.IsRequest)
                {
                    expectedException = ODataExpectedExceptions.ODataException("ODataJsonLightDeserializer_ContextLinkNotFoundAsFirstProperty");
                }
                else if (!withExpectedType && !withPayloadType && !withContextUri)
                {
                    string firstPropertyName = isEmpty ? null : complexValue.Properties.First().Name;

                    // An open property without expected and payload type cannot be read; expect an exception.
                    expectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ResourceWithoutType");
                }

                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = testCase.DebugDescription + "[Expected type: " + withExpectedType + ", payload type: " + withPayloadType + "]",
                    PayloadElement   = property
                                       .JsonRepresentation("{" + json + "}"),
                    PayloadEdmModel   = model,
                    ExpectedException = expectedException,
                };

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

                testDescriptor.RunTest(testConfiguration);
            });
        }
Exemple #7
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);
            });
        }
Exemple #8
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);
            });
        }
Exemple #9
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);
                });
            });
        }
        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 void StreamWriteReadEntry()
        {
            EdmModel        model        = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            ComplexInstance complexValue = ODataStreamingTestCase.GetComplexInstanceWithManyPrimitiveProperties(model);

            var payloadDescriptors = new PayloadTestDescriptor[]
            {
                // Multiple nesting of Complex Values and Multiple Values.
                new PayloadTestDescriptor()
                {
                    PayloadElement        = PayloadBuilder.Property("propertyName", complexValue),
                    PayloadEdmModel       = model.Clone(),
                    SkipTestConfiguration = (tc) => tc.Version < ODataVersion.V4
                }.InComplexValue().InCollection().InProperty().InComplexValue().InCollection().InProperty().InComplexValue()
                .InCollection().InProperty().InComplexValue().InCollection().InProperty().InEntity(),

                // Multiple nesting of Complex Values.
                new PayloadTestDescriptor()
                {
                    PayloadElement  = PayloadBuilder.Property("propertyName", complexValue),
                    PayloadEdmModel = model.Clone(),
                }.InComplexValue().InProperty().InComplexValue().InProperty().InComplexValue().InProperty()
                .InComplexValue().InProperty().InComplexValue().InProperty().InComplexValue().InProperty().InEntity(1, 0),

                // Entry With an Expanded Link which is an entry containing a Complex collection.
                new PayloadTestDescriptor()
                {
                    PayloadElement        = complexValue,
                    PayloadEdmModel       = model.Clone(),
                    SkipTestConfiguration = (tc) => tc.Version < ODataVersion.V4
                }.InCollection(1, 1).InProperty().InComplexValue().InCollection().InProperty().InEntity().InEntryWithExpandedLink(/*singletonRelationship*/ true),

                // Entry With an Expanded Link which is a Feed containing an Entry with Complex collection properties.
                new PayloadTestDescriptor()
                {
                    PayloadElement        = complexValue,
                    PayloadEdmModel       = model.Clone(),
                    SkipTestConfiguration = (tc) => tc.Version < ODataVersion.V4
                }.InCollection(1, 2).InProperty().InComplexValue(1, 1).InCollection(1, 0).InProperty().InEntity(1, 1).InFeed(2).InEntryWithExpandedLink(),

                // Entry With Nested Expanded Links which contain Entries.
                new PayloadTestDescriptor()
                {
                    PayloadElement  = PayloadBuilder.Property("propertyName", complexValue),
                    PayloadEdmModel = model.Clone(),
                }.InEntity(1, 1, ODataVersion.V4).InEntryWithExpandedLink(/*singletonRelationship*/ true).InEntryWithExpandedLink(/*singletonRelationship*/ true)
                .InEntryWithExpandedLink(/*singletonRelationship*/ true).InEntryWithExpandedLink(/*singletonRelationship*/ true)
                .InEntryWithExpandedLink(/*singletonRelationship*/ true).InEntryWithExpandedLink(/*singletonRelationship*/ true),

                // Entry with inline expanded feed association to an arbitrary depth (7) where the expanded feed has no entries
                new PayloadTestDescriptor()
                {
                    PayloadElement  = PayloadBuilder.EntitySet().WithTypeAnnotation(model.FindDeclaredType("TestModel.OfficeType")),
                    PayloadEdmModel = model.Clone(),
                }.InEntryWithExpandedLink().InFeed(2).InEntryWithExpandedLink().InFeed(2).InEntryWithExpandedLink().InFeed(2).InEntryWithExpandedLink()
                .InFeed(2).InEntryWithExpandedLink(),
            };

            var testDescriptors = this.PayloadDescriptorsToStreamDescriptors(payloadDescriptors);

            //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent.Where(tc => tc.Synchronous && tc.Format == ODataFormat.Atom),
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
        /// <summary>
        /// Creates a set of interesting entity instances along with metadata.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <param name="model">If non-null, the method creates complex types for the complex values and adds them to the model.</param>
        /// <param name="withTypeNames">true if the payloads should specify type names.</param>
        /// <returns>List of test descriptors with interesting entity instances as payload.</returns>
        public static IEnumerable <PayloadTestDescriptor> CreateEntityInstanceTestDescriptors(
            EdmModel model,
            bool withTypeNames)
        {
            IEnumerable <PrimitiveValue>             primitiveValues       = TestValues.CreatePrimitiveValuesWithMetadata(fullSet: false);
            IEnumerable <ComplexInstance>            complexValues         = TestValues.CreateComplexValues(model, withTypeNames, fullSet: false);
            IEnumerable <NamedStreamInstance>        streamReferenceValues = TestValues.CreateStreamReferenceValues(fullSet: false);
            IEnumerable <PrimitiveMultiValue>        primitiveMultiValues  = TestValues.CreatePrimitiveCollections(withTypeNames, fullSet: false);
            IEnumerable <ComplexMultiValue>          complexMultiValues    = TestValues.CreateComplexCollections(model, withTypeNames, fullSet: false);
            IEnumerable <NavigationPropertyInstance> navigationProperties  = TestValues.CreateDeferredNavigationLinks();

            // NOTE we have to copy the EntityModelTypeAnnotation on the primitive value to the NullPropertyInstance for null values since the
            //      NullPropertyInstance does not expose a value. We will later copy it back to the value we generate for the null property.
            IEnumerable <PropertyInstance> primitiveProperties =
                primitiveValues.Select((pv, ix) => PayloadBuilder.Property("PrimitiveProperty" + ix, pv).CopyAnnotation <PropertyInstance, EntityModelTypeAnnotation>(pv));
            IEnumerable <PropertyInstance> complexProperties             = complexValues.Select((cv, ix) => PayloadBuilder.Property("ComplexProperty" + ix, cv));
            IEnumerable <PropertyInstance> primitiveMultiValueProperties = primitiveMultiValues.Select((pmv, ix) => PayloadBuilder.Property("PrimitiveMultiValueProperty" + ix, pmv));
            IEnumerable <PropertyInstance> complexMultiValueProperties   = complexMultiValues.Select((cmv, ix) => PayloadBuilder.Property("ComplexMultiValueProperty" + ix, cmv));

            PropertyInstance[][] propertyMatrix = new PropertyInstance[6][];
            propertyMatrix[0] = primitiveProperties.ToArray();
            propertyMatrix[1] = complexProperties.ToArray();
            propertyMatrix[2] = streamReferenceValues.ToArray();
            propertyMatrix[3] = primitiveMultiValueProperties.ToArray();
            propertyMatrix[4] = complexMultiValueProperties.ToArray();
            propertyMatrix[5] = navigationProperties.ToArray();

            IEnumerable <PropertyInstance[]> propertyCombinations = propertyMatrix.ColumnCombinations(0, 1, 6);

            int count = 0;

            foreach (PropertyInstance[] propertyCombination in propertyCombinations)
            {
                // build the entity type, add it to the model
                EdmEntityType      generatedEntityType = null;
                string             typeName            = "PGEntityType" + count;
                EdmEntityContainer container           = null;
                EdmEntitySet       entitySet           = null;
                if (model != null)
                {
                    // generate a new type with the auto-generated name, check that no type with this name exists and add the default key property to it.
                    Debug.Assert(model.FindDeclaredType(typeName) == null, "Entity type '" + typeName + "' already exists.");
                    generatedEntityType = new EdmEntityType("TestModel", typeName);
                    generatedEntityType.AddKeys(generatedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    model.AddElement(generatedEntityType);
                    container = model.EntityContainer as EdmEntityContainer;

                    if (container == null)
                    {
                        container = new EdmEntityContainer("TestModel", "DefaultNamespace");
                        model.AddElement(container);
                    }

                    entitySet = container.AddEntitySet(typeName, generatedEntityType);
                }

                EntityInstance entityInstance = PayloadBuilder.Entity("TestModel." + typeName)
                                                .Property("Id", PayloadBuilder.PrimitiveValue(count).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false)));

                for (int i = 0; i < propertyCombination.Length; ++i)
                {
                    PropertyInstance currentProperty = propertyCombination[i];
                    entityInstance.Add(currentProperty);

                    if (model != null)
                    {
                        if (entitySet == null)
                        {
                            entitySet = container.FindEntitySet(typeName) as EdmEntitySet;
                        }

                        switch (currentProperty.ElementType)
                        {
                        case ODataPayloadElementType.ComplexProperty:
                            ComplexProperty complexProperty = (ComplexProperty)currentProperty;
                            generatedEntityType.AddStructuralProperty(complexProperty.Name,
                                                                      complexProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            break;

                        case ODataPayloadElementType.PrimitiveProperty:
                            PrimitiveProperty primitiveProperty = (PrimitiveProperty)currentProperty;
                            if (primitiveProperty.Value == null)
                            {
                                generatedEntityType.AddStructuralProperty(
                                    primitiveProperty.Name,
                                    PayloadBuilder.PrimitiveValueType(null));
                            }
                            else
                            {
                                generatedEntityType.AddStructuralProperty(primitiveProperty.Name,
                                                                          primitiveProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            }
                            break;

                        case ODataPayloadElementType.NamedStreamInstance:
                            NamedStreamInstance streamProperty = (NamedStreamInstance)currentProperty;
                            generatedEntityType.AddStructuralProperty(streamProperty.Name, EdmPrimitiveTypeKind.Stream);
                            break;

                        case ODataPayloadElementType.EmptyCollectionProperty:
                            throw new NotImplementedException();

                        case ODataPayloadElementType.NavigationPropertyInstance:
                            NavigationPropertyInstance navigationProperty = (NavigationPropertyInstance)currentProperty;
                            var navProperty = generatedEntityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
                            {
                                ContainsTarget     = false,
                                Name               = navigationProperty.Name,
                                Target             = generatedEntityType,
                                TargetMultiplicity = EdmMultiplicity.One
                            });
                            entitySet.AddNavigationTarget(navProperty, entitySet);
                            break;

                        case ODataPayloadElementType.ComplexMultiValueProperty:
                            ComplexMultiValueProperty complexMultiValueProperty = (ComplexMultiValueProperty)currentProperty;
                            generatedEntityType.AddStructuralProperty(complexMultiValueProperty.Name,
                                                                      complexMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            break;

                        case ODataPayloadElementType.PrimitiveMultiValueProperty:
                            PrimitiveMultiValueProperty primitiveMultiValueProperty = (PrimitiveMultiValueProperty)currentProperty;
                            generatedEntityType.AddStructuralProperty(primitiveMultiValueProperty.Name,
                                                                      primitiveMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            break;

                        default:
                            throw new NotSupportedException("Unsupported element type found : " + propertyCombination[i].ElementType);
                        }
                    }
                }

                if (generatedEntityType != null)
                {
                    entityInstance.AddAnnotation(new EntityModelTypeAnnotation(generatedEntityType.ToTypeReference(true)));
                }

                yield return(new PayloadTestDescriptor()
                {
                    PayloadElement = entityInstance, PayloadEdmModel = model
                });

                count++;
            }
        }
        public void ComplexValueTest()
        {
            var injectedProperties = new[]
            {
                new
                {
                    InjectedJSON      = string.Empty,
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataAnnotationNamespacePrefix + "unknown\": { }",
                    ExpectedException = (ExpectedException)null
                },
                new
                {
                    InjectedJSON      = "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\": { }",
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties", JsonLightConstants.ODataContextAnnotationName)
                },
                new
                {
                    InjectedJSON      = "\"@custom.annotation\": null, \"@custom.annotation\": 42",
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationNotAllowed", "custom.annotation")
                },
            };

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

            EdmModel model = new EdmModel();

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

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

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

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

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

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

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

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

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = payloads.SelectMany(payload => injectedProperties.Select(injectedProperty =>
            {
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Property("TopLevelProperty", payload.ExpectedValue.DeepCopy()
                                                             .JsonRepresentation(string.Format(payload.Json, injectedProperty.InjectedJSON, string.IsNullOrEmpty(injectedProperty.InjectedJSON) ? string.Empty : ","))
                                                             // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                                             .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     .ExpectedProperty(owningType, "TopLevelProperty"),
                    PayloadEdmModel = model,
                    ExpectedException = injectedProperty.ExpectedException,
                    ExpectedResultPayloadElement = tc => tc.IsRequest
                        ? PayloadBuilder.Property(string.Empty, payload.ExpectedValue.DeepCopy()
                                                  .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                        : PayloadBuilder.Property("TopLevelProperty", payload.ExpectedValue.DeepCopy()
                                                  .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                });
            }));

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

            testDescriptors = testDescriptors.Concat(explicitPayloads.Select(payload =>
            {
                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Property("TopLevelProperty", payload.ExpectedPayload.DeepCopy()
                                                             .JsonRepresentation(payload.Json)
                                                             // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                                             .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                     // Don't reorder the properties on serialization
                                     .SetAnnotation(new JsonLightMaintainPropertyOrderAnnotation())
                                     .ExpectedProperty(owningType, "TopLevelProperty"),
                    PayloadEdmModel = model,
                    ExpectedException = payload.ExpectedException,
                    DebugDescription = payload.Description,
                    ExpectedResultPayloadElement = tc => tc.IsRequest
                        ? PayloadBuilder.Property(string.Empty, payload.ExpectedPayload.DeepCopy()
                                                  .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                        : PayloadBuilder.Property("TopLevelProperty", payload.ExpectedPayload.DeepCopy()
                                                  .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                });
            }));

            // Manual test descriptors
            testDescriptors = testDescriptors.Concat(new PayloadReaderTestDescriptor[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "null complex value in request.",
                    PayloadElement   = PayloadBuilder.Property("TopLevelProperty", PayloadBuilder.ComplexValue("TestModel.ComplexType", true)
                                                               // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                                               .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                       .JsonRepresentation("{\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\":true}")
                                       .ExpectedProperty(owningType, "TopLevelProperty"),
                    //PayloadModel = model,
                    PayloadEdmModel = model,
                    ExpectedResultPayloadElement = tc => PayloadBuilder.Property(string.Empty, PayloadBuilder.ComplexValue("TestModel.ComplexType", true)
                                                                                 .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })),
                    SkipTestConfiguration = tc => !tc.IsRequest
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "null complex value in response.",
                    PayloadElement   = PayloadBuilder.Property("TopLevelProperty", PayloadBuilder.ComplexValue("TestModel.ComplexType", true)
                                                               // JSON Light payloads don't store complex type names since the type can be inferred from the context URI and or API.
                                                               .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    }))
                                       .JsonRepresentation(
                        "{" +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.ComplexType\"," +
                        "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataNullAnnotationName + "\":true" +
                        "}")
                                       .ExpectedProperty(owningType, "TopLevelProperty"),
                    //PayloadModel = model,
                    PayloadEdmModel = model,
                    ExpectedResultPayloadElement = tc => PayloadBuilder.Property("TopLevelProperty", PayloadBuilder.ComplexValue("TestModel.ComplexType", true)
                                                                                 .SetAnnotation(new SerializationTypeNameTestAnnotation()
                    {
                        TypeName = null
                    })),
                    SkipTestConfiguration = tc => tc.IsRequest
                }
            });

            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);
            });
        }