diff --git a/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs b/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs index 0c84f53ef..cb72241c0 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 99fff5a18..8fba4ab0b 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 fef92cbc0..c62baa896 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 Mapping 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 5832ededc..a67e6b70d 100644 --- a/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs +++ b/src/WireMock.Net.Minimal/Owin/WireMockMiddleware.cs @@ -299,7 +299,7 @@ private void UpdateScenarioState(IMapping mapping) 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 71f29e5c7..22bc92118 100644 --- a/src/WireMock.Net.Minimal/Serialization/MappingConverter.cs +++ b/src/WireMock.Net.Minimal/Serialization/MappingConverter.cs @@ -267,6 +267,7 @@ public MappingModel ToMappingModel(IMapping mapping) 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 15b85941f..50d8c4e69 100644 --- a/src/WireMock.Net.Minimal/Server/WireMockServer.ConvertMapping.cs +++ b/src/WireMock.Net.Minimal/Server/WireMockServer.ConvertMapping.cs @@ -97,7 +97,7 @@ private Guid ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingMode 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 018343e87..26e0ecb45 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 acbcffa44..010898356 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 d6d622514..fc2bb7741 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 559f4f259..4c0d6c6c3 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 751468fd5..5e445d07f 100644 --- a/test/WireMock.Net.Tests/MappingBuilderTests.cs +++ b/test/WireMock.Net.Tests/MappingBuilderTests.cs @@ -34,6 +34,7 @@ static 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 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 void SaveMappingsToFolder_FolderIsNull() _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 void SaveMappingsToFolder_FolderExists_IsTrue() // 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(); } }