diff --git a/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs b/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
index 0c84f53e..cb72241c 100644
--- a/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
+++ b/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
@@ -56,6 +56,11 @@ public class MappingModel
/// In case the value is null state will not be changed.
///
public string? SetStateTo { get; set; }
+
+ ///
+ /// The number of times this match should be matched before the state will be changed to the specified one.
+ ///
+ public int? TimesInSameState { get; set; }
///
/// The request model.
@@ -86,7 +91,7 @@ public class MappingModel
/// Fire and forget for webhooks.
///
public bool? UseWebhooksFireAndForget { get; set; }
-
+
///
/// Data Object which can be used when WithTransformer is used.
/// e.g. lookup a path in this object using
diff --git a/src/WireMock.Net.Minimal/IMapping.cs b/src/WireMock.Net.Minimal/IMapping.cs
index 99fff5a1..8fba4ab0 100644
--- a/src/WireMock.Net.Minimal/IMapping.cs
+++ b/src/WireMock.Net.Minimal/IMapping.cs
@@ -68,7 +68,7 @@ public interface IMapping
///
/// The number of times this match should be matched before the state will be changed to the next state.
///
- int? StateTimes { get; }
+ int? TimesInSameState { get; }
///
/// The RequestMatcher.
diff --git a/src/WireMock.Net.Minimal/Mapping.cs b/src/WireMock.Net.Minimal/Mapping.cs
index fef92cbc..c62baa89 100644
--- a/src/WireMock.Net.Minimal/Mapping.cs
+++ b/src/WireMock.Net.Minimal/Mapping.cs
@@ -43,7 +43,7 @@ public class Mapping : IMapping
public string? NextState { get; }
///
- public int? StateTimes { get; }
+ public int? TimesInSameState { get; }
///
public IRequestMatcher RequestMatcher { get; }
@@ -137,7 +137,7 @@ public class Mapping : IMapping
Scenario = scenario;
ExecutionConditionState = executionConditionState;
NextState = nextState;
- StateTimes = stateTimes;
+ TimesInSameState = stateTimes;
Webhooks = webhooks;
UseWebhooksFireAndForget = useWebhooksFireAndForget;
TimeSettings = timeSettings;
diff --git a/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs b/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs
index 5832eded..a67e6b70 100644
--- a/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs
+++ b/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs
@@ -299,7 +299,7 @@ namespace WireMock.Owin
scenario.Counter++;
// Only if the number of times this state is executed equals the required StateTimes, proceed to next state and reset the counter to 0
- if (scenario.Counter == (mapping.StateTimes ?? 1))
+ if (scenario.Counter == (mapping.TimesInSameState ?? 1))
{
scenario.NextState = mapping.NextState;
scenario.Counter = 0;
diff --git a/src/WireMock.Net.Minimal/Serialization/MappingConverter.cs b/src/WireMock.Net.Minimal/Serialization/MappingConverter.cs
index 71f29e5c..22bc9211 100644
--- a/src/WireMock.Net.Minimal/Serialization/MappingConverter.cs
+++ b/src/WireMock.Net.Minimal/Serialization/MappingConverter.cs
@@ -267,6 +267,7 @@ internal class MappingConverter(MatcherMapper mapper)
Scenario = mapping.Scenario,
WhenStateIs = mapping.ExecutionConditionState,
SetStateTo = mapping.NextState,
+ TimesInSameState = !string.IsNullOrWhiteSpace(mapping.NextState) ? mapping.TimesInSameState : null,
Data = mapping.Data,
Probability = mapping.Probability,
Request = new RequestModel
diff --git a/src/WireMock.Net.Minimal/Server/WireMockServer.ConvertMapping.cs b/src/WireMock.Net.Minimal/Server/WireMockServer.ConvertMapping.cs
index 15b85941..50d8c4e6 100644
--- a/src/WireMock.Net.Minimal/Server/WireMockServer.ConvertMapping.cs
+++ b/src/WireMock.Net.Minimal/Server/WireMockServer.ConvertMapping.cs
@@ -97,7 +97,7 @@ public partial class WireMockServer
if (!string.IsNullOrEmpty(mappingModel.SetStateTo))
{
- respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo!);
+ respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo!, mappingModel.TimesInSameState);
}
}
diff --git a/test/WireMock.Net.Tests/MappingBuilderTests.GetMappings.verified.txt b/test/WireMock.Net.Tests/MappingBuilderTests.GetMappings.verified.txt
index 018343e8..26e0ecb4 100644
--- a/test/WireMock.Net.Tests/MappingBuilderTests.GetMappings.verified.txt
+++ b/test/WireMock.Net.Tests/MappingBuilderTests.GetMappings.verified.txt
@@ -165,5 +165,30 @@
]
},
Response: {}
+ },
+ {
+ Guid: 98fae52e-76df-47d9-876f-2ee32e931005,
+ UpdatedAt: 2023-01-14 15:16:17,
+ Scenario: To do list,
+ SetStateTo: TodoList State Started,
+ TimesInSameState: 2,
+ Request: {
+ Path: {
+ Matchers: [
+ {
+ Name: WildcardMatcher,
+ Pattern: /todo/items,
+ IgnoreCase: false
+ }
+ ]
+ },
+ Methods: [
+ GET
+ ]
+ },
+ Response: {
+ BodyDestination: SameAsSource,
+ Body: Buy milk
+ }
}
]
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Builder.verified.txt b/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Builder.verified.txt
index acbcffa4..01089835 100644
--- a/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Builder.verified.txt
+++ b/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Builder.verified.txt
@@ -66,3 +66,13 @@ builder
.RespondWith(Response.Create()
);
+builder
+ .Given(Request.Create()
+ .UsingMethod("GET")
+ .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/todo/items", false, WireMock.Matchers.MatchOperator.Or))
+ )
+ .WithGuid("98fae52e-76df-47d9-876f-2ee32e931005")
+ .RespondWith(Response.Create()
+ .WithBody("Buy milk")
+ );
+
diff --git a/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Server.verified.txt b/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Server.verified.txt
index d6d62251..fc2bb774 100644
--- a/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Server.verified.txt
+++ b/test/WireMock.Net.Tests/MappingBuilderTests.ToCSharpCode_Server.verified.txt
@@ -66,3 +66,13 @@ server
.RespondWith(Response.Create()
);
+server
+ .Given(Request.Create()
+ .UsingMethod("GET")
+ .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/todo/items", false, WireMock.Matchers.MatchOperator.Or))
+ )
+ .WithGuid("98fae52e-76df-47d9-876f-2ee32e931005")
+ .RespondWith(Response.Create()
+ .WithBody("Buy milk")
+ );
+
diff --git a/test/WireMock.Net.Tests/MappingBuilderTests.ToJson.verified.txt b/test/WireMock.Net.Tests/MappingBuilderTests.ToJson.verified.txt
index 559f4f25..4c0d6c6c 100644
--- a/test/WireMock.Net.Tests/MappingBuilderTests.ToJson.verified.txt
+++ b/test/WireMock.Net.Tests/MappingBuilderTests.ToJson.verified.txt
@@ -161,5 +161,30 @@
}
]
}
+ },
+ {
+ Guid: 98fae52e-76df-47d9-876f-2ee32e931005,
+ UpdatedAt: 2023-01-14T15:16:17,
+ Scenario: To do list,
+ SetStateTo: TodoList State Started,
+ TimesInSameState: 2,
+ Request: {
+ Path: {
+ Matchers: [
+ {
+ Name: WildcardMatcher,
+ Pattern: /todo/items,
+ IgnoreCase: false
+ }
+ ]
+ },
+ Methods: [
+ GET
+ ]
+ },
+ Response: {
+ BodyDestination: SameAsSource,
+ Body: Buy milk
+ }
}
]
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/MappingBuilderTests.cs b/test/WireMock.Net.Tests/MappingBuilderTests.cs
index 751468fd..5e445d07 100644
--- a/test/WireMock.Net.Tests/MappingBuilderTests.cs
+++ b/test/WireMock.Net.Tests/MappingBuilderTests.cs
@@ -34,6 +34,7 @@ public class MappingBuilderTests
private static readonly DateTime UtcNow = new(2023, 1, 14, 15, 16, 17);
private readonly Mock _fileSystemHandlerMock;
+ private readonly int _numMappings;
private readonly MappingBuilder _sut;
@@ -104,11 +105,20 @@ public class MappingBuilderTests
).RespondWith(Response.Create());
_sut.Given(Request.Create()
- .WithPath("/regex")
- .WithParam("foo", new RegexMatcher(".*"))
- .UsingGet()
- )
- .RespondWith(Response.Create());
+ .WithPath("/regex")
+ .WithParam("foo", new RegexMatcher(".*"))
+ .UsingGet()
+ ).RespondWith(Response.Create());
+
+ _sut.Given(Request.Create()
+ .WithPath("/todo/items")
+ .UsingGet())
+ .InScenario("To do list")
+ .WillSetStateTo("TodoList State Started", 2)
+ .RespondWith(Response.Create()
+ .WithBody("Buy milk"));
+
+ _numMappings = _sut.GetMappings().Length;
}
[Fact]
@@ -197,9 +207,9 @@ public class MappingBuilderTests
_sut.SaveMappingsToFolder(null);
// Verify
- _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(5));
- _fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(5));
- _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny(), It.IsAny()), Times.Exactly(5));
+ _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(_numMappings));
+ _fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(_numMappings));
+ _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny(), It.IsAny()), Times.Exactly(_numMappings));
_fileSystemHandlerMock.VerifyNoOtherCalls();
}
@@ -215,8 +225,8 @@ public class MappingBuilderTests
// Verify
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never);
- _fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(5));
- _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny(), It.IsAny()), Times.Exactly(5));
+ _fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(_numMappings));
+ _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny(), It.IsAny()), Times.Exactly(_numMappings));
_fileSystemHandlerMock.VerifyNoOtherCalls();
}
}