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);
        }
Example #2
0
        public void AddActionShouldAddActionToEntry()
        {
            ODataResource entry = ReaderUtils.CreateNewResource();

            Assert.Empty(entry.Actions);
            entry.AddAction(new ODataAction());
            Assert.Single(entry.Actions);
        }
Example #3
0
        public void AddActionShouldAddActionToEntry()
        {
            ODataResource entry = ReaderUtils.CreateNewResource();

            entry.Actions.Count().Should().Be(0);
            entry.AddAction(new ODataAction());
            entry.Actions.Count().Should().Be(1);
        }
Example #4
0
        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);
        }
Example #7
0
        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);
            });
        }
Example #8
0
        /// <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);
        }
Example #9
0
        /// <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
        }