public void DuplicatePropertyNamesTest()
        {
            ODataProperty primitiveProperty = new ODataProperty { Name = "Foo", Value = 1 };
            ODataProperty complexProperty = new ODataProperty { Name = "Foo", Value = new ODataComplexValue { Properties = new[] { new ODataProperty() { Name = "StringProperty", Value = "xyz" } } } };
            ODataProperty collectionProperty = new ODataProperty { Name = "Foo", Value = new ODataCollectionValue { Items = new int[] { 1, 2 } } };

            ExpectedException expectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "Foo");
            Func<WriterTestConfiguration, ExpectedException> expectedExceptionFunc = (tc) => tc.MessageWriterSettings.GetAllowDuplicatePropertyNames() ? null : expectedException;

            DuplicatePropertyNamesTestCase[] testCases = new DuplicatePropertyNamesTestCase[]
            {
                new DuplicatePropertyNamesTestCase
                {
                    CollectionItem = new ODataComplexValue() { Properties = new ODataProperty[] { primitiveProperty, primitiveProperty } },
                    ExpectedODataException = expectedExceptionFunc,
                },
                new DuplicatePropertyNamesTestCase
                {
                    CollectionItem = new ODataComplexValue() { Properties = new ODataProperty[] { primitiveProperty, complexProperty } },
                    ExpectedODataException = expectedExceptionFunc,
                },
                new DuplicatePropertyNamesTestCase
                {
                    CollectionItem = new ODataComplexValue() { Properties = new ODataProperty[] { complexProperty, complexProperty } },
                    ExpectedODataException = expectedExceptionFunc,
                },
                new DuplicatePropertyNamesTestCase
                {
                    CollectionItem = new ODataComplexValue() { Properties = new ODataProperty[] { primitiveProperty, collectionProperty } },
                    ExpectedODataException = (tc) => expectedException,
                },
                new DuplicatePropertyNamesTestCase
                {
                    CollectionItem = new ODataComplexValue() { Properties = new ODataProperty[] { complexProperty, collectionProperty } },
                    ExpectedODataException = (tc) => expectedException,
                },
                new DuplicatePropertyNamesTestCase
                {
                    CollectionItem = new ODataComplexValue() { Properties = new ODataProperty[] { collectionProperty, collectionProperty } },
                    ExpectedODataException = (tc) => expectedException,
                },
            };

            var invocations = new CollectionWriterTestDescriptor.WriterInvocations[] 
            { 
                CollectionWriterTestDescriptor.WriterInvocations.StartCollection, 
                CollectionWriterTestDescriptor.WriterInvocations.Item,
                CollectionWriterTestDescriptor.WriterInvocations.EndCollection 
            };

            const string collectionName = "TestCollection";

            IEnumerable<CollectionWriterTestDescriptor> testDescriptors = testCases.Select(testCase =>
                new CollectionWriterTestDescriptor(
                    this.Settings,
                    collectionName, 
                    invocations, 
                    testCase.ExpectedODataException,
                    new CollectionWriterTestDescriptor.ItemDescription { Item = testCase.CollectionItem }
                ));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.WriterTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfig) =>
                {
                    CollectionWriterUtils.WriteAndVerifyCollectionPayload(testDescriptor, testConfig, this.Assert, this.Logger);
                });
        }
Example #2
0
        public void DuplicatePropertyNamesTest()
        {
            ODataFeed defaultFeed = ObjectModelUtils.CreateDefaultFeed();
            ODataEntry defaultEntry = ObjectModelUtils.CreateDefaultEntry();

            ODataProperty primitiveProperty = new ODataProperty { Name = "Foo", Value = 1 };
            ODataProperty complexProperty = new ODataProperty { Name = "Foo", Value = new ODataComplexValue { Properties = new[] { new ODataProperty() { Name = "StringProperty", Value = "xyz" } } } };
            ODataProperty collectionProperty = new ODataProperty { Name = "Foo", Value = new ODataCollectionValue { Items = new int[] { 1, 2 } } };
            ODataProperty streamProperty = new ODataProperty { Name = "Foo", Value = new ODataStreamReferenceValue { ReadLink = new Uri("http://odata.org/readlink") } };

            ODataNavigationLink singletonLink = new ODataNavigationLink { Name = "Foo", IsCollection = false, Url = new Uri("http://odata.org/link") };
            ODataNavigationLink collectionLink = new ODataNavigationLink { Name = "Foo", IsCollection = true, Url = new Uri("http://odata.org/links") };

            ExpectedException error = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "Foo");
            ExpectedException duplicateExpandedLinkError = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_MultipleLinksForSingleton", "Foo");
            ExpectedException streamPropertyInRequest = ODataExpectedExceptions.ODataException("WriterValidationUtils_StreamPropertyInRequest", "Foo");

            DuplicatePropertyNamesTestCase[] testCases = new DuplicatePropertyNamesTestCase[]
            {
                #region Duplicate primitive properties
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { primitiveProperty, primitiveProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { complexProperty, complexProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { primitiveProperty, complexProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { collectionProperty, collectionProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { primitiveProperty, collectionProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { complexProperty, collectionProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { primitiveProperty, streamProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => tc.IsRequest && tc.Format == ODataFormat.Atom ? streamPropertyInRequest : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { complexProperty, streamProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => tc.IsRequest && tc.Format == ODataFormat.Atom ? streamPropertyInRequest : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { collectionProperty, streamProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => tc.IsRequest && tc.Format == ODataFormat.Atom ? streamPropertyInRequest : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { streamProperty, streamProperty } } },
                    ExpectedException = (duplicatesAllowed, tc) => tc.IsRequest ? streamPropertyInRequest : error,
                },
                #endregion Duplicate primitive properties

                #region Deferred navigation links
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        defaultEntry,
                            singletonLink,
                            null,
                            singletonLink,
                            null,
                    },
                    // Duplicate singleton entity reference links are allowed in requests, they're used for binding
                    ExpectedException = (duplicatesAllowed, tc) => (duplicatesAllowed || tc.IsRequest) ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        defaultEntry,
                            singletonLink,
                            null,
                            collectionLink,
                            null,
                    },
                    // Singleton and collection entity reference links are allowed in requests, possible binding case.
                    ExpectedException = (duplicatesAllowed, tc) => (duplicatesAllowed || tc.IsRequest) ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        defaultEntry,
                            collectionLink,
                            null,
                            collectionLink,
                            null,
                    },
                    // Duplicate collection entity reference links are allowed in requests, possible binding case.
                    ExpectedException = (duplicatesAllowed, tc) => (duplicatesAllowed || tc.IsRequest) ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { primitiveProperty } },
                            singletonLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { primitiveProperty } },
                            collectionLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { complexProperty } },
                            singletonLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { complexProperty } },
                            collectionLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { collectionProperty } },
                            singletonLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { collectionProperty } },
                            collectionLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { streamProperty } },
                            singletonLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { streamProperty } },
                            collectionLink,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                #endregion Deferred navigation links

                #region Expanded navigation links
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        defaultEntry,
                            singletonLink,
                                defaultEntry,
                                null,
                            null,
                            singletonLink,
                                defaultEntry,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : (tc.IsRequest ? duplicateExpandedLinkError : error),
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        defaultEntry,
                            singletonLink,
                                defaultEntry,
                                null,
                            null,
                            collectionLink,
                                defaultFeed,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : (tc.IsRequest ? duplicateExpandedLinkError : error),
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        defaultEntry,
                            collectionLink,
                                defaultFeed,
                                null,
                            null,
                            collectionLink,
                                defaultFeed,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : (tc.IsRequest ? null : error),
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { primitiveProperty } },
                            singletonLink,
                                defaultEntry,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { primitiveProperty } },
                            collectionLink,
                                defaultFeed,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { complexProperty } },
                            singletonLink,
                                defaultEntry,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { complexProperty } },
                            collectionLink,
                                defaultFeed,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { collectionProperty } },
                            singletonLink,
                                defaultEntry,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { collectionProperty } },
                            collectionLink,
                                defaultFeed,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { streamProperty } },
                            singletonLink,
                                defaultEntry,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] 
                    { 
                        new ODataEntry { Properties = new [] { streamProperty } },
                            collectionLink,
                                defaultFeed,
                                null,
                            null,
                    },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                #endregion Expanded navigation links

                #region Duplicate properties on complex values
                // We should also put these complex values at the top-level and inside of collections.
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { new ODataProperty { Name = "ComplexProp", Value = new ODataComplexValue { Properties = new [] { primitiveProperty, primitiveProperty } } } } } },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { new ODataProperty { Name = "ComplexProp", Value = new ODataComplexValue { Properties = new [] { complexProperty, complexProperty } } } } } },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { new ODataProperty { Name = "ComplexProp", Value = new ODataComplexValue { Properties = new [] { collectionProperty, collectionProperty } } } } } },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { new ODataProperty { Name = "ComplexProp", Value = new ODataComplexValue { Properties = new [] { primitiveProperty, complexProperty } } } } } },
                    ExpectedException = (duplicatesAllowed, tc) => duplicatesAllowed ? null : error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { new ODataProperty { Name = "ComplexProp", Value = new ODataComplexValue { Properties = new [] { primitiveProperty, collectionProperty } } } } } },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                new DuplicatePropertyNamesTestCase 
                {
                    PayloadItems = new ODataItem[] { new ODataEntry { Properties = new [] { new ODataProperty { Name = "ComplexProp", Value = new ODataComplexValue { Properties = new [] { complexProperty, collectionProperty } } } } } },
                    ExpectedException = (duplicatesAllowed, tc) => error,
                },
                #endregion Duplicate properties on complex values
            };

            IEnumerable<PayloadWriterTestDescriptor<ODataItem>> testDescriptors = testCases.Select(testCase =>
                new PayloadWriterTestDescriptor<ODataItem>(
                    this.Settings,
                    testCase.PayloadItems,
                    tc =>
                    {
                        bool allowDuplicateNames = tc.MessageWriterSettings.GetAllowDuplicatePropertyNames();
                        ExpectedException expectedError = testCase.ExpectedException(allowDuplicateNames, tc);
                        if (expectedError == null)
                        {
                            if (tc.Format == ODataFormat.Atom)
                            {
                                return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                                {
                                    // we skip validation if we don't expect an error message
                                    Xml = null
                                };
                            }
                            else
                            {
                                throw new NotSupportedException("Only ATOM and JSON formats are supported.");
                            }
                        }
                        else
                        {
                            return new WriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                            {
                                ExpectedException2 = expectedError,
                            };
                        }
                    }
                ));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.PayloadCases(WriterPayloads.EntryPayloads),
                new bool[] { true, false },
                this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent,
                (testDescriptor, allowDuplicates, testConfiguration) =>
                {
                    if (allowDuplicates)
                    {
                        testConfiguration = testConfiguration.Clone();
                        testConfiguration.MessageWriterSettings.EnableODataServerBehavior(false);
                    }

                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor.DeferredLinksToEntityReferenceLinksInRequest(testConfiguration), testConfiguration, this.Assert, this.Logger);
                });
        }