Skip to content

Commit

Permalink
Stop subsequent ExecuteAsync calls from executing previously executed…
Browse files Browse the repository at this point in the history
… steps. Add rewind method to allow ExecuteAsync to execute previously executed steps.
  • Loading branch information
Robert Bennett committed Jun 13, 2023
1 parent 86b5e69 commit 83504d9
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 8 deletions.
7 changes: 7 additions & 0 deletions src/Fluent.Http/Abstractions/IFluentHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,12 @@ IFluentHttpClient Step(
/// Executes all the steps defined in the <see cref="Steps"/>
/// </summary>
Task ExecuteAsync();

/// <summary>
/// Rewinds the number of steps provided or all of them if null is passed. This allows multiple calls to execute async to run the same steps.
/// </summary>
/// <param name="count">The number of steps to rewind. All of them if null is provided.</param>
/// <returns></returns>
IFluentHttpClient Rewind(Int32? count = null);
}
}
30 changes: 22 additions & 8 deletions src/Fluent.Http/FluentHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Fluent.Http.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

Expand All @@ -12,6 +13,7 @@ namespace Fluent.Http
public class FluentHttpClient : IFluentHttpClient
{
private readonly HttpClient _client;
private Int32 _numberOfStepsExectued = 0;

private FluentHttpClient(HttpClient? client) => _client = client ?? new HttpClient();

Expand Down Expand Up @@ -65,19 +67,18 @@ public IFluentHttpClient Step(
/// <inheritdoc/>
public async Task ExecuteAsync()
{
Int32 counter = 1;

foreach (IFluentStep step in Steps)
foreach (IFluentStep step in Steps.Skip(_numberOfStepsExectued))
{
step.SequenceNumber = counter;
Int32 stepSequenceNumber = _numberOfStepsExectued + 1;
step.SequenceNumber = stepSequenceNumber;

try
{
await step.ExecuteAsync();
}
catch (Exception e)
{
throw new FluentStepFailedException(counter, step.Name, e);
throw new FluentStepFailedException(stepSequenceNumber, step.Name, e);
}

if (step is IFluentValidationStep validationStep)
Expand All @@ -88,13 +89,26 @@ public async Task ExecuteAsync()
}
catch (Exception e)
{
throw new FluentStepValidationFailedException(counter, step.Name, e);
throw new FluentStepValidationFailedException(stepSequenceNumber, step.Name, e);
}
}

counter++;
_numberOfStepsExectued++;
}
}

/// <inheritdoc/>
public IFluentHttpClient Rewind(Int32? count = null)
{
count ??= _numberOfStepsExectued;
_numberOfStepsExectued -= count.Value;

if (_numberOfStepsExectued < 0)
{
_numberOfStepsExectued = 0;
}

return this;
}
}
}
72 changes: 72 additions & 0 deletions tests/Fluent.Http.Tests/FluentHttpClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,77 @@ await client.Step(
calledStep.Should().BeTrue();
calledPostStep.Should().BeTrue();
}

[Fact]
public async Task ExecuteAsync_MultipleCalls_DoesNotExecuteStepsTwice()
{
_handler
.When(HttpMethod.Get, "http://test.com/api/test")
.Respond(HttpStatusCode.OK);

int stepOneCallCount = 0;
int stepTwoCallCount = 0;

IFluentHttpClient client = FluentHttpClient.Build(_client);

await client.Step(
() =>
{
stepOneCallCount++;
return Task.CompletedTask;
})
.ExecuteAsync();

await client.Step(
() =>
{
stepTwoCallCount++;
return Task.CompletedTask;
})
.ExecuteAsync();

stepOneCallCount.Should().Be(1);
stepTwoCallCount.Should().Be(1);
}

[Fact]
public async Task ExecuteAsync_WithRewind_AllowsMultipleCalls()
{
_handler
.When(HttpMethod.Get, "http://test.com/api/test")
.Respond(HttpStatusCode.OK);

int stepOneCallCount = 0;
int stepTwoCallCount = 0;

IFluentHttpClient client = FluentHttpClient.Build(_client);

await client.Step(
() =>
{
stepOneCallCount++;
return Task.CompletedTask;
})
.ExecuteAsync();

await client.Step(
() =>
{
stepTwoCallCount++;
return Task.CompletedTask;
})
.ExecuteAsync();

await client
.Rewind(1)
.ExecuteAsync();

await client
.Rewind()
.ExecuteAsync();

stepOneCallCount.Should().Be(2);
stepTwoCallCount.Should().Be(3);
}
}
}

0 comments on commit 83504d9

Please sign in to comment.