using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Globalization;

using Microsoft.VisualStudio.TestTools.WebTesting;

using Microsoft.VisualStudio.TestTools.WebTesting.Rules;

 

namespace WhidbeyCorrelation

{

   

    public class DynamicQueryStringExtraction : ExtractionRule

    {

 

        public override string RuleName

        {

            get

            {

                return "DynamicQueryStringExtraction";

            }

        }

 

        public override string RuleDescription

        {

            get

            {

                return "Extracts a url querystring parameter embedded in an <a> "

                + "tags href attribute in the page response.";

            }

        }

 

        [Description("The name of the querystring parameter you wish to extract")]

        public string ParameterName

        {

            get

            {

                return m_ParameterName;

            }

 

            set

            {

                m_ParameterName = value;

            }

        }

 

        [Description("The zero-based numerical index of the <a> tag you want to " +

            "extract the querystring parameter from")]

        [DefaultValue(-1)]

        public int Instance

        {

            get

            {

                return m_Instance;

            }

            set

            {

                m_Instance = value;

            }

        }

 

        [Description("Turning this on will automatically correlate the extracted value " +

            "in matching querystring parameters for subsequent requests")]

        [DefaultValue(true)]

        public bool AutomaticCorrelation

        {

            get

            {

                return m_AutomaticCorrelation;

            }

            set

            {

                m_AutomaticCorrelation = value;

            }

        }

 

        [Description("If AutomaticCorrelation is set to true, setting this to true will " +

            "cause only the next request to be correlated.")]

        [DefaultValue(false)]

        public bool CorrelateNextRequestOnly

        {

            get

            {

                return m_CorrelateNextRequestOnly;

            }

            set

            {

                m_CorrelateNextRequestOnly = value;

            }

        }

 

 

        public override void Extract(object sender, ExtractionEventArgs e)

        {

            List<HtmlTag> aTags = new List<HtmlTag>();

            foreach (HtmlTag tag in e.Response.HtmlDocument.GetFilteredHtmlTags(new string[] { "a" }))

            {

                aTags.Add(tag);

            }

 

            if (m_Instance < 0 || m_Instance >= aTags.Count)

            {

                e.Success = false;

                e.Message = "Instance must be between 0 and the number of <a> tags on the page.";

                return;

            }

 

            string href = aTags[m_Instance].GetAttributeValueAsString("href");

            string[] tmp = href.Split('?');

            if (tmp.Length != 2)

            {

                e.Success = false;

                e.Message = "href attribute in specified <a> tag did not contain any embedded "

                + "querystring parameters";

                return;

            }

 

            string qs = tmp[1];

            string[] qsParams = qs.Split('&');

            foreach (string qsParam in qsParams)

            {

                string[] name_value = qsParam.Split('=');

                if (name_value[0] == m_ParameterName)

                {

                    e.WebTest.Context.Add(ContextParameterName, name_value[1]);

                    e.Success = true;

                    e.Message = "Value: " + name_value[1] + " was extracted.";

 

                    if (m_AutomaticCorrelation == true)

                    {

                       

                        e.WebTest.PreRequest += new EventHandler<PreRequestEventArgs>(WebTest_PreRequest);

                    }

 

                    return;

                }

            }

                                  

            e.Success = false;

            e.Message = "Could not find querystring parameter in href attribute of specified <a> tag.";

        }

 

        void WebTest_PreRequest(object sender, PreRequestEventArgs e)

        {

            foreach (QueryStringParameter param in e.Request.QueryStringParameters)

            {

                if (param.Name == m_ParameterName)

                {

                    param.Value = e.WebTest.Context[ContextParameterName].ToString();

                    break;

                }

            }

 

            if (m_CorrelateNextRequestOnly == true)

            {

                e.WebTest.PreRequest -= WebTest_PreRequest;

            }

        }

       

        private int m_Instance;

        private string m_ParameterName;

        private bool m_AutomaticCorrelation;

        private bool m_CorrelateNextRequestOnly;

    }

}