Example #1
0
        public void SetNextLinkAfterFeedStartTests()
        {
            var testPayloads = this.CreateFeedNextLinkDescriptors().ToArray();

            foreach (var descriptor in testPayloads)
            {
                // Replace each feed with one without the next link value, and an action to write it back
                // after writing Feed Start.
                var nextLink = new Uri(descriptor.PayloadItems.OfType <ODataFeed>().Single().NextPageLink.OriginalString);
                var newFeed  = ObjectModelUtils.CreateDefaultFeed().WithAnnotation(new WriteFeedCallbacksAnnotation {
                    AfterWriteStartCallback = (f) => f.NextPageLink = nextLink
                });
                descriptor.PayloadItems = new ReadOnlyCollection <ODataItem>(new List <ODataItem> {
                    newFeed
                });
            }

            this.CombinatorialEngineProvider.RunCombinations(
                testPayloads.PayloadCases(WriterPayloads.FeedPayloads),
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
            {
                if (testDescriptor.IsGeneratedPayload && (testConfiguration.Format == ODataFormat.Json || testDescriptor.Model != null))
                {
                    return;
                }

                TestWriterUtils.WriteAndVerifyODataEdmPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
            });
        }
        [Ignore] // Remove Atom
        // [TestMethod, Variation(Description = "Verifies that sync and async calls cannot be mixed on a single writer.")]
        public void SyncAsyncMismatchTest()
        {
            // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                TestCalls,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => false),
                new bool[] { false, true },
                new bool[] { false, true },
                (testCall, testConfiguration, writingFeed, testSynchronousCall) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                using (TestStream memoryStream = new TestStream())
                {
                    // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will
                    // fail here because the writer is not left in a valid state.
                    var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert);

                    // Note that the CreateODataWriter call will call either sync or async variant based on the testConfiguration
                    // which is independent axis to the testSynchronousCall and thus we will end up with async creation but sync write
                    // and vice versa.
                    ODataWriter odataWriter       = messageWriter.CreateODataWriter(writingFeed);
                    ODataWriterTestWrapper writer = (ODataWriterTestWrapper)odataWriter;
                    if (testCall.AssumesFeedWriter)
                    {
                        if (!writingFeed)
                        {
                            // Skip this case since we need feed writer for this case.
                            return;
                        }
                    }
                    else
                    {
                        if (writingFeed)
                        {
                            writer.WriteStart(ObjectModelUtils.CreateDefaultFeed());
                        }
                    }

                    this.Assert.ExpectedException <ODataException>(
                        () =>
                    {
                        if (testSynchronousCall)
                        {
                            testCall.Sync(writer);
                        }
                        else
                        {
                            testCall.Async(writer);
                        }
                    },
                        testConfiguration.Synchronous == testSynchronousCall ?
                        null :
                        testSynchronousCall ?
                        "A synchronous operation was called on an asynchronous writer. Calls on a writer instance must be either all synchronous or all asynchronous." :
                        "An asynchronous operation was called on a synchronous writer. Calls on a writer instance must be either all synchronous or all asynchronous.");
                }
            });
        }
Example #3
0
        /// <summary>
        /// Returns all interesting payloads for a navigation link itself. That is the ODataNestedResourceInfo without any subsequent events.
        /// </summary>
        /// <param name="testDescriptor">Test descriptor which will end up writing a single navigation link.</param>
        /// <returns>Enumeration of test descriptors which will include the original navigation link in some interesting scenarios.</returns>
        public static IEnumerable <PayloadWriterTestDescriptor <ODataItem> > NavigationLinkOnlyPayloads(PayloadWriterTestDescriptor <ODataItem> testDescriptor)
        {
            ODataNestedResourceInfo navigationLink = testDescriptor.PayloadItems[0] as ODataNestedResourceInfo;

            Debug.Assert(navigationLink != null, "Navigation link payload expected.");
            Debug.Assert(navigationLink.IsCollection.HasValue, "ODataNestedResourceInfo.IsCollection required.");

            var payloadCases = new WriterPayloadCase <ODataItem>[] {
                new WriterPayloadCase <ODataItem>()  // Just the link as non-expanded
                {
                    GetPayloadItems = () => new ODataItem[] { navigationLink }
                },
                new WriterPayloadCase <ODataItem>()  // The link with expanded entry
                {
                    GetPayloadItems = () => {
                        if (navigationLink.IsCollection.Value)
                        {
                            return(new ODataItem[] { navigationLink, ObjectModelUtils.CreateDefaultFeed() });
                        }
                        else
                        {
                            return(new ODataItem[] { navigationLink, ObjectModelUtils.CreateDefaultEntry() });
                        }
                    }
                }
            };

            // Apply the cases here and then wrap the link in some entry/feed cases
            return(ApplyPayloadCases <ODataItem>(testDescriptor, payloadCases).PayloadCases(NavigationLinkPayloads));
        }
Example #4
0
        private void InvokeWriterAction(ODataMessageWriterTestWrapper messageWriter, ODataWriter writer, WriterAction writerAction)
        {
            switch (writerAction)
            {
            case WriterAction.StartResource:
                writer.WriteStart(ObjectModelUtils.CreateDefaultEntry());
                break;

            case WriterAction.StartFeed:
                writer.WriteStart(ObjectModelUtils.CreateDefaultFeed());
                break;

            case WriterAction.StartLink:
                writer.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink());
                break;

            case WriterAction.End:
                writer.WriteEnd();
                break;

            case WriterAction.Error:
                messageWriter.WriteError(new ODataError(), false);
                break;
            }
        }
Example #5
0
        private PayloadWriterTestDescriptor <ODataItem> CreateDefaultFeedMetadataDescriptor(bool withModel)
        {
            EdmModel model = null;

            if (withModel)
            {
                model = new EdmModel();
            }

            ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed("CustomersSet", "CustomerType", model);

            EdmEntitySet  customerSet  = null;
            EdmEntityType customerType = null;

            if (model != null)
            {
                var container = model.FindEntityContainer("DefaultContainer");
                customerSet  = container.FindEntitySet("CustomersSet") as EdmEntitySet;
                customerType = model.FindType("TestModel.CustomerType") as EdmEntityType;
            }

            return(new PayloadWriterTestDescriptor <ODataItem>(
                       this.Settings,
                       feed,
                       (testConfiguration) =>
            {
                if (testConfiguration.Format == ODataFormat.Json)
                {
                    return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Json = string.Join("$(NL)",
                                           "{",
                                           "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#CustomersSet\",\"value\":[",
                                           string.Empty,
                                           "]",
                                           "}"),
                        FragmentExtractor = (result) => result.RemoveAllAnnotations(true)
                    };
                }
                else
                {
                    string formatName = testConfiguration.Format == null ? "null" : testConfiguration.Format.GetType().Name;
                    throw new NotSupportedException("Invalid format detected: " + formatName);
                }
            })
            {
                // JSON Light does not support writing without model
                SkipTestConfiguration = tc => model == null && tc.Format == ODataFormat.Json,
                Model = model,
                PayloadEdmElementContainer = customerSet,
                PayloadEdmElementType = customerType,
            });
        }
        public void FeedIdTest()
        {
            var testCases = new[]
            {
                new
                {
                    Id  = (Uri)null,
                    Xml = (string)null,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomWriter_FeedsMustHaveNonEmptyId"),
                },
                new
                {
                    Id  = new Uri("urn:id"),
                    Xml = @"<id xmlns=""" + TestAtomConstants.AtomNamespace + @""">urn:id</id>",
                    ExpectedException = (ExpectedException)null,
                },
            };

            var testDescriptors = testCases.Select(tc =>
            {
                ODataFeed feed = ObjectModelUtils.CreateDefaultFeed();
                feed.Id        = tc.Id;

                return(new PayloadWriterTestDescriptor <ODataItem>(
                           this.Settings,
                           feed,
                           testConfiguration =>
                {
                    this.Assert.AreEqual(ODataFormat.Atom, testConfiguration.Format, "Only ATOM feeds support ID.");
                    return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = tc.Xml,
                        FragmentExtractor = (element) => element.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomIdElementName).Single(),
                        ExpectedException2 = tc.ExpectedException,
                    };
                }));
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.PayloadCases(WriterPayloads.FeedPayloads),
                this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent.Where(tc => !tc.IsRequest),
                (testPayload, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                TestWriterUtils.WriteAndVerifyODataPayload(testPayload, testConfiguration, this.Assert, this.Logger);
            });
        }
Example #7
0
 private Action <WriterTestConfiguration> WriteFeed(Func <XElement, XElement> fragmentExtractor, Func <ODataVersion, string> expectedXml)
 {
     return((testConfiguration) => TestWriterUtils.WriteAndVerifyODataPayload(
                new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    ObjectModelUtils.CreateDefaultFeed(),
                    expectedXml(testConfiguration.Version),
                    null,
                    fragmentExtractor,
                    null,
                    /*disableXmlNamespaceNormalization*/ true),
                testConfiguration,
                this.Assert,
                this.Logger));
 }
Example #8
0
        public void FeedInvalidContentTests()
        {
            ODataFeed defaultFeed = ObjectModelUtils.CreateDefaultFeed();

            ODataItem[] invalidPayload1 = new ODataItem[] { defaultFeed, defaultFeed };

            var testCases = new[]
            {
                new
                {
                    Items         = invalidPayload1,
                    ExpectedError = "Cannot transition from state 'Feed' to state 'Feed'. The only valid action in state 'Feed' is to write an entry."
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                ODataFormatUtils.ODataFormats.Where(f => f != null),

// Async  test configuration is not supported for Phone and Silverlight
#if !SILVERLIGHT && !WINDOWS_PHONE
                new bool[] { false, true },
#else
                new bool[] { true },
#endif
                (testCase, format, synchronous) =>
            {
                using (var memoryStream = new TestStream())
                {
                    ODataMessageWriterSettings settings = new ODataMessageWriterSettings();
                    settings.Version = ODataVersion.V4;
                    settings.SetServiceDocumentUri(ServiceDocumentUri);

                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, new WriterTestConfiguration(format, settings, false, synchronous), this.Assert))
                    {
                        ODataWriter writer = messageWriter.CreateODataWriter(isFeed: true);
                        TestExceptionUtils.ExpectedException <ODataException>(
                            this.Assert,
                            () => TestWriterUtils.WritePayload(messageWriter, writer, true, testCase.Items),
                            testCase.ExpectedError);
                    }
                }
            });
        }
Example #9
0
        public void WriteAfterExceptionTest()
        {
            // create a default entry and then set both read and edit links to null to provoke an exception during writing
            ODataResource faultyEntry = ObjectModelUtils.CreateDefaultEntry();

            this.Assert.IsNull(faultyEntry.EditLink, "entry.EditLink == null");

            ODataResource    defaultEntry = ObjectModelUtils.CreateDefaultEntry();
            ODataResourceSet defaultFeed  = ObjectModelUtils.CreateDefaultFeed();

            this.CombinatorialEngineProvider.RunCombinations(
                new ODataItem[] { faultyEntry },
                new ODataItem[] { defaultFeed, defaultEntry },
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations,
                (faultyPayload, contentPayload, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                using (var memoryStream = new TestStream())
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert))
                    {
                        ODataWriter writer = messageWriter.CreateODataWriter(isFeed: false);
                        ODataWriterCoreInspector inspector = new ODataWriterCoreInspector(writer);

                        // write the invalid entry and expect an exception
                        this.Assert.ExpectedException(
                            () => TestWriterUtils.WritePayload(messageWriter, writer, false, faultyEntry),
                            ODataExpectedExceptions.ODataException("WriterValidationUtils_EntriesMustHaveNonEmptyId"),
                            this.ExceptionVerifier);
                        this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'error' state.");

                        // now write some non-error content which is invalid to do
                        Exception ex = TestExceptionUtils.RunCatching(() => TestWriterUtils.WritePayload(messageWriter, writer, false, contentPayload));
                        ex           = TestExceptionUtils.UnwrapAggregateException(ex, this.Assert);
                        this.Assert.IsNotNull(ex, "Expected exception but none was thrown");
                        this.Assert.IsTrue(ex is ODataException, "Expected an ODataException instance but got a " + ex.GetType().FullName + ".");
                        this.Assert.IsTrue(ex.Message.Contains("Cannot transition from state 'Error' to state "), "Did not find expected start of error message.");
                        this.Assert.IsTrue(ex.Message.Contains("Nothing can be written once the writer entered the error state."), "Did not find expected end of error message in '" + ex.Message + "'.");
                        this.Assert.IsTrue(inspector.IsInErrorState, "Writer is not in expected 'error' state.");
                        writer.Flush();
                    }
            });
        }
Example #10
0
        public void WriteAfterDisposeTest()
        {
            this.CombinatorialEngineProvider.RunCombinations(
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations,
                (testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                using (var stream = new TestStream())
                {
                    ODataWriter writer;
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert))
                    {
                        writer = messageWriter.CreateODataWriter(isFeed: true);
                        // Message writer is disposed outside of this scope.
                    }

                    this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultFeed()));
                    this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultEntry()));
                    this.VerifyWriterAlreadyDisposed(() => writer.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()));
                }
            });
        }
Example #11
0
        private PayloadWriterTestDescriptor <ODataItem>[] CreateFeedQueryCountDescriptors()
        {
            Func <long?, ODataFeed> feedCreator = (c) =>
            {
                ODataFeed feed = ObjectModelUtils.CreateDefaultFeed();
                feed.Count = c;
                return(feed);
            };

            long?[] counts = new long?[] { 0, 1, 2, 1000, -1 - 10, long.MaxValue, long.MinValue, null };

            EdmModel   model = new EdmModel();
            ODataEntry entry = ObjectModelUtils.CreateDefaultEntryWithAtomMetadata("DefaultEntitySet", "DefaultEntityType", model);

            var container  = model.FindEntityContainer("DefaultContainer");
            var entitySet  = container.FindEntitySet("DefaultEntitySet") as EdmEntitySet;
            var entityType = model.FindType("TestModel.DefaultEntityType") as EdmEntityType;

            var descriptors = counts.Select(count => new PayloadWriterTestDescriptor <ODataItem>(this.Settings, feedCreator(count),
                                                                                                 (testConfiguration) =>
            {
                if (testConfiguration.IsRequest && count.HasValue)
                {
                    return(new WriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException2 = ODataExpectedExceptions.ODataException("ODataWriterCore_QueryCountInRequest")
                    });
                }

                if (testConfiguration.Format == ODataFormat.Atom)
                {
                    if (count.HasValue)
                    {
                        return(new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Xml = @"<m:count xmlns:m =""" + TestAtomConstants.ODataMetadataNamespace + @""">" + count + "</m:count>",
                            FragmentExtractor = (result) => result.Elements(XName.Get("count", TestAtomConstants.ODataMetadataNamespace)).Single()
                        });
                    }
                    else
                    {
                        return(new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Xml = @"<nocount xmlns=""" + TestAtomConstants.ODataMetadataNamespace + @"""/>",
                            FragmentExtractor = (result) =>
                            {
                                var countElement = result.Elements(XName.Get("count", TestAtomConstants.ODataMetadataNamespace)).SingleOrDefault();
                                if (countElement == null)
                                {
                                    countElement = new XElement(TestAtomConstants.ODataMetadataXNamespace + "nocount");
                                }
                                return countElement;
                            }
                        });
                    }
                }
                else if (testConfiguration.Format == ODataFormat.Json)
                {
                    if (count.HasValue)
                    {
                        return(new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Json = "$(Indent)$(Indent)\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataCountAnnotationName + "\":\"" + count + "\"",
                            FragmentExtractor = (result) => result.Object().Property(JsonLightConstants.ODataCountAnnotationName)
                        });
                    }
                    else
                    {
                        return(new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                        {
                            Json = string.Join("$(NL)",
                                               "[",
                                               string.Empty,
                                               "]"),
                            FragmentExtractor = (result) =>
                            {
                                return JsonLightWriterUtils.GetTopLevelFeedItemsArray(testConfiguration, result).RemoveAllAnnotations(true);
                            }
                        });
                    }
                }
                else
                {
                    string formatName = testConfiguration.Format == null ? "null" : testConfiguration.Format.GetType().Name;
                    throw new NotSupportedException("Invalid format detected: " + formatName);
                }
            })
            {
                Model = model,
                PayloadEdmElementContainer = entitySet,
                PayloadEdmElementType      = entityType,
            });

            return(descriptors.ToArray());
        }
Example #12
0
        private void WriterStatesTestImplementation(bool feedWriter)
        {
            var testCases = new WriterStatesTestDescriptor[]
            {
                // Start
                new WriterStatesTestDescriptor {
                    Setup           = null,
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, feedWriter ? ODataExpectedExceptions.ODataException("ODataWriterCore_CannotWriteTopLevelResourceWithResourceSetWriter") : (ExpectedException)null },
                        { WriterAction.StartFeed, feedWriter ? (ExpectedException)null : ODataExpectedExceptions.ODataException("ODataWriterCore_CannotWriteTopLevelResourceSetWithResourceWriter") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromStart", "Start", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Start") },
                        { WriterAction.Error, null },
                    }
                },

                // Entry
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        if (feedWriter)
                        {
                            w.WriteStart(ObjectModelUtils.CreateDefaultFeed());
                        }
                        w.WriteStart(ObjectModelUtils.CreateDefaultEntry());
                    },
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResource", "Entry", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResource", "Entry", "Feed") },
                        { WriterAction.StartLink, null },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    }
                },

                // Feed
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        if (feedWriter)
                        {
                            w.WriteStart(ObjectModelUtils.CreateDefaultFeed());
                        }
                        else
                        {
                            w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()); w.WriteStart(ObjectModelUtils.CreateDefaultFeed());
                        }
                    },
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, null },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResourceSet", "Feed", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromResourceSet", "Feed", "NavigationLink") },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    }
                },

                // Link - single
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        if (feedWriter)
                        {
                            w.WriteStart(ObjectModelUtils.CreateDefaultFeed());
                        }
                        w.WriteStart(ObjectModelUtils.CreateDefaultEntry());
                        w.WriteStart(new ODataNestedResourceInfo {
                            Name = ObjectModelUtils.DefaultLinkName, Url = ObjectModelUtils.DefaultLinkUrl, IsCollection = false
                        });
                    },
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, null },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithResourceSetContent", "http://odata.org/link") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidStateTransition", "NavigationLink", "NavigationLink") },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest
                },

                // Link - collection
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        if (feedWriter)
                        {
                            w.WriteStart(ObjectModelUtils.CreateDefaultFeed());
                        }
                        w.WriteStart(ObjectModelUtils.CreateDefaultEntry());
                        w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink());
                    },
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithResourceContent", "http://odata.org/link") },
                        { WriterAction.StartFeed, null },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidStateTransition", "NavigationLink", "NavigationLink") },
                        { WriterAction.End, null },
                        { WriterAction.Error, null },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest
                },

                // Expanded link - there's no way to get to the expanded link state alone since the writer will always
                //   immediately transition to either entry or feed state instead.

                // Completed
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        if (feedWriter)
                        {
                            w.WriteStart(ObjectModelUtils.CreateDefaultFeed()); w.WriteEnd();
                        }
                        else
                        {
                            w.WriteStart(ObjectModelUtils.CreateDefaultEntry()); w.WriteEnd();
                        }
                    },
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Completed") },
                        { WriterAction.Error, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromCompleted", "Completed", "Error") },
                    }
                },

                // ODataExceptionThrown
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        TestExceptionUtils.RunCatching(() => w.WriteStart(ObjectModelUtils.CreateDefaultCollectionLink()));
                    },
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Error") },
                        { WriterAction.Error, null },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest,
                },

                // Error
                new WriterStatesTestDescriptor {
                    Setup = (mw, w, s) => {
                        mw.WriteError(new ODataError(), false);
                    },
                    ExpectedResults = new Dictionary <WriterAction, ExpectedException> {
                        { WriterAction.StartResource, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Entry") },
                        { WriterAction.StartFeed, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "Feed") },
                        { WriterAction.StartLink, ODataExpectedExceptions.ODataException("ODataWriterCore_InvalidTransitionFromError", "Error", "NavigationLink") },
                        { WriterAction.End, ODataExpectedExceptions.ODataException("ODataWriterCore_WriteEndCalledInInvalidState", "Error") },
                        { WriterAction.Error, ODataExpectedExceptions.ODataException("ODataMessageWriter_WriteErrorAlreadyCalled") },
                    },
                    SkipForTestConfiguration = tc => tc.IsRequest,
                },
            };

            ExpectedException errorNotAllowedException = ODataExpectedExceptions.ODataException("ODataMessageWriter_ErrorPayloadInRequest");

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                EnumExtensionMethods.GetValues <WriterAction>().Cast <WriterAction>(),
                this.WriterTestConfigurationProvider.AtomFormatConfigurations,
                (testCase, writerAction, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                if (testCase.SkipForTestConfiguration != null && testCase.SkipForTestConfiguration(testConfiguration))
                {
                    return;
                }

                ExpectedException expectedExceptionOnError;
                if (testCase.ExpectedResults.TryGetValue(WriterAction.Error, out expectedExceptionOnError))
                {
                    if (testConfiguration.IsRequest)
                    {
                        testCase = new WriterStatesTestDescriptor(testCase);
                        testCase.ExpectedResults[WriterAction.Error] = errorNotAllowedException;
                    }
                }

                using (TestStream stream = new TestStream())
                {
                    // We purposely don't use the using pattern around the messageWriter here. Disposing the message writer will
                    // fail here because the writer is not left in a valid state.
                    var messageWriter  = TestWriterUtils.CreateMessageWriter(stream, testConfiguration, this.Assert);
                    ODataWriter writer = messageWriter.CreateODataWriter(feedWriter);

                    TestExceptionUtils.ExpectedException(
                        this.Assert,
                        () =>
                    {
                        if (testCase.Setup != null)
                        {
                            testCase.Setup(messageWriter, writer, stream);
                        }
                        this.InvokeWriterAction(messageWriter, writer, writerAction);
                    },
                        testCase.ExpectedResults[writerAction],
                        this.ExceptionVerifier);
                }
            });
        }
Example #13
0
        public void ExpandedLinkWithMultiplicityTests()
        {
            ODataNavigationLink expandedEntryLink = ObjectModelUtils.CreateDefaultCollectionLink();

            expandedEntryLink.IsCollection = false;

            ODataNavigationLink expandedFeedLink = ObjectModelUtils.CreateDefaultCollectionLink();

            expandedFeedLink.IsCollection = true;

            ODataEntry defaultEntry = ObjectModelUtils.CreateDefaultEntry();
            ODataFeed  defaultFeed  = ObjectModelUtils.CreateDefaultFeed();
            ODataEntityReferenceLink defaultEntityReferenceLink = ObjectModelUtils.CreateDefaultEntityReferenceLink();

            ODataEntry officeEntry           = ObjectModelUtils.CreateDefaultEntry("TestModel.OfficeType");
            ODataEntry officeWithNumberEntry = ObjectModelUtils.CreateDefaultEntry("TestModel.OfficeWithNumberType");
            ODataEntry cityEntry             = ObjectModelUtils.CreateDefaultEntry("TestModel.CityType");

            // CityHall is a nav prop with multiplicity '*' of type 'TestModel.OfficeType'
            ODataNavigationLink cityHallLinkIsCollectionNull  = ObjectModelUtils.CreateDefaultCollectionLink("CityHall", /*isCollection*/ null);
            ODataNavigationLink cityHallLinkIsCollectionTrue  = ObjectModelUtils.CreateDefaultCollectionLink("CityHall", /*isCollection*/ true);
            ODataNavigationLink cityHallLinkIsCollectionFalse = ObjectModelUtils.CreateDefaultCollectionLink("CityHall", /*isCollection*/ false);

            // PoliceStation is a nav prop with multiplicity '1' of type 'TestModel.OfficeType'
            ODataNavigationLink policeStationLinkIsCollectionNull  = ObjectModelUtils.CreateDefaultCollectionLink("PoliceStation", /*isCollection*/ null);
            ODataNavigationLink policeStationLinkIsCollectionTrue  = ObjectModelUtils.CreateDefaultCollectionLink("PoliceStation", /*isCollection*/ true);
            ODataNavigationLink policeStationLinkIsCollectionFalse = ObjectModelUtils.CreateDefaultCollectionLink("PoliceStation", /*isCollection*/ false);

            ExpectedException expandedEntryLinkWithFeedContentError  = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedContent", "http://odata.org/link");
            ExpectedException expandedFeedLinkWithEntryContentError  = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryContent", "http://odata.org/link");
            ExpectedException expandedFeedLinkWithEntryMetadataError = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryMetadata", "http://odata.org/link");

            ExpectedException expandedEntryLinkWithFeedMetadataErrorResponse        = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedMetadata", "http://odata.org/link");
            ExpectedException expandedFeedLinkPayloadWithEntryMetadataErrorRequest  = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkWithFeedPayloadAndEntryMetadata", "http://odata.org/link");
            ExpectedException expandedFeedLinkPayloadWithEntryMetadataErrorResponse = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionTrueWithEntryMetadata", "http://odata.org/link");
            ExpectedException expandedEntryLinkPayloadWithFeedMetadataErrorResponse = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkIsCollectionFalseWithFeedMetadata", "http://odata.org/link");
            ExpectedException expandedEntryLinkPayloadWithFeedMetadataError         = ODataExpectedExceptions.ODataException("WriterValidationUtils_ExpandedLinkWithEntryPayloadAndFeedMetadata", "http://odata.org/link");
            ExpectedException multipleItemsInExpandedLinkError   = ODataExpectedExceptions.ODataException("ODataWriterCore_MultipleItemsInNavigationLinkContent", "http://odata.org/link");
            ExpectedException entityReferenceLinkInResponseError = ODataExpectedExceptions.ODataException("ODataWriterCore_EntityReferenceLinkInResponse");

            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            var testCases = new ExpandedLinkMultiplicityTestCase[]
            {
                #region IsCollection flag does not match payload
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link with IsCollection is 'false' and feed payload
                    Items         = new ODataItem[] { defaultEntry, expandedEntryLink, defaultFeed },
                    ExpectedError = tc => expandedEntryLinkWithFeedContentError,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link with IsCollection is 'true' and entry payload
                    Items         = new ODataItem[] { defaultEntry, expandedFeedLink, defaultEntry },
                    ExpectedError = tc => expandedFeedLinkWithEntryContentError,
                },
                #endregion IsCollection flag does not match payload
                #region IsCollection == null; check compatibility of entity types of navigation property and entity in expanded link
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link of singleton type without IsCollection value and an entry of a non-matching entity type;
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, cityEntry },
                    ExpectedError = tc => tc.Format == ODataFormat.Atom || !tc.IsRequest
                            ? ODataExpectedExceptions.ODataException("WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType", "TestModel.CityType", "TestModel.OfficeType")
                            : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation"),
                    Model = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link of singleton type without IsCollection value and an entry of a matching entity type; no error expected.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, officeEntry },
                    ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest ? null : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation"),
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link of singleton type without IsCollection and an entry of a derived entity type; no error expected.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, officeWithNumberEntry },
                    ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest ? null : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation"),
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link of collection type without IsCollection value and an entry of a non-matching entity type;
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, cityEntry },
                    ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest
                            ? ODataExpectedExceptions.ODataException("WriterValidationUtils_EntryTypeInExpandedLinkNotCompatibleWithNavigationPropertyType", "TestModel.CityType", "TestModel.OfficeType")
                            : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall"),
                    Model = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link of collection type without IsCollection value and an entry of a matching entity type; no error expected.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, officeEntry },
                    ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest
                            ? null
                            : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall"),
                    Model = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Expanded link of collection type without IsCollection and an entry of a derived entity type; no error expected.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, officeWithNumberEntry },
                    ExpectedError = tc => tc.Format == ODataFormat.Json && !tc.IsRequest
                            ? null
                            : ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall"),
                    Model = model,
                },
                #endregion IsCollection == null; check compatibility of entity types of navigation property and entity in expanded link
                #region Expanded link with entry content
                new ExpandedLinkMultiplicityTestCase
                {
                    // Entry content, IsCollection == false, singleton nav prop; should not fail.
                    Items = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, officeEntry },
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Entry content, IsCollection == true, singleton nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, officeEntry },
                    ExpectedError = tc => expandedFeedLinkWithEntryContentError,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Entry content, IsCollection == false, collection nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, officeEntry },
                    ExpectedError = tc => tc.IsRequest ? expandedEntryLinkPayloadWithFeedMetadataError : expandedEntryLinkPayloadWithFeedMetadataErrorResponse,
                    Model         = model
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Entry content, IsCollection == true, collection nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, officeEntry },
                    ExpectedError = tc => expandedFeedLinkWithEntryContentError,
                    Model         = model
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Entry content, IsCollection == null, singleton nav prop; should not fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, officeEntry },
                    ExpectedError = tc => tc.IsRequest || tc.Format == ODataFormat.Atom
                            ? ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "PoliceStation")
                            : null,
                    Model = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Entry content, IsCollection == null, collection nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, officeEntry },
                    ExpectedError = tc => expandedEntryLinkPayloadWithFeedMetadataError,
                    Model         = model,
                },
                #endregion Expanded collection link with entry content
                #region Expanded link with feed content
                new ExpandedLinkMultiplicityTestCase
                {
                    // Feed content, IsCollection == false, singleton nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, defaultFeed, officeEntry },
                    ExpectedError = tc => expandedEntryLinkWithFeedContentError,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Feed content, IsCollection == true, singleton nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, defaultFeed, officeEntry },
                    ExpectedError = tc => tc.IsRequest ? expandedFeedLinkPayloadWithEntryMetadataErrorRequest : expandedFeedLinkPayloadWithEntryMetadataErrorResponse,
                    Model         = model
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Feed content, IsCollection == false, collection nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, defaultFeed, officeEntry },
                    ExpectedError = tc => tc.IsRequest ? expandedEntryLinkWithFeedContentError : expandedEntryLinkWithFeedMetadataErrorResponse,
                    Model         = model
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Feed content, IsCollection == true, collection nav prop; should not fail.
                    Items = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, defaultFeed, officeEntry },
                    Model = model
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Feed content, IsCollection == null, singleton nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionNull, defaultFeed, officeEntry },
                    ExpectedError = tc => expandedFeedLinkPayloadWithEntryMetadataErrorRequest,
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Feed content, IsCollection == null, collection nav prop; should not fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionNull, defaultFeed, officeEntry },
                    ExpectedError = tc => tc.IsRequest || tc.Format == ODataFormat.Atom
                            ? ODataExpectedExceptions.ODataException("WriterValidationUtils_NavigationLinkMustSpecifyIsCollection", "CityHall")
                            : null,
                    Model = model,
                },
                #endregion Expanded collection link with entry content
                #region Expanded link with entity reference link content
                new ExpandedLinkMultiplicityTestCase
                {
                    // Single ERL (entity reference link) content, IsCollection == false, singleton nav prop; should not fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, defaultEntityReferenceLink },
                    ExpectedError = tc => tc.IsRequest ? null : entityReferenceLinkInResponseError
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Multiple ERL (entity reference link) content, IsCollection == false, singleton nav prop; should not fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionFalse, defaultEntityReferenceLink, defaultEntityReferenceLink },
                    ExpectedError = tc => tc.IsRequest ? multipleItemsInExpandedLinkError : entityReferenceLinkInResponseError,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Single ERL content, IsCollection == true, singleton nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, defaultEntityReferenceLink },
                    ExpectedError = tc => expandedFeedLinkWithEntryMetadataError,
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Multiple ERL content, IsCollection == true, singleton nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, policeStationLinkIsCollectionTrue, defaultEntityReferenceLink, defaultEntityReferenceLink },
                    ExpectedError = tc => expandedFeedLinkWithEntryMetadataError,
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Single ERL content, IsCollection == false, collection nav prop; should not fail (metadata mismatch explicitly allowed).
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, defaultEntityReferenceLink },
                    ExpectedError = tc => tc.IsRequest ? null : expandedEntryLinkWithFeedMetadataErrorResponse,
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Multiple ERL content, IsCollection == false, collection nav prop; should fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionFalse, defaultEntityReferenceLink, defaultEntityReferenceLink },
                    ExpectedError = tc => tc.IsRequest ? multipleItemsInExpandedLinkError : expandedEntryLinkWithFeedMetadataErrorResponse,
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Single ERL content, IsCollection == true, collection nav prop; should not fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, defaultEntityReferenceLink },
                    ExpectedError = tc => tc.IsRequest ? null : entityReferenceLinkInResponseError,
                    Model         = model,
                },
                new ExpandedLinkMultiplicityTestCase
                {
                    // Multiple ERL content, IsCollection == true, collection nav prop; should not fail.
                    Items         = new ODataItem[] { cityEntry, cityHallLinkIsCollectionTrue, defaultEntityReferenceLink, defaultEntityReferenceLink },
                    ExpectedError = tc => tc.IsRequest ? null : entityReferenceLinkInResponseError,
                    Model         = model,
                },

                //// NOTE: Not testing the cases where IsCollection == null here since ERL payloads are only allowed in
                ////       requests where IsCollection is required (in ATOM and JSON)
                #endregion Expanded link with entity reference link content
            };

            // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.Format == ODataFormat.Atom),
                (testCase, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                using (var memoryStream = new TestStream())
                    using (var messageWriter = TestWriterUtils.CreateMessageWriter(memoryStream, testConfiguration, this.Assert, null, testCase.Model))
                    {
                        ODataWriter writer = messageWriter.CreateODataWriter(isFeed: false);
                        TestExceptionUtils.ExpectedException(
                            this.Assert,
                            () => TestWriterUtils.WritePayload(messageWriter, writer, true, testCase.Items),
                            testCase.ExpectedError == null ? null : testCase.ExpectedError(testConfiguration),
                            this.ExceptionVerifier);
                    }
            });
        }
Example #14
0
        public void ExpandedLinkWithNullNavigationTests()
        {
            ODataNavigationLink expandedEntryLink = ObjectModelUtils.CreateDefaultCollectionLink();

            expandedEntryLink.IsCollection = false;

            ODataNavigationLink expandedEntryLink2 = ObjectModelUtils.CreateDefaultCollectionLink();

            expandedEntryLink2.IsCollection = false;
            expandedEntryLink2.Name         = expandedEntryLink2.Name + "2";

            ODataEntry defaultEntry = ObjectModelUtils.CreateDefaultEntry();
            ODataFeed  defaultFeed  = ObjectModelUtils.CreateDefaultFeed();
            ODataEntry nullEntry    = ObjectModelUtils.ODataNullEntry;

            PayloadWriterTestDescriptor.WriterTestExpectedResultCallback successCallback = (testConfiguration) =>
            {
                if (testConfiguration.Format == ODataFormat.Atom)
                {
                    return(new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName).ToString(),
                        FragmentExtractor = (result) =>
                        {
                            return result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                            .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                            .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName);
                        }
                    });
                }
                else
                {
                    return(new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Json = "null", //new JsonPrimitiveValue(null).ToText(testConfiguration.MessageWriterSettings.Indent),
                        FragmentExtractor = (result) =>
                        {
                            return JsonUtils.UnwrapTopLevelValue(testConfiguration, result).Object().Properties.First(p => p.Name == ObjectModelUtils.DefaultLinkName).Value;
                        }
                    });
                }
            };

            Func <ExpectedException, PayloadWriterTestDescriptor.WriterTestExpectedResultCallback> errorCallback = (expectedException) =>
            {
                return((testConfiguration) =>
                {
                    return new WriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException2 = expectedException,
                    };
                });
            };

            var testCases = new PayloadWriterTestDescriptor <ODataItem>[]
            {
                // navigation to a null entry
                new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    new ODataItem[] { defaultEntry, expandedEntryLink, nullEntry },
                    successCallback),

                // navigation to a null entry twice
                new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    new ODataItem[] { defaultEntry, expandedEntryLink, nullEntry, null, null, expandedEntryLink2, nullEntry, null },
                    successCallback),

                // top level null entry.
                new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    new ODataItem[] { nullEntry },
                    errorCallback(new ExpectedException(typeof(ArgumentNullException)))),

                // navigation to a null entry twice in expanded link
                // this actually throws ArgumentNullException when WriteStart() for the second nullEntry is called since
                // the state has been changed from NavigationLink to ExpandedLink after the first one.
                // TODO: check if ArgumentNullException needs to change the WriterState.
                new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    new ODataItem[] { defaultEntry, expandedEntryLink, nullEntry, null, nullEntry },
                    errorCallback(new ExpectedException(typeof(ArgumentNullException)))),

                // Null entry inside a feed, same as above this throws ArgumentNullException but state is not put to error state.
                new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    new ODataItem[] { defaultFeed, nullEntry },
                    errorCallback(new ExpectedException(typeof(ArgumentNullException)))),
            };

            // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight
            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent.Where(tc => tc.Format == ODataFormat.Atom),
                (testCase, testConfig) =>
            {
                testConfig = testConfig.Clone();
                testConfig.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                TestWriterUtils.WriteAndVerifyODataPayload(testCase, testConfig, this.Assert, this.Logger);
            });
        }
Example #15
0
        /// <summary>
        /// Returns all interesting payloads for an entry.
        /// </summary>
        /// <param name="testDescriptor">The test descriptor which will end up writing a single entry.</param>
        /// <returns>Enumeration of test descriptors which will include the original entry in some interesting scenarios.</returns>
        public static IEnumerable <PayloadWriterTestDescriptor <ODataItem> > EntryPayloads(PayloadWriterTestDescriptor <ODataItem> testDescriptor)
        {
            Debug.Assert(testDescriptor.PayloadItems[0] is ODataResource, "The payload does not specify an entry.");

            var payloadCases = new WriterPayloadCase <ODataItem>[]
            {
                // Feed with a single entry
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems       = () => new ODataItem[] { ObjectModelUtils.CreateDefaultFeed() }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName).First());
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },

                // Feed with three (identical) entries, picking the second one
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultFeed()
                    }
                    .Concat(testDescriptor.PayloadItems)
                    .Concat(LinqExtensions.FromSingle((ODataItem)null))
                    .Concat(testDescriptor.PayloadItems)
                    .Concat(LinqExtensions.FromSingle((ODataItem)null))
                    .Concat(testDescriptor.PayloadItems)
                    .Concat(LinqExtensions.FromSingle((ODataItem)null)),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        var entries = result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName);
                        Debug.Assert(entries.Count() == 3, "Expected three entries in the feed.");
                        return(entries.ElementAt(2));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },

                // Top-level entry with an expanded link containing a single entry
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultSingletonLink(),
                    }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },

                // Top-level entry with an expanded link containing a feed with a single entry
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultCollectionLink(),
                            ObjectModelUtils.CreateDefaultFeed()
                    }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },

                // Top-level entry with an expanded link containing a feed with three entries; picking the second one
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultCollectionLink(),
                            ObjectModelUtils.CreateDefaultFeed()
                    }
                    .Concat(testDescriptor.PayloadItems)
                    .Concat(LinqExtensions.FromSingle((ODataItem)null))
                    .Concat(testDescriptor.PayloadItems)
                    .Concat(LinqExtensions.FromSingle((ODataItem)null))
                    .Concat(testDescriptor.PayloadItems)
                    .Concat(LinqExtensions.FromSingle((ODataItem)null)),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName)
                               .Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName)
                               .ElementAt(2));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },

                // Top-level entry with an expanded link containing a feed with a single entry;
                // that entry has another expanded link containing a feed with the payload entry
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultCollectionLink(),
                            ObjectModelUtils.CreateDefaultFeed(),
                            ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultCollectionLink(),
                            ObjectModelUtils.CreateDefaultFeed(),
                    }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName)
                               .Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },
            };

            return(ApplyPayloadCases <ODataItem>(testDescriptor, payloadCases));
        }
Example #16
0
        public void FeedUserExceptionTests()
        {
            IEdmModel edmModel = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            ODataFeed           cityFeed  = ObjectModelUtils.CreateDefaultFeed();
            ODataEntry          cityEntry = ObjectModelUtils.CreateDefaultEntry("TestModel.CityType");
            ODataNavigationLink cityHallCollectionLink     = ObjectModelUtils.CreateDefaultCollectionLink("CityHall");
            ODataNavigationLink policeStationSingletonLink = ObjectModelUtils.CreateDefaultSingletonLink("PoliceStation");
            ODataFeed           officeFeed  = ObjectModelUtils.CreateDefaultFeed();
            ODataEntry          officeEntry = ObjectModelUtils.CreateDefaultEntry("TestModel.OfficeType");

            var container = edmModel.FindEntityContainer("DefaultContainer");
            var citySet   = container.FindEntitySet("Cities") as EdmEntitySet;
            var cityType  = edmModel.FindType("TestModel.CityType") as EdmEntityType;

            ODataItem[] writerPayload = new ODataItem[]
            {
                cityFeed,
                cityEntry,
                null,
                cityEntry,
                cityHallCollectionLink,
                officeFeed,
                officeEntry,
                null,
                null,
                null,
                null,
                cityEntry,
                null,
                cityEntry,
                policeStationSingletonLink,
                officeEntry,
                null,
                null,
                null,
            };

            IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testDescriptors = new PayloadWriterTestDescriptor <ODataItem>[]
            {
                new PayloadWriterTestDescriptor <ODataItem>(
                    this.Settings,
                    writerPayload,
                    tc => new WriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                {
                    ExpectedException = new Exception("User code triggered an exception."),
                }
                    )
                {
                    Model = edmModel,
                    PayloadEdmElementContainer = citySet,
                    PayloadEdmElementType      = cityType,
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.PayloadCases(WriterPayloads.FeedPayloads),
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent,
                (testDescriptor, testConfiguration) =>
            {
                if (testDescriptor.IsGeneratedPayload && (testConfiguration.Format == ODataFormat.Json || testDescriptor.Model != null))
                {
                    return;
                }

                foreach (int throwUserExceptionAt in Enumerable.Range(0, testDescriptor.PayloadItems.Count + 1))
                {
                    var configuredTestDescriptor = new PayloadWriterTestDescriptor <ODataItem>(this.Settings, testDescriptor.PayloadItems, testDescriptor.ExpectedResultCallback)
                    {
                        Model = testDescriptor.Model,
                        PayloadEdmElementContainer = testDescriptor.PayloadEdmElementContainer,
                        PayloadEdmElementType      = testDescriptor.PayloadEdmElementType,
                        ThrowUserExceptionAt       = throwUserExceptionAt,
                    };

                    TestWriterUtils.WriteAndVerifyODataEdmPayload(configuredTestDescriptor, testConfiguration, this.Assert, this.Logger);
                }
            });
        }
Example #17
0
        /// <summary>
        /// Returns all interesting payloads for a feed.
        /// </summary>
        /// <param name="testDescriptor">The test descriptor which will end up writing a single feed.</param>
        /// <returns>Enumeration of test descriptors which will include the original feed in some interesting scenarios.</returns>
        public static IEnumerable <PayloadWriterTestDescriptor <ODataItem> > FeedPayloads(PayloadWriterTestDescriptor <ODataItem> testDescriptor)
        {
            Debug.Assert(testDescriptor.PayloadItems[0] is ODataResourceSet, "The payload does not specify a feed.");

            var payloadCases = new WriterPayloadCase <ODataItem>[]
            {
                // Top-level feed with an entry that has an expanded link containing the feed
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultFeed(),
                ObjectModelUtils.CreateDefaultEntry(),
                ObjectModelUtils.CreateDefaultCollectionLink(),
                    }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName)
                               .Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },

                // Top-level entry with an expanded link containing the feed
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultCollectionLink(),
                    }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },

                // Top-level entry with an expanded link containing a feed with a single entry;
                // that entry has another expanded link containing the payload feed
                new WriterPayloadCase <ODataItem>()
                {
                    GetPayloadItems = () => new ODataItem[]
                    {
                        ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultCollectionLink(),
                            ObjectModelUtils.CreateDefaultFeed(),
                            ObjectModelUtils.CreateDefaultEntry(),
                            ObjectModelUtils.CreateDefaultCollectionLink(),
                    }.Concat(testDescriptor.PayloadItems),
                    AtomFragmentExtractor = (testConfiguration, result) =>
                    {
                        return(result.Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName)
                               .Elements(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomLinkElementName)
                               .First(e => e.Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName) != null)
                               .Element(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataInlineElementName)
                               .Element(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomFeedElementName));
                    },
                    //ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
                },
            };

            return(ApplyPayloadCases <ODataItem>(testDescriptor, payloadCases));
        }
        private void CreateTestDescriptorsAndRunTests(FeedMetadataTestCase[] testCases, Func <PayloadWriterTestDescriptor <ODataItem>, IEnumerable <PayloadWriterTestDescriptor <ODataItem> > > payloads)
        {
            // Convert test cases to test descriptions
            IEnumerable <Func <ODataFeed> > feedCreators = new Func <ODataFeed>[] { () => ObjectModelUtils.CreateDefaultFeed(), () => ObjectModelUtils.CreateDefaultFeedWithAtomMetadata(), };
            var testDescriptors = testCases.SelectMany(testCase => feedCreators.Select(feedCreator =>
            {
                ODataFeed feed            = feedCreator();
                AtomFeedMetadata metadata = feed.Atom();
                this.Assert.IsNotNull(metadata, "Expected default feed metadata on a default feed.");
                testCase.CustomizeMetadata(metadata);
                ODataItem[] payloadItems = testCase.CustomizePayload == null ? new ODataItem[] { feed } : testCase.CustomizePayload(feed);
                return(new PayloadWriterTestDescriptor <ODataItem>(this.Settings, payloadItems, testConfiguration =>
                {
                    if (testCase.SkipTestConfiguration != null && testCase.SkipTestConfiguration(testConfiguration))
                    {
                        return null;
                    }
                    return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = testCase.Xml, FragmentExtractor = testCase.Extractor, ExpectedException2 = testCase.ExpectedException
                    };
                }));
            }));

            this.CombinatorialEngineProvider.RunCombinations(testDescriptors.PayloadCases(WriterPayloads.TopLevelValuePayload), this.WriterTestConfigurationProvider.AtomFormatConfigurations, (testDescriptor, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger);
            });
        }
Example #19
0
        public void FeedAndEntryUpdatedTimeTests()
        {
            ODataFeed defaultFeedWithEmptyMetadata = ObjectModelUtils.CreateDefaultFeed();

            defaultFeedWithEmptyMetadata.SetAnnotation <AtomFeedMetadata>(new AtomFeedMetadata());
            ODataEntry defaultEntryWithEmptyMetadata = ObjectModelUtils.CreateDefaultEntry();

            defaultEntryWithEmptyMetadata.SetAnnotation <AtomEntryMetadata>(new AtomEntryMetadata());

            IEnumerable <PayloadWriterTestDescriptor <ODataItem> > testPayloads =
                new[]
            {
                new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultFeed()),
                new PayloadWriterTestDescriptor <ODataItem>(this.Settings, defaultFeedWithEmptyMetadata),
                new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultFeedWithAtomMetadata()),
            }.PayloadCases(WriterPayloads.FeedPayloads)
            .Concat((new[]
            {
                new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultEntry()),
                new PayloadWriterTestDescriptor <ODataItem>(this.Settings, defaultEntryWithEmptyMetadata),
                new PayloadWriterTestDescriptor <ODataItem>(this.Settings, ObjectModelUtils.CreateDefaultEntryWithAtomMetadata()),
            }.PayloadCases(WriterPayloads.EntryPayloads)));

            this.CombinatorialEngineProvider.RunCombinations(
                testPayloads,
                this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent.Where(tc => !tc.IsRequest),
                (testPayload, testConfiguration) =>
            {
                testConfiguration = testConfiguration.Clone();
                testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                string lastUpdatedTimeStr = null;
                using (var memoryStream = new MemoryStream())
                {
                    using (var testMemoryStream = TestWriterUtils.CreateTestStream(testConfiguration, memoryStream, ignoreDispose: true))
                    {
                        bool feedWriter         = testPayload.PayloadItems[0] is ODataFeed;
                        TestMessage testMessage = null;
                        Exception exception     = TestExceptionUtils.RunCatching(() =>
                        {
                            using (var messageWriter = TestWriterUtils.CreateMessageWriter(testMemoryStream, testConfiguration, this.Assert, out testMessage, null, testPayload.Model))
                            {
                                ODataWriter writer = messageWriter.CreateODataWriter(feedWriter);
                                TestWriterUtils.WritePayload(messageWriter, writer, true, testPayload.PayloadItems, testPayload.ThrowUserExceptionAt);
                            }
                        });
                        this.Assert.IsNull(exception, "Received exception but expected none.");
                    }

                    memoryStream.Position = 0;
                    XElement result       = XElement.Load(memoryStream);
                    foreach (XElement updated in result.Descendants(((XNamespace)TestAtomConstants.AtomNamespace) + "updated"))
                    {
                        if (updated.Value != ObjectModelUtils.DefaultFeedUpdated && updated.Value != ObjectModelUtils.DefaultEntryUpdated)
                        {
                            if (lastUpdatedTimeStr == null)
                            {
                                lastUpdatedTimeStr = updated.Value;
                            }
                            else
                            {
                                this.Assert.AreEqual(lastUpdatedTimeStr, updated.Value, "<atom:updated> should contain the same value.");
                            }
                        }
                    }
                }
            });
        }
Example #20
0
        public void BaseUriErrorTest()
        {
            Uri baseUri = new Uri("http://odata.org");
            Uri testUri = new Uri("http://odata.org/relative");
            IEnumerable <Func <Uri, BaseUriErrorTestCase> > testCaseFuncs = new Func <Uri, BaseUriErrorTestCase>[]
            {
                relativeUri => new BaseUriErrorTestCase
                {   // next page link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed();
                        feed.NextPageLink     = relativeUri;
                        return(new [] { feed });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // entry read link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResource entry = ObjectModelUtils.CreateDefaultEntry();
                        entry.ReadLink      = relativeUri;
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // entry edit link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResource entry = ObjectModelUtils.CreateDefaultEntry();
                        entry.EditLink      = relativeUri;
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // media resource (default stream) read link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue();
                        mediaResource.ContentType = "image/jpg";
                        mediaResource.ReadLink    = relativeUri;
                        ODataResource entry       = ObjectModelUtils.CreateDefaultEntry();
                        entry.MediaResource       = mediaResource;
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // media resource (default stream) edit link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataStreamReferenceValue mediaResource = new ODataStreamReferenceValue();
                        mediaResource.ContentType = "image/jpg";    // required
                        mediaResource.ReadLink    = testUri;        // required
                        mediaResource.EditLink    = relativeUri;
                        ODataResource entry       = ObjectModelUtils.CreateDefaultEntry();
                        entry.MediaResource       = mediaResource;
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // link Url
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataNestedResourceInfo link = ObjectModelUtils.CreateDefaultCollectionLink();
                        link.Url = relativeUri;

                        ODataResource entry = ObjectModelUtils.CreateDefaultEntry();
                        return(new ODataItem[] { entry, link });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // association link Url
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataNestedResourceInfo link = ObjectModelUtils.CreateDefaultSingletonLink();
                        link.AssociationLinkUrl      = relativeUri;

                        ODataResource entry = ObjectModelUtils.CreateDefaultEntry();
                        return(new ODataItem[] { entry, link });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // named stream read link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataStreamReferenceValue namedStream = new ODataStreamReferenceValue()
                        {
                            ContentType = "image/jpg",
                            ReadLink    = relativeUri,
                        };
                        ODataResource entry    = ObjectModelUtils.CreateDefaultEntry();
                        ODataProperty property = new ODataProperty()
                        {
                            Name  = "NamedStream",
                            Value = namedStream
                        };

                        entry.Properties = new[] { property };
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // named stream edit link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataStreamReferenceValue namedStream = new ODataStreamReferenceValue()
                        {
                            ContentType = "image/jpg",
                            ReadLink    = testUri,
                            EditLink    = relativeUri
                        };
                        ODataResource entry    = ObjectModelUtils.CreateDefaultEntry();
                        ODataProperty property = new ODataProperty()
                        {
                            Name  = "NamedStream",
                            Value = namedStream
                        };

                        entry.Properties = new[] { property };
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: feed generator Uri
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed();
                        return(new [] { feed });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: feed logo
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed();
                        return(new [] { feed });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: feed icon
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed();
                        return(new [] { feed });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: feed author
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed();
                        return(new [] { feed });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: feed contributor
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed();
                        return(new [] { feed });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: feed link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResourceSet feed = ObjectModelUtils.CreateDefaultFeed();
                        return(new [] { feed });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: entry author
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResource entry = ObjectModelUtils.CreateDefaultEntry();
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: entry contributor
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResource entry = ObjectModelUtils.CreateDefaultEntry();
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
                relativeUri => new BaseUriErrorTestCase
                {   // Atom metadata: entry link
                    ItemFunc = new Func <IEnumerable <ODataItem> >(() =>
                    {
                        ODataResource entry = ObjectModelUtils.CreateDefaultEntry();
                        return(new [] { entry });
                    }),
                    Formats = new [] { ODataFormat.Json }
                },
            };

            // ToDo: Fix places where we've lost JsonVerbose coverage to add JsonLight
            Uri testRelativeUri    = baseUri.MakeRelativeUri(testUri);
            Uri invalidRelativeUri = new Uri("../invalid/relative/uri", UriKind.Relative);

            this.CombinatorialEngineProvider.RunCombinations(
                testCaseFuncs,
                this.WriterTestConfigurationProvider.ExplicitFormatConfigurations.Where(c => false),
                new Uri[] { testRelativeUri, invalidRelativeUri },
                new bool[] { false, true },
                (testCaseFunc, testConfiguration, uri, implementUrlResolver) =>
            {
                var testCase       = testCaseFunc(uri);
                var testDescriptor = new
                {
                    Descriptor = new PayloadWriterTestDescriptor <ODataItem>(
                        this.Settings,
                        testCase.ItemFunc(),
                        testConfig => new WriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException2 = ODataExpectedExceptions.ODataException("ODataWriter_RelativeUriUsedWithoutBaseUriSpecified", uri.OriginalString)
                    }),
                    Formats = testCase.Formats
                };

                if (testDescriptor.Formats.Contains(testConfiguration.Format))
                {
                    PayloadWriterTestDescriptor <ODataItem> payloadTestDescriptor = testDescriptor.Descriptor;
                    TestUrlResolver urlResolver = null;
                    if (implementUrlResolver)
                    {
                        payloadTestDescriptor             = new PayloadWriterTestDescriptor <ODataItem>(payloadTestDescriptor);
                        urlResolver                       = new TestUrlResolver();
                        payloadTestDescriptor.UrlResolver = urlResolver;
                    }

                    testConfiguration = testConfiguration.Clone();
                    testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri);

                    TestWriterUtils.WriteAndVerifyODataPayload(payloadTestDescriptor, testConfiguration, this.Assert, this.Logger);

                    if (implementUrlResolver)
                    {
                        this.Assert.AreEqual(1, urlResolver.Calls.Where(call => call.Value.OriginalString == uri.OriginalString).Count(), "The resolver should be called exactly once for each URL.");
                    }
                }
            });
        }
Example #21
0
        private PayloadWriterTestDescriptor <ODataItem>[] CreateFeedNextLinkDescriptors()
        {
            string[] nextLinkUris = new string[]
            {
                "http://my.customers.com/?skiptoken=1234",
                "http://my.customers.com/?",
                "http://my.customers.com/",
                "http://my.customers.com/?$filter=3.14E%2B%20ne%20null",
                "http://my.customers.com/?$filter='foo%20%26%20'%20ne%20null",
                "http://my.customers.com/?$filter=not%20endswith(Name,'%2B')",
                "http://my.customers.com/?$filter=geo.distance(Point,%20geometry'SRID=0;Point(6.28E%2B3%20-2.1e%2B4)')%20eq%20null",
            };

            Func <string, ODataFeed> feedCreator = (nextLink) =>
            {
                ODataFeed feed = ObjectModelUtils.CreateDefaultFeed();
                feed.NextPageLink = new Uri(nextLink);
                return(feed);
            };

            EdmModel model = new EdmModel();

            ODataFeed dummyFeed = ObjectModelUtils.CreateDefaultFeed("CustomersSet", "CustomerType", model);

            var container    = model.FindEntityContainer("DefaultContainer");
            var customerSet  = container.FindEntitySet("CustomersSet") as EdmEntitySet;
            var customerType = model.FindType("TestModel.CustomerType") as EdmEntityType;

            return(nextLinkUris.Select(nextLink => new PayloadWriterTestDescriptor <ODataItem>(
                                           this.Settings,
                                           feedCreator(nextLink),
                                           (testConfiguration) =>
            {
                if (testConfiguration.IsRequest)
                {
                    return new WriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        ExpectedException2 = ODataExpectedExceptions.ODataException("WriterValidationUtils_NextPageLinkInRequest")
                    };
                }

                if (testConfiguration.Format == ODataFormat.Atom)
                {
                    return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Xml = @"<link rel=""next"" href=""" + nextLink + @""" xmlns=""" + TestAtomConstants.AtomNamespace + @""" />",
                        FragmentExtractor = (result) => result.Elements(XName.Get("link", TestAtomConstants.AtomNamespace)).Single()
                    };
                }
                else if (testConfiguration.Format == ODataFormat.Json)
                {
                    return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings)
                    {
                        Json = "\"" + JsonLightConstants.ODataNextLinkAnnotationName + "\":\"" + nextLink + "\"",
                        FragmentExtractor = (result) => result.Object().Property(JsonLightConstants.ODataNextLinkAnnotationName)
                    };
                }
                else
                {
                    string formatName = testConfiguration.Format == null ? "null" : testConfiguration.Format.GetType().Name;
                    throw new NotSupportedException("Invalid format detected: " + formatName);
                }
            })
            {
                Model = model,
                PayloadEdmElementContainer = customerSet,
                PayloadEdmElementType = customerType,
            }).ToArray());
        }