コード例 #1
0
        /// <summary>
        /// Converts a <see cref="PayloadReaderTestDescriptor"/> to an in-stream error <see cref="PayloadReaderTestDescriptor"/>.
        /// </summary>
        /// <param name="descriptor">The <see cref="PayloadReaderTestDescriptor"/> to convert.</param>
        /// <param name="format">The <see cref="ODataFormat"/> the test descriptor is created for.</param>
        /// <returns>An in-stream error <see cref="PayloadReaderTestDescriptor"/> based on the <paramref name="descriptor"/>.</returns>
        /// <remarks>The <paramref name="descriptor"/> is expected to represent a top-level error payload test descriptor.</remarks>
        internal static PayloadReaderTestDescriptor ToInStreamErrorTestDescriptor(this PayloadReaderTestDescriptor descriptor, ODataFormat format)
        {
            ExceptionUtilities.CheckArgumentNotNull(descriptor, "descriptor");
            ExceptionUtilities.CheckArgumentNotNull(format, "format");
            ExceptionUtilities.Assert(descriptor.PayloadElement.ElementType == ODataPayloadElementType.ODataErrorPayload, "Only error payloads expected.");
            ExceptionUtilities.Assert(descriptor.ExpectedResultCallback == null, "No expected results callback expected.");
            ExceptionUtilities.Assert(descriptor.PayloadEdmModel == null, "No model expected.");

            // Model that defines the CityType to be used for wrapping the error payload to convert it into an in-stream error.
            IEdmModel testModel = Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            bool isValidTopLevelError = descriptor.ExpectedException == null;

            ODataPayloadElement wrappedPayloadElement = null;
            ExpectedException expectedException = null;

            if (format == ODataFormat.Atom)
            {
                var atomRepresentation = (XmlPayloadElementRepresentationAnnotation)descriptor.PayloadElement.GetAnnotation(typeof(XmlPayloadElementRepresentationAnnotation));
                ExceptionUtilities.Assert(atomRepresentation != null, "Expected a format-specific annotation.");
                XNode xmlRepresentation = atomRepresentation.XmlNodes.Single();

                XElement wrapperObject = new XElement(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName,
                    new XElement(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomCategoryElementName,
                        new XAttribute(TestAtomConstants.AtomCategoryTermAttributeName, "TestModel.CityType"),
                        new XAttribute(TestAtomConstants.AtomCategorySchemeAttributeName, TestAtomConstants.ODataSchemeNamespace),
                    new XElement(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName,
                        new XAttribute(TestAtomConstants.AtomTypeAttributeName, "application/xml"),
                        new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName,
                            new XElement(TestAtomConstants.ODataXNamespace + "PoliceStation", xmlRepresentation)))));

                // replace the payload and ATOM representation of the test descriptor and set the expected error message
                wrappedPayloadElement = PayloadBuilder.Entity("TestModel.CityType").XmlRepresentation(wrapperObject);

                if (isValidTopLevelError)
                {
                    // if we have a valid top-level error we expect an ODataErrorException to be thrown.
                    ODataError error = ConvertErrorPayload((ODataErrorPayload)descriptor.PayloadElement, /*forAtom*/true);
                    expectedException = ODataExpectedExceptions.ODataErrorException(error, "ODataErrorException_GeneralError");
                }
                else
                {
                    expectedException = descriptor.ExpectedException;
                }
            }
            else if (format == ODataFormat.Json)
            {
                IEdmEntitySet citiesSet = testModel.EntityContainer.FindEntitySet("Cities");
                IEdmEntityType cityType = testModel.FindType("TestModel.CityType") as IEdmEntityType;

                var jsonRepresentation = (JsonPayloadElementRepresentationAnnotation)descriptor.PayloadElement.GetAnnotation(typeof(JsonPayloadElementRepresentationAnnotation));
                ExceptionUtilities.Assert(jsonRepresentation != null, "Expected a format-specific annotation.");
                JsonObject jsonObject = (JsonObject)jsonRepresentation.Json;

                // wrap the existing payload in an entity of type 'CityType'; the existing payload is used as value of the 'PoliceStation' property
                JsonObject wrapperObject = (JsonObject)JsonTextPreservingParser.ParseValue(new StringReader("{ \"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities/$entity\" }"));
                wrapperObject.Add(new JsonProperty("PoliceStation", jsonObject));

                // replace the payload and Json representation of the test descriptor and set the expected error message
                wrappedPayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                    .ExpectedEntityType(cityType, citiesSet)
                    .JsonRepresentation(wrapperObject);

                if (isValidTopLevelError)
                {
                    // if we have a valid top-level error we expect an ODataErrorException to be thrown.
                    ODataError error = ConvertErrorPayload((ODataErrorPayload)descriptor.PayloadElement, /*forAtom*/false);
                    expectedException = ODataExpectedExceptions.ODataErrorException(error, "ODataErrorException_GeneralError");
                }
                else
                {
                    // if the top-level error is too deeply recursive, we expect to fail in the same way for the in-stream error.
                    if (descriptor.ExpectedException.ExpectedMessage.ResourceIdentifier == "ValidationUtils_RecursionDepthLimitReached")
                    {
                        expectedException = descriptor.ExpectedException;
                    }
                    else
                    {
                        // otherwise, if the top-level error is not valid, we expect an error message that the first
                        // property of the invalid top-level error object is not defined on type OfficeType.
                        string firstPropertyName = jsonObject.Properties.First().Name;
                        expectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", firstPropertyName, "TestModel.OfficeType");
                    }
                }
            }
            else
            {
                throw new TaupoInvalidOperationException("Unsupported format for error test descriptor found: " + format.GetType().Name);
            }

            return new PayloadReaderTestDescriptor(descriptor)
            {
                PayloadElement = wrappedPayloadElement,
                PayloadEdmModel = testModel,
                ExpectedResultPayloadElement = tc => descriptor.PayloadElement,
                ExpectedException = expectedException,
            };
        }