public void DefaultValuesTest() { ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue(); this.Assert.IsNull(mediaResource.ContentType, "Expected null default value for property 'ContentType'."); this.Assert.IsNull(mediaResource.EditLink, "Expected null default value for property 'EditLink'."); this.Assert.IsNull(mediaResource.ETag, "Expected null default value for property 'ETag'."); this.Assert.IsNull(mediaResource.ReadLink, "Expected null default value for property 'ReadLink'."); }
private ODataMediaAnnotations CreateAnnotations(ODataStreamReferenceValue value) { return value == null ? null : new ODataMediaAnnotations { ContentType = value.ContentType, ReadLink = value.ReadLink, EditLink = value.EditLink, ETag = value.ETag, }; }
public void NoOpMetadataBuilderShouldReturnMediaResourceSetByUser() { var mediaResource = new ODataStreamReferenceValue { ContentType = "image/jpeg", EditLink = new Uri("http://example.com/stream/edit"), ReadLink = new Uri("http://example.com/stream/read"), ETag = "stream etag" }; new NoOpEntityMetadataBuilder(new ODataEntry { MediaResource = mediaResource }).GetMediaResource() .Should().Be(mediaResource); }
/// <summary> /// Visits a stream reference value (named stream). /// </summary> /// <param name="streamReferenceValue">The stream reference value to visit.</param> protected override ODataPayloadElement VisitStreamReferenceValue(ODataStreamReferenceValue streamReferenceValue) { ExceptionUtilities.CheckArgumentNotNull(streamReferenceValue, "streamReferenceValue"); // Note that we're creating a named stream instance without a name here - name will be supplied by the caller if necessary. return new NamedStreamInstance() { SourceLink = streamReferenceValue.ReadLink == null ? null : streamReferenceValue.ReadLink.OriginalString, EditLink = streamReferenceValue.EditLink == null ? null : streamReferenceValue.EditLink.OriginalString, ETag = streamReferenceValue.ETag, SourceLinkContentType = streamReferenceValue.ContentType, EditLinkContentType = streamReferenceValue.ContentType, }; }
public void InjectMetadataBuilderShouldNotSetBuilderOnEntryNamedStreamProperties() { var entry = new ODataEntry(); var builder = new TestEntityMetadataBuilder(entry); var stream1 = new ODataStreamReferenceValue(); var stream2 = new ODataStreamReferenceValue(); entry.Properties = new[] { new ODataProperty {Name = "Stream1", Value = stream1}, new ODataProperty {Name = "Stream2", Value = stream2} }; testSubject.InjectMetadataBuilder(entry, builder); stream1.GetMetadataBuilder().Should().BeNull(); stream2.GetMetadataBuilder().Should().BeNull(); }
public void PropertyGettersAndSettersTest() { string etag = "ETag"; Uri id = new Uri("http://odatalib.org/id"); Uri readlink = new Uri("http://odatalib.org/readlink"); Uri editlink = new Uri("http://odatalib.org/editlink"); ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue(); ODataProperty primitiveProperty = new ODataProperty(); ODataProperty complexProperty = new ODataProperty(); ODataProperty multiValueProperty = new ODataProperty(); ODataProperty namedStreamProperty = new ODataProperty(); List<ODataProperty> properties = new List<ODataProperty>() { primitiveProperty, complexProperty, multiValueProperty, namedStreamProperty }; string typeName = "ODataLibSample.DummyType"; ODataEntry entry = new ODataEntry() { ETag = etag, Id = id, EditLink = editlink, Properties = properties, TypeName = typeName, MediaResource = mediaResource }; this.Assert.IsNull(entry.ReadLink, "Expect ReadLink to be null if it was not set."); entry.ReadLink = readlink; this.Assert.AreSame(etag, entry.ETag, "Expected reference equal values for property 'ETag'."); this.Assert.AreSame(id, entry.Id, "Expected reference equal values for property 'Id'."); this.Assert.AreSame(readlink, entry.ReadLink, "Expected reference equal values for property 'ReadLink'."); this.Assert.AreSame(editlink, entry.EditLink, "Expected reference equal values for property 'EditLink'."); this.Assert.AreSame(properties, entry.Properties, "Expected reference equal values for property 'Properties'."); this.Assert.AreSame(typeName, entry.TypeName, "Expected reference equal values for property 'TypeName'."); this.Assert.AreSame(mediaResource, entry.MediaResource, "Expected reference equals for property 'MediaResource'."); }
public void PropertyGettersAndSettersTest() { Uri readLink = new Uri("http://odata.org/read"); Uri editLink = new Uri("http://odata.org/edit"); string etag = "MyETagValue"; string contentType = "application/binary"; ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue() { ContentType = contentType, EditLink = editLink, ETag = etag, ReadLink = readLink, }; this.Assert.AreSame(contentType, mediaResource.ContentType, "Expected reference equal values for property 'ContentType'."); this.Assert.AreSame(editLink, mediaResource.EditLink, "Expected reference equal values for property 'EditLink'."); this.Assert.AreSame(etag, mediaResource.ETag, "Expected reference equal values for property 'ETag'."); this.Assert.AreSame(readLink, mediaResource.ReadLink, "Expected reference equal values for property 'ReadLink'."); }
public void PropertySettersNullTest() { ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue() { ReadLink = new Uri("http://odata.org/read"), EditLink = new Uri("http://odata.org/edit"), ETag = "MyETagValue", ContentType = "application/binary" }; mediaResource.ReadLink = null; mediaResource.EditLink = null; mediaResource.ETag = null; mediaResource.ContentType = null; this.Assert.IsNull(mediaResource.ContentType, "Expected null value for property 'ContentType'."); this.Assert.IsNull(mediaResource.EditLink, "Expected null value for property 'EditLink'."); this.Assert.IsNull(mediaResource.ETag, "Expected null value for property 'ETag'."); this.Assert.IsNull(mediaResource.ReadLink, "Expected null value for property 'ReadLink'."); }
public void InitTest() { this.testSubject = new ODataStreamReferenceValue(); var entry = new ODataEntry { TypeName = "ns.DerivedType", Properties = new[] { new ODataProperty{Name = "Id", Value = 1, SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.Key}}, new ODataProperty{Name = "Name", Value = "Bob", SerializationInfo = new ODataPropertySerializationInfo{PropertyKind = ODataPropertyKind.ETag}} } }; var serializationInfo = new ODataFeedAndEntrySerializationInfo { NavigationSourceName = "Set", NavigationSourceEntityTypeName = "ns.BaseType", ExpectedTypeName = "ns.BaseType" }; var typeContext = ODataFeedAndEntryTypeContext.Create(serializationInfo, null, null, null, EdmCoreModel.Instance, true); var metadataContext = new TestMetadataContext(); var entryMetadataContext = ODataEntryMetadataContext.Create(entry, typeContext, serializationInfo, null, metadataContext, SelectedPropertiesNode.EntireSubtree); var fullMetadataBuilder = new ODataConventionalEntityMetadataBuilder(entryMetadataContext, metadataContext, new ODataConventionalUriBuilder(ServiceUri, UrlConvention.CreateWithExplicitValue(false))); this.streamWithFullBuilder = new ODataStreamReferenceValue(); this.streamWithFullBuilder.SetMetadataBuilder(fullMetadataBuilder, "Stream"); }
internal void SetContentType(ODataStreamReferenceValue stream, string contentType) { Debug.Assert(stream != null, "stream != null"); if (this.interpreter.ShouldIncludeStreamMetadata(PayloadMetadataKind.Stream.ContentType)) { stream.ContentType = contentType; } }
internal void SetReadLink(ODataStreamReferenceValue stream, Func<Uri> computeReadLink) { Debug.Assert(stream != null, "stream != null"); if (this.interpreter.ShouldIncludeStreamMetadata(PayloadMetadataKind.Stream.ReadLink)) { stream.ReadLink = computeReadLink(); } }
/// <summary> /// Visits a stream reference value item. /// </summary> /// <param name="streamReferenceValue">The stream reference value item to visit.</param> /// <returns>An ODataPayloadElement representing the stream reference value.</returns> protected override ODataPayloadElement VisitStreamReferenceValue(ODataStreamReferenceValue streamReferenceValue) { ExceptionUtilities.CheckArgumentNotNull(streamReferenceValue, "streamReferenceValue"); NamedStreamInstance namedStreamInstance = (NamedStreamInstance)base.VisitStreamReferenceValue(streamReferenceValue); AtomStreamReferenceMetadata streamMetadata = streamReferenceValue.GetAnnotation<AtomStreamReferenceMetadata>(); if (streamMetadata != null) { if (streamMetadata.EditLink != null) { AtomLinkMetadata editMetadata = streamMetadata.EditLink; namedStreamInstance.AtomNamedStreamLink(editMetadata.Href == null ? null : editMetadata.Href.OriginalString, editMetadata.Relation, editMetadata.MediaType, editMetadata.HrefLang, editMetadata.Title, ToString(editMetadata.Length)); } if (streamMetadata.SelfLink != null) { AtomLinkMetadata selfMetadata = streamMetadata.SelfLink; namedStreamInstance.AtomNamedStreamLink(selfMetadata.Href == null ? null : selfMetadata.Href.OriginalString, selfMetadata.Relation, selfMetadata.MediaType, selfMetadata.HrefLang, selfMetadata.Title, ToString(selfMetadata.Length)); } } return namedStreamInstance; }
/// <summary> /// Adds all properties found on a stream reference value to the payload order items. /// </summary> /// <param name="prefix">The prefix to add to all property names found.</param> /// <param name="streamReferenceValue">The stream reference value to inspect.</param> /// <param name="payloadOrderItems">The payload order items to add to, or null, if nothing should be done.</param> private static void AddStreamReferenceValuePayloadOrderItems(string prefix, ODataStreamReferenceValue streamReferenceValue, ODataEntryPayloadOrderObjectModelAnnotation payloadOrderItems) { if (payloadOrderItems == null) return; if (streamReferenceValue.ReadLink != null) payloadOrderItems.AddEntryProperty(prefix + "ReadLink"); if (streamReferenceValue.ContentType != null) payloadOrderItems.AddEntryProperty(prefix + "ContentType"); if (streamReferenceValue.EditLink != null) payloadOrderItems.AddEntryProperty(prefix + "EditLink"); if (streamReferenceValue.ETag != null) payloadOrderItems.AddEntryProperty(prefix + "ETag"); }
/// <summary> /// Get the stream reference value for media resource (the default stream of an entity). /// </summary> /// <param name="entityToSerialize">Entity that is currently being serialized.</param> /// <param name="title">The title for the element being written.</param> /// <returns> /// An instance of ODataStreamReferenceValue containing the metadata about the media resource. /// </returns> private ODataStreamReferenceValue GetMediaResource(EntityToSerialize entityToSerialize, string title) { Debug.Assert(entityToSerialize.Entity != null, "element != null"); Debug.Assert(entityToSerialize.ResourceType != null && entityToSerialize.ResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "type != null && type.ResourceTypeKind == ResourceTypeKind.EntityType"); Debug.Assert(!string.IsNullOrEmpty(title), "!string.IsNullOrEmpty(title)"); ODataStreamReferenceValue mediaResource = null; // Handle MLE if (entityToSerialize.ResourceType.IsMediaLinkEntry) { string mediaETag; Uri readStreamUri; string mediaContentType; Debug.Assert(entityToSerialize.ResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "type.ResourceTypeKind == ResourceTypeKind.EntityType"); this.Service.StreamProvider.GetStreamDescription(entityToSerialize.Entity, null /*null for MLE*/, this.Service.OperationContext, out mediaETag, out readStreamUri, out mediaContentType); Debug.Assert(WebUtil.IsETagValueValid(mediaETag, true), "WebUtil.IsETagValueValid(mediaETag, true)"); Debug.Assert(!string.IsNullOrEmpty(mediaContentType), "!string.IsNullOrEmpty(mediaContentType)"); mediaResource = new ODataStreamReferenceValue(); // build the stream's edit link lazily to avoid creating the entity's edit link if it is not needed. SimpleLazy<Uri> lazyStreamEditLink = new SimpleLazy<Uri>(() => RequestUriProcessor.AppendEscapedSegment(entityToSerialize.SerializedKey.RelativeEditLink, XmlConstants.UriValueSegment)); this.PayloadMetadataPropertyManager.SetEditLink(mediaResource, () => lazyStreamEditLink.Value); this.PayloadMetadataPropertyManager.SetContentType(mediaResource, mediaContentType); // If the stream provider did not provider a read link, then we should use the edit link as the read link. this.PayloadMetadataPropertyManager.SetReadLink(mediaResource, () => readStreamUri ?? lazyStreamEditLink.Value); #pragma warning disable 618 if (this.contentFormat == ODataFormat.Atom) #pragma warning restore 618 { AtomStreamReferenceMetadata mediaResourceAtom = new AtomStreamReferenceMetadata() { EditLink = new AtomLinkMetadata { Title = title } }; mediaResource.SetAnnotation(mediaResourceAtom); } if (!string.IsNullOrEmpty(mediaETag)) { this.PayloadMetadataPropertyManager.SetETag(mediaResource, mediaETag); } } return mediaResource; }
/// <summary> /// Visits an entity instance: creates a new ODataEntry instance, collects and sets all the properties, /// calls ODataWriter.WriteStart(), then visits the navigation properties and calls ODataWriter.WriteEnd() /// </summary> /// <param name="payloadElement">The entity instance to write.</param> public override void Visit(EntityInstance payloadElement) { // create an ODataEntry and write it string editLinkString = payloadElement.GetEditLink(); string selfLinkString = payloadElement.GetSelfLink(); string entryId = payloadElement.Id; var entry = new ODataEntry() { Id = string.IsNullOrEmpty(entryId) ? null:new Uri(entryId), ETag = payloadElement.ETag, EditLink = string.IsNullOrEmpty(editLinkString) ? null : new Uri(editLinkString), ReadLink = string.IsNullOrEmpty(selfLinkString) ? null : new Uri(selfLinkString), TypeName = payloadElement.FullTypeName, SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceEntityTypeName = payloadElement.FullTypeName, NavigationSourceName = "MySet", ExpectedTypeName = payloadElement.FullTypeName } }; if (payloadElement.IsMediaLinkEntry()) { ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue(); mediaResource.ContentType = payloadElement.StreamContentType; mediaResource.ETag = payloadElement.StreamETag; mediaResource.ReadLink = new Uri(payloadElement.StreamSourceLink); mediaResource.EditLink = new Uri(payloadElement.StreamEditLink); entry.MediaResource = mediaResource; } // TODO: add support for custom extensions at some point AddEntryMetadata(payloadElement, entry); Debug.Assert(this.currentNavigationProperties.Count == 0); Debug.Assert(this.currentProperties.Count == 0); // visit the properties (incl. navigation properties and named stream properties) base.Visit(payloadElement); // set the primitive and complex properties if (this.currentProperties.Count > 0) { entry.Properties = this.currentProperties; this.currentProperties = new List<ODataProperty>(); } this.writer.WriteStart(entry); var navigationProperties = new ReadOnlyCollection<NavigationPropertyInstance>(this.currentNavigationProperties); this.currentNavigationProperties.Clear(); // process the navigation properties/links for (int i = 0; i < navigationProperties.Count; ++i) { NavigationPropertyInstance navigationProperty = navigationProperties[i]; this.currentLink = new ODataNavigationLink() { Name = navigationProperty.Name }; base.Visit(navigationProperty); Debug.Assert(this.currentLink == null); } this.writer.WriteEnd(); }
public void DefaultStreamEditLinkMetadataWriterTest() { Func<XElement, XElement> fragmentExtractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + "link").Last(); // NOTE: no self-link test cases since the self link is represented as the <content> element and not customizable through link metadata var testDescriptors = linkMetadataTestCases.Select(testCase => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntryWithAtomMetadata(); ODataStreamReferenceValue streamReferenceValue = new ODataStreamReferenceValue() { ReadLink = new Uri(readLinkHref), EditLink = new Uri(editLinkHref), ContentType = linkMediaType, }; AtomStreamReferenceMetadata streamReferenceMetadata = new AtomStreamReferenceMetadata() { EditLink = testCase.LinkMetadata("edit-media", editLinkHref) }; streamReferenceValue.SetAnnotation<AtomStreamReferenceMetadata>(streamReferenceMetadata); entry.MediaResource = streamReferenceValue; return new PayloadWriterTestDescriptor<ODataItem>(this.Settings, entry, testConfiguration => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.ExpectedXml == null ? null : testCase.ExpectedXml("edit-media", editLinkHref, null, null), ExpectedException2 = testCase.ExpectedException == null ? null : testCase.ExpectedException("edit-media", editLinkHref), FragmentExtractor = fragmentExtractor }); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.EntryPayloads), this.WriterTestConfigurationProvider.AtomFormatConfigurations, (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger); }); }
/// <summary> /// Creates a new ODataStreamReferenceValue for the named stream and initializes it. /// </summary> /// <param name="payloadElement">The named stream to process.</param> public override void Visit(NamedStreamInstance payloadElement) { var odataNamedStream = new ODataStreamReferenceValue() { ETag = payloadElement.ETag, ContentType = payloadElement.EditLink == null ? payloadElement.SourceLinkContentType : payloadElement.EditLinkContentType, ReadLink = payloadElement.SourceLink == null ? null : new Uri(payloadElement.SourceLink), EditLink = payloadElement.EditLink == null ? null : new Uri(payloadElement.EditLink), }; var odataNamedStreamProperty = new ODataProperty() { Name = payloadElement.Name, Value = odataNamedStream }; var parent = this.items.Peek(); if (parent != null) { var entry = parent as ODataEntry; if (entry != null) { var properties = (List<ODataProperty>)entry.Properties; properties.Add(odataNamedStreamProperty); } var complex = parent as ODataComplexValue; if (complex != null) { var properties = (List<ODataProperty>)complex.Properties; properties.Add(odataNamedStreamProperty); } } base.Visit(payloadElement); }
/// <summary> /// Visits an entity instance: creates a new ODataEntry instance, collects and sets all the properties, /// calls ODataWriter.WriteStart(), then visits the navigation properties and calls ODataWriter.WriteEnd() /// </summary> /// <param name="payloadElement">The entity instance to write.</param> public override void Visit(EntityInstance payloadElement) { // create an ODataEntry and write it string editLinkString = payloadElement.GetEditLink(); string selfLinkString = payloadElement.GetSelfLink(); string entryId = payloadElement.Id; var entry = new ODataEntry() { Id = string.IsNullOrEmpty(entryId) ? null : new Uri(entryId), ETag = payloadElement.ETag, EditLink = string.IsNullOrEmpty(editLinkString) ? null : new Uri(editLinkString), ReadLink = string.IsNullOrEmpty(selfLinkString) ? null : new Uri(selfLinkString), TypeName = payloadElement.FullTypeName, Properties = new List<ODataProperty>(), SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceEntityTypeName = payloadElement.FullTypeName, NavigationSourceName = "MySet", ExpectedTypeName = payloadElement.FullTypeName } }; if (payloadElement.IsMediaLinkEntry()) { ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue(); mediaResource.ContentType = payloadElement.StreamContentType; mediaResource.ETag = payloadElement.StreamETag; mediaResource.ReadLink = new Uri(payloadElement.StreamSourceLink); mediaResource.EditLink = new Uri(payloadElement.StreamEditLink); entry.MediaResource = mediaResource; } // TODO: add support for custom extensions at some point AddEntryMetadata(payloadElement, entry); if (this.items.Count > 0) { var parent = this.items.Peek(); var navLink = parent as ODataNavigationLink; if (navLink != null) { navLink.SetAnnotation(new ODataNavigationLinkExpandedItemObjectModelAnnotation() { ExpandedItem = entry }); } else { var feed = parent as ODataFeed; ExceptionUtilities.CheckObjectNotNull(feed, "Feed was expected"); ODataFeedEntriesObjectModelAnnotation annotation = feed.GetAnnotation<ODataFeedEntriesObjectModelAnnotation>(); if (annotation == null) { annotation = new ODataFeedEntriesObjectModelAnnotation(); feed.SetAnnotation(annotation); } annotation.Add(entry); } } //Initialise stuff for the entry var originalPosition = this.currentPropertyPosition; this.currentPropertyPosition = 0; try { this.items.Push(entry); // visit the properties (incl. navigation properties and named stream properties) base.Visit(payloadElement); } finally { entry = (ODataEntry) this.items.Pop(); } //Return to original values this.currentPropertyPosition = originalPosition; //If we are at the top level push this to items to make it the result. if (this.items.Count == 0) { this.items.Push(entry); } }
private PayloadWriterTestDescriptor<ODataItem> CreateDefaultStreamMetadataTestDescriptor( IEdmModel model, string typeName, ODataStreamReferenceValue mediaResourceValue, ExpectedException expectedException = null) { return new PayloadWriterTestDescriptor<ODataItem>( this.Settings, new ODataEntry() { TypeName = typeName, MediaResource = mediaResourceValue, SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceEntityTypeName = typeName, NavigationSourceName = "MySet", ExpectedTypeName = typeName }}, (tc) => { if (expectedException != null) { return new WriterTestExpectedResults(this.Settings.ExpectedResultSettings) { ExpectedException2 = expectedException }; } else { if (tc.Format == ODataFormat.Atom) { return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { FragmentExtractor = (result) => new XElement("root"), Xml = "<root/>" }; } else { return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { FragmentExtractor = (result) => new JsonObject(), Json = "{}" }; } } }) { Model = model }; }
/// <summary> /// Validates an <see cref="ODataStreamReferenceValue"/> to ensure all required information is specified and valid. /// </summary> /// <param name="streamReference">The stream reference to validate.</param> /// <param name="isDefaultStream">true if <paramref name="streamReference"/> is the default stream for an entity; false if it is a named stream property value.</param> public void ValidateStreamReferenceValue(ODataStreamReferenceValue streamReference, bool isDefaultStream) { }
/// <summary> /// Get the ODataStreamReferenceValue instance containing the metadata for named stream property. /// </summary> /// <param name="entityToSerialize">Entity that is currently being serialized.</param> /// <param name="namedStreamProperty">Named stream property for which the link element needs to be written.</param> /// <returns> /// An instance of ODataStreamReferenceValue containing all the metadata about the named stream property. /// </returns> private ODataStreamReferenceValue GetNamedStreamPropertyValue(EntityToSerialize entityToSerialize, ResourceProperty namedStreamProperty) { Debug.Assert(entityToSerialize != null, "entityToSerialize != null"); Debug.Assert(namedStreamProperty != null, "namedStreamProperty != null"); Debug.Assert(namedStreamProperty.IsOfKind(ResourcePropertyKind.Stream), "namedStreamProperty.IsOfKind(ResourcePropertyKind.Stream)"); string mediaETag; Uri readStreamUri; string mediaContentType; this.Service.StreamProvider.GetStreamDescription(entityToSerialize.Entity, namedStreamProperty, this.Service.OperationContext, out mediaETag, out readStreamUri, out mediaContentType); Debug.Assert(WebUtil.IsETagValueValid(mediaETag, true), "WebUtil.IsETagValueValid(mediaETag, true)"); ODataStreamReferenceValue streamReferenceValue = new ODataStreamReferenceValue(); this.PayloadMetadataPropertyManager.SetContentType(streamReferenceValue, mediaContentType); this.PayloadMetadataPropertyManager.SetEditLink( streamReferenceValue, () => { Uri relativeUri = entityToSerialize.SerializedKey.RelativeEditLink; return RequestUriProcessor.AppendUnescapedSegment(relativeUri, namedStreamProperty.Name); }); if (!string.IsNullOrEmpty(mediaETag)) { this.PayloadMetadataPropertyManager.SetETag(streamReferenceValue, mediaETag); } // Note if readStreamUri is null, the self link for the named stream will be omitted. this.PayloadMetadataPropertyManager.SetReadLink(streamReferenceValue, () => readStreamUri); return streamReferenceValue; }
internal void SetETag(ODataStreamReferenceValue stream, string streamETag) { Debug.Assert(stream != null, "stream != null"); if (this.interpreter.ShouldIncludeStreamMetadata(PayloadMetadataKind.Stream.ETag)) { stream.ETag = streamETag; } }
/// <summary> /// Creates a new ODataStreamReferenceValue for the named stream and initializes it. /// </summary> /// <param name="payloadElement">The named stream to process.</param> public override void Visit(NamedStreamInstance payloadElement) { var odataNamedStream = new ODataStreamReferenceValue() { ETag = payloadElement.ETag, ContentType = payloadElement.EditLink == null ? payloadElement.SourceLinkContentType : payloadElement.EditLinkContentType, ReadLink = payloadElement.SourceLink == null ? null : new Uri(payloadElement.SourceLink), EditLink = payloadElement.EditLink == null ? null : new Uri(payloadElement.EditLink), }; var odataNamedStreamProperty = new ODataProperty() { Name = payloadElement.Name, Value = odataNamedStream }; this.currentProperties.Add(odataNamedStreamProperty); base.Visit(payloadElement); }
public void NamedStreamReadAndEditLinkMetadataWriterTest() { Func<XElement, XElement> fragmentExtractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + "link").Last(); var allTestCases = linkMetadataTestCases.ConcatSingle(incorrectMediaTypeLinkMetadataTestCases).ConcatSingle(incorrectTitleLinkMetadataTestCases); var readLinkTestDescriptors = allTestCases.Select(testCase => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntryWithAtomMetadata(); ODataStreamReferenceValue streamReferenceValue = new ODataStreamReferenceValue() { ReadLink = new Uri(readLinkHref), ContentType = linkMediaType, }; AtomStreamReferenceMetadata streamReferenceMetadata = new AtomStreamReferenceMetadata() { SelfLink = testCase.LinkMetadata("http://docs.oasis-open.org/odata/ns/mediaresource/Stream", readLinkHref) }; streamReferenceValue.SetAnnotation<AtomStreamReferenceMetadata>(streamReferenceMetadata); entry.Properties = new ODataProperty[] { new ODataProperty { Name = "Id", Value = 1 }, new ODataProperty { Name = "Stream", Value = streamReferenceValue } }; return new PayloadWriterTestDescriptor<ODataItem>(this.Settings, entry, testConfiguration => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.ExpectedXml == null ? null : testCase.ExpectedXml("http://docs.oasis-open.org/odata/ns/mediaresource/Stream", readLinkHref, "Stream", linkMediaType), ExpectedException2 = testCase.ExpectedException == null ? null : testCase.ExpectedException("http://docs.oasis-open.org/odata/ns/mediaresource/Stream", readLinkHref), FragmentExtractor = fragmentExtractor }); }); var editLinkTestDescriptors = allTestCases.Select(testCase => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntryWithAtomMetadata(); ODataStreamReferenceValue streamReferenceValue = new ODataStreamReferenceValue() { ReadLink = new Uri(readLinkHref), EditLink = new Uri(editLinkHref), ContentType = linkMediaType, }; AtomStreamReferenceMetadata streamReferenceMetadata = new AtomStreamReferenceMetadata() { EditLink = testCase.LinkMetadata("http://docs.oasis-open.org/odata/ns/edit-media/Stream", editLinkHref) }; streamReferenceValue.SetAnnotation<AtomStreamReferenceMetadata>(streamReferenceMetadata); entry.Properties = new ODataProperty[] { new ODataProperty { Name = "Id", Value = 1 }, new ODataProperty { Name = "Stream", Value = streamReferenceValue } }; return new PayloadWriterTestDescriptor<ODataItem>(this.Settings, entry, testConfiguration => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.ExpectedXml == null ? null : testCase.ExpectedXml("http://docs.oasis-open.org/odata/ns/edit-media/Stream", editLinkHref, "Stream", linkMediaType), ExpectedException2 = testCase.ExpectedException == null ? null : testCase.ExpectedException("http://docs.oasis-open.org/odata/ns/edit-media/Stream", editLinkHref), FragmentExtractor = fragmentExtractor }); }); var testDescriptors = readLinkTestDescriptors.Concat(editLinkTestDescriptors); this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.EntryPayloads), this.WriterTestConfigurationProvider.AtomFormatConfigurations .Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger); }); }
public void ETagValidationTest() { string[] etagValues = new string[] { "\"", "W/\"", "W/", "etagValue", "etagValue\"", "\"etagValue", "etag\"Value", "\"etagV\"alue\"", "W/etagValue", "W/etagValue\"", "W/\"etagValue", "W/etag\"Value", "W/\"etagV\"alue\"" }; var testDescriptors = etagValues.SelectMany(etagValue => { var stream1 = new ODataStreamReferenceValue() { ReadLink = new Uri("http://foo/", UriKind.RelativeOrAbsolute), EditLink = new Uri("http://foo/", UriKind.RelativeOrAbsolute), ContentType = "customType/customSubtype", ETag = etagValue }; WriterTestDescriptor.WriterTestExpectedResultCallback formatSelector = testConfiguration => (testConfiguration.Format == ODataFormat.Atom) ? (WriterTestExpectedResults) new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) : (WriterTestExpectedResults) new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings); return new[] { // entity etag new PayloadWriterTestDescriptor<ODataItem>( this.Settings, new ODataEntry() { ETag = etagValue, Properties = ObjectModelUtils.CreateDefaultPrimitiveProperties(), SerializationInfo = SerializationInfo }, formatSelector), // default stream etag new PayloadWriterTestDescriptor<ODataItem>( this.Settings, new ODataEntry() { MediaResource = stream1, Properties = ObjectModelUtils.CreateDefaultPrimitiveProperties(), SerializationInfo = SerializationInfo }, formatSelector), // named stream etag new PayloadWriterTestDescriptor<ODataItem>( this.Settings, new ODataEntry() { Properties = new ODataProperty[] { new ODataProperty() { Name = "Stream1", Value = stream1 }}, SerializationInfo = SerializationInfo}, formatSelector) { // No stream properties in requests SkipTestConfiguration = tc => tc.IsRequest }, }; }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations, (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger); }); }
/// <summary> /// Visits a stream reference value (named stream). /// </summary> /// <param name="streamReferenceValue">The stream reference value to visit.</param> protected virtual void VisitStreamReferenceValue(ODataStreamReferenceValue streamReferenceValue) { }
/// <summary> /// Visits a stream reference value (named stream). /// </summary> /// <param name="streamReferenceValue">The stream reference value to visit.</param> protected override void VisitStreamReferenceValue(ODataStreamReferenceValue streamReferenceValue) { this.ValidateUri(streamReferenceValue.EditLink); this.ValidateUri(streamReferenceValue.ReadLink); base.VisitStreamReferenceValue(streamReferenceValue); }
public void BaseUriErrorTest() { Uri baseUri = new Uri("http://odata.org"); Uri testUri = new Uri("http://odata.org/relative"); IEnumerable<Func<Uri, BaseUriErrorTestCase>> testCaseFuncs = new Func<Uri, BaseUriErrorTestCase>[] { relativeUri => new BaseUriErrorTestCase { // next page link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataFeed feed = ObjectModelUtils.CreateDefaultFeed(); feed.NextPageLink = relativeUri; return new [] { feed }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // entry read link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); entry.ReadLink = relativeUri; return new [] { entry }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // entry edit link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); entry.EditLink = relativeUri; return new [] { entry }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // media resource (default stream) read link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue(); mediaResource.ContentType = "image/jpg"; mediaResource.ReadLink = relativeUri; ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); entry.MediaResource = mediaResource; return new [] { entry }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // media resource (default stream) edit link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue(); mediaResource.ContentType = "image/jpg"; // required mediaResource.ReadLink = testUri; // required mediaResource.EditLink = relativeUri; ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); entry.MediaResource = mediaResource; return new [] { entry }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // link Url ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataNavigationLink link = ObjectModelUtils.CreateDefaultCollectionLink(); link.Url = relativeUri; ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); return new ODataItem[] { entry, link }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // association link Url ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataNavigationLink link = ObjectModelUtils.CreateDefaultSingletonLink(); link.AssociationLinkUrl = relativeUri; ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); return new ODataItem[] { entry, link }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // named stream read link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataStreamReferenceValue namedStream = new ODataStreamReferenceValue() { ContentType = "image/jpg", ReadLink = relativeUri, }; ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); ODataProperty property = new ODataProperty() { Name = "NamedStream", Value = namedStream }; entry.Properties = new[] { property }; return new [] { entry }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // named stream edit link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataStreamReferenceValue namedStream = new ODataStreamReferenceValue() { ContentType = "image/jpg", ReadLink = testUri, EditLink = relativeUri }; ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); ODataProperty property = new ODataProperty() { Name = "NamedStream", Value = namedStream }; entry.Properties = new[] { property }; return new [] { entry }; }), Formats = new [] { ODataFormat.Atom, ODataFormat.Json } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: feed generator Uri ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataFeed feed = ObjectModelUtils.CreateDefaultFeed(); AtomFeedMetadata metadata = new AtomFeedMetadata() { Generator = new AtomGeneratorMetadata() { Uri = relativeUri } }; feed.SetAnnotation<AtomFeedMetadata>(metadata); return new [] { feed }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: feed logo ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataFeed feed = ObjectModelUtils.CreateDefaultFeed(); AtomFeedMetadata metadata = new AtomFeedMetadata() { Logo = relativeUri }; feed.SetAnnotation<AtomFeedMetadata>(metadata); return new [] { feed }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: feed icon ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataFeed feed = ObjectModelUtils.CreateDefaultFeed(); AtomFeedMetadata metadata = new AtomFeedMetadata() { Icon = relativeUri }; feed.SetAnnotation<AtomFeedMetadata>(metadata); return new [] { feed }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: feed author ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataFeed feed = ObjectModelUtils.CreateDefaultFeed(); AtomFeedMetadata metadata = new AtomFeedMetadata() { Authors = new [] { new AtomPersonMetadata() { Uri = relativeUri } } }; feed.SetAnnotation<AtomFeedMetadata>(metadata); return new [] { feed }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: feed contributor ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataFeed feed = ObjectModelUtils.CreateDefaultFeed(); AtomFeedMetadata metadata = new AtomFeedMetadata() { Contributors = new [] { new AtomPersonMetadata() { Uri = relativeUri } } }; feed.SetAnnotation<AtomFeedMetadata>(metadata); return new [] { feed }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: feed link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataFeed feed = ObjectModelUtils.CreateDefaultFeed(); AtomFeedMetadata metadata = new AtomFeedMetadata() { Links = new [] { new AtomLinkMetadata() { Href = relativeUri } } }; feed.SetAnnotation<AtomFeedMetadata>(metadata); return new [] { feed }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: entry author ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); AtomEntryMetadata metadata = new AtomEntryMetadata() { Authors = new [] { new AtomPersonMetadata() { Uri = relativeUri } } }; entry.SetAnnotation<AtomEntryMetadata>(metadata); return new [] { entry }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: entry contributor ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); AtomEntryMetadata metadata = new AtomEntryMetadata() { Contributors = new [] { new AtomPersonMetadata() { Uri = relativeUri } } }; entry.SetAnnotation<AtomEntryMetadata>(metadata); return new [] { entry }; }), Formats = new [] { ODataFormat.Atom } }, relativeUri => new BaseUriErrorTestCase { // Atom metadata: entry link ItemFunc = new Func<IEnumerable<ODataItem>>(() => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntry(); AtomEntryMetadata metadata = new AtomEntryMetadata() { Links = new [] { new AtomLinkMetadata() { Href = relativeUri } } }; entry.SetAnnotation<AtomEntryMetadata>(metadata); return new [] { entry }; }), Formats = new [] { ODataFormat.Atom } }, }; // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight Uri testRelativeUri = baseUri.MakeRelativeUri(testUri); Uri invalidRelativeUri = new Uri("../invalid/relative/uri", UriKind.Relative); this.CombinatorialEngineProvider.RunCombinations( testCaseFuncs, this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(c => c.IsRequest == false && c.Format == ODataFormat.Atom), new Uri[] { testRelativeUri, invalidRelativeUri }, new bool[] { false, true }, (testCaseFunc, testConfiguration, uri, implementUrlResolver) => { var testCase = testCaseFunc(uri); var testDescriptor = new { Descriptor = new PayloadWriterTestDescriptor<ODataItem>( this.Settings, testCase.ItemFunc(), testConfig => new WriterTestExpectedResults(this.Settings.ExpectedResultSettings) { ExpectedException2 = ODataExpectedExceptions.ODataException("ODataWriter_RelativeUriUsedWithoutBaseUriSpecified", uri.OriginalString) }), Formats = testCase.Formats }; if (testDescriptor.Formats.Contains(testConfiguration.Format)) { PayloadWriterTestDescriptor<ODataItem> payloadTestDescriptor = testDescriptor.Descriptor; TestUrlResolver urlResolver = null; if (implementUrlResolver) { payloadTestDescriptor = new PayloadWriterTestDescriptor<ODataItem>(payloadTestDescriptor); urlResolver = new TestUrlResolver(); payloadTestDescriptor.UrlResolver = urlResolver; } testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataPayload(payloadTestDescriptor, testConfiguration, this.Assert, this.Logger); if (implementUrlResolver) { this.Assert.AreEqual(1, urlResolver.Calls.Where(call => call.Value.OriginalString == uri.OriginalString).Count(), "The resolver should be called exactly once for each URL."); } } }); }
/// <summary> /// Validates an <see cref="ODataStreamReferenceValue"/> to ensure all required information is specified and valid. /// </summary> /// <param name="streamReference">The stream reference to validate.</param> /// <param name="isDefaultStream">true if <paramref name="streamReference"/> is the default stream for an entity; false if it is a named stream property value.</param> internal static void ValidateStreamReferenceValue(ODataStreamReferenceValue streamReference, bool isDefaultStream) { Debug.Assert(streamReference != null, "streamReference != null"); if (streamReference.ContentType != null && streamReference.ContentType.Length == 0) { throw new ODataException(Strings.WriterValidationUtils_StreamReferenceValueEmptyContentType); } if (isDefaultStream && streamReference.ReadLink == null && streamReference.ContentType != null) { throw new ODataException(Strings.WriterValidationUtils_DefaultStreamWithContentTypeWithoutReadLink); } if (isDefaultStream && streamReference.ReadLink != null && streamReference.ContentType == null) { throw new ODataException(Strings.WriterValidationUtils_DefaultStreamWithReadLinkWithoutContentType); } // Default stream can be completely empty (no links or anything) // that is used to effectively mark the entry as MLE without providing any MR information. // OData clients when creating new MLE/MR might not have the MR information (yet) when sending the first PUT, but they still // need to mark the entry as MLE so that properties are written out-of-content. In such scenario the client can just set an empty // default stream to mark the entry as MLE. // That will cause the ATOM writer to write the properties outside the content without producing any content element. if (streamReference.EditLink == null && streamReference.ReadLink == null && !isDefaultStream) { throw new ODataException(Strings.WriterValidationUtils_StreamReferenceValueMustHaveEditLinkOrReadLink); } if (streamReference.EditLink == null && streamReference.ETag != null) { throw new ODataException(Strings.WriterValidationUtils_StreamReferenceValueMustHaveEditLinkToHaveETag); } }
/// <summary> /// Validates an <see cref="ODataStreamReferenceValue"/> to ensure all required information is specified and valid. /// </summary> /// <param name="streamReference">The stream reference to validate.</param> /// <param name="isDefaultStream">true if <paramref name="streamReference"/> is the default stream for an entity; false if it is a named stream property value.</param> public void ValidateStreamReferenceValue(ODataStreamReferenceValue streamReference, bool isDefaultStream) { WriterValidationUtils.ValidateStreamReferenceValue(streamReference, isDefaultStream); }