Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>

<PropertyGroup>
<VersionPrefix>1.8.12</VersionPrefix>
<VersionPrefix>1.8.13-preview-02</VersionPrefix>
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
<PackageProjectUrl>https://github.com/wiremock/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="SonarAnalyzer.CSharp" Version="10.12.0.118525" />
</ItemGroup>

<!--<ItemGroup>
<PackageReference Include="WireMock.Net" Version="1.8.11" />
</ItemGroup>-->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright © WireMock.Net

namespace WireMock.Admin.Scenarios;

/// <summary>
/// ScenarioStateModel
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class ScenarioStateUpdateModel
{
/// <summary>
/// Gets or sets the NextState.
/// </summary>
public string? State { get; set; }
}
5 changes: 5 additions & 0 deletions src/WireMock.Net.Abstractions/Server/IWireMockServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ public interface IWireMockServer : IDisposable
/// </summary>
bool ResetScenario(string name);

/// <summary>
/// Sets a scenario to a state.
/// </summary>
bool SetScenarioState(string name, string? state);

/// <summary>
/// Resets the LogEntries.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/WireMock.Net.Minimal/IMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public interface IMapping
WireMockServerSettings Settings { get; }

/// <summary>
/// Is State started ?
/// Indicates if the state is started or manually set to a value.
/// </summary>
bool IsStartState { get; }

Expand Down
19 changes: 19 additions & 0 deletions src/WireMock.Net.Minimal/Server/WireMockServer.Admin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
public RegexMatcher MappingsCodeGuidPathMatcher => new($"^{_prefixEscaped}\\/mappings\\/code\\/([0-9A-Fa-f]{{8}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{12}})$");
public RegexMatcher RequestsGuidPathMatcher => new($"^{_prefixEscaped}\\/requests\\/([0-9A-Fa-f]{{8}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{12}})$");
public RegexMatcher ScenariosNameMatcher => new($"^{_prefixEscaped}\\/scenarios\\/.+$");
public RegexMatcher ScenariosNameWithStateMatcher => new($"^{_prefixEscaped}\\/scenarios\\/.+\\/state$");
public RegexMatcher ScenariosNameWithResetMatcher => new($"^{_prefixEscaped}\\/scenarios\\/.+\\/reset$");
public RegexMatcher FilesFilenamePathMatcher => new($"^{_prefixEscaped}\\/files\\/.+$");
public RegexMatcher ProtoDefinitionsIdPathMatcher => new($"^{_prefixEscaped}\\/protodefinitions\\/.+$");
Expand Down Expand Up @@ -138,6 +139,9 @@
Given(Request.Create().WithPath(_adminPaths.Scenarios + "/reset").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosReset));
Given(Request.Create().WithPath(_adminPaths.ScenariosNameWithResetMatcher).UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenarioReset));

// __admin/scenarios/{scenario}/state
Given(Request.Create().WithPath(_adminPaths.ScenariosNameWithStateMatcher).UsingPut()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosSetState));

Check warning on line 144 in src/WireMock.Net.Minimal/Server/WireMockServer.Admin.cs

View check run for this annotation

Codecov / codecov/patch

src/WireMock.Net.Minimal/Server/WireMockServer.Admin.cs#L144

Added line #L144 was not covered by tests
// __admin/files/{filename}
Given(Request.Create().WithPath(_adminPaths.FilesFilenamePathMatcher).UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePost));
Given(Request.Create().WithPath(_adminPaths.FilesFilenamePathMatcher).UsingPut()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePut));
Expand Down Expand Up @@ -705,6 +709,21 @@
ResponseMessageBuilder.Create(200, "Scenario reset") :
ResponseMessageBuilder.Create(HttpStatusCode.NotFound, $"No scenario found by name '{name}'.");
}

private IResponseMessage ScenariosSetState(IRequestMessage requestMessage)
{
var name = requestMessage.Path.Split('/').Reverse().Skip(1).First();
if (!_options.Scenarios.ContainsKey(name))
{
ResponseMessageBuilder.Create(HttpStatusCode.NotFound, $"No scenario found by name '{name}'.");
}

var update = DeserializeObject<ScenarioStateUpdateModel>(requestMessage);

return SetScenarioState(name, update.State) ?
ResponseMessageBuilder.Create(200, $"Scenario state set to '{update.State}'") :
ResponseMessageBuilder.Create(HttpStatusCode.NotFound, $"No scenario found by name '{name}'.");
}
#endregion

#region Pact
Expand Down
26 changes: 26 additions & 0 deletions src/WireMock.Net.Minimal/Server/WireMockServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,32 @@
return _options.Scenarios.ContainsKey(name) && _options.Scenarios.TryRemove(name, out _);
}

/// <inheritdoc />

Check warning on line 570 in src/WireMock.Net.Minimal/Server/WireMockServer.cs

View check run for this annotation

Codecov / codecov/patch

src/WireMock.Net.Minimal/Server/WireMockServer.cs#L570

Added line #L570 was not covered by tests
[PublicAPI]
public bool SetScenarioState(string name, string? state)
{
if (state == null)
{
return ResetScenario(name);
}

_options.Scenarios.AddOrUpdate(
name,
_ => new ScenarioState
{
Name = name,
NextState = state
},
(_, current) =>
{
current.NextState = state;
return current;
}
);

return true;
}

/// <inheritdoc cref="IWireMockServer.WithMapping(MappingModel[])" />
[PublicAPI]
public IWireMockServer WithMapping(params MappingModel[] mappings)
Expand Down
14 changes: 12 additions & 2 deletions src/WireMock.Net.RestClient/IWireMockAdminApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public interface IWireMockAdminApi
/// Delete (reset) all scenarios
/// </summary>
/// <param name="cancellationToken">The optional cancellationToken.</param>
[Post("scenarios")]
[Post("scenarios/reset")]
Task<StatusModel> ResetScenariosAsync(CancellationToken cancellationToken = default);

/// <summary>
Expand All @@ -269,14 +269,24 @@ public interface IWireMockAdminApi
Task<StatusModel> DeleteScenarioAsync([Path] string name, CancellationToken cancellationToken = default);

/// <summary>
/// Delete (reset) all scenarios
/// Delete (reset) a specific scenario
/// </summary>
/// <param name="name">Scenario name.</param>
/// <param name="cancellationToken">The optional cancellationToken.</param>
[Post("scenarios/{name}/reset")]
[AllowAnyStatusCode]
Task<StatusModel> ResetScenarioAsync([Path] string name, CancellationToken cancellationToken = default);

/// <summary>
/// Update the state for a scenario.
/// </summary>
/// <param name="name">Scenario name.</param>
/// <param name="updateModel">Scenario state update model.</param>
/// <param name="cancellationToken">The optional cancellationToken.</param>
[Put("scenarios/{name}/state")]
[AllowAnyStatusCode]
Task<StatusModel> PutScenarioStateAsync([Path] string name, [Body] ScenarioStateUpdateModel updateModel, CancellationToken cancellationToken = default);

/// <summary>
/// Create a new File
/// </summary>
Expand Down
52 changes: 52 additions & 0 deletions test/WireMock.Net.Tests/AdminApi/WireMockAdminApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using VerifyTests;
using VerifyXunit;
using WireMock.Admin.Mappings;
using WireMock.Admin.Scenarios;
using WireMock.Admin.Settings;
using WireMock.Client;
using WireMock.Client.Extensions;
Expand Down Expand Up @@ -743,6 +744,57 @@ public async Task IWireMockAdminApi_DeleteScenarioUsingPostAsync()
status.Status.Should().Be("No scenario found by name 'x'.");
}

[Fact]
public async Task IWireMockAdminApi_UpdateNonExistingScenarioState()
{
// Arrange
using var server = WireMockServer.StartWithAdminInterface();

var api = RestClient.For<IWireMockAdminApi>(server.Urls[0]);

// Act
var update = new ScenarioStateUpdateModel
{
State = null
};
var status = await api.PutScenarioStateAsync("x", update).ConfigureAwait(false);
status.Status.Should().Be("No scenario found by name 'x'.");
}

[Fact]
public async Task IWireMockAdminApi_UpdateScenarioState()
{
// Arrange
using var server = WireMockServer.StartWithAdminInterface();
server
.Given(Request.Create()
.WithPath("/state1")
.UsingGet())
.InScenario("s1")
.WillSetStateTo("Test state 1")
.RespondWith(Response.Create()
.WithBody("No state msg 1"));

server
.Given(Request.Create()
.WithPath("/foostate1")
.UsingGet())
.InScenario("s1")
.WhenStateIs("Test state 1")
.RespondWith(Response.Create()
.WithBody("Test state msg 1"));

var api = RestClient.For<IWireMockAdminApi>(server.Urls[0]);

// Act
var update = new ScenarioStateUpdateModel
{
State = null
};
var status = await api.PutScenarioStateAsync("s1", update).ConfigureAwait(false);
status.Status.Should().Be("Scenario state set to ''");
}

[Fact]
public async Task IWireMockAdminApi_GetMappingByGuidAsync()
{
Expand Down
2 changes: 1 addition & 1 deletion test/WireMock.Net.Tests/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ internal static class Constants
{
internal const int NumStaticMappings = 10;

internal const int NumAdminMappings = 36;
internal const int NumAdminMappings = 37;
}
Loading
Loading