public void OmitOperations() { var resource = new ODataResource(); ODataMessageWriterSettings settings = new ODataMessageWriterSettings(); settings.MetadataSelector = new TestMetadataSelector(); ODataResourceMetadataBuilder resourceMetadataBuilder = fullMetadataLevel.CreateResourceMetadataBuilder( resource, personTypeContext, null, HardCodedTestModel.GetPersonType(), new SelectedPropertiesNode(SelectedPropertiesNode.SelectionType.EntireSubtree), /*isResponse*/ true, /*keyAsSegment*/ false, /*requestUri*/ null, /*settings*/ settings); fullMetadataLevel.InjectMetadataBuilder(resource, resourceMetadataBuilder); var function = new ODataFunction { Metadata = new Uri(MetadataDocumentUri, "#function1"), }; var action = new ODataAction { Metadata = new Uri(MetadataDocumentUri, "#action2") }; resource.AddFunction(function); resource.AddAction(action); resource.MetadataBuilder.Should().BeSameAs(resourceMetadataBuilder); //metadataselector only allows for two HasHat functions to be written as metadata Assert.True(resource.Functions.Count() == 3); Assert.True(resource.Actions.Count() == 1); }
public void AddActionShouldAddActionToEntry() { ODataResource entry = ReaderUtils.CreateNewResource(); Assert.Empty(entry.Actions); entry.AddAction(new ODataAction()); Assert.Single(entry.Actions); }
public void AddActionShouldAddActionToEntry() { ODataResource entry = ReaderUtils.CreateNewResource(); entry.Actions.Count().Should().Be(0); entry.AddAction(new ODataAction()); entry.Actions.Count().Should().Be(1); }
public void InjectMetadataBuilderShouldSetBuilderOnEntryActions() { var entry = new ODataResource(); var builder = new TestEntityMetadataBuilder(entry); var action1 = new ODataAction { Metadata = new Uri(MetadataDocumentUri, "#action1") }; var action2 = new ODataAction { Metadata = new Uri(MetadataDocumentUri, "#action2") }; entry.AddAction(action1); entry.AddAction(action2); testSubject.InjectMetadataBuilder(entry, builder); action1.GetMetadataBuilder().Should().BeSameAs(builder); action2.GetMetadataBuilder().Should().BeSameAs(builder); }
public void InjectMetadataBuilderShouldNotSetBuilderOnEntryActions() { var entry = new ODataResource(); var builder = new TestEntityMetadataBuilder(entry); var action1 = new ODataAction { Metadata = new Uri("http://service/$metadata#action1", UriKind.Absolute) }; var action2 = new ODataAction { Metadata = new Uri("http://service/$metadata#action2", UriKind.Absolute) }; entry.AddAction(action1); entry.AddAction(action2); testSubject.InjectMetadataBuilder(entry, builder); action1.GetMetadataBuilder().Should().BeNull(); action2.GetMetadataBuilder().Should().BeNull(); }
public void NoOpMetadataBuilderShouldReturnActionsSetByUser() { ODataAction action = new ODataAction() { Metadata = new Uri("http://example.com/$metadata#Action"), Target = new Uri("http://example.com/Action"), Title = "ActionTitle" }; ODataResource entry = new ODataResource(); entry.AddAction(action); Assert.Single(new NoOpResourceMetadataBuilder(entry).GetActions().Where(a => a == action)); // Verify that the action information wasn't removed or changed. Assert.Equal(new Uri("http://example.com/$metadata#Action"), action.Metadata); Assert.Equal(new Uri("http://example.com/Action"), action.Target); Assert.Equal("ActionTitle", action.Title); }
public void ActionAndFunctionTest() { // <m:action Metadata=URI title?="title" target=URI /> Uri actionMetadata = new Uri("http://odata.org/test/$metadata#defaultAction"); Uri actionMetadata2 = new Uri("#action escaped relative metadata", UriKind.Relative); Uri actionMetadata3 = new Uri("../#action escaped relative metadata", UriKind.Relative); string actionTitle = "Default Action"; Uri actionTarget = new Uri("http://odata.org/defaultActionTarget"); Uri actionTarget2 = new Uri("http://odata.org/defaultActionTarget2"); ODataAction action_r1_t1 = new ODataAction() { Metadata = actionMetadata, Title = actionTitle, Target = actionTarget }; ODataAction action_r1_t2 = new ODataAction() { Metadata = actionMetadata, Title = actionTitle, Target = actionTarget2 }; ODataAction action_r2_t1 = new ODataAction() { Metadata = actionMetadata2, Title = actionTitle, Target = actionTarget }; ODataAction action_r3_t1 = new ODataAction() { Metadata = actionMetadata3, Title = actionTitle, Target = actionTarget }; Uri functionMetadata = new Uri("http://odata.org/test/$metadata#defaultFunction"); Uri functionMetadata2 = new Uri("#function escaped relative metadata", UriKind.Relative); Uri functionMetadata3 = new Uri("\\#function escaped relative metadata", UriKind.Relative); string functionTitle = "Default Function"; Uri functionTarget = new Uri("http://odata.org/defaultFunctionTarget"); Uri functionTarget2 = new Uri("http://odata.org/defaultFunctionTarget2"); ODataFunction function_r1_t1 = new ODataFunction() { Metadata = functionMetadata, Title = functionTitle, Target = functionTarget }; ODataFunction function_r1_t2 = new ODataFunction() { Metadata = functionMetadata, Title = functionTitle, Target = functionTarget2 }; ODataFunction function_r2_t1 = new ODataFunction() { Metadata = functionMetadata2, Title = functionTitle, Target = functionTarget }; ODataFunction function_r3_t1 = new ODataFunction() { Metadata = functionMetadata3, Title = functionTitle, Target = functionTarget }; var actionCases = new[] { new { ODataActions = new ODataAction[] { action_r1_t1 }, Atom = GetAtom(action_r1_t1), JsonLight = GetJsonLightForRelGroup(action_r1_t1), }, new { ODataActions = new ODataAction[] { action_r1_t1, action_r1_t2 }, Atom = GetAtom(action_r1_t1) + GetAtom(action_r1_t2), JsonLight = GetJsonLightForRelGroup(action_r1_t1, action_r1_t2), }, new { ODataActions = new ODataAction[] { action_r1_t1, action_r2_t1 }, Atom = GetAtom(action_r1_t1) + GetAtom(action_r2_t1), JsonLight = GetJsonLightForRelGroup(action_r1_t1) + "," + GetJsonLightForRelGroup(action_r2_t1), }, new { ODataActions = new ODataAction[] { action_r1_t1, action_r2_t1, action_r1_t2 }, Atom = GetAtom(action_r1_t1) + GetAtom(action_r2_t1) + GetAtom(action_r1_t2), JsonLight = GetJsonLightForRelGroup(action_r1_t1, action_r1_t2) + "," + GetJsonLightForRelGroup(action_r2_t1), }, new { ODataActions = new ODataAction[] { action_r3_t1 }, Atom = GetAtom(action_r3_t1), JsonLight = GetJsonLightForRelGroup(action_r3_t1), }, }; var functionCases = new[] { new { ODataFunctions = new ODataFunction[] { function_r1_t1 }, Atom = GetAtom(function_r1_t1), JsonLight = GetJsonLightForRelGroup(function_r1_t1), }, new { ODataFunctions = new ODataFunction[] { function_r1_t1, function_r1_t2 }, Atom = GetAtom(function_r1_t1) + GetAtom(function_r1_t2), JsonLight = GetJsonLightForRelGroup(function_r1_t1, function_r1_t2), }, new { ODataFunctions = new ODataFunction[] { function_r1_t1, function_r2_t1 }, Atom = GetAtom(function_r1_t1) + GetAtom(function_r2_t1), JsonLight = GetJsonLightForRelGroup(function_r1_t1) + "," + GetJsonLightForRelGroup(function_r2_t1), }, new { ODataFunctions = new ODataFunction[] { function_r1_t1, function_r2_t1, function_r1_t2 }, Atom = GetAtom(function_r1_t1) + GetAtom(function_r2_t1) + GetAtom(function_r1_t2), JsonLight = GetJsonLightForRelGroup(function_r1_t1, function_r1_t2) + "," + GetJsonLightForRelGroup(function_r2_t1), }, new { ODataFunctions = new ODataFunction[] { function_r3_t1 }, Atom = GetAtom(function_r3_t1), JsonLight = GetJsonLightForRelGroup(function_r3_t1), }, }; var queryResults = from actionCase in actionCases from functionCase in functionCases select new { actionCase.ODataActions, functionCase.ODataFunctions, Atom = string.Concat(actionCase.Atom, functionCase.Atom), JsonLight = string.Join(",", new[] { actionCase.JsonLight, functionCase.JsonLight }.Where(x => x != null)) }; EdmModel model = new EdmModel(); EdmEntityType edmEntityTypeCustomer = model.EntityType("Customer", "TestModel"); EdmEntityContainer edmEntityContainer = model.EntityContainer("DefaultContainer", "TestModel"); EdmEntitySet edmEntitySetCustermors = model.EntitySet("Customers", edmEntityTypeCustomer); var testDescriptors = queryResults.Select(testCase => { ODataResource entry = ObjectModelUtils.CreateDefaultEntry("TestModel.Customer"); if (testCase.ODataActions != null) { foreach (var action in testCase.ODataActions) { entry.AddAction(action); } } if (testCase.ODataFunctions != null) { foreach (var function in testCase.ODataFunctions) { entry.AddFunction(function); } } return(new PayloadWriterTestDescriptor <ODataItem>( this.Settings, entry, (testConfiguration) => { if (testConfiguration.Format == ODataFormat.Json) { return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Json = string.Join( "$(NL)", "{", testCase.JsonLight, "}"), ExpectedException2 = entry.Actions != null && entry.Actions.Contains(null) ? ODataExpectedExceptions.ODataException("ValidationUtils_EnumerableContainsANullItem", "ODataResource.Actions") : testConfiguration.IsRequest && entry.Actions != null && entry.Actions.Any() ? ODataExpectedExceptions.ODataException("WriterValidationUtils_OperationInRequest", GetFirstOperationMetadata(entry)) : entry.Actions != null && entry.Actions.Any(a => !a.Metadata.IsAbsoluteUri && !a.Metadata.OriginalString.StartsWith("#")) ? ODataExpectedExceptions.ODataException("ValidationUtils_InvalidMetadataReferenceProperty", entry.Actions.First(a => a.Metadata.OriginalString.Contains(" ")).Metadata.OriginalString) : entry.Functions != null && entry.Functions.Contains(null) ? ODataExpectedExceptions.ODataException("ValidationUtils_EnumerableContainsANullItem", "ODataResource.Functions") : testConfiguration.IsRequest && entry.Functions != null && entry.Functions.Any() ? ODataExpectedExceptions.ODataException("WriterValidationUtils_OperationInRequest", GetFirstOperationMetadata(entry)) : entry.Functions != null && entry.Functions.Any(f => !f.Metadata.IsAbsoluteUri && !f.Metadata.OriginalString.StartsWith("#")) ? ODataExpectedExceptions.ODataException("ValidationUtils_InvalidMetadataReferenceProperty", entry.Functions.First(f => f.Metadata.OriginalString.Contains(" ")).Metadata.OriginalString) : null, FragmentExtractor = (result) => { var actionsAndFunctions = result.Object().Properties.Where(p => p.Name.Contains("#")).ToList(); var jsonResult = new JsonObject(); actionsAndFunctions.ForEach(p => { // NOTE we remove all annotations here and in particular the text annotations to be able to easily compare // against the expected results. This however means that we do not distinguish between the indented and non-indented case here. p.RemoveAllAnnotations(true); jsonResult.Add(p); }); return jsonResult; } }; } else { string formatName = testConfiguration.Format == null ? "null" : testConfiguration.Format.GetType().Name; throw new NotSupportedException("Invalid format detected: " + formatName); } })); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.EntryPayloads), this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent, (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); if (testConfiguration.Format == ODataFormat.Json) { if (testDescriptor.IsGeneratedPayload) { return; } // We need a model, entity set and entity type for JSON Light testDescriptor = new PayloadWriterTestDescriptor <ODataItem>(testDescriptor) { Model = model, PayloadEdmElementContainer = edmEntitySetCustermors, PayloadEdmElementType = edmEntityTypeCustomer, }; } TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger); }); }
/// <summary> /// Creates the <see cref="ODataResource"/> to be written while writing this resource. /// </summary> /// <param name="selectExpandNode">The <see cref="SelectExpandNode"/> describing the response graph.</param> /// <param name="resourceContext">The context for the resource instance being written.</param> /// <returns>The created <see cref="ODataResource"/>.</returns> public virtual ODataResource CreateResource(SelectExpandNode selectExpandNode, ResourceContext resourceContext) { if (selectExpandNode == null) { throw Error.ArgumentNull("selectExpandNode"); } if (resourceContext == null) { throw Error.ArgumentNull("resourceContext"); } string typeName = resourceContext.StructuredType.FullTypeName(); ODataResource resource = new ODataResource { TypeName = typeName, Properties = CreateStructuralPropertyBag(selectExpandNode.SelectedStructuralProperties, resourceContext), }; // Try to add the dynamic properties if the structural type is open. AppendDynamicProperties(resource, selectExpandNode, resourceContext); IEnumerable <ODataAction> actions = CreateODataActions(selectExpandNode.SelectedActions, resourceContext); foreach (ODataAction action in actions) { resource.AddAction(action); } IEnumerable <ODataFunction> functions = CreateODataFunctions(selectExpandNode.SelectedFunctions, resourceContext); foreach (ODataFunction function in functions) { resource.AddFunction(function); } IEdmStructuredType pathType = GetODataPathType(resourceContext.SerializerContext); if (resourceContext.StructuredType.TypeKind == EdmTypeKind.Complex) { AddTypeNameAnnotationAsNeededForComplex(resource, resourceContext.SerializerContext.MetadataLevel); } else { AddTypeNameAnnotationAsNeeded(resource, pathType, resourceContext.SerializerContext.MetadataLevel); } if (resourceContext.StructuredType.TypeKind == EdmTypeKind.Entity && resourceContext.NavigationSource != null) { if (!(resourceContext.NavigationSource is IEdmContainedEntitySet)) { IEdmModel model = resourceContext.SerializerContext.Model; NavigationSourceLinkBuilderAnnotation linkBuilder = model.GetNavigationSourceLinkBuilder(resourceContext.NavigationSource); EntitySelfLinks selfLinks = linkBuilder.BuildEntitySelfLinks(resourceContext, resourceContext.SerializerContext.MetadataLevel); if (selfLinks.IdLink != null) { resource.Id = selfLinks.IdLink; } if (selfLinks.ReadLink != null) { resource.ReadLink = selfLinks.ReadLink; } if (selfLinks.EditLink != null) { resource.EditLink = selfLinks.EditLink; } } string etag = CreateETag(resourceContext); if (etag != null) { resource.ETag = etag; } } return(resource); }
/// <summary>Write the entry element.</summary> /// <param name="expanded">Expanded result provider for the specified <paramref name="element"/>.</param> /// <param name="element">Element representing the entry element.</param> /// <param name="resourceInstanceInFeed">true if the resource instance being serialized is inside a feed; false otherwise.</param> /// <param name="expectedType">Expected type of the entry element.</param> private void WriteEntry(IExpandedResult expanded, object element, bool resourceInstanceInFeed, ResourceType expectedType) { Debug.Assert(element != null, "element != null"); Debug.Assert(expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType, "expectedType != null && expectedType.ResourceTypeKind == ResourceTypeKind.EntityType"); this.IncrementSegmentResultCount(); ODataResource entry = new ODataResource(); if (!resourceInstanceInFeed) { entry.SetSerializationInfo(new ODataResourceSerializationInfo { NavigationSourceName = this.CurrentContainer.Name, NavigationSourceEntityTypeName = this.CurrentContainer.ResourceType.FullName, ExpectedTypeName = expectedType.FullName }); } string title = expectedType.Name; ResourceType actualResourceType = WebUtil.GetNonPrimitiveResourceType(this.Provider, element); if (actualResourceType.ResourceTypeKind != ResourceTypeKind.EntityType) { // making sure that the actual resource type is an entity type throw new DataServiceException(500, Microsoft.OData.Service.Strings.BadProvider_InconsistentEntityOrComplexTypeUsage(actualResourceType.FullName)); } EntityToSerialize entityToSerialize = this.WrapEntity(element, actualResourceType); // populate the media resource, if the entity is a MLE. entry.MediaResource = this.GetMediaResource(entityToSerialize, title); // Write the type name this.PayloadMetadataPropertyManager.SetTypeName(entry, this.CurrentContainer.ResourceType.FullName, actualResourceType.FullName); // Write Id element this.PayloadMetadataPropertyManager.SetId(entry, () => entityToSerialize.SerializedKey.Identity); // Write "edit" link this.PayloadMetadataPropertyManager.SetEditLink(entry, () => entityToSerialize.SerializedKey.RelativeEditLink); // Write the etag property, if the type has etag properties this.PayloadMetadataPropertyManager.SetETag(entry, () => this.GetETagValue(element, actualResourceType)); IEnumerable <ProjectionNode> projectionNodes = this.GetProjections(); if (projectionNodes != null) { // Filter the projection nodes for the actual type of the entity // The projection node might refer to the property in a derived type. If the TargetResourceType of // the projection node is not a super type, then we do not want to serialize this property. projectionNodes = projectionNodes.Where(projectionNode => projectionNode.TargetResourceType.IsAssignableFrom(actualResourceType)); // Because we are going to enumerate through these multiple times, create a list. projectionNodes = projectionNodes.ToList(); } // Populate the advertised actions IEnumerable <ODataAction> actions; if (this.TryGetAdvertisedActions(entityToSerialize, resourceInstanceInFeed, out actions)) { foreach (ODataAction action in actions) { entry.AddAction(action); } } // Populate all the normal properties entry.Properties = this.GetEntityProperties(entityToSerialize, projectionNodes); // And start the entry var args = new DataServiceODataWriterEntryArgs(entry, element, this.Service.OperationContext); this.dataServicesODataWriter.WriteStart(args); this.WriteAllNestedComplexProperties(entityToSerialize, projectionNodes); // Now write all the navigation properties this.WriteNavigationProperties(expanded, entityToSerialize, resourceInstanceInFeed, projectionNodes); // And write the end of the entry this.dataServicesODataWriter.WriteEnd(args); #if ASTORIA_FF_CALLBACKS this.Service.InternalOnWriteItem(target, element); #endif }