public void ReadXml()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 xpath='*/some-node'/>"
                + "<s0:Property2 promoted='true' xpath='*/other-node'/>"
                + "<s0:Property3 mode='write' value='constant'/>"
                + "<s0:Property4 mode='clear'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                sut.ReadXml(reader);
                Assert.That(
                    sut,
                    Is.EqualTo(
                        new[] {
                    new XPathExtractor(new XmlQualifiedName("Property1", "urn"), "*/some-node", ExtractionMode.Write),
                    new XPathExtractor(new XmlQualifiedName("Property2", "urn"), "*/other-node", ExtractionMode.Promote),
                    new ConstantExtractor(new XmlQualifiedName("Property3", "urn"), "constant", ExtractionMode.Write),
                    new PropertyExtractor(new XmlQualifiedName("Property4", "urn"), ExtractionMode.Clear)
                }));
            }
        }
        public void ReadXmlWithoutProperties()
        {
            var xml = string.Format("<san:Properties xmlns:s0='urn' xmlns:san='{0}' />", SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                sut.ReadXml(reader);
                Assert.That(sut, Is.Empty);
            }
        }
        public void ReadXmlThrowsWhenRootElementNamespaceIsInvalid()
        {
            const string xml      = "<san:Properties xmlns:s0='urn' xmlns:san='urn:schemas.stateless.be:biztalk:2012:12:extractors'><s0:PropertyName xpath='*'/></san:Properties>";
            var          expected = string.Format("Element 'Properties' with namespace name '{0}' was not found. Line 1, position 2.", SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.TypeOf <ConfigurationErrorsException>()
                    .With.InnerException.TypeOf <XmlException>()
                    .With.InnerException.Message.EqualTo(expected));
            }
        }
        public void ReadXmlForExtractorPrecedence()
        {
            var xml = string.Format(
                "<san:Properties precedence='schemaOnly' xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 mode='clear'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                sut.ReadXml(reader);
                Assert.That(sut.Precedence, Is.EqualTo(ExtractorPrecedence.SchemaOnly));
            }
        }
 /// <summary>
 /// Deserializes a <see cref="PropertyExtractorCollection"/> from its XML serialization <see cref="string"/>.
 /// </summary>
 /// <param name="xml">
 /// A <see cref="string"/> denoting the XML serialization of a <see cref="PropertyExtractorCollection"/>.
 /// </param>
 /// <returns>
 /// The deserialized <see cref="PropertyExtractorCollection"/>.
 /// </returns>
 /// <seealso cref="Serialize"/>
 public static PropertyExtractorCollection Deserialize(string xml)
 {
     if (xml.IsNullOrEmpty())
     {
         return(PropertyExtractorCollection.Empty);
     }
     using (var reader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings {
         IgnoreWhitespace = true, IgnoreComments = true
     }))
     {
         var collection = new PropertyExtractorCollection();
         collection.ReadXml(reader);
         return(collection);
     }
 }
        public void ReadXmlForPropertyExtractorThrowsWhenPromotedAttributeIsPresent()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 promoted='true'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.TypeOf <ConfigurationErrorsException>().With.Message.EqualTo("ExtractionMode is missing for PropertyExtractor without a Value or an XPath."));
            }
        }
        public void ReadXmlForPropertyExtractorThrowsWhenModeAttributeIsInvalid()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 mode='promote'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.ArgumentException.With.Message.StartsWith("Invalid ExtractionMode, only Clear and Ignore are supported for PropertyExtractor without a Value or an XPath."));
            }
        }
        public void ReadXmlForConstantExtractorThrowsWhenValueIsEmpty()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 value=''/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.ArgumentNullException.With.Message.StartsWith("Value cannot be null."));
            }
        }
        public void ReadXmlForConstantExtractorThrowsWhenModeAttributeIsInvalid()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 mode='demote' value='constant'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.ArgumentException.With.Message.StartsWith("ExtractionMode 'Demote' is not supported by ConstantExtractor."));
            }
        }
        public void ReadXmlForPropertyExtractor()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 mode='clear'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                sut.ReadXml(reader);
                Assert.That(
                    sut,
                    Is.EqualTo(new[] { new PropertyExtractor(new XmlQualifiedName("Property1", "urn"), ExtractionMode.Clear) }));
            }
        }
        public void ReadXmlThrowsWhenPropertyToExtractHasNoNamespace()
        {
            var xml = string.Format(
                "<san:Properties xmlns:san='{0}'>"
                + "<PropertyName xpath='*'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.TypeOf <ConfigurationErrorsException>()
                    .With.InnerException.TypeOf <XmlException>()
                    .With.InnerException.Message.EqualTo("The following properties are not associated with the target namespace URI of some property schema: [PropertyName]."));
            }
        }
        public void ReadXmlThrowsWhenDuplicatePropertyToExtract()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:PropertyName xpath='*'/><s0:PropertyName xpath='*'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.TypeOf <ConfigurationErrorsException>()
                    .With.InnerException.TypeOf <XmlException>()
                    .With.InnerException.Message.EqualTo("The following properties are declared multiple times: [urn:PropertyName]."));
            }
        }
        public void ReadXmlForXPathExtractorThrowsWhenXPathIsEmpty()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:PropertyName xpath=''/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                Assert.That(
                    () => sut.ReadXml(reader),
                    Throws.TypeOf <ConfigurationErrorsException>()
                    .With.InnerException.TypeOf <XPathException>()
                    // ReSharper disable once StringLiteralTypo
                    .With.InnerException.Message.StartsWith("Bad Query string encoundered in XPath:"));
            }
        }
        public void ReadXmlForXPathExtractorWithPromotedAttribute()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property2 promoted='true' xpath='*/other-node'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                sut.ReadXml(reader);
                Assert.That(
                    sut,
                    Is.EqualTo(
                        new PropertyExtractor[] {
                    new XPathExtractor(new XmlQualifiedName("Property2", "urn"), "*/other-node", ExtractionMode.Promote)
                }));
            }
        }
        public void ReadXmlForQNameValueExtractorFallsBackOnXPathExtractorWhenQNameValueExtractionModeIsDefault()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property3 mode='promote' qnameValue='name' xpath='*/extra-node'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                sut.ReadXml(reader);
                Assert.That(
                    sut,
                    Is.EqualTo(
                        new PropertyExtractor[] {
                    new XPathExtractor(new XmlQualifiedName("Property3", "urn"), "*/extra-node", ExtractionMode.Promote),
                }));
            }
        }
        public void ReadXmlForConstantExtractorWithModeAttribute()
        {
            var xml = string.Format(
                "<san:Properties xmlns:s0='urn' xmlns:san='{0}'>"
                + "<s0:Property1 mode='promote' value='constant'/>"
                + "</san:Properties>",
                SchemaAnnotations.NAMESPACE);

            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                var sut = new PropertyExtractorCollection();
                sut.ReadXml(reader);
                Assert.That(
                    sut,
                    Is.EqualTo(
                        new PropertyExtractor[] {
                    new ConstantExtractor(new XmlQualifiedName("Property1", "urn"), "constant", ExtractionMode.Promote)
                }));
            }
        }