Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/numeric provider state param #506

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: CI

on: [push, pull_request]
on: [push, pull_request, workflow_dispatch]

env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
Expand Down
4 changes: 2 additions & 2 deletions samples/OrdersApi/Consumer.Tests/OrdersClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public async Task GetOrderAsync_WhenCalled_ReturnsOrder()

this.pact
.UponReceiving("a request for an order by ID")
.Given("an order with ID {id} exists", new Dictionary<string, string> { ["id"] = "1" })
.Given("an order with ID {id} exists", new Dictionary<string, object> { ["id"] = 1 })
.WithRequest(HttpMethod.Get, "/api/orders/1")
.WithHeader("Accept", "application/json")
.WillRespond()
Expand Down Expand Up @@ -121,7 +121,7 @@ public async Task UpdateOrderAsync_WhenCalled_UpdatesOrder()
{
this.pact
.UponReceiving("a request to update the status of an order")
.Given("an order with ID {id} exists", new Dictionary<string, string> { ["id"] = "1" })
.Given("an order with ID {id} exists", new Dictionary<string, object> { ["id"] = 1 })
.WithRequest(HttpMethod.Put, "/api/orders/1/status")
.WithJsonBody(Match.Regex(OrderStatus.Fulfilling.ToString(), string.Join("|", Enum.GetNames<OrderStatus>())))
.WillRespond()
Expand Down
4 changes: 2 additions & 2 deletions src/PactNet.Abstractions/IMessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public interface IMessageBuilderV3
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Fluent builder</returns>
IMessageBuilderV3 Given(string providerState, IDictionary<string, string> parameters);
IMessageBuilderV3 Given(string providerState, IDictionary<string, object> parameters);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is a breaking change to the public API


/// <summary>
/// Set the metadata
Expand Down Expand Up @@ -65,7 +65,7 @@ public interface IMessageBuilderV4
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Fluent builder</returns>
IMessageBuilderV4 Given(string providerState, IDictionary<string, string> parameters);
IMessageBuilderV4 Given(string providerState, IDictionary<string, object> parameters);

/// <summary>
/// Set the metadata
Expand Down
4 changes: 2 additions & 2 deletions src/PactNet.Abstractions/IRequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public interface IRequestBuilderV3
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Fluent builder</returns>
IRequestBuilderV3 Given(string providerState, IDictionary<string, string> parameters);
IRequestBuilderV3 Given(string providerState, IDictionary<string, object> parameters);

/// <summary>
/// Set the request
Expand Down Expand Up @@ -242,7 +242,7 @@ public interface IRequestBuilderV4
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Fluent builder</returns>
IRequestBuilderV4 Given(string providerState, IDictionary<string, string> parameters);
IRequestBuilderV4 Given(string providerState, IDictionary<string, object> parameters);

/// <summary>
/// Set the request
Expand Down
2 changes: 1 addition & 1 deletion src/PactNet.Abstractions/ProviderState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public class ProviderState
/// <summary>
/// State parameters
/// </summary>
public IDictionary<string, string> Params { get; set; }
public IDictionary<string, object> Params { get; set; }
}
}
9 changes: 6 additions & 3 deletions src/PactNet/Drivers/HttpInteractionDriver.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using PactNet.Interop;

using System.Text.Json.Serialization;
namespace PactNet.Drivers
{
/// <summary>
Expand Down Expand Up @@ -37,8 +37,11 @@ public void Given(string description)
/// <param name="name">Parameter name</param>
/// <param name="value">Parameter value</param>
/// <returns>Success</returns>
public void GivenWithParam(string description, string name, string value)
=> NativeInterop.GivenWithParam(this.interaction, description, name, value).CheckInteropSuccess();
public void GivenWithParam(string description, string name, object value)
{
var jsonValue = System.Text.Json.JsonSerializer.Serialize(value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Don't use var when it's not obvious what the type is

style: Don't use fully qualified references inline, use an import instead

NativeInterop.GivenWithParam(this.interaction, description, name, jsonValue).CheckInteropSuccess();
}

/// <summary>
/// Add a request to the interaction
Expand Down
2 changes: 1 addition & 1 deletion src/PactNet/Drivers/IProviderStateDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ internal interface IProviderStateDriver
/// <param name="description">Provider state description</param>
/// <param name="name">Parameter name</param>
/// <param name="value">Parameter value</param>
void GivenWithParam(string description, string name, string value);
void GivenWithParam(string description, string name, object value);
}
}
9 changes: 6 additions & 3 deletions src/PactNet/Drivers/MessageInteractionDriver.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
using PactNet.Interop;

using System.Text.Json.Serialization;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Blank line after import statements

namespace PactNet.Drivers
{
/// <summary>
Expand Down Expand Up @@ -34,8 +34,11 @@ public void Given(string description)
/// <param name="description">Provider state description</param>
/// <param name="name">Parameter name</param>
/// <param name="value">Parameter value</param>
public void GivenWithParam(string description, string name, string value)
=> NativeInterop.GivenWithParam(this.interaction, description, name, value).CheckInteropSuccess();
public void GivenWithParam(string description, string name, object value)
{
var jsonValue = System.Text.Json.JsonSerializer.Serialize(value);
NativeInterop.GivenWithParam(this.interaction, description, name, jsonValue).CheckInteropSuccess();
}

/// <summary>
/// Set the description of the message interaction
Expand Down
6 changes: 3 additions & 3 deletions src/PactNet/MessageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ IMessageBuilderV3 IMessageBuilderV3.Given(string providerState)
=> Given(providerState);

/// <inheritdoc cref="IMessageBuilderV3"/>
IMessageBuilderV3 IMessageBuilderV3.Given(string providerState, IDictionary<string, string> parameters)
IMessageBuilderV3 IMessageBuilderV3.Given(string providerState, IDictionary<string, object> parameters)
=> Given(providerState, parameters);

/// <inheritdoc cref="IMessageBuilderV3"/>
Expand All @@ -59,7 +59,7 @@ IMessageBuilderV4 IMessageBuilderV4.Given(string providerState)
=> Given(providerState);

/// <inheritdoc cref="IMessageBuilderV4"/>
IMessageBuilderV4 IMessageBuilderV4.Given(string providerState, IDictionary<string, string> parameters)
IMessageBuilderV4 IMessageBuilderV4.Given(string providerState, IDictionary<string, object> parameters)
=> Given(providerState, parameters);

/// <inheritdoc cref="IMessageBuilderV4"/>
Expand Down Expand Up @@ -96,7 +96,7 @@ internal MessageBuilder Given(string providerState)
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Fluent builder</returns>
internal MessageBuilder Given(string providerState, IDictionary<string, string> parameters)
internal MessageBuilder Given(string providerState, IDictionary<string, object> parameters)
{
foreach (var param in parameters)
{
Expand Down
8 changes: 4 additions & 4 deletions src/PactNet/RequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ IRequestBuilderV3 IRequestBuilderV3.Given(string providerState)
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Flient builder</returns>
IRequestBuilderV3 IRequestBuilderV3.Given(string providerState, IDictionary<string, string> parameters)
IRequestBuilderV3 IRequestBuilderV3.Given(string providerState, IDictionary<string, object> parameters)
=> this.Given(providerState, parameters);

/// <summary>
Expand Down Expand Up @@ -287,7 +287,7 @@ IRequestBuilderV4 IRequestBuilderV4.Given(string providerState)
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Flient builder</returns>
IRequestBuilderV4 IRequestBuilderV4.Given(string providerState, IDictionary<string, string> parameters)
IRequestBuilderV4 IRequestBuilderV4.Given(string providerState, IDictionary<string, object> parameters)
=> this.Given(providerState, parameters);

/// <summary>
Expand Down Expand Up @@ -416,8 +416,8 @@ internal RequestBuilder Given(string providerState)
/// </summary>
/// <param name="providerState">Provider state description</param>
/// <param name="parameters">Provider state parameters</param>
/// <returns>Flient builder</returns>
internal RequestBuilder Given(string providerState, IDictionary<string, string> parameters)
/// <returns>Fluent builder</returns>
internal RequestBuilder Given(string providerState, IDictionary<string, object> parameters)
{
foreach (var param in parameters)
{
Expand Down
108 changes: 108 additions & 0 deletions tests/PactNet.Tests/Drivers/FfiIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,113 @@ public void MessageInteraction_v3_CreatesPactFile()
string expectedPactContent = File.ReadAllText("data/v3-message-integration.json").TrimEnd();
pactContents.Should().Be(expectedPactContent);
}

[Fact]
[Trait("issue", "449")]
public async Task HttpInteraction_NumericProviderStateParameter_CreatesPactFile()
{
var driver = new PactDriver();

try
{
IHttpPactDriver pact = driver.NewHttpPact("NativeDriverTests-Consumer-NumericProviderStateParam",
"NativeDriverTests-Provider",
PactSpecification.V3);

IHttpInteractionDriver interaction = pact.NewHttpInteraction("an interaction with a numeric provider state param");

interaction.GivenWithParam("state with param", "issue", 449);
interaction.WithRequest("GET", "/path");

interaction.WithResponseStatus((ushort)HttpStatusCode.OK);
interaction.WithResponseBody("application/json", @"{""foo"":42}");

using IMockServerDriver mockServer = pact.CreateMockServer("127.0.0.1", null, false);

var client = new HttpClient { BaseAddress = mockServer.Uri };

HttpResponseMessage result = await client.GetAsync("/path");
result.StatusCode.Should().Be(HttpStatusCode.OK);

string content = await result.Content.ReadAsStringAsync();
content.Should().Be(@"{""foo"":42}");

mockServer.MockServerMismatches().Should().Be("[]");

string logs = mockServer.MockServerLogs();
logs.Should().NotBeEmpty();

this.output.WriteLine("Mock Server Logs");
this.output.WriteLine("----------------");
this.output.WriteLine(logs);

pact.WritePactFile(Environment.CurrentDirectory);
}
finally
{
this.WriteDriverLogs(driver);
}

var file = new FileInfo("NativeDriverTests-Consumer-NumericProviderStateParam-NativeDriverTests-Provider.json");
file.Exists.Should().BeTrue();

string pactContents = File.ReadAllText(file.FullName).TrimEnd();
string expectedPactContent = File.ReadAllText("data/v3-server-numeric-provider-state-param.json").TrimEnd();
pactContents.Should().Be(expectedPactContent);
}

[Fact]
[Trait("issue", "449")]
public async Task HttpInteraction_StringProviderStateParameter_CreatesPactFile()
{
var driver = new PactDriver();

try
{
IHttpPactDriver pact = driver.NewHttpPact("NativeDriverTests-Consumer-StringProviderStateParam",
"NativeDriverTests-Provider",
PactSpecification.V3);

IHttpInteractionDriver interaction = pact.NewHttpInteraction("an interaction with a string provider state param");

interaction.GivenWithParam("state with param", "issue", "449");
interaction.WithRequest("GET", "/path");

interaction.WithResponseStatus((ushort)HttpStatusCode.OK);
interaction.WithResponseBody("application/json", @"{""foo"":42}");

using IMockServerDriver mockServer = pact.CreateMockServer("127.0.0.1", null, false);

var client = new HttpClient { BaseAddress = mockServer.Uri };

HttpResponseMessage result = await client.GetAsync("/path");
result.StatusCode.Should().Be(HttpStatusCode.OK);

string content = await result.Content.ReadAsStringAsync();
content.Should().Be(@"{""foo"":42}");

mockServer.MockServerMismatches().Should().Be("[]");

string logs = mockServer.MockServerLogs();
logs.Should().NotBeEmpty();

this.output.WriteLine("Mock Server Logs");
this.output.WriteLine("----------------");
this.output.WriteLine(logs);

pact.WritePactFile(Environment.CurrentDirectory);
}
finally
{
this.WriteDriverLogs(driver);
}

var file = new FileInfo("NativeDriverTests-Consumer-StringProviderStateParam-NativeDriverTests-Provider.json");
file.Exists.Should().BeTrue();

string pactContents = File.ReadAllText(file.FullName).TrimEnd();
string expectedPactContent = File.ReadAllText("data/v3-server-string-provider-state-param.json").TrimEnd();
pactContents.Should().Be(expectedPactContent);
}
}
}
2 changes: 1 addition & 1 deletion tests/PactNet.Tests/MessageBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void Given_WhenCalled_AddsProviderState()
public void Given_WithParams_AddsProviderState()
{
this.builder.Given("provider state",
new Dictionary<string, string>
new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash",
Expand Down
12 changes: 6 additions & 6 deletions tests/PactNet.Tests/PactExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public async Task WithHttpInteractions_V3_CreatesExpectedPactFile()
builder.UponReceiving("a sample request")
.Given("a provider state")
.Given("another provider state")
.Given("a provider state with params", new Dictionary<string, string>
.Given("a provider state with params", new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash"
Expand Down Expand Up @@ -150,7 +150,7 @@ public async Task WithHttpInteractions_V4_CreatesExpectedPactFile()
builder.UponReceiving("a sample request")
.Given("a provider state")
.Given("another provider state")
.Given("a provider state with params", new Dictionary<string, string>
.Given("a provider state with params", new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash"
Expand Down Expand Up @@ -189,7 +189,7 @@ public void WithMessageInteractions_V3_CreatesExpectedPactFile()
.ExpectsToReceive("a sample request")
.Given("a provider state")
.Given("another provider state")
.Given("a provider state with params", new Dictionary<string, string>
.Given("a provider state with params", new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash"
Expand All @@ -215,7 +215,7 @@ public void WithMessageInteractions_V4_CreatesExpectedPactFile()
.ExpectsToReceive("a sample request")
.Given("a provider state")
.Given("another provider state")
.Given("a provider state with params", new Dictionary<string, string>
.Given("a provider state with params", new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash"
Expand All @@ -241,7 +241,7 @@ public async Task CombinedHttpAndMessageInteractions_v4_CreatesExpectedPactFile(
http.UponReceiving("a HTTP request")
.Given("a provider state")
.Given("another provider state")
.Given("a provider state with params", new Dictionary<string, string>
.Given("a provider state with params", new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash"
Expand Down Expand Up @@ -271,7 +271,7 @@ await http.VerifyAsync(async ctx =>
.ExpectsToReceive("a message")
.Given("a provider state")
.Given("another provider state")
.Given("a provider state with params", new Dictionary<string, string>
.Given("a provider state with params", new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash"
Expand Down
2 changes: 1 addition & 1 deletion tests/PactNet.Tests/RequestBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void Given_WhenCalled_AddsProviderState()
public void Given_WithParams_AddsProviderState()
{
this.builder.Given("provider state",
new Dictionary<string, string>
new Dictionary<string, object>
{
["foo"] = "bar",
["baz"] = "bash",
Expand Down
Loading