Skip to content

Commit

Permalink
Merge pull request #51 from keenlabs/jm_HttpClient_Refactor
Browse files Browse the repository at this point in the history
Refactor HttpClient usage
  • Loading branch information
masojus authored Jun 7, 2017
2 parents 0b08716 + 2ad96ec commit ba037e0
Show file tree
Hide file tree
Showing 54 changed files with 2,000 additions and 464 deletions.
29 changes: 29 additions & 0 deletions Keen.NET.Test/DelegatingHandlerMock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;


namespace Keen.Net.Test
{
/// <summary>
/// Wraps an <see cref="IHttpMessageHandler"/> and allows for using it as a DelegatingHandler.
/// If the IHttpMessageHandler doesn't already have a default action set, we'll have it call
/// our own base SendAsync() which will forward the request down the handler chain.
/// </summary>
internal class DelegatingHandlerMock : DelegatingHandler
{
private readonly IHttpMessageHandler _handler;

internal DelegatingHandlerMock(IHttpMessageHandler handler)
{
_handler = handler;
_handler.DefaultAsync = (_handler.DefaultAsync ?? base.SendAsync);
}

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
return _handler.SendAsync(request, cancellationToken);
}
}
}
7 changes: 4 additions & 3 deletions Keen.NET.Test/EventCollectionMock.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System;
using System.Threading.Tasks;
using Keen.Core;
using Keen.Core;
using Newtonsoft.Json.Linq;
using System;
using System.Threading.Tasks;


namespace Keen.Net.Test
{
Expand Down
64 changes: 64 additions & 0 deletions Keen.NET.Test/FuncHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;


namespace Keen.Net.Test
{
/// <summary>
/// An <see cref="IHttpMessageHandler"/> that has pre/post/default message handlers functors,
/// as well as a Func<> that produces the actual HttpResponseMessage. These can all be set by
/// test code and will be called if available. There are defaults in place that essentially do
/// nothing, but client code should make sure DefaultAsync gets set, either by a wrapper or
/// explicitly.
/// </summary>
internal class FuncHandler : IHttpMessageHandler
{
internal Action<HttpRequestMessage, CancellationToken> PreProcess = (request, ct) => { };

internal Func<HttpRequestMessage,
CancellationToken,
Task<HttpResponseMessage>> ProduceResultAsync =
(request, ct) => Task.FromResult<HttpResponseMessage>(null);

internal Func<HttpRequestMessage,
HttpResponseMessage,
HttpResponseMessage> PostProcess = (request, response) => response;

internal bool DeferToDefault { get; set; } = true;

public Func<HttpRequestMessage,
CancellationToken,
Task<HttpResponseMessage>> DefaultAsync { get; set; }


public async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
PreProcess(request, cancellationToken);
HttpResponseMessage response =
await ProduceResultAsync(request, cancellationToken).ConfigureAwait(false);

// Pass it along down the line if we didn't create a result already.
if (null == response)
{
if (DeferToDefault)
{
response = await DefaultAsync(request, cancellationToken).ConfigureAwait(false);
}
else
{
// Create a dummy successful response so HttpClient doesn't just throw always.
response = await HttpTests.CreateJsonStringResponseAsync(new { dummy = "" })
.ConfigureAwait(false);
}
}

PostProcess(request, response);

return response;
}
}
}
60 changes: 31 additions & 29 deletions Keen.NET.Test/FunnelTest.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Keen.Core;
using Keen.Core;
using Keen.Core.Query;
using Moq;
using NUnit.Framework;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;


namespace Keen.Net.Test
{
Expand Down Expand Up @@ -52,6 +53,7 @@ public override void Setup()
public async Task Funnel_Simple_Success()
{
var client = new KeenClient(SettingsEnv);
var timeframe = QueryRelativeTimeframe.ThisHour();

IEnumerable<FunnelStep> funnelsteps = new List<FunnelStep>
{
Expand Down Expand Up @@ -83,22 +85,21 @@ public async Task Funnel_Simple_Success()
Result = new[] { 3, 2 }
};


Mock<IQueries> queryMock = null;
if (UseMocks)
{
queryMock = new Mock<IQueries>();
queryMock.Setup(m => m.Funnel(
It.Is<IEnumerable<FunnelStep>>(f => f.Equals(funnelsteps)),
It.Is<QueryTimeframe>(t => t == null),
It.Is<QueryTimeframe>(t => t == timeframe),
It.Is<string>(t => t == "")
))
.Returns(Task.FromResult(expected));

client.Queries = queryMock.Object;
}

var reply = (await client.QueryFunnelAsync(funnelsteps));
var reply = (await client.QueryFunnelAsync(funnelsteps, timeframe));
Assert.NotNull(reply);
Assert.NotNull(reply.Result);
Assert.NotNull(reply.Steps);
Expand All @@ -112,6 +113,7 @@ public async Task Funnel_Simple_Success()
public async Task Funnel_Inverted_Success()
{
var client = new KeenClient(SettingsEnv);
var timeframe = QueryRelativeTimeframe.ThisHour();

IEnumerable<FunnelStep> funnelsteps = new List<FunnelStep>
{
Expand Down Expand Up @@ -144,22 +146,21 @@ public async Task Funnel_Inverted_Success()
Result = new [] { 3, 1 }
};


Mock<IQueries> queryMock = null;
if (UseMocks)
{
queryMock = new Mock<IQueries>();
queryMock.Setup(m => m.Funnel(
It.Is<IEnumerable<FunnelStep>>(f => f.Equals(funnelsteps)),
It.Is<QueryTimeframe>(t => t == null),
It.Is<QueryTimeframe>(t => t == timeframe),
It.Is<string>(t => t == "")
))
.Returns(Task.FromResult(expected));

client.Queries = queryMock.Object;
}

var reply = (await client.QueryFunnelAsync(funnelsteps));
var reply = (await client.QueryFunnelAsync(funnelsteps, timeframe));
Assert.NotNull(reply);
Assert.NotNull(reply.Result);
Assert.True(reply.Result.SequenceEqual(expected.Result));
Expand All @@ -174,6 +175,7 @@ public async Task Funnel_Inverted_Success()
public async Task Funnel_Optional_Success()
{
var client = new KeenClient(SettingsEnv);
var timeframe = QueryRelativeTimeframe.ThisHour();

IEnumerable<FunnelStep> funnelsteps = new []
{
Expand Down Expand Up @@ -215,22 +217,21 @@ public async Task Funnel_Optional_Success()
Result = new [] { 3, 2, 1 }
};


Mock<IQueries> queryMock = null;
if (UseMocks)
{
queryMock = new Mock<IQueries>();
queryMock.Setup(m => m.Funnel(
It.Is<IEnumerable<FunnelStep>>(f => f.Equals(funnelsteps)),
It.Is<QueryTimeframe>(t => t == null),
It.Is<QueryTimeframe>(t => t == timeframe),
It.Is<string>(t => t == "")
))
.Returns(Task.FromResult(expected));

client.Queries = queryMock.Object;
}

var reply = (await client.QueryFunnelAsync(funnelsteps));
var reply = (await client.QueryFunnelAsync(funnelsteps, timeframe));
Assert.NotNull(reply);
Assert.NotNull(reply.Result);
Assert.True(reply.Result.SequenceEqual(expected.Result));
Expand All @@ -245,6 +246,7 @@ public async Task Funnel_Optional_Success()
public async Task Funnel_ValidFilter_Success()
{
var client = new KeenClient(SettingsEnv);
var timeframe = QueryRelativeTimeframe.ThisHour();
var filters = new List<QueryFilter> { new QueryFilter("id", QueryFilter.FilterOperator.GreaterThanOrEqual(), 0) };

IEnumerable<FunnelStep> funnelsteps = new []
Expand Down Expand Up @@ -279,22 +281,21 @@ public async Task Funnel_ValidFilter_Success()
Result = new [] { 3, 2 }
};


Mock<IQueries> queryMock = null;
if (UseMocks)
{
queryMock = new Mock<IQueries>();
queryMock.Setup(m => m.Funnel(
It.Is<IEnumerable<FunnelStep>>(f => f.Equals(funnelsteps)),
It.Is<QueryTimeframe>(t => t == null),
It.Is<QueryTimeframe>(t => t == timeframe),
It.Is<string>(t => t == "")
))
.Returns(Task.FromResult(expected));

client.Queries = queryMock.Object;
}

var reply = (await client.QueryFunnelAsync(funnelsteps));
var reply = (await client.QueryFunnelAsync(funnelsteps, timeframe));
Assert.NotNull(reply);
Assert.NotNull(reply.Result);
Assert.True(reply.Result.SequenceEqual(expected.Result));
Expand All @@ -309,20 +310,21 @@ public async Task Funnel_ValidFilter_Success()
public async Task Funnel_ValidTimeframe_Success()
{
var client = new KeenClient(SettingsEnv);
var timeframe = QueryRelativeTimeframe.PreviousHour();
var timeframe = QueryRelativeTimeframe.ThisHour();

IEnumerable<FunnelStep> funnelsteps = new []
{
new FunnelStep
{
EventCollection = FunnelColA,
EventCollection = FunnelColA,
ActorProperty = "id",
Timeframe = timeframe,
Timeframe = timeframe, // Issue #50 : These are ignored.
},
new FunnelStep
{
EventCollection = FunnelColB,
ActorProperty = "id"
EventCollection = FunnelColB,
ActorProperty = "id",
Timeframe = timeframe,
},
};

Expand All @@ -332,32 +334,31 @@ public async Task Funnel_ValidTimeframe_Success()
{
new FunnelResultStep
{
EventCollection = FunnelColA,
EventCollection = FunnelColA,
},
new FunnelResultStep
{
EventCollection = FunnelColB,
EventCollection = FunnelColB,
},
},
Result = new [] { 3, 2 }
};


Mock<IQueries> queryMock = null;
if (UseMocks)
{
queryMock = new Mock<IQueries>();
queryMock.Setup(m => m.Funnel(
It.Is<IEnumerable<FunnelStep>>(f => f.Equals(funnelsteps)),
It.Is<QueryTimeframe>(t => t == null),
It.Is<QueryTimeframe>(t => t == timeframe),
It.Is<string>(t => t == "")
))
.Returns(Task.FromResult(expected));

client.Queries = queryMock.Object;
}

var reply = (await client.QueryFunnelAsync(funnelsteps));
var reply = (await client.QueryFunnelAsync(funnelsteps, timeframe));
Assert.NotNull(reply);
Assert.NotNull(reply.Result);
Assert.True(reply.Result.SequenceEqual(expected.Result));
Expand All @@ -372,6 +373,7 @@ public async Task Funnel_ValidTimeframe_Success()
public async Task Funnel_WithActors_Success()
{
var client = new KeenClient(SettingsEnv);
var timeframe = QueryRelativeTimeframe.ThisHour();

IEnumerable<FunnelStep> funnelsteps = new []
{
Expand Down Expand Up @@ -413,15 +415,15 @@ public async Task Funnel_WithActors_Success()
queryMock = new Mock<IQueries>();
queryMock.Setup(m => m.Funnel(
It.Is<IEnumerable<FunnelStep>>(f => f.Equals(funnelsteps)),
It.Is<QueryTimeframe>(t => t == null),
It.Is<QueryTimeframe>(t => t == timeframe),
It.Is<string>(t => t == "")
))
.Returns(Task.FromResult(expected));

client.Queries = queryMock.Object;
}

var reply = (await client.QueryFunnelAsync(funnelsteps));
var reply = (await client.QueryFunnelAsync(funnelsteps, timeframe));
Assert.NotNull(reply);
Assert.NotNull(reply.Actors);
Assert.AreEqual(reply.Actors.Count(), 2);
Expand Down
31 changes: 31 additions & 0 deletions Keen.NET.Test/HttpClientHandlerMock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;


namespace Keen.Net.Test
{
/// <summary>
/// Wraps an <see cref="IHttpMessageHandler"/> and allows for using it as an HttpClientHandler.
/// If the IHttpMessageHandler doesn't already have a default action set, we'll have it call
/// our own base SendAsync() which will forward the request to the actual HttpClientHandler
/// implementation, with all the configuration and proxies and such, which may actually go out
/// over the network.
/// </summary>
internal class HttpClientHandlerMock : HttpClientHandler
{
internal readonly IHttpMessageHandler _handler;

internal HttpClientHandlerMock(IHttpMessageHandler handler)
{
_handler = handler;
_handler.DefaultAsync = (_handler.DefaultAsync ?? base.SendAsync);
}

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
return _handler.SendAsync(request, cancellationToken);
}
}
}
Loading

0 comments on commit ba037e0

Please sign in to comment.