diff --git a/examples/WireMock.Net.Client/Program.cs b/examples/WireMock.Net.Client/Program.cs
index 84c77fa2..560195f0 100644
--- a/examples/WireMock.Net.Client/Program.cs
+++ b/examples/WireMock.Net.Client/Program.cs
@@ -43,11 +43,14 @@ namespace WireMock.Net.Client
var request = api.GetRequestsAsync().Result;
Console.WriteLine($"request = {JsonConvert.SerializeObject(request)}");
- var deleteRequestsAsync = api.DeleteRequestsAsync().Result;
- Console.WriteLine($"deleteRequestsAsync = {deleteRequestsAsync.Status}");
+ //var deleteRequestsAsync = api.DeleteRequestsAsync().Result;
+ //Console.WriteLine($"DeleteRequestsAsync = {deleteRequestsAsync.Status}");
- var resetRequestsAsync = api.ResetRequestsAsync().Result;
- Console.WriteLine($"resetRequestsAsync = {resetRequestsAsync.Status}");
+ //var resetRequestsAsync = api.ResetRequestsAsync().Result;
+ //Console.WriteLine($"ResetRequestsAsync = {resetRequestsAsync.Status}");
+
+ var scenarioStates = api.GetScenariosAsync().Result;
+ Console.WriteLine($"GetScenariosAsync = {JsonConvert.SerializeObject(scenarioStates)}");
Console.WriteLine("Press any key to quit");
Console.ReadKey();
diff --git a/src/WireMock.Net/Admin/Mappings/MappingModel.cs b/src/WireMock.Net/Admin/Mappings/MappingModel.cs
index 200b5297..2e005729 100644
--- a/src/WireMock.Net/Admin/Mappings/MappingModel.cs
+++ b/src/WireMock.Net/Admin/Mappings/MappingModel.cs
@@ -30,13 +30,13 @@ namespace WireMock.Admin.Mappings
///
/// Execution state condition for the current mapping.
///
- public object WhenStateIs { get; set; }
+ public string WhenStateIs { get; set; }
///
/// The next state which will be signaled after the current mapping execution.
/// In case the value is null state will not be changed.
///
- public object SetStateTo { get; set; }
+ public string SetStateTo { get; set; }
///
/// The request.
diff --git a/src/WireMock.Net/Admin/Scenarios/ScenarioStateModel.cs b/src/WireMock.Net/Admin/Scenarios/ScenarioStateModel.cs
new file mode 100644
index 00000000..a6b1fa9e
--- /dev/null
+++ b/src/WireMock.Net/Admin/Scenarios/ScenarioStateModel.cs
@@ -0,0 +1,28 @@
+namespace WireMock.Admin.Scenarios
+{
+ ///
+ /// ScenarioStateModel
+ ///
+ public class ScenarioStateModel
+ {
+ ///
+ /// Gets or sets the name.
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the NextState.
+ ///
+ public string NextState { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this is started.
+ ///
+ public bool Started { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this is finished.
+ ///
+ public bool Finished { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/Client/IFluentMockServerAdmin.cs b/src/WireMock.Net/Client/IFluentMockServerAdmin.cs
index c1539ea9..e7acb7d9 100644
--- a/src/WireMock.Net/Client/IFluentMockServerAdmin.cs
+++ b/src/WireMock.Net/Client/IFluentMockServerAdmin.cs
@@ -145,7 +145,7 @@ namespace WireMock.Client
/// Get all scenarios
///
[Get("__admin/scenarios")]
- Task GetScenariosAsync();
+ Task> GetScenariosAsync();
///
/// Delete (reset) all scenarios
diff --git a/src/WireMock.Net/Mapping.cs b/src/WireMock.Net/Mapping.cs
index 8eb56d73..31e40de9 100644
--- a/src/WireMock.Net/Mapping.cs
+++ b/src/WireMock.Net/Mapping.cs
@@ -41,14 +41,14 @@ namespace WireMock
/// Execution state condition for the current mapping.
///
[CanBeNull]
- public object ExecutionConditionState { get; }
+ public string ExecutionConditionState { get; }
///
/// The next state which will be signaled after the current mapping execution.
- /// In case the value is null state will not be changed.
+ /// In case the value is null, state will not be changed.
///
[CanBeNull]
- public object NextState { get; }
+ public string NextState { get; }
///
/// The Request matcher.
@@ -77,7 +77,7 @@ namespace WireMock
/// The scenario. [Optional]
/// State in which the current mapping can occur. [Optional]
/// The next state which will occur after the current mapping execution. [Optional]
- public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path, IRequestMatcher requestMatcher, IResponseProvider provider, int priority, [CanBeNull] string scenario, [CanBeNull] object executionConditionState, [CanBeNull] object nextState)
+ public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path, IRequestMatcher requestMatcher, IResponseProvider provider, int priority, [CanBeNull] string scenario, [CanBeNull] string executionConditionState, [CanBeNull] string nextState)
{
Guid = guid;
Title = title;
@@ -106,7 +106,7 @@ namespace WireMock
/// The request message.
/// The Next State.
/// The .
- public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, [CanBeNull] object nextState)
+ public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, [CanBeNull] string nextState)
{
var result = new RequestMatchResult();
diff --git a/src/WireMock.Net/Matchers/Request/RequestMessageScenarioAndStateMatcher.cs b/src/WireMock.Net/Matchers/Request/RequestMessageScenarioAndStateMatcher.cs
index 8bb0aeb7..f4ffde5d 100644
--- a/src/WireMock.Net/Matchers/Request/RequestMessageScenarioAndStateMatcher.cs
+++ b/src/WireMock.Net/Matchers/Request/RequestMessageScenarioAndStateMatcher.cs
@@ -11,21 +11,21 @@ namespace WireMock.Matchers.Request
/// Execution state condition for the current mapping.
///
[CanBeNull]
- private readonly object _executionConditionState;
+ private readonly string _executionConditionState;
///
/// The next state which will be signaled after the current mapping execution.
/// In case the value is null state will not be changed.
///
[CanBeNull]
- private readonly object _nextState;
+ private readonly string _nextState;
///
/// Initializes a new instance of the class.
///
/// The next state.
/// Execution state condition for the current mapping.
- public RequestMessageScenarioAndStateMatcher([CanBeNull] object nextState, [CanBeNull] object executionConditionState)
+ public RequestMessageScenarioAndStateMatcher([CanBeNull] string nextState, [CanBeNull] string executionConditionState)
{
_nextState = nextState;
_executionConditionState = executionConditionState;
diff --git a/src/WireMock.Net/Owin/WireMockMiddleware.cs b/src/WireMock.Net/Owin/WireMockMiddleware.cs
index 67c85189..d7575c32 100644
--- a/src/WireMock.Net/Owin/WireMockMiddleware.cs
+++ b/src/WireMock.Net/Owin/WireMockMiddleware.cs
@@ -60,7 +60,10 @@ namespace WireMock.Owin
// Set start
if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
{
- _options.Scenarios.TryAdd(mapping.Scenario, null);
+ _options.Scenarios.TryAdd(mapping.Scenario, new ScenarioState
+ {
+ Name = mapping.Scenario
+ });
}
}
@@ -68,7 +71,7 @@ namespace WireMock.Owin
.Select(m => new
{
Mapping = m,
- MatchResult = m.GetRequestMatchResult(request, m.Scenario != null && _options.Scenarios.ContainsKey(m.Scenario) ? _options.Scenarios[m.Scenario] : null)
+ MatchResult = m.GetRequestMatchResult(request, m.Scenario != null && _options.Scenarios.ContainsKey(m.Scenario) ? _options.Scenarios[m.Scenario].NextState : null)
})
.ToList();
@@ -125,7 +128,9 @@ namespace WireMock.Owin
if (targetMapping.Scenario != null)
{
- _options.Scenarios[targetMapping.Scenario] = targetMapping.NextState;
+ _options.Scenarios[targetMapping.Scenario].NextState = targetMapping.NextState;
+ _options.Scenarios[targetMapping.Scenario].Started = true;
+ _options.Scenarios[targetMapping.Scenario].Finished = targetMapping.NextState == null;
}
}
catch (Exception ex)
diff --git a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
index 694ec065..2111e7e8 100644
--- a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
+++ b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
@@ -22,9 +22,9 @@ namespace WireMock.Owin
public bool AllowPartialMapping { get; set; }
- public ConcurrentDictionary Mappings { get; } = new ConcurrentDictionary(); // Checked
+ public ConcurrentDictionary Mappings { get; } = new ConcurrentDictionary();
- public ConcurrentDictionary Scenarios { get; } = new ConcurrentDictionary(); // Checked
+ public ConcurrentDictionary Scenarios { get; } = new ConcurrentDictionary();
public ObservableCollection LogEntries { get; } = new ConcurentObservableCollection();
diff --git a/src/WireMock.Net/ScenarioState.cs b/src/WireMock.Net/ScenarioState.cs
new file mode 100644
index 00000000..8a28da93
--- /dev/null
+++ b/src/WireMock.Net/ScenarioState.cs
@@ -0,0 +1,28 @@
+namespace WireMock
+{
+ ///
+ /// The ScenarioState
+ ///
+ public class ScenarioState
+ {
+ ///
+ /// Gets or sets the Name (from the Scenario).
+ ///
+ public string Name { get; set; }
+
+ ///
+ /// Gets or sets the NextState.
+ ///
+ public string NextState { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this is started.
+ ///
+ public bool Started { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether this is finished.
+ ///
+ public bool Finished { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/Serialization/MappingConverter.cs b/src/WireMock.Net/Serialization/MappingConverter.cs
index 92069cc7..c5a11fa9 100644
--- a/src/WireMock.Net/Serialization/MappingConverter.cs
+++ b/src/WireMock.Net/Serialization/MappingConverter.cs
@@ -37,19 +37,16 @@ namespace WireMock.Serialization
ClientIP = clientIPMatchers != null && clientIPMatchers.Any() ? new ClientIPModel
{
Matchers = MatcherMapper.Map(clientIPMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
- //Funcs = Map(clientIPMatchers.Where(m => m.Funcs != null).SelectMany(m => m.Funcs))
} : null,
Path = pathMatchers != null && pathMatchers.Any() ? new PathModel
{
Matchers = MatcherMapper.Map(pathMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
- //Funcs = Map(pathMatchers.Where(m => m.Funcs != null).SelectMany(m => m.Funcs))
} : null,
Url = urlMatchers != null && urlMatchers.Any() ? new UrlModel
{
Matchers = MatcherMapper.Map(urlMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers))
- //Funcs = Map(urlMatchers.Where(m => m.Funcs != null).SelectMany(m => m.Funcs))
} : null,
Methods = methodMatcher?.Methods,
@@ -58,28 +55,23 @@ namespace WireMock.Serialization
{
Name = hm.Name,
Matchers = MatcherMapper.Map(hm.Matchers)
- //Funcs = Map(hm.Funcs)
}).ToList() : null,
Cookies = cookieMatchers != null && cookieMatchers.Any() ? cookieMatchers.Select(cm => new CookieModel
{
Name = cm.Name,
Matchers = MatcherMapper.Map(cm.Matchers)
- //Funcs = Map(cm.Funcs)
}).ToList() : null,
Params = paramsMatchers != null && paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
{
Name = pm.Key,
Matchers = MatcherMapper.Map(pm.Matchers)
- //Funcs = Map(pm.Funcs)
}).ToList() : null,
Body = methodMatcher?.Methods != null && methodMatcher.Methods.Any(m => m == "get") ? null : new BodyModel
{
Matcher = bodyMatcher != null ? MatcherMapper.Map(bodyMatcher.Matcher) : null
- //Func = bodyMatcher != null ? Map(bodyMatcher.Func) : null,
- //DataFunc = bodyMatcher != null ? Map(bodyMatcher.DataFunc) : null
}
},
Response = new ResponseModel
diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
index ddb397cd..c32d2991 100644
--- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
@@ -9,6 +9,7 @@ using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WireMock.Admin.Mappings;
+using WireMock.Admin.Scenarios;
using WireMock.Admin.Settings;
using WireMock.Http;
using WireMock.Logging;
@@ -41,7 +42,13 @@ namespace WireMock.Server
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
- NullValueHandling = NullValueHandling.Ignore,
+ NullValueHandling = NullValueHandling.Ignore
+ };
+
+ private readonly JsonSerializerSettings _settingsIncludeNullValues = new JsonSerializerSettings
+ {
+ Formatting = Formatting.Indented,
+ NullValueHandling = NullValueHandling.Include
};
#region InitAdmin
@@ -525,13 +532,15 @@ namespace WireMock.Server
#region Scenarios
private ResponseMessage ScenariosGet(RequestMessage requestMessage)
{
- var scenarios = Scenarios.ToArray().Select(s => new
+ var scenariosStates = Scenarios.Values.Select(s => new ScenarioStateModel
{
- Name = s.Key,
- Started = s.Value != null,
- NextState = s.Value
+ Name = s.Name,
+ NextState = s.NextState,
+ Started = s.Started,
+ Finished = s.Finished
});
- return ToJson(scenarios);
+
+ return ToJson(scenariosStates, true);
}
private ResponseMessage ScenariosReset(RequestMessage requestMessage)
@@ -706,11 +715,11 @@ namespace WireMock.Server
return responseBuilder;
}
- private ResponseMessage ToJson(T result)
+ private ResponseMessage ToJson(T result, bool keepNullValues = false)
{
return new ResponseMessage
{
- Body = JsonConvert.SerializeObject(result, _settings),
+ Body = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings),
StatusCode = 200,
Headers = new Dictionary> { { HttpKnownHeaderNames.ContentType, new WireMockList("application/json") } }
};
diff --git a/src/WireMock.Net/Server/FluentMockServer.cs b/src/WireMock.Net/Server/FluentMockServer.cs
index f4df8a4c..6b43b302 100644
--- a/src/WireMock.Net/Server/FluentMockServer.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.cs
@@ -56,7 +56,7 @@ namespace WireMock.Server
/// Gets the scenarios.
///
[PublicAPI]
- public ConcurrentDictionary Scenarios => new ConcurrentDictionary(_options.Scenarios);
+ public ConcurrentDictionary Scenarios => new ConcurrentDictionary(_options.Scenarios);
#region IDisposable Members
///
diff --git a/src/WireMock.Net/Server/IRespondWithAProvider.cs b/src/WireMock.Net/Server/IRespondWithAProvider.cs
index 5c430bae..a2d67e31 100644
--- a/src/WireMock.Net/Server/IRespondWithAProvider.cs
+++ b/src/WireMock.Net/Server/IRespondWithAProvider.cs
@@ -66,13 +66,13 @@ namespace WireMock.Server
///
/// Any object which identifies the current state
/// The .
- IRespondWithAProvider WhenStateIs(object state);
+ IRespondWithAProvider WhenStateIs(string state);
///
/// Once this mapping is executed the state will be changed to specified one.
///
/// Any object which identifies the new state
/// The .
- IRespondWithAProvider WillSetStateTo(object state);
+ IRespondWithAProvider WillSetStateTo(string state);
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Server/RespondWithAProvider.cs b/src/WireMock.Net/Server/RespondWithAProvider.cs
index 71b16072..b4325d69 100644
--- a/src/WireMock.Net/Server/RespondWithAProvider.cs
+++ b/src/WireMock.Net/Server/RespondWithAProvider.cs
@@ -12,8 +12,8 @@ namespace WireMock.Server
private int _priority;
private string _title;
private string _path;
- private object _executionConditionState;
- private object _nextState;
+ private string _executionConditionState;
+ private string _nextState;
private string _scenario;
private readonly RegistrationCallback _registrationCallback;
private readonly IRequestMatcher _requestMatcher;
@@ -87,25 +87,20 @@ namespace WireMock.Server
}
///
- public IRespondWithAProvider WhenStateIs(object state)
+ public IRespondWithAProvider WhenStateIs(string state)
{
if (string.IsNullOrEmpty(_scenario))
{
throw new NotSupportedException("Unable to set state condition when no scenario is defined.");
}
- //if (_nextState != null)
- //{
- // throw new NotSupportedException("Unable to set state condition when next state is defined.");
- //}
-
_executionConditionState = state;
return this;
}
///
- public IRespondWithAProvider WillSetStateTo(object state)
+ public IRespondWithAProvider WillSetStateTo(string state)
{
if (string.IsNullOrEmpty(_scenario))
{
diff --git a/test/WireMock.Net.Tests/StatefulBehaviorTests.cs b/test/WireMock.Net.Tests/StatefulBehaviorTests.cs
index 098f0840..53738249 100644
--- a/test/WireMock.Net.Tests/StatefulBehaviorTests.cs
+++ b/test/WireMock.Net.Tests/StatefulBehaviorTests.cs
@@ -1,4 +1,5 @@
-using System.Net;
+using System.Linq;
+using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using NFluent;
@@ -12,7 +13,7 @@ namespace WireMock.Net.Tests
public class StatefulBehaviorTests
{
[Fact]
- public async Task Should_skip_non_relevant_states()
+ public async Task Scenarios_Should_skip_non_relevant_states()
{
// given
var server = FluentMockServer.Start();
@@ -33,7 +34,7 @@ namespace WireMock.Net.Tests
}
[Fact]
- public async Task Should_process_request_if_equals_state_and_single_state_defined()
+ public async Task Scenarios_Should_process_request_if_equals_state_and_single_state_defined()
{
// given
var server = FluentMockServer.Start();
@@ -62,7 +63,7 @@ namespace WireMock.Net.Tests
}
[Fact]
- public async Task Scenario_and_State_TodoList_Example()
+ public async Task Scenarios_TodoList_Example()
{
// Assign
var server = FluentMockServer.Start();
@@ -86,22 +87,39 @@ namespace WireMock.Net.Tests
.WhenStateIs("Cancel newspaper item added")
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
+ Check.That(server.Scenarios.Any()).IsFalse();
+
// Act and Assert
string url = "http://localhost:" + server.Ports[0];
string getResponse1 = new HttpClient().GetStringAsync(url + "/todo/items").Result;
Check.That(getResponse1).Equals("Buy milk");
+ Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
+ Check.That(server.Scenarios["To do list"].NextState).IsEqualTo("TodoList State Started");
+ Check.That(server.Scenarios["To do list"].Started).IsTrue();
+ Check.That(server.Scenarios["To do list"].Finished).IsFalse();
+
var postResponse = await new HttpClient().PostAsync(url + "/todo/items", new StringContent("Cancel newspaper subscription"));
Check.That(postResponse.StatusCode).Equals(HttpStatusCode.Created);
+ Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
+ Check.That(server.Scenarios["To do list"].NextState).IsEqualTo("Cancel newspaper item added");
+ Check.That(server.Scenarios["To do list"].Started).IsTrue();
+ Check.That(server.Scenarios["To do list"].Finished).IsFalse();
+
string getResponse2 = await new HttpClient().GetStringAsync(url + "/todo/items");
Check.That(getResponse2).Equals("Buy milk;Cancel newspaper subscription");
+ Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
+ Check.That(server.Scenarios["To do list"].NextState).IsNull();
+ Check.That(server.Scenarios["To do list"].Started).IsTrue();
+ Check.That(server.Scenarios["To do list"].Finished).IsTrue();
+
server.Dispose();
}
- // [Fact]
- public async Task Should_process_request_if_equals_state_and_multiple_state_defined()
+ [Fact]
+ public async Task Scenarios_Should_process_request_if_equals_state_and_multiple_state_defined()
{
// Assign
var server = FluentMockServer.Start();
@@ -113,7 +131,7 @@ namespace WireMock.Net.Tests
.RespondWith(Response.Create().WithBody("No state msg 1"));
server
- .Given(Request.Create().WithPath("/fooX").UsingGet())
+ .Given(Request.Create().WithPath("/foo1X").UsingGet())
.InScenario("s1")
.WhenStateIs("Test state 1")
.RespondWith(Response.Create().WithBody("Test state msg 1"));
@@ -125,7 +143,7 @@ namespace WireMock.Net.Tests
.RespondWith(Response.Create().WithBody("No state msg 2"));
server
- .Given(Request.Create().WithPath("/fooX").UsingGet())
+ .Given(Request.Create().WithPath("/foo2X").UsingGet())
.InScenario("s2")
.WhenStateIs("Test state 2")
.RespondWith(Response.Create().WithBody("Test state msg 2"));
@@ -138,10 +156,10 @@ namespace WireMock.Net.Tests
var responseNoState2 = await new HttpClient().GetStringAsync(url + "/state2");
Check.That(responseNoState2).Equals("No state msg 2");
- var responseWithState1 = await new HttpClient().GetStringAsync(url + "/fooX");
+ var responseWithState1 = await new HttpClient().GetStringAsync(url + "/foo1X");
Check.That(responseWithState1).Equals("Test state msg 1");
- var responseWithState2 = await new HttpClient().GetStringAsync(url + "/fooX");
+ var responseWithState2 = await new HttpClient().GetStringAsync(url + "/foo2X");
Check.That(responseWithState2).Equals("Test state msg 2");
server.Dispose();