<commit_before>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Web.Mvc;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
using SpecsFor.Mvc.Authentication;
using SpecsFor.Mvc.Helpers;

namespace SpecsFor.Mvc
{
    //NOTE: MvcWebApp has definitely picked up too many responsibilites.  It's in need of 
    //		refactoring.  The project could probably benefit from a simple IoC container 
    //		or service locator for handling some of these things. 
    public class MvcWebApp
    {
        //TODO: Move to Service Locator class?  

        public static readonly IList<Action<MvcWebApp>> PreTestCallbacks = new List<Action<MvcWebApp>>();
        public static string BaseUrl { get; set; }
        public static BrowserDriver Driver { get; set; }
        public static IHandleAuthentication Authentication { get; set; }
        public static TimeSpan Delay { get; set; }

	    public static IElementConventions ElementConventions = new DefaultElementConventions();

        public RemoteWebDriver Browser { get; private set; }

        static MvcWebApp()
        {
            BaseUrl = "http://localhost";
            Driver = BrowserDriver.InternetExplorer;
        }

        public MvcWebApp()
        {
            Browser = Driver.GetDriver();

            try
            {
                foreach (var callback in PreTestCallbacks)
                {
                    callback(this);
                }

                if (Authentication != null)
                {
                    Authentication.Authenticate(this);
                }
            }
            //If something happens and the class can't be created, we still need to destroy the browser.
            catch (Exception)
            {
                Browser.Quit();
                Browser.Dispose();
                throw;
            }
        }

		public FluentForm<TModel> FindFormFor<TModel>() where TModel : class
        {
            return new FluentForm<TModel>(this);
        }

		public FluentDisplay<T> FindDisplayFor<T>() where T : class
        {
            return new FluentDisplay<T>(this);
        }

        public IWebElement ValidationSummary
        {
            get
            {
	            try
	            {
		            return Browser.FindElement(ElementConventions.FindValidationSummary());
	            }
	            catch (NoSuchElementException)
	            {
					throw new NoSuchElementException("Unable to find a validation summary using the configured convention.  You can change the convention by calling SpecsForMvcConfig.UseConventions<TConventions>() with your custom conventions.");
	            }
            }
        }

        public RouteData Route
        {
            get
            {
                //Strip the host, port, etc. off the route.  The routing helpers
                //expect the URL to look like "~/virtual/path"
                var url = Browser.Url.Replace(BaseUrl, "~");

                var queryStringParams = new Dictionary<string, string>();

                //Parse out the query string params. 
                if (url.Contains("?"))
                {
                    var parts = url.Split('?');
                    url = parts[0];

                    queryStringParams = parts[1].Split('&')
                        .Select(v => v.Split('='))
                        .ToDictionary(a => a[0], a => a[1]);
                }

                var context = new FakeHttpContext(url, null, null, null, null, null);
                context.SetRequest(new FakeHttpRequest(url, new Uri(Browser.Url), null));

                var routeData = RouteTable.Routes.GetRouteData(context);

                //Add in query string params.  This will allow the ShouldMapTo extension method to work 
                //with query string parameters.
                foreach (var kvp in queryStringParams.Where(kvp => !routeData.Values.ContainsKey(kvp.Key)))
                {
                    routeData.Values.Add(kvp.Key, kvp.Value);
                }

                return routeData;
            }
        }

        public void NavigateTo<TController>(Expression<Action<TController>> action) where TController : Controller
        {
            var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
            //TODO: workaround to fixes MattHoneycutt/SpecsFor#25
            var url = BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, action);

            Browser.Navigate().GoToUrl(BaseUrl + url);
        }

        public IWebElement FindLinkTo<TController>(Expression<Action<TController>> action) where TController : Controller
        {
            var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
            //TODO: workaround to fixes MattHoneycutt/SpecsFor#25
            var url = BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, action);
            var element = Browser.FindElement(By.CssSelector("a[href='" + url + "']"));

            return element;
        }

		public bool UrlMapsTo<TController>(Expression<Action<TController>> action) where TController : Controller
		{
			var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
			//TODO: workaround to fixes MattHoneycutt/SpecsFor#25
			var url = BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, action);
			var expectedUrl = MvcWebApp.BaseUrl + helper.BuildUrlFromExpression(action);

			return (Browser.Url == expectedUrl);
		}

		public void UrlShouldMapTo<TController>(Expression<Action<TController>> action) where TController : Controller
		{
			if (!UrlMapsTo(action))
			{
				var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
				var expectedUrl = MvcWebApp.BaseUrl + helper.BuildUrlFromExpression(action);

				throw new AssertionException(string.Format("URL does not match target action. \r\n\tExpected {0}\r\n\tActual:{1}",
					expectedUrl, Browser.Url));
			}
		}

        internal void Pause()
        {
            if (Delay != default(TimeSpan))
            {
                Thread.Sleep(Delay);
            }
        }

        public static void AddPreTestCallback(Action action)
        {
            AddPreTestCallback(_ => action());
        }

        public static void AddPreTestCallback(Action<MvcWebApp> action)
        {
            PreTestCallbacks.Add(action);
        }
<commit_msg>fixing url should map to<commit_after>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Web.Mvc;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
using SpecsFor.Mvc.Authentication;
using SpecsFor.Mvc.Helpers;

namespace SpecsFor.Mvc
{
    //NOTE: MvcWebApp has definitely picked up too many responsibilites.  It's in need of 
    //		refactoring.  The project could probably benefit from a simple IoC container 
    //		or service locator for handling some of these things. 
    public class MvcWebApp
    {
        //TODO: Move to Service Locator class?  

        public static readonly IList<Action<MvcWebApp>> PreTestCallbacks = new List<Action<MvcWebApp>>();
        public static string BaseUrl { get; set; }
        public static BrowserDriver Driver { get; set; }
        public static IHandleAuthentication Authentication { get; set; }
        public static TimeSpan Delay { get; set; }

	    public static IElementConventions ElementConventions = new DefaultElementConventions();

        public RemoteWebDriver Browser { get; private set; }

        static MvcWebApp()
        {
            BaseUrl = "http://localhost";
            Driver = BrowserDriver.InternetExplorer;
        }

        public MvcWebApp()
        {
            Browser = Driver.GetDriver();

            try
            {
                foreach (var callback in PreTestCallbacks)
                {
                    callback(this);
                }

                if (Authentication != null)
                {
                    Authentication.Authenticate(this);
                }
            }
            //If something happens and the class can't be created, we still need to destroy the browser.
            catch (Exception)
            {
                Browser.Quit();
                Browser.Dispose();
                throw;
            }
        }

		public FluentForm<TModel> FindFormFor<TModel>() where TModel : class
        {
            return new FluentForm<TModel>(this);
        }

		public FluentDisplay<T> FindDisplayFor<T>() where T : class
        {
            return new FluentDisplay<T>(this);
        }

        public IWebElement ValidationSummary
        {
            get
            {
	            try
	            {
		            return Browser.FindElement(ElementConventions.FindValidationSummary());
	            }
	            catch (NoSuchElementException)
	            {
					throw new NoSuchElementException("Unable to find a validation summary using the configured convention.  You can change the convention by calling SpecsForMvcConfig.UseConventions<TConventions>() with your custom conventions.");
	            }
            }
        }

        public RouteData Route
        {
            get
            {
                //Strip the host, port, etc. off the route.  The routing helpers
                //expect the URL to look like "~/virtual/path"
                var url = Browser.Url.Replace(BaseUrl, "~");

                var queryStringParams = new Dictionary<string, string>();

                //Parse out the query string params. 
                if (url.Contains("?"))
                {
                    var parts = url.Split('?');
                    url = parts[0];

                    queryStringParams = parts[1].Split('&')
                        .Select(v => v.Split('='))
                        .ToDictionary(a => a[0], a => a[1]);
                }

                var context = new FakeHttpContext(url, null, null, null, null, null);
                context.SetRequest(new FakeHttpRequest(url, new Uri(Browser.Url), null));

                var routeData = RouteTable.Routes.GetRouteData(context);

                //Add in query string params.  This will allow the ShouldMapTo extension method to work 
                //with query string parameters.
                foreach (var kvp in queryStringParams.Where(kvp => !routeData.Values.ContainsKey(kvp.Key)))
                {
                    routeData.Values.Add(kvp.Key, kvp.Value);
                }

                return routeData;
            }
        }

        public void NavigateTo<TController>(Expression<Action<TController>> action) where TController : Controller
        {
            var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
            //TODO: workaround to fixes MattHoneycutt/SpecsFor#25
            var url = BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, action);

            Browser.Navigate().GoToUrl(BaseUrl + url);
        }

        public IWebElement FindLinkTo<TController>(Expression<Action<TController>> action) where TController : Controller
        {
            var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
            //TODO: workaround to fixes MattHoneycutt/SpecsFor#25
            var url = BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, action);
            var element = Browser.FindElement(By.CssSelector("a[href='" + url + "']"));

            return element;
        }

		public bool UrlMapsTo<TController>(Expression<Action<TController>> action) where TController : Controller
		{
			var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
			//TODO: workaround to fixes MattHoneycutt/SpecsFor#25
			var expectedUrl = MvcWebApp.BaseUrl + BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, action);

			return (Browser.Url == expectedUrl);
		}

		public void UrlShouldMapTo<TController>(Expression<Action<TController>> action) where TController : Controller
		{
			if (!UrlMapsTo(action))
			{
				var helper = new HtmlHelper(new ViewContext { HttpContext = FakeHttpContext.Root() }, new FakeViewDataContainer());
				var expectedUrl = MvcWebApp.BaseUrl + BuildUrlFromExpression(helper.ViewContext.RequestContext, helper.RouteCollection, action);

				throw new AssertionException(string.Format("URL does not match target action. \r\n\tExpected {0}\r\n\tActual:{1}",
					expectedUrl, Browser.Url));
			}
		}

        internal void Pause()
        {
            if (Delay != default(TimeSpan))
            {
                Thread.Sleep(Delay);
            }
        }

        public static void AddPreTestCallback(Action action)
        {
            AddPreTestCallback(_ => action());
        }

        public static void AddPreTestCallback(Action<MvcWebApp> action)
        {
            PreTestCallbacks.Add(action);
        }

{'fraction_non_alphanumeric': 0.09006962257237083, 'fraction_numerical': 0.0017588860388420666, 'mean_word_length': 2.0824486107973796, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2233411', 'n_tokens_mistral': 3705, 'n_tokens_neox': 3420, 'n_words': 909}