8000 Removes repetition from method attributes and fixes failing specs by alexandru-calinoiu · Pull Request #40 · reactiveui/refit · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Removes repetition from method attributes and fixes failing specs #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 62 additions & 11 deletions Refit-Tests/RequestBuilder.cs
8000
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,9 @@
using System.Net.Http;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Net;
using NUnit.Framework;
using System.Text;
using Newtonsoft.Json;
using System.IO;
using System.Web;
using System.Threading;

namespace Refit.Tests
Expand All @@ -19,7 +14,7 @@ public interface IRestMethodInfoTests
{
[Get("@)!@_!($_!@($\\\\|||::::")]
Task<string> GarbagePath();

[Get("/foo/bar/{id}")]
Task<string> FetchSomeStuffMissingParameters();

Expand All @@ -34,7 +29,7 @@ public interface IRestMethodInfoTests

[Get("/foo/bar/{id}")]
Task<string> FetchSomeStuffWithAlias([AliasAs("id")] int anId);

[Get("/foo/bar/{id}")]
IObservable<string> FetchSomeStuffWithBody([AliasAs("id")] int anId, [Body] Dictionary<int, string> theData);

Expand Down Expand Up @@ -218,17 +213,34 @@ public interface IDummyHttpApi
[Get("/foo/bar/{id}")]
[Headers("Api-Version: ")]
Task<string> FetchSomeStuffWithEmptyHardcodedHeader(int id);

[Get("/foo/bar/{id}")]
[Headers("Authorization: SRSLY aHR0cDovL2kuaW1ndXIuY29tL0NGRzJaLmdpZg==")]
Task<string> FetchSomeStuffWithDynamicHeader(int id, [Header("Authorization")] string authorization);

[Get("/foo/bar/{id}")]
Task<string> FetchSomeStuffWithCustomHeader(int id, [Header("X-Emoji")] string custom);

[Get("/string")]
Task<string> FetchSomeStuffWithoutFullPath();

[Get("/void")]
Task FetchSomeStuffWithVoid();

string SomeOtherMethod();
}

public class TestHttpMessageHandler : HttpMessageHandler
{
public HttpRequestMessage RequestMessage { get; private set; }

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
RequestMessage = request;
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("test") });
}
}

[TestFixture]
public class RequestBuilderTests
{
Expand Down Expand Up @@ -281,7 +293,7 @@ public void HardcodedQueryParamShouldBeInUrl()
var uri = new Uri(new Uri("http://api"), output.RequestUri);
Assert.AreEqual("/foo/bar/6?baz=bamf", uri.PathAndQuery);
}

[Test]
public void ParameterizedQueryParamsShouldBeInUrl()
{
Expand Down Expand Up @@ -342,7 +354,7 @@ public void DynamicHeaderShouldBeInHeaders()
}

[Test]
public void CustomDynamicHeaderShouldBeInHeaders()
public void CustomDynamicHeaderShouldBeInHeaders()
{
var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi));
var factory = fixture.BuildRequestFactoryForMethod("FetchSomeStuffWithCustomHeader");
Expand Down Expand Up @@ -372,5 +384,44 @@ public void NullDynamicHeaderShouldNotBeInHeaders()

Assert.IsNull(output.Headers.Authorization, "Headers include Authorization header");
}

[Test]
public void HttpClientShouldPrefixedAbsolutePathToTheRequestUri()
{
var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi));
var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithoutFullPath");
var testHttpMessageHandler = new TestHttpMessageHandler();

var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, new object[0]);
task.Wait();

Assert.AreEqual("http://api/foo/bar/string", testHttpMessageHandler.RequestMessage.RequestUri.ToString());
}

[Test]
public void HttpClientForVoidMethodShouldPrefixedAbsolutePathToTheRequestUri()
{
var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi));
var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuffWithVoid");
var testHttpMessageHandler = new TestHttpMessageHandler();

var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/foo/bar") }, new object[0]);
task.Wait();

Assert.AreEqual("http://api/foo/bar/void", testHttpMessageHandler.RequestMessage.RequestUri.ToString());
}

[Test]
public void HttpClientShouldNotPrefixEmptyAbsolutePathToTheRequestUri()
{
var fixture = new RequestBuilderImplementation(typeof(IDummyHttpApi));
var factory = fixture.BuildRestResultFuncForMethod("FetchSomeStuff");
var testHttpMessageHandler = new TestHttpMessageHandler();

var task = (Task)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { 42 });
task.Wait();

Assert.AreEqual("http://api/foo/bar/42", testHttpMessageHandler.RequestMessage.RequestUri.ToString());
}
}
}
54 changes: 46 additions & 8 deletions Refit-Tests/RestService.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Linq;
using Castle.DynamicProxy;
using NUnit.Framework;
using System.Threading.Tasks;
using System.Threading;

namespace Refit.Tests
{
Expand Down Expand Up @@ -52,11 +48,25 @@ public interface IGitHubApi
Task<HttpResponseMessage> GetIndex();
}

public class RootObject
{
public string _id { get; set; }
public string _rev { get; set; }
public string name { get; set; }
}

[Headers("User-Agent: Refit Integration Tests")]
public interface INpmJs
{
[Get("/congruence")]
Task<RootObject> GetCongruence();
}

[TestFixture]
public class RestServiceIntegrationTests
{
[Test]
public void HitTheGitHubUserAPI()
public void HitTheGitHubUserApi()
{
var fixture = RestService.For<IGitHubApi>("https://api.github.com");
var result = fixture.GetUser("octocat");
Expand All @@ -66,7 +76,7 @@ public void HitTheGitHubUserAPI()
}

[Test]
public void ShouldRetHttpResponseMessage()
public void ShouldRetHttpResponseMessage()
{
var fixture = RestService.For<IGitHubApi>("https://api.github.com");
var result = fixture.GetIndex();
Expand All @@ -76,16 +86,44 @@ public void ShouldRetHttpResponseMessage()
Assert.IsTrue(result.Result.IsSuccessStatusCode);
}

[Test]
public void HitTheNpmJs()
{
var fixture = RestService.For<INpmJs>("https://registry.npmjs.us/public");
var result = fixture.GetCongruence();

result.Wait();
Assert.AreEqual("congruence", result.Result._id);
}

[Test]
public void PostToRequestBin()
{
var fixture = RestService.For<IRequestBin>("http://requestb.in/");
var result = fixture.Post();

result.Wait();
try
{
result.Wait();
}
catch (AggregateException ae)
{
ae.Handle(
x =>
{
if (x is HttpRequestException)
{
// we should be good but maybe a 404 occurred
return true;
}

// other exception types might be valid failures
return false;
});
}
}

interface IRequestBin
public interface IRequestBin
{
[Post("/1h3a5jm1")]
Task Post();
Expand Down
2 changes: 1 addition & 1 deletion Refit/RequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Refit
public interface IRequestBuilder
{
IEnumerable<string> InterfaceHttpMethods { get; }
Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(string methodName);
Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(string methodName, string basePath = "");
Func<HttpClient, object[], object> BuildRestResultFuncForMethod(string methodName);
}

Expand Down
12 changes: 5 additions & 7 deletions Refit/RequestBuilderImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public IEnumerable<string> InterfaceHttpMethods {
get { return interfaceHttpMethods.Keys; }
}

public Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(string methodName)
public Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(string methodName, string basePath = "")
{
if (!interfaceHttpMethods.ContainsKey(methodName)) {
throw new ArgumentException("Method must be defined and have an HTTP Method attribute");
Expand All @@ -64,7 +64,7 @@ public Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(string me
setHeader(ret, header.Key, header.Value);
}

var urlTarget = new StringBuilder(restMethod.RelativePath);
var urlTarget = new StringBuilder(basePath == "/" ? String.Empty : basePath).Append(restMethod.RelativePath);
var queryParamsToAdd = new Dictionary<string, string>();

for(int i=0; i < paramList.Length; i++) {
Expand Down Expand Up @@ -174,10 +174,9 @@ public Func<HttpClient, object[], object> BuildRestResultFuncForMethod(string me
}

Func<HttpClient, object[], Task> buildVoidTaskFuncForMethod(RestMethodInfo restMethod)
{
var factory = BuildRequestFactoryForMethod(restMethod.Name);

{
return async (client, paramList) => {
var factory = BuildRequestFactoryForMethod(restMethod.Name, client.BaseAddress.AbsolutePath);
var rq = factory(paramList);
var resp = await client.SendAsync(rq);

Expand All @@ -188,9 +187,8 @@ Func<HttpClient, object[], Task> buildVoidTaskFuncForMethod(RestMethodInfo restM
Func<HttpClient, object[], Task<T>> buildTaskFuncForMethod<T>(RestMethodInfo restMethod)
where T 5492 : class
{
var factory = BuildRequestFactoryForMethod(restMethod.Name);

return async (client, paramList) => {
var factory = BuildRequestFactoryForMethod(restMethod.Name, client.BaseAddress.AbsolutePath);
var rq = factory(paramList);
var resp = await client.SendAsync(rq);
if (restMethod.SerializedReturnType == typeof(HttpResponseMessage)) {
Expand Down
0