public ProjectedPropertiesTestCase(ProjectedPropertiesTestCase other) { this.DebugDescription = other.DebugDescription; this.TopLevelProjectedProperties = other.TopLevelProjectedProperties; this.NestedProjectedProperties = other.NestedProjectedProperties; this.ExpectedProperties = other.ExpectedProperties; this.ResponseOnly = other.ResponseOnly; this.NestedPayload = other.NestedPayload; this.IgnoreFormats = other.IgnoreFormats; this.ExpectedException = other.ExpectedException; }
private WriterTestExpectedResults CreateExpectedResults(WriterTestConfiguration testConfiguration, ProjectedPropertiesTestCase testCase, bool withModel) { if (testCase.ExpectedException != null) { ExpectedException expectedException = testCase.ExpectedException(withModel); if (expectedException != null) { return(new WriterTestExpectedResults(this.Settings.ExpectedResultSettings) { ExpectedException2 = expectedException }); } } if (testConfiguration.Format == ODataFormat.Atom) { #region Atom expected result var atomExpectedResults = new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = new XElement("properties", testCase.ExpectedProperties.OrderBy(p => p).Select(p => new XElement(p))).ToString(), FragmentExtractor = (result) => { // Navigation links IEnumerable <string> actualProperties; if (result == null) { actualProperties = new string[0]; } else { actualProperties = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix)) .Select(link => link.Attribute(TestAtomConstants.AtomLinkTitleAttributeName).Value); // Named stream links actualProperties = actualProperties.Concat(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(TestAtomConstants.ODataStreamPropertyEditMediaRelatedLinkRelationPrefix)) .Select(link => link.Attribute(TestAtomConstants.AtomLinkTitleAttributeName).Value)); // Association links actualProperties = actualProperties.Concat(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(TestAtomConstants.ODataNavigationPropertiesAssociationLinkRelationPrefix)) .Select(link => link.Attribute(TestAtomConstants.AtomLinkTitleAttributeName).Value)); // Properties actualProperties = actualProperties.Concat(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName) .Elements(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName) .Elements().Where(e => e.Name.Namespace == TestAtomConstants.ODataXNamespace) .Select(pe => pe.Name.LocalName)); } return(new XElement("properties", actualProperties.OrderBy(p => p).Select(p => new XElement(p)))); } }; if (testCase.NestedPayload) { var originalFragmentExtractor = atomExpectedResults.FragmentExtractor; atomExpectedResults.FragmentExtractor = (result) => { // Verify that the Wrapping_ID property is not written this.Assert.IsNull(result .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName) .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName), "There should be no other property but the nav link and thus no m:properties in the content."); XElement expandedNavLinkElement = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value .StartsWith(TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix + "Wrapping_ExpandedEntry")) .SingleOrDefault(); return(originalFragmentExtractor( expandedNavLinkElement == null ? null : expandedNavLinkElement .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName))); }; } return(atomExpectedResults); #endregion Atom expected result } else if (testConfiguration.Format == ODataFormat.Json) { #region JSON Light expected result JsonArray expectedJson = new JsonArray(); foreach (var p in testCase.ExpectedProperties.Distinct().OrderBy(p => p)) { expectedJson.Add(new JsonPrimitiveValue(p)); } var jsonExpectedResults = new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Json = expectedJson.ToText(/*writingJsonLight*/ true, testConfiguration.MessageWriterSettings.Indent), FragmentExtractor = (result) => { // Everything except association links IEnumerable <string> actualProperties; if (result == null) { actualProperties = new string[0]; } else { List <string> propertyNames = new List <string>(); foreach (JsonProperty jsonProperty in result.Object().Properties) { string propertyName = jsonProperty.Name; int atIndex = propertyName.IndexOf('@'); int dotIndex = propertyName.IndexOf('.'); if (dotIndex < 0) { propertyNames.Add(propertyName); } else if (atIndex >= 0) { propertyNames.Add(propertyName.Substring(0, atIndex)); } } actualProperties = propertyNames.Distinct(); } JsonArray r = new JsonArray(); foreach (var p in actualProperties.OrderBy(p => p)) { r.Add(new JsonPrimitiveValue(p)); } return(r); } }; if (testCase.NestedPayload) { var originalFragmentExtractor = jsonExpectedResults.FragmentExtractor; jsonExpectedResults.FragmentExtractor = (result) => { // Verify that the Wrapping_ID property is not written JsonObject resultObject = result.Object(); this.Assert.IsNull(resultObject.Property("Wrapping_ID"), "No other property but the nav. link should be written."); return(originalFragmentExtractor( resultObject.Property("Wrapping_ExpandedEntry") == null ? null : resultObject.PropertyObject("Wrapping_ExpandedEntry"))); }; } return(jsonExpectedResults); #endregion JSON Light expected result } else { throw new TaupoInvalidOperationException("The format " + testConfiguration.Format.GetType().FullName + " is not supported."); } }
public void ProjectedPropertiesTest() { // Start with top-level payloads IEnumerable <ProjectedPropertiesTestCase> topLevelTestCases = new ProjectedPropertiesTestCase[] { // No point testing case where no annotation is specified, as all the other tests do that. // It's important to sort these in the payload order, so nav props go first, then named streams and then normal properties // Also note that assoc link and nav link might have the same name, in which case they will be twice in the list below new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[0]), ExpectedProperties = new string[0], }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty" }), ExpectedProperties = new string[] { "StringProperty" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty", "NumberProperty" }), ExpectedProperties = new string[] { "StringProperty", "NumberProperty" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "SimpleComplexProperty", "PrimitiveCollection" }), ExpectedProperties = new string[] { "SimpleComplexProperty", "PrimitiveCollection" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "NamedStream" }), ExpectedProperties = new string[] { "NamedStream" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "AssociationLink" }), ExpectedProperties = new string[] { "AssociationLink" }, ResponseOnly = true, IgnoreFormats = new ODataFormat[] { ODataFormat.Json }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "NamedStream", "StringProperty", "NumberProperty", "SimpleComplexProperty", "DeepComplexProperty", "PrimitiveCollection", "ComplexCollection" }), ExpectedProperties = new string[] { "NamedStream", "StringProperty", "NumberProperty", "SimpleComplexProperty", "DeepComplexProperty", "PrimitiveCollection", "ComplexCollection" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "DeferredNavigation" }), ExpectedProperties = new string[] { "DeferredNavigation", "DeferredNavigation" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "ExpandedEntry" }), ExpectedProperties = new string[] { "ExpandedEntry" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "ExpandedFeed" }), ExpectedProperties = new string[] { "ExpandedFeed" }, }, }; // Then create wrapped test cases var nestedTestCases = topLevelTestCases.Select(t => new ProjectedPropertiesTestCase(t) { NestedPayload = true, NestedProjectedProperties = t.TopLevelProjectedProperties, TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "Wrapping_ExpandedEntry" }), }); // Create more interesting test cases with multiple annotations var manualTestCases = new ProjectedPropertiesTestCase[] { new ProjectedPropertiesTestCase { DebugDescription = "Non-existant name in top-level annotation is ignored.", TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "NumberProperty", "NamedStream", "NamedStream", "DeferredNavigation", "ExpandedEntry", "ExpandedFeed", "NonExistant" }), ExpectedProperties = new string[] { "DeferredNavigation", "ExpandedEntry", "ExpandedFeed", "NamedStream", "DeferredNavigation", "NumberProperty" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { DebugDescription = "Make sure a top-level annotation with invalid property names or paths projects nothing.", TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { string.Empty, null, "Invalid", "SimpleComplexProperty/Name" }), ExpectedProperties = new string[] { }, }, new ProjectedPropertiesTestCase { DebugDescription = "Make sure a nested annotation works with a top-level annotation.", NestedPayload = true, TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "Wrapping_ExpandedEntry" }), NestedProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty", "NumberProperty" }), ExpectedProperties = new string[] { "StringProperty", "NumberProperty" }, }, new ProjectedPropertiesTestCase { DebugDescription = "Make sure a nested annotation is ignored if a top-level annotation does not include the navigation property.", NestedPayload = true, TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "Invalid" }), NestedProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty", "NumberProperty" }), ExpectedProperties = new string[0], }, }; var testCases = topLevelTestCases.Concat(nestedTestCases).Concat(manualTestCases); IEdmModel edmModel = this.CreateEdmModel(); // First create test descriptors that use the model var testDescriptors = this.CreateEdmTestDescriptors(testCases, edmModel); // Then append the test descriptors without model testDescriptors = testDescriptors.Concat(this.CreateEdmTestDescriptors(testCases, /*model*/ null)); //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.TopLevelValuePayload), this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.Format == ODataFormat.Atom), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor.DeferredLinksToEntityReferenceLinksInRequest(testConfiguration), testConfiguration, this.Assert, this.Logger); }); }
private IEnumerable <ODataItem> CreatePayload(ProjectedPropertiesTestCase testCase) { // First create the entry itself (it might get wrapped later) ODataEntry entry = new ODataEntry() { TypeName = "TestModel.EntityType", Properties = new List <ODataProperty>() { new ODataProperty { Name = "StringProperty", Value = "foo" }, new ODataProperty { Name = "NumberProperty", Value = 42 }, new ODataProperty { Name = "SimpleComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Name", Value = "Bart" } } } }, new ODataProperty { Name = "DeepComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.NestedComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "InnerComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType2", Properties = new ODataProperty[] { new ODataProperty { Name = "Value", Value = 43 } } } } } } }, new ODataProperty { Name = "PrimitiveCollection", Value = new ODataCollectionValue { TypeName = "Collection(Edm.String)", Items = new object[] { "Simpson" } } }, new ODataProperty { Name = "ComplexCollection", Value = new ODataCollectionValue { TypeName = "Collection(TestModel.RatingComplexType)", Items = new object[] { new ODataComplexValue { TypeName = "TestModel.RatingComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Rating", Value = -3 } } } } } } }, SerializationInfo = MySerializationInfo }; if (testCase.ResponseOnly) { // Add a stream property for responses ((List <ODataProperty>)entry.Properties).Add(new ODataProperty { Name = "NamedStream", Value = new ODataStreamReferenceValue { EditLink = new Uri("http://odata.org/namedstream") } }); } ODataItem[] entryItems = new ODataItem[] { entry, new ODataNavigationLink { Name = "DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred"), AssociationLinkUrl = testCase.ResponseOnly ? new Uri("http://odata.org/associationlink2") : null }, null, // End deferred link new ODataNavigationLink { Name = "ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/entry") }, new ODataEntry() { TypeName = "TestModel.ExpandedEntryType", Properties = new ODataProperty[] { new ODataProperty { Name = "ExpandedEntryName", Value = "bar" } }, SerializationInfo = MySerializationInfo }, new ODataNavigationLink { Name = "ExpandedEntry_DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred") }, null, // End deffered link new ODataNavigationLink { Name = "ExpandedEntry_ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid1"), SerializationInfo = MySerializationInfo }, null, // End feed null, // End exanded expanded feed link null, // End expanded entry null, // End expanded entry nav link new ODataNavigationLink { Name = "ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid2") }, new ODataEntry { TypeName = "TestModel.EntityType" }, null, // End entry new ODataEntry { TypeName = "TestModel.EntityType", SerializationInfo = MySerializationInfo }, null, // End entry null, // End expanded feed null, // End expanded feed nav link null, // End the top-level entry }; ProjectedPropertiesAnnotation projectedProperties = testCase.TopLevelProjectedProperties; if (!testCase.NestedPayload) { this.Assert.IsNull(testCase.NestedProjectedProperties, "For a non-nested payload, no nested annotation must be specified."); entry.SetAnnotation(projectedProperties); return(entryItems); } // If we are processing a test case for a nested payload, wrap the entry items into a wrapping entry with an expanded navigation link. ODataEntry wrappingEntry = new ODataEntry() { TypeName = "TestModel.WrappingEntityType", Properties = new[] { new ODataProperty { Name = "Wrapping_ID", Value = 1 } }, SerializationInfo = MySerializationInfo }; IEnumerable <ODataItem> wrappedItems = new ODataItem[] { wrappingEntry, new ODataNavigationLink { Name = "Wrapping_ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/wrapping") } } .Concat(entryItems) .Concat(new ODataItem[] { null, null }); ProjectedPropertiesAnnotation nestedProjectedProperties = testCase.NestedProjectedProperties; entry.SetAnnotation(nestedProjectedProperties); wrappingEntry.SetAnnotation(projectedProperties); return(wrappedItems); }
public void ProjectedPropertiesTest() { // Start with top-level payloads IEnumerable<ProjectedPropertiesTestCase> topLevelTestCases = new ProjectedPropertiesTestCase[] { // No point testing case where no annotation is specified, as all the other tests do that. // It's important to sort these in the payload order, so nav props go first, then named streams and then normal properties // Also note that assoc link and nav link might have the same name, in which case they will be twice in the list below new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[0]), ExpectedProperties = new string[0], }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty" }), ExpectedProperties = new string[] { "StringProperty" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty", "NumberProperty" }), ExpectedProperties = new string[] { "StringProperty", "NumberProperty" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "SimpleComplexProperty", "PrimitiveCollection" }), ExpectedProperties = new string[] { "SimpleComplexProperty", "PrimitiveCollection" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "NamedStream" }), ExpectedProperties = new string[] { "NamedStream" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "AssociationLink" }), ExpectedProperties = new string[] { "AssociationLink" }, ResponseOnly = true, IgnoreFormats = new ODataFormat[] { ODataFormat.Json }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "NamedStream", "StringProperty", "NumberProperty", "SimpleComplexProperty", "DeepComplexProperty", "PrimitiveCollection", "ComplexCollection" }), ExpectedProperties = new string[] { "NamedStream", "StringProperty", "NumberProperty", "SimpleComplexProperty", "DeepComplexProperty", "PrimitiveCollection", "ComplexCollection" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "DeferredNavigation" }), ExpectedProperties = new string[] { "DeferredNavigation", "DeferredNavigation" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "ExpandedEntry" }), ExpectedProperties = new string[] { "ExpandedEntry" }, }, new ProjectedPropertiesTestCase { TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "ExpandedFeed" }), ExpectedProperties = new string[] { "ExpandedFeed" }, }, }; // Then create wrapped test cases var nestedTestCases = topLevelTestCases.Select(t => new ProjectedPropertiesTestCase(t) { NestedPayload = true, NestedProjectedProperties = t.TopLevelProjectedProperties, TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "Wrapping_ExpandedEntry" }), }); // Create more interesting test cases with multiple annotations var manualTestCases = new ProjectedPropertiesTestCase[] { new ProjectedPropertiesTestCase { DebugDescription = "Non-existant name in top-level annotation is ignored.", TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "NumberProperty", "NamedStream", "NamedStream", "DeferredNavigation", "ExpandedEntry", "ExpandedFeed", "NonExistant" }), ExpectedProperties = new string[] { "DeferredNavigation", "ExpandedEntry", "ExpandedFeed", "NamedStream", "DeferredNavigation", "NumberProperty" }, ResponseOnly = true, }, new ProjectedPropertiesTestCase { DebugDescription = "Make sure a top-level annotation with invalid property names or paths projects nothing.", TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { string.Empty, null, "Invalid", "SimpleComplexProperty/Name" }), ExpectedProperties = new string[] { }, }, new ProjectedPropertiesTestCase { DebugDescription = "Make sure a nested annotation works with a top-level annotation.", NestedPayload = true, TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "Wrapping_ExpandedEntry" }), NestedProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty", "NumberProperty" }), ExpectedProperties = new string[] { "StringProperty", "NumberProperty" }, }, new ProjectedPropertiesTestCase { DebugDescription = "Make sure a nested annotation is ignored if a top-level annotation does not include the navigation property.", NestedPayload = true, TopLevelProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "Invalid" }), NestedProjectedProperties = new ProjectedPropertiesAnnotation(new string[] { "StringProperty", "NumberProperty" }), ExpectedProperties = new string[0], }, }; var testCases = topLevelTestCases.Concat(nestedTestCases).Concat(manualTestCases); IEdmModel edmModel = this.CreateEdmModel(); // First create test descriptors that use the model var testDescriptors = this.CreateEdmTestDescriptors(testCases, edmModel); // Then append the test descriptors without model testDescriptors = testDescriptors.Concat(this.CreateEdmTestDescriptors(testCases, /*model*/null)); //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.TopLevelValuePayload), this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.Format == ODataFormat.Atom), (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor.DeferredLinksToEntityReferenceLinksInRequest(testConfiguration), testConfiguration, this.Assert, this.Logger); }); }
private WriterTestExpectedResults CreateExpectedResults(WriterTestConfiguration testConfiguration, ProjectedPropertiesTestCase testCase, bool withModel) { if (testCase.ExpectedException != null) { ExpectedException expectedException = testCase.ExpectedException(withModel); if (expectedException != null) { return new WriterTestExpectedResults(this.Settings.ExpectedResultSettings) { ExpectedException2 = expectedException }; } } if (testConfiguration.Format == ODataFormat.Atom) { #region Atom expected result var atomExpectedResults = new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = new XElement("properties", testCase.ExpectedProperties.OrderBy(p => p).Select(p => new XElement(p))).ToString(), FragmentExtractor = (result) => { // Navigation links IEnumerable<string> actualProperties; if (result == null) { actualProperties = new string[0]; } else { actualProperties = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix)) .Select(link => link.Attribute(TestAtomConstants.AtomLinkTitleAttributeName).Value); // Named stream links actualProperties = actualProperties.Concat(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(TestAtomConstants.ODataStreamPropertyEditMediaRelatedLinkRelationPrefix)) .Select(link => link.Attribute(TestAtomConstants.AtomLinkTitleAttributeName).Value)); // Association links actualProperties = actualProperties.Concat(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value.StartsWith(TestAtomConstants.ODataNavigationPropertiesAssociationLinkRelationPrefix)) .Select(link => link.Attribute(TestAtomConstants.AtomLinkTitleAttributeName).Value)); // Properties actualProperties = actualProperties.Concat(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName) .Elements(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName) .Elements().Where(e => e.Name.Namespace == TestAtomConstants.ODataXNamespace) .Select(pe => pe.Name.LocalName)); } return new XElement("properties", actualProperties.OrderBy(p => p).Select(p => new XElement(p))); } }; if (testCase.NestedPayload) { var originalFragmentExtractor = atomExpectedResults.FragmentExtractor; atomExpectedResults.FragmentExtractor = (result) => { // Verify that the Wrapping_ID property is not written this.Assert.IsNull(result .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName) .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName), "There should be no other property but the nav link and thus no m:properties in the content."); XElement expandedNavLinkElement = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName) .Where(link => link.Attribute(TestAtomConstants.AtomLinkRelationAttributeName).Value .StartsWith(TestAtomConstants.ODataNavigationPropertiesRelatedLinkRelationPrefix + "Wrapping_ExpandedEntry")) .SingleOrDefault(); return originalFragmentExtractor( expandedNavLinkElement == null ? null : expandedNavLinkElement .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName)); }; } return atomExpectedResults; #endregion Atom expected result } else if (testConfiguration.Format == ODataFormat.Json) { #region JSON Light expected result JsonArray expectedJson = new JsonArray(); foreach (var p in testCase.ExpectedProperties.Distinct().OrderBy(p => p)) { expectedJson.Add(new JsonPrimitiveValue(p)); } var jsonExpectedResults = new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Json = expectedJson.ToText(/*writingJsonLight*/ true, testConfiguration.MessageWriterSettings.Indent), FragmentExtractor = (result) => { // Everything except association links IEnumerable<string> actualProperties; if (result == null) { actualProperties = new string[0]; } else { List<string> propertyNames = new List<string>(); foreach (JsonProperty jsonProperty in result.Object().Properties) { string propertyName = jsonProperty.Name; int atIndex = propertyName.IndexOf('@'); int dotIndex = propertyName.IndexOf('.'); if (dotIndex < 0) { propertyNames.Add(propertyName); } else if (atIndex >= 0) { propertyNames.Add(propertyName.Substring(0, atIndex)); } } actualProperties = propertyNames.Distinct(); } JsonArray r = new JsonArray(); foreach (var p in actualProperties.OrderBy(p => p)) { r.Add(new JsonPrimitiveValue(p)); } return r; } }; if (testCase.NestedPayload) { var originalFragmentExtractor = jsonExpectedResults.FragmentExtractor; jsonExpectedResults.FragmentExtractor = (result) => { // Verify that the Wrapping_ID property is not written JsonObject resultObject = result.Object(); this.Assert.IsNull(resultObject.Property("Wrapping_ID"), "No other property but the nav. link should be written."); return originalFragmentExtractor( resultObject.Property("Wrapping_ExpandedEntry") == null ? null : resultObject.PropertyObject("Wrapping_ExpandedEntry")); }; } return jsonExpectedResults; #endregion JSON Light expected result } else { throw new TaupoInvalidOperationException("The format " + testConfiguration.Format.GetType().FullName + " is not supported."); } }
private IEnumerable<ODataItem> CreatePayload(ProjectedPropertiesTestCase testCase) { // First create the entry itself (it might get wrapped later) ODataEntry entry = new ODataEntry() { TypeName = "TestModel.EntityType", Properties = new List<ODataProperty>() { new ODataProperty { Name = "StringProperty", Value = "foo" }, new ODataProperty { Name = "NumberProperty", Value = 42 }, new ODataProperty { Name = "SimpleComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Name", Value = "Bart" } } } }, new ODataProperty { Name = "DeepComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.NestedComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "InnerComplexProperty", Value = new ODataComplexValue { TypeName = "TestModel.SimplexComplexType2", Properties = new ODataProperty[] { new ODataProperty { Name = "Value", Value = 43 } } } } } } }, new ODataProperty { Name = "PrimitiveCollection", Value = new ODataCollectionValue { TypeName = "Collection(Edm.String)", Items = new object[] { "Simpson" } } }, new ODataProperty { Name = "ComplexCollection", Value = new ODataCollectionValue { TypeName = "Collection(TestModel.RatingComplexType)", Items = new object[] { new ODataComplexValue { TypeName = "TestModel.RatingComplexType", Properties = new ODataProperty[] { new ODataProperty { Name = "Rating", Value = -3 } } } } } } }, SerializationInfo = MySerializationInfo }; if (testCase.ResponseOnly) { // Add a stream property for responses ((List<ODataProperty>)entry.Properties).Add(new ODataProperty { Name = "NamedStream", Value = new ODataStreamReferenceValue { EditLink = new Uri("http://odata.org/namedstream") } }); } ODataItem[] entryItems = new ODataItem[] { entry, new ODataNavigationLink { Name = "DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred"), AssociationLinkUrl = testCase.ResponseOnly ? new Uri("http://odata.org/associationlink2") : null }, null, // End deferred link new ODataNavigationLink { Name = "ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/entry") }, new ODataEntry() { TypeName = "TestModel.ExpandedEntryType", Properties = new ODataProperty[] { new ODataProperty { Name = "ExpandedEntryName", Value = "bar" } }, SerializationInfo = MySerializationInfo }, new ODataNavigationLink { Name = "ExpandedEntry_DeferredNavigation", IsCollection = false, Url = new Uri("http://odata.org/deferred") }, null, // End deffered link new ODataNavigationLink { Name = "ExpandedEntry_ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid1"), SerializationInfo = MySerializationInfo }, null, // End feed null, // End exanded expanded feed link null, // End expanded entry null, // End expanded entry nav link new ODataNavigationLink { Name = "ExpandedFeed", IsCollection = true, Url = new Uri("http://odata.org/feed") }, new ODataFeed { Id = new Uri("http://test/feedid2") }, new ODataEntry { TypeName = "TestModel.EntityType" }, null, // End entry new ODataEntry { TypeName = "TestModel.EntityType", SerializationInfo = MySerializationInfo }, null, // End entry null, // End expanded feed null, // End expanded feed nav link null, // End the top-level entry }; ProjectedPropertiesAnnotation projectedProperties = testCase.TopLevelProjectedProperties; if (!testCase.NestedPayload) { this.Assert.IsNull(testCase.NestedProjectedProperties, "For a non-nested payload, no nested annotation must be specified."); entry.SetAnnotation(projectedProperties); return entryItems; } // If we are processing a test case for a nested payload, wrap the entry items into a wrapping entry with an expanded navigation link. ODataEntry wrappingEntry = new ODataEntry() { TypeName = "TestModel.WrappingEntityType", Properties = new[] { new ODataProperty { Name = "Wrapping_ID", Value = 1 } }, SerializationInfo = MySerializationInfo }; IEnumerable<ODataItem> wrappedItems = new ODataItem[] { wrappingEntry, new ODataNavigationLink { Name = "Wrapping_ExpandedEntry", IsCollection = false, Url = new Uri("http://odata.org/wrapping") }} .Concat(entryItems) .Concat(new ODataItem[] { null, null }); ProjectedPropertiesAnnotation nestedProjectedProperties = testCase.NestedProjectedProperties; entry.SetAnnotation(nestedProjectedProperties); wrappingEntry.SetAnnotation(projectedProperties); return wrappedItems; }