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); }); }
/// <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, }); }
/// <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, }); }
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); }); }
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); }); }
public void TopLevelPropertiesWithMetadataTest() { IEnumerable <PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreatePrimitiveValueTestDescriptors(this.Settings); testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, true)); testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateCollectionTestDescriptors(this.Settings, true)); testDescriptors = testDescriptors.Select(collectionTestDescriptor => collectionTestDescriptor.InProperty("propertyName")); testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td)); // Limit to only top-level property payloads testDescriptors = testDescriptors.Where(td => td.PayloadElement is PropertyInstance); // Add a couple of invalid cases which use a standard model EdmModel model = new EdmModel(); model.ComplexType("UnusedComplexType"); EdmEntityType unusedEntityType = model.EntityType("UnusedEntityType"); unusedEntityType.AddKeys(unusedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false)); unusedEntityType.Property("Name", EdmPrimitiveTypeKind.String, isNullable: false); EdmEntityType streamPropertyEntityType = model.EntityType("EntityTypeWithStreamProperty"); streamPropertyEntityType.AddKeys(streamPropertyEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false)); streamPropertyEntityType.AddStructuralProperty("Video", EdmPrimitiveTypeKind.Stream, isNullable: false); streamPropertyEntityType.Property("NonStreamProperty", EdmPrimitiveTypeKind.Boolean, isNullable: false); EdmEntityType navigationPropertyEntityType = model.EntityType("EntityTypeWithNavigationProperty"); navigationPropertyEntityType.AddKeys(navigationPropertyEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false)); navigationPropertyEntityType.NavigationProperty("Navigation", streamPropertyEntityType); model.Fixup(); EdmEntityContainer container = model.EntityContainer as EdmEntityContainer; EdmFunction nameFunction = new EdmFunction(container.Namespace, "NameFunctionImport", EdmCoreModel.Instance.GetInt32(false), false /*isBound*/, null, false /*isComposable*/); model.AddElement(nameFunction); container.AddFunctionImport("NameFunctionImport", nameFunction); model.Fixup(); var videoPropertyType = model.GetEntityType("TestModel.EntityTypeWithStreamProperty").Properties().Single(p => p.Name == "Video").Type; var explicitTestDescriptors = new[] { // Non existant type name new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("TestModel.NonExistantType")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "TestModel.NonExistantType"), // This test has different meaning in JSON-L (no expected type + non-existent typename) SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, // Existing type name without namespace new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("UnusedComplexType")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "UnusedComplexType"), // This test has different meaning in JSON-L (no expected type + non-existent typename) SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, // Existing type of wrong kind new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("TestModel.UnusedEntityType")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectValueTypeKind", "TestModel.UnusedEntityType", "Entity"), // This test has different meaning in JSON-L SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, // A stream is not allowed in a property with a non-stream property kind. new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.EntityTypeWithStreamProperty").StreamProperty("NonStreamProperty", "http://readlink", "http://editlink"), PayloadEdmModel = model, ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings) { ExpectedException = tc.Format == ODataFormat.Atom ? tc.IsRequest ? null : ODataExpectedExceptions.ODataException("ValidationUtils_MismatchPropertyKindForStreamProperty", "NonStreamProperty") : tc.Format == ODataFormat.Json ? ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithWrongType", "NonStreamProperty", "Edm.Boolean") : ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject") }, }, // Top-level property of stream type is not allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(videoPropertyType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeStream"), }, // Top-level deferred navigation property is not allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(streamPropertyEntityType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeEntityKind"), }, // Top-level expanded navigation property is not allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(streamPropertyEntityType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeEntityKind"), }, // Top-level collection without expected type and without type name is not allowed (when metadata is specified) new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName2", PayloadBuilder.PrimitiveMultiValue(null).Item(42)), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ValueWithoutType"), // This test has different meaning in JSON-L (no expected type + non-existent typename) SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, // Top-level complex property without expected type and without type name is not allowed (when metadata is specified) new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue(null).PrimitiveProperty("foo", "bar")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_ValueWithoutType"), // This test has different meaning in JSON-L (no expected type + non-existent typename) SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, }; testDescriptors = testDescriptors.Concat(explicitTestDescriptors); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations, (testDescriptor, testConfiguration) => { var property = testDescriptor.PayloadElement as PropertyInstance; if (property != null && testConfiguration.Format == ODataFormat.Atom) { property.Name = null; } testDescriptor.RunTest(testConfiguration); }); }
public void 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); }); }