diff --git a/src/Fluent.Http/Abstractions/IFluentHttpClient.cs b/src/Fluent.Http/Abstractions/IFluentHttpClient.cs
index 50624f9..92a957d 100644
--- a/src/Fluent.Http/Abstractions/IFluentHttpClient.cs
+++ b/src/Fluent.Http/Abstractions/IFluentHttpClient.cs
@@ -53,5 +53,12 @@ IFluentHttpClient Step(
/// Executes all the steps defined in the
///
Task ExecuteAsync();
+
+ ///
+ /// 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.
+ ///
+ /// The number of steps to rewind. All of them if null is provided.
+ ///
+ IFluentHttpClient Rewind(Int32? count = null);
}
}
\ No newline at end of file
diff --git a/src/Fluent.Http/FluentHttpClient.cs b/src/Fluent.Http/FluentHttpClient.cs
index 5d17f45..489f53a 100644
--- a/src/Fluent.Http/FluentHttpClient.cs
+++ b/src/Fluent.Http/FluentHttpClient.cs
@@ -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;
@@ -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();
@@ -65,11 +67,10 @@ public IFluentHttpClient Step(
///
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
{
@@ -77,7 +78,7 @@ public async Task ExecuteAsync()
}
catch (Exception e)
{
- throw new FluentStepFailedException(counter, step.Name, e);
+ throw new FluentStepFailedException(stepSequenceNumber, step.Name, e);
}
if (step is IFluentValidationStep validationStep)
@@ -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++;
}
}
+ ///
+ public IFluentHttpClient Rewind(Int32? count = null)
+ {
+ count ??= _numberOfStepsExectued;
+ _numberOfStepsExectued -= count.Value;
+
+ if (_numberOfStepsExectued < 0)
+ {
+ _numberOfStepsExectued = 0;
+ }
+
+ return this;
+ }
}
}
\ No newline at end of file
diff --git a/tests/Fluent.Http.Tests/FluentHttpClientTests.cs b/tests/Fluent.Http.Tests/FluentHttpClientTests.cs
index 0b25410..d03b429 100644
--- a/tests/Fluent.Http.Tests/FluentHttpClientTests.cs
+++ b/tests/Fluent.Http.Tests/FluentHttpClientTests.cs
@@ -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);
+ }
}
}
\ No newline at end of file