public void SelectOperationCallsTrySelectOperation()
        {
            HttpOperationAssert.Execute <UriTemplateService>(
                (operations) =>
            {
                Uri baseAddress = new Uri("http://localhost/baseAddress");
                SUriAndMethodOperationSelector selector = new SUriAndMethodOperationSelector(baseAddress, operations, TrailingSlashMode.Ignore);
                bool OnTrySelectOperationCalled         = false;
                string expectedOperationName            = "operationName";
                HttpRequestMessage expectedRequest      = new HttpRequestMessage();
                expectedRequest.RequestUri = new Uri("http://differntUri");

                selector.OnTrySelectOperationHttpRequestMessageStringOutBooleanOut =
                    delegate(HttpRequestMessage request, out string operationName, out bool differsByTrailingSlash)
                {
                    OnTrySelectOperationCalled = true;
                    operationName          = expectedOperationName;
                    differsByTrailingSlash = false;

                    Assert.AreEqual(expectedRequest, request, "The HttpRequestMessage passed to TrySelectOperation should have been passed to OnTrySelectOperation.");
                    return(true);
                };

                string actualOperationName = selector.SelectOperation(expectedRequest);

                Assert.IsTrue(OnTrySelectOperationCalled, "TrySelectOperation should have called OnTrySelectionOperation.");
                Assert.AreEqual(expectedOperationName, actualOperationName, "TrySelectOperation should have returned the operationName value from OnTrySelectionOperation.");
            });
        }
        public void SelectOperationReturnsOperationName()
        {
            HttpOperationAssert.Execute <UriTemplateService>(
                (operations) =>
            {
                Uri baseAddress = new Uri("http://localhost/baseAddress");
                UriAndMethodOperationSelector selector = new UriAndMethodOperationSelector(baseAddress, operations, TrailingSlashMode.Ignore);

                foreach (HttpOperationDescription operation in operations)
                {
                    UriTemplate uriTemplate  = operation.GetUriTemplate();
                    HttpMethod method        = operation.GetHttpMethod();
                    string expectedOperation = operation.Name;

                    string[] uriParameters = uriTemplate.PathSegmentVariableNames
                                             .Concat(uriTemplate.QueryValueVariableNames)
                                             .ToArray();
                    Uri requestUri             = uriTemplate.BindByPosition(baseAddress, uriParameters);
                    HttpRequestMessage request = new HttpRequestMessage(method, requestUri);

                    string actualOperation = selector.SelectOperation(request);
                    Assert.AreEqual(expectedOperation, actualOperation, "The UriAndMethodOperationSelector should have returned the selected operation name.");
                }
            });
        }
        public void SelectOperationThrowsWithUriMatchingButMethodNotMatching()
        {
            HttpOperationAssert.Execute <UriTemplateService>(
                (IEnumerable <HttpOperationDescription> operations) =>
            {
                Uri baseAddress = new Uri("http://localhost/baseAddress");
                UriAndMethodOperationSelector selector = new UriAndMethodOperationSelector(baseAddress, operations, TrailingSlashMode.Ignore);

                bool oneMethodNotAllowedFound = false;

                foreach (HttpOperationDescription operation in operations)
                {
                    List <HttpMethod> otherAllowedMethods = operations
                                                            .Where(otherOperation => otherOperation.GetUriTemplate().IsEquivalentTo(operation.GetUriTemplate()))
                                                            .Select(otherOperation => otherOperation.GetHttpMethod())
                                                            .ToList();

                    if (otherAllowedMethods.Count > 1)
                    {
                        UriTemplate uriTemplate  = operation.GetUriTemplate();
                        string expectedOperation = operation.Name;
                        string[] uriParameters   = uriTemplate.PathSegmentVariableNames
                                                   .Concat(uriTemplate.QueryValueVariableNames)
                                                   .ToArray();
                        Uri requestUri = uriTemplate.BindByPosition(baseAddress, uriParameters);

                        foreach (HttpMethod method in HttpTestData.AllHttpMethods.Except(otherAllowedMethods))
                        {
                            HttpRequestMessage request = new HttpRequestMessage(method, requestUri);
                            ExceptionAssert.Throws <HttpResponseException>(
                                () => selector.SelectOperation(request),
                                (responseException) =>
                            {
                                HttpResponseMessage expectedResponse = StandardHttpResponseMessageBuilder.CreateMethodNotAllowedResponse(request, otherAllowedMethods, null);
                                HttpAssert.AreEqual(expectedResponse, responseException.Response);
                                oneMethodNotAllowedFound = true;
                            });
                        }
                    }
                }

                Assert.IsTrue(oneMethodNotAllowedFound, "No interesting test cases actually executed.");
            });
        }
        public void SelectOperationThrowsWithMatchDifferingByTrailingSlash()
        {
            HttpOperationAssert.Execute <UriTemplateService>(
                (operations) =>
            {
                Uri baseAddress = new Uri("http://localhost/baseAddress");
                UriAndMethodOperationSelector selector = new UriAndMethodOperationSelector(baseAddress, operations, TrailingSlashMode.AutoRedirect);

                foreach (HttpOperationDescription operation in operations)
                {
                    UriTemplate uriTemplate  = operation.GetUriTemplate();
                    HttpMethod method        = operation.GetHttpMethod();
                    string expectedOperation = operation.Name;

                    string[] uriParameters = uriTemplate.PathSegmentVariableNames
                                             .Concat(uriTemplate.QueryValueVariableNames)
                                             .ToArray();
                    Uri requestUri          = uriTemplate.BindByPosition(baseAddress, uriParameters);
                    UriBuilder uriBuilder   = new UriBuilder(requestUri);
                    uriBuilder.Path         = requestUri.AbsolutePath.EndsWith("/") ? uriBuilder.Path.TrimEnd('/') : uriBuilder.Path + "/";
                    Uri backSlashAlteredUri = uriBuilder.Uri;

                    // Because UriTemplate.BindByPosition always adds a backslash for templates "" and "/",
                    //  the original requestUri is actually the correct backSlashAlteredUri in these cases.
                    if (uriTemplate.ToString() == "" || uriTemplate.ToString() == "/")
                    {
                        Uri temp            = requestUri;
                        requestUri          = backSlashAlteredUri;
                        backSlashAlteredUri = temp;
                    }

                    HttpRequestMessage request = new HttpRequestMessage(method, backSlashAlteredUri);

                    ExceptionAssert.Throws <HttpResponseException>(
                        () => selector.SelectOperation(request),
                        (responseException) =>
                    {
                        HttpResponseMessage expectedResponse = StandardHttpResponseMessageBuilder.CreateTemporaryRedirectResponse(request, backSlashAlteredUri, requestUri);
                        HttpAssert.AreEqual(expectedResponse, responseException.Response);
                    });
                }
            });
        }