private static AtomGeneratorMetadata CreateGeneratorMetadata(XmlTreeAnnotation epmTree) { AtomGeneratorMetadata metadata = new AtomGeneratorMetadata() { Name = epmTree.PropertyValue }; foreach (XmlTreeAnnotation attribute in epmTree.Children.Where(child => child.IsAttribute)) { if (string.IsNullOrEmpty(attribute.NamespaceName)) { string localName = attribute.LocalName; if (localName == TestAtomConstants.AtomGeneratorUriAttributeName) { metadata.Uri = string.IsNullOrEmpty(attribute.PropertyValue) ? null : new Uri(attribute.PropertyValue); } else if (localName == TestAtomConstants.AtomGeneratorVersionAttributeName) { metadata.Version = attribute.PropertyValue; } else { throw new NotSupportedException("Unsupported metadata '" + localName + "' found for a generator."); } } } return(metadata); }
/// <summary> /// Write the given feed metadata in atom format /// </summary> /// <param name="writer">The Xml writer to write to.</param> /// <param name="baseUri">The base Uri of the document or null if none was specified.</param> /// <param name="feedMetadata">The metadata to write.</param> /// <param name="feed">The feed for which to write the meadata or null if it is the metadata of an atom:source element.</param> private static void WriteFeedMetadata(XmlWriter writer, Uri baseUri, AtomFeedMetadata feedMetadata, ODataFeed feed) { Debug.Assert(writer != null, "writer != null"); Debug.Assert(feedMetadata != null, "Feed metadata must not be null!"); // <atom:id>text</atom:id> // NOTE: this is the Id of the feed. For a regular feed this is stored on the feed itself; // if used in the context of an <atom:source> element it is stored in metadata Debug.Assert(feed == null || !string.IsNullOrEmpty(feed.Id), "The feed Id should have been validated by now."); string id = feed == null ? feedMetadata.SourceId : feed.Id; ODataAtomWriterUtils.WriteElementWithTextContent( writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomIdElementName, AtomConstants.AtomNamespace, id); // <atom:title>text</atom:title> // NOTE: write an empty element if no title is specified since the element is required ODataAtomWriterMetadataUtils.WriteTextConstruct(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomTitleElementName, AtomConstants.AtomNamespace, feedMetadata.Title); if (feedMetadata.Subtitle != null) { // <atom:subtitle>text</atom:subtitle> ODataAtomWriterMetadataUtils.WriteTextConstruct(writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomSubtitleElementName, AtomConstants.AtomNamespace, feedMetadata.Subtitle); } // <atom:updated>date</atom:updated> // NOTE: the <updated> element is required and if not specified the best we can do is to create a default // one with the current date/time. DateTimeOffset updated = feedMetadata.Updated.HasValue ? feedMetadata.Updated.Value : DateTimeOffset.UtcNow; ODataAtomWriterUtils.WriteElementWithTextContent( writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomUpdatedElementName, AtomConstants.AtomNamespace, ODataAtomConvert.ToString(updated)); IEnumerable <AtomPersonMetadata> authors = feedMetadata.Authors; if (authors != null) { foreach (AtomPersonMetadata author in authors) { // <atom:author>author data</atom:author> writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomAuthorElementName, AtomConstants.AtomNamespace); WritePersonMetadata(writer, baseUri, author); writer.WriteEndElement(); } } IEnumerable <AtomLinkMetadata> links = feedMetadata.Links; if (links != null) { foreach (AtomLinkMetadata link in links) { // <atom:link>...</atom:link> WriteAtomLinkMetadata(writer, baseUri, link); } } IEnumerable <AtomCategoryMetadata> categories = feedMetadata.Categories; if (categories != null) { foreach (AtomCategoryMetadata category in categories) { // <atom:category term="..." scheme="..." label="..."></atom:category> WriteCategory(writer, category); } } Uri logo = feedMetadata.Logo; if (logo != null) { // <atom:logo>Uri</atom:logo> ODataAtomWriterUtils.WriteElementWithTextContent( writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomLogoElementName, AtomConstants.AtomNamespace, AtomUtils.ToUrlAttributeValue(logo, baseUri)); } if (feedMetadata.Rights != null) { // <atom:rights>rights</atom:rights> ODataAtomWriterMetadataUtils.WriteTextConstruct( writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomRightsElementName, AtomConstants.AtomNamespace, feedMetadata.Rights); } IEnumerable <AtomPersonMetadata> contributors = feedMetadata.Contributors; if (contributors != null) { foreach (AtomPersonMetadata contributor in contributors) { // <atom:contributor>contributor data</atom:contributor> writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomContributorElementName, AtomConstants.AtomNamespace); WritePersonMetadata(writer, baseUri, contributor); writer.WriteEndElement(); } } AtomGeneratorMetadata generator = feedMetadata.Generator; if (generator != null) { // <atom:generator uri="..." version="...">name</atom:generator> writer.WriteStartElement(AtomConstants.AtomNamespacePrefix, AtomConstants.AtomGeneratorElementName, AtomConstants.AtomNamespace); if (generator.Uri != null) { writer.WriteAttributeString(AtomConstants.AtomGeneratorUriAttributeName, AtomUtils.ToUrlAttributeValue(generator.Uri, baseUri)); } if (!string.IsNullOrEmpty(generator.Version)) { writer.WriteAttributeString(AtomConstants.AtomGeneratorVersionAttributeName, generator.Version); } writer.WriteString(generator.Name); writer.WriteEndElement(); } Uri icon = feedMetadata.Icon; if (icon != null) { // <atom:icon>Uri</atom:icon> ODataAtomWriterUtils.WriteElementWithTextContent( writer, AtomConstants.AtomNamespacePrefix, AtomConstants.AtomIconElementName, AtomConstants.AtomNamespace, AtomUtils.ToUrlAttributeValue(icon, baseUri)); } }
/// <summary> /// Visits an ATOM metadata object. /// </summary> /// <param name="atomMetadata"></param> protected virtual void VisitAtomMetadata(object atomMetadata) { if (atomMetadata == null) { return; } AtomCategoryMetadata atomCategoryMetadata = atomMetadata as AtomCategoryMetadata; if (atomCategoryMetadata != null) { this.VisitAtomCategoryMetadata(atomCategoryMetadata); return; } AtomEntryMetadata atomEntryMetadata = atomMetadata as AtomEntryMetadata; if (atomEntryMetadata != null) { this.VisitAtomEntryMetadata(atomEntryMetadata); return; } AtomFeedMetadata atomFeedMetadata = atomMetadata as AtomFeedMetadata; if (atomFeedMetadata != null) { this.VisitAtomFeedMetadata(atomFeedMetadata); return; } AtomGeneratorMetadata atomGeneratorMetadata = atomMetadata as AtomGeneratorMetadata; if (atomGeneratorMetadata != null) { this.VisitAtomGeneratorMetadata(atomGeneratorMetadata); return; } AtomLinkMetadata atomLinkMetadata = atomMetadata as AtomLinkMetadata; if (atomLinkMetadata != null) { this.VisitAtomLinkMetadata(atomLinkMetadata); return; } AtomPersonMetadata atomPersonMetadata = atomMetadata as AtomPersonMetadata; if (atomPersonMetadata != null) { this.VisitAtomPersonMetadata(atomPersonMetadata); return; } AtomResourceCollectionMetadata atomResourceCollectionMetadata = atomMetadata as AtomResourceCollectionMetadata; if (atomResourceCollectionMetadata != null) { this.VisitAtomResourceCollectionMetadata(atomResourceCollectionMetadata); return; } AtomStreamReferenceMetadata atomStreamReferenceMetadata = atomMetadata as AtomStreamReferenceMetadata; if (atomStreamReferenceMetadata != null) { this.VisitAtomStreamReferenceMetadata(atomStreamReferenceMetadata); return; } AtomTextConstruct atomTextConstruct = atomMetadata as AtomTextConstruct; if (atomTextConstruct != null) { this.VisitAtomTextConstruct(atomTextConstruct); return; } AtomWorkspaceMetadata atomWorkspaceMetadata = atomMetadata as AtomWorkspaceMetadata; if (atomWorkspaceMetadata != null) { this.VisitAtomWorkspaceMetadata(atomWorkspaceMetadata); return; } AtomCategoriesMetadata atomCategoriesMetadata = atomMetadata as AtomCategoriesMetadata; if (atomCategoriesMetadata != null) { this.VisitAtomCategoriesMetadata(atomCategoriesMetadata); return; } ExceptionUtilities.Assert(false, "Unrecognized ATOM metadata object {0} of type {1}.", atomMetadata.ToString(), atomMetadata.GetType().ToString()); }
/// <summary> /// Visits an ATOM generator metadata. /// </summary> /// <param name="atomGeneratorMetadata">The generator metadata to visit.</param> protected virtual void VisitAtomGeneratorMetadata(AtomGeneratorMetadata atomGeneratorMetadata) { }
public void EntryMetadataWriterTest() { const string testPublished = "2010-10-20T20:10:00Z"; AtomTextConstruct testRights = new AtomTextConstruct { Text = "Copyright Data Fx team." }; AtomTextConstruct testSummary = new AtomTextConstruct { Text = "Test summary." }; AtomTextConstruct testTitle = new AtomTextConstruct { Text = "Test title" }; const string testUpdated = "2010-11-01T00:04:00Z"; const string testIcon = "http://odata.org/icon"; const string testSourceId = "http://odata.org/id/random"; const string testLogo = "http://odata.org/logo"; AtomTextConstruct testSubtitle = new AtomTextConstruct { Text = "Test subtitle." }; const string testAuthorName = "Test Author 1"; const string testAuthorEmail = "*****@*****.**"; const string testAuthorUri = "http://odata.org/authors/1"; var testAuthors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testAuthorEmail, Name = testAuthorName, Uri = new Uri(testAuthorUri) } }; var testAuthors2 = new AtomPersonMetadata[0]; const string testCategoryTerm = "Test category 1 term"; const string testCategoryLabel = "Test category 1 label"; const string testCategoryScheme = "http://odata.org/categories/1"; var testCategories = new AtomCategoryMetadata[] { new AtomCategoryMetadata() { Term = testCategoryTerm, Label = testCategoryLabel, Scheme = testCategoryScheme } }; const string testContributorName = "Test Contributor 1"; const string testContributorEmail = "*****@*****.**"; const string testContributorUri = "http://odata.org/contributors/1"; var testContributors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testContributorEmail, Name = testContributorName, Uri = new Uri(testContributorUri) } }; const string testGeneratorName = "Test generator"; const string testGeneratorUri = "http://odata.org/generator"; const string testGeneratorVersion = "3.0"; var testGenerator = new AtomGeneratorMetadata() { Name = testGeneratorName, Uri = new Uri(testGeneratorUri), Version = testGeneratorVersion }; const string testLinkRelation = "http://odata.org/links/1"; const string testLinkTitle = "Test link 1"; const string testLinkHref = "http://odata.org/links/1"; const string testLinkHrefLang = "de-AT"; int? testLinkLength = 999; const string testLinkMediaType = "image/png"; var testLinks = new AtomLinkMetadata[] { new AtomLinkMetadata() { Relation = testLinkRelation, Title = testLinkTitle, Href = new Uri(testLinkHref), HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType } }; AtomFeedMetadata testSource = new AtomFeedMetadata() { Authors = testAuthors, Categories = testCategories, Contributors = testContributors, Generator = testGenerator, Icon = new Uri(testIcon), SourceId = new Uri(testSourceId), Links = testLinks, Logo = new Uri(testLogo), Rights = testRights, Subtitle = testSubtitle, Title = testTitle, Updated = DateTimeOffset.Parse(testUpdated) }; Func <string, Func <XElement, XElement> > fragmentExtractor = (localName) => (e) => e.Element(TestAtomConstants.AtomXNamespace + localName); // TODO, ckerer: specify an Id via metadata if the entry does not specify one; we first have to decide what rules // we want to apply to merging of metadata and ODataLib OM data. var testCases = new[] { new { // specify an author via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Authors = testAuthors), Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new { // specify an empty author array via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Authors = testAuthors2), Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name />", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new { // specify no authors via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Authors = null), Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @"$(Indent)<name />", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new { // specify a category via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Categories = testCategories), Xml = @"<category term=""" + testCategoryTerm + @""" scheme=""" + testCategoryScheme + @""" label=""" + testCategoryLabel + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @""" />", Extractor = fragmentExtractor(TestAtomConstants.AtomCategoryElementName) }, new { // specify a contributor via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Contributors = testContributors), Xml = string.Join( "$(NL)", @"<contributor xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testContributorName + @"</name>", @" <uri>" + testContributorUri + @"</uri>", @" <email>" + testContributorEmail + @"</email>", @"</contributor>"), Extractor = fragmentExtractor(TestAtomConstants.AtomContributorElementName) }, new { // specify a link via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Links = testLinks), Xml = @"<link rel=""" + testLinkRelation + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = new Func <XElement, XElement>( (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(l => l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value != TestAtomConstants.AtomSelfRelationAttributeValue) .Single()) }, new { // specify a published date via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Published = DateTimeOffset.Parse(testPublished)), Xml = @"<published xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testPublished + @"</published>", Extractor = fragmentExtractor(TestAtomConstants.AtomPublishedElementName) }, new { // specify rights via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Rights = testRights), Xml = @"<rights type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testRights.Text + @"</rights>", Extractor = fragmentExtractor(TestAtomConstants.AtomRightsElementName) }, new { // specify a source via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Source = testSource), Xml = string.Join( "$(NL)", @"<source xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <id>" + testSourceId + "</id>", @" <title type=""text"">" + testTitle.Text + @"</title>", @" <subtitle type=""text"">" + testSubtitle.Text + @"</subtitle>", @" <updated>" + testUpdated + @"</updated>", @" <link rel=""" + testLinkRelation + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @"""/>", @" <category term=""" + testCategoryTerm + @""" scheme=""" + testCategoryScheme + @""" label=""" + testCategoryLabel + @""" />", @" <logo>" + testLogo + @"</logo>", @" <rights type=""text"">" + testRights.Text + @"</rights>", @" <contributor>", @" <name>" + testContributorName + @"</name>", @" <uri>" + testContributorUri + @"</uri>", @" <email>" + testContributorEmail + @"</email>", @" </contributor>", @" <generator uri=""" + testGeneratorUri + @""" version=""" + testGeneratorVersion + @""">" + testGeneratorName + @"</generator>", @" <icon>" + testIcon + @"</icon>", @" <author>", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @" </author>", @"</source>"), Extractor = fragmentExtractor(TestAtomConstants.AtomSourceElementName) }, new { // specify default feed metadata as source CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Source = new AtomFeedMetadata()), Xml = string.Join( "$(NL)", @"<source xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <id />", @" <title />", @" <updated />", @"</source>"), Extractor = new Func <XElement, XElement>(result => { var source = fragmentExtractor(TestAtomConstants.AtomSourceElementName)(result); // Remove the value of updates as it can't be reliably predicted source.Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomUpdatedElementName).Nodes().Remove(); return(source); }) }, new { // specify a summary via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Summary = testSummary), Xml = @"<summary type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testSummary.Text + @"</summary>", Extractor = fragmentExtractor(TestAtomConstants.AtomSummaryElementName) }, new { // specify a title via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Title = testTitle), Xml = @"<title type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testTitle.Text + @"</title>", Extractor = fragmentExtractor(TestAtomConstants.AtomTitleElementName) }, new { // specify an updated date via metadata CustomizeMetadata = new Action <AtomEntryMetadata>(metadata => metadata.Updated = DateTimeOffset.Parse(testUpdated)), Xml = @"<updated xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testUpdated + @"</updated>", Extractor = fragmentExtractor(TestAtomConstants.AtomUpdatedElementName) }, }; // Convert test cases to test descriptions IEnumerable <Func <ODataEntry> > entryCreators = new Func <ODataEntry>[] { () => ObjectModelUtils.CreateDefaultEntry(), () => ObjectModelUtils.CreateDefaultEntryWithAtomMetadata(), }; var testDescriptors = testCases.SelectMany(testCase => entryCreators.Select(entryCreator => { ODataEntry entry = entryCreator(); AtomEntryMetadata metadata = entry.Atom(); this.Assert.IsNotNull(metadata, "Expected default entry metadata on a default entry."); testCase.CustomizeMetadata(metadata); return(new PayloadWriterTestDescriptor <ODataItem>(this.Settings, entry, testConfiguration => new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = testCase.Xml, FragmentExtractor = testCase.Extractor })); })); 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); }); }
public void FeedMetadataWriterTest() { AtomTextConstruct testRights = new AtomTextConstruct { Text = "Copyright Data Fx team." }; AtomTextConstruct testTitle = new AtomTextConstruct { Text = "Test title" }; AtomTextConstruct testSubtitle = new AtomTextConstruct { Text = "Test subtitle" }; const string testUpdated = "2010-11-01T00:04:00Z"; const string testIcon = "http://odata.org/icon"; const string testLogo = "http://odata.org/logo"; const string testAuthorName = "Test Author 1"; const string testAuthorEmail = "*****@*****.**"; const string testAuthorUri = "http://odata.org/authors/1"; var testAuthors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testAuthorEmail, Name = testAuthorName, Uri = new Uri(testAuthorUri) } }; const string testCategoryTerm = "Test category 1 term"; const string testCategoryLabel = "Test category 1 label"; const string testCategoryScheme = "http://odata.org/categories/1"; var testCategories = new AtomCategoryMetadata[] { new AtomCategoryMetadata() { Term = testCategoryTerm, Label = testCategoryLabel, Scheme = testCategoryScheme } }; const string testContributorName = "Test Contributor 1"; const string testContributorEmail = "*****@*****.**"; const string testContributorUri = "http://odata.org/contributors/1"; var testContributors = new AtomPersonMetadata[] { new AtomPersonMetadata() { Email = testContributorEmail, Name = testContributorName, Uri = new Uri(testContributorUri) } }; const string testGeneratorName = "Test generator"; const string testGeneratorUri = "http://odata.org/generator"; const string testGeneratorVersion = "3.0"; var testGenerator = new AtomGeneratorMetadata() { Name = testGeneratorName, Uri = new Uri(testGeneratorUri), Version = testGeneratorVersion }; const string testLinkRelation = "http://odata.org/links/1"; const string testLinkTitle = "Test link 1"; const string testLinkHref = "http://odata.org/links/1"; const string testLinkHrefLang = "de-AT"; int? testLinkLength = 999; const string testLinkMediaType = "image/png"; var testLinks = new AtomLinkMetadata[] { new AtomLinkMetadata() { Relation = testLinkRelation, Title = testLinkTitle, Href = new Uri(testLinkHref), HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType } }; var selfLink = new AtomLinkMetadata() { Relation = TestAtomConstants.AtomSelfRelationAttributeValue, Title = testLinkTitle, Href = new Uri(testLinkHref), HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }; Func <string, Func <XElement, XElement> > fragmentExtractor = (localName) => (e) => e.Element(TestAtomConstants.AtomXNamespace + localName); // TODO, ckerer: specify an Id via metadata if the entry does not specify one; we first have to decide what rules // we want to apply to merging of metadata and ODataLib OM data. var testCases = new FeedMetadataTestCase[] { new FeedMetadataTestCase { // specify an icon via metadata CustomizeMetadata = metadata => metadata.Icon = new Uri(testIcon), Xml = @"<icon xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testIcon + @"</icon>", Extractor = fragmentExtractor(TestAtomConstants.AtomIconElementName) }, new FeedMetadataTestCase { // specify a logo via metadata CustomizeMetadata = metadata => metadata.Logo = new Uri(testLogo), Xml = @"<logo xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testLogo + @"</logo>", Extractor = fragmentExtractor(TestAtomConstants.AtomLogoElementName) }, new FeedMetadataTestCase { // specify rights via metadata CustomizeMetadata = metadata => metadata.Rights = testRights, Xml = @"<rights type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testRights.Text + @"</rights>", Extractor = fragmentExtractor(TestAtomConstants.AtomRightsElementName) }, new FeedMetadataTestCase { // specify a subtitle via metadata CustomizeMetadata = metadata => metadata.Subtitle = testSubtitle, Xml = @"<subtitle type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testSubtitle.Text + @"</subtitle>", Extractor = fragmentExtractor(TestAtomConstants.AtomSubtitleElementName) }, new FeedMetadataTestCase { // specify a title via metadata CustomizeMetadata = metadata => metadata.Title = testTitle, Xml = @"<title type=""text"" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testTitle.Text + @"</title>", Extractor = fragmentExtractor(TestAtomConstants.AtomTitleElementName) }, new FeedMetadataTestCase { // specify an updated date via metadata CustomizeMetadata = metadata => metadata.Updated = DateTimeOffset.Parse(testUpdated), Xml = @"<updated xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testUpdated + @"</updated>", Extractor = fragmentExtractor(TestAtomConstants.AtomUpdatedElementName) }, new FeedMetadataTestCase { // no author specified, the default author with empty name is written CustomizeMetadata = metadata => metadata.Authors = null, Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name />", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new FeedMetadataTestCase { // specify an author via metadata CustomizeMetadata = metadata => metadata.Authors = testAuthors, Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new FeedMetadataTestCase { // no author specified but some entries written, no author should be written CustomizeMetadata = metadata => metadata.Authors = null, CustomizePayload = feed => new ODataItem[] { feed, ObjectModelUtils.CreateDefaultEntry() }, Xml = "<authors />", Extractor = result => new XElement("authors", fragmentExtractor(TestAtomConstants.AtomAuthorElementName)(result)) }, new FeedMetadataTestCase { // specify an author via metadata and some entries (the author should be written anyway) CustomizeMetadata = metadata => metadata.Authors = testAuthors, CustomizePayload = feed => new ODataItem[] { feed, ObjectModelUtils.CreateDefaultEntry() }, Xml = string.Join( "$(NL)", @"<author xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testAuthorName + @"</name>", @" <uri>" + testAuthorUri + @"</uri>", @" <email>" + testAuthorEmail + @"</email>", @"</author>"), Extractor = fragmentExtractor(TestAtomConstants.AtomAuthorElementName) }, new FeedMetadataTestCase { // specify a category via metadata CustomizeMetadata = metadata => metadata.Categories = testCategories, Xml = @"<category term=""" + testCategoryTerm + @""" scheme=""" + testCategoryScheme + @""" label=""" + testCategoryLabel + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @""" />", Extractor = fragmentExtractor(TestAtomConstants.AtomCategoryElementName) }, new FeedMetadataTestCase { // specify a contributor via metadata CustomizeMetadata = metadata => metadata.Contributors = testContributors, Xml = string.Join( "$(NL)", @"<contributor xmlns=""" + TestAtomConstants.AtomNamespace + @""">", @" <name>" + testContributorName + @"</name>", @" <uri>" + testContributorUri + @"</uri>", @" <email>" + testContributorEmail + @"</email>", @"</contributor>"), Extractor = fragmentExtractor(TestAtomConstants.AtomContributorElementName) }, new FeedMetadataTestCase { // specify a generator via metadata CustomizeMetadata = metadata => metadata.Generator = testGenerator, Xml = @"<generator uri=""" + testGeneratorUri + @""" version=""" + testGeneratorVersion + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @""">" + testGeneratorName + @"</generator>", Extractor = fragmentExtractor(TestAtomConstants.AtomGeneratorElementName) }, new FeedMetadataTestCase { // specify a link via metadata CustomizeMetadata = metadata => metadata.Links = testLinks, Xml = @"<link rel=""" + testLinkRelation + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Single() }, new FeedMetadataTestCase { // no self link specified CustomizeMetadata = metadata => metadata.SelfLink = null, Xml = @"<selflink/>", Extractor = (e) => new XElement("selflink", e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomSelfRelationAttributeValue)) }, new FeedMetadataTestCase { // Some self link specified CustomizeMetadata = metadata => metadata.SelfLink = selfLink, Xml = @"<link rel=""" + TestAtomConstants.AtomSelfRelationAttributeValue + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomSelfRelationAttributeValue) }, new FeedMetadataTestCase { // Non-self relation CustomizeMetadata = metadata => metadata.SelfLink = new AtomLinkMetadata { Relation = "SelF", Href = new Uri(testLinkHref) }, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_LinkRelationsMustMatch", "self", "SelF"), }, new FeedMetadataTestCase { // no next link on either OM or metadata specified CustomizeMetadata = metadata => metadata.NextPageLink = null, Xml = @"<nextlink/>", Extractor = (e) => new XElement("nextlink", e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue)), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // the next link is only specified on metadata - nothing is written CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Relation = "next", Href = new Uri(testLinkHref) }, Xml = @"<nextlink/>", Extractor = (e) => new XElement("nextlink", e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue)), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified only on the OM CustomizeMetadata = metadata => metadata.NextPageLink = null, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, Xml = @"<link rel=""" + TestAtomConstants.AtomNextRelationAttributeValue + @""" href=""" + testLinkHref + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - no conflicts CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, Xml = @"<link rel=""" + TestAtomConstants.AtomNextRelationAttributeValue + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - no conflicts cause values are identical CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Relation = TestAtomConstants.AtomNextRelationAttributeValue, Href = new Uri(testLinkHref), Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, Xml = @"<link rel=""" + TestAtomConstants.AtomNextRelationAttributeValue + @""" type = """ + testLinkMediaType + @""" title=""" + testLinkTitle + @""" href=""" + testLinkHref + @""" hreflang=""" + testLinkHrefLang + @""" length=""" + testLinkLength + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @"""/>", Extractor = (e) => e.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .SingleOrDefault(l => (string)l.Attribute(TestAtomConstants.AtomLinkRelationAttributeName) == TestAtomConstants.AtomNextRelationAttributeValue), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - conflict on relation CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Relation = "Next", Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_LinkRelationsMustMatch", "next", "Next"), SkipTestConfiguration = tc => tc.IsRequest }, new FeedMetadataTestCase { // Next link specified both on OM and on metadata - conflict on href CustomizeMetadata = metadata => metadata.NextPageLink = new AtomLinkMetadata { Href = new Uri("http://odata.org/different"), Title = testLinkTitle, HrefLang = testLinkHrefLang, Length = testLinkLength, MediaType = testLinkMediaType }, CustomizePayload = feed => { feed.NextPageLink = new Uri(testLinkHref); return(new ODataItem[] { feed }); }, ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriterMetadataUtils_LinkHrefsMustMatch", testLinkHref, "http://odata.org/different"), SkipTestConfiguration = tc => tc.IsRequest }, }; this.CreateTestDescriptorsAndRunTests(testCases, WriterPayloads.FeedPayloads); }
/// <summary> /// Visits an ATOM generator metadata. /// </summary> /// <param name="atomGeneratorMetadata">The generator metadata to visit.</param> protected override void VisitAtomGeneratorMetadata(AtomGeneratorMetadata atomGeneratorMetadata) { this.ValidateUri(atomGeneratorMetadata.Uri); base.VisitAtomGeneratorMetadata(atomGeneratorMetadata); }