Skip to content

Commit 0b1de47

Browse files
committed
feat: Support injecting HttpClient
Closes #21
1 parent 0ebe743 commit 0b1de47

File tree

9 files changed

+156
-32
lines changed

9 files changed

+156
-32
lines changed

.github/workflows/dotnet-build.yml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,16 @@ jobs:
5050
with:
5151
dotnet-version: 8.x.x
5252

53-
- name: Release
54-
id: release
55-
uses: cycjimmy/semantic-release-action@v4
53+
- name: Setup Node.js
54+
uses: actions/setup-node@v4
5655
with:
57-
tag_format: ${version}
58-
working_directory: ./src/MockServerClientNet
59-
extra_plugins: |
60-
@semantic-release/commit-analyzer
61-
@semantic-release/release-notes-generator
62-
@semantic-release/github
63-
@semantic-release/git
64-
@semantic-release/exec
56+
node-version: 'lts/*'
57+
58+
- name: Setup semantic-release
59+
run: npm install -g semantic-release @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/github @semantic-release/git @semantic-release/exec -D
60+
61+
- name: Release
62+
run: npx semantic-release
6563
env:
6664
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
6765

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
*.nuget.props
88
*.nuget.targets
99
*.user
10-
10+
.idea

.releaserc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"prerelease": true
1111
}
1212
],
13+
"tagFormat": "${version}",
1314
"plugins": [
1415
"@semantic-release/commit-analyzer",
1516
"@semantic-release/release-notes-generator",
@@ -23,7 +24,8 @@
2324
[
2425
"@semantic-release/exec",
2526
{
26-
"prepareCmd": "../../semver.sh '${nextRelease.version}' 'MockServerClientNet.csproj'"
27+
"prepareCmd": "./semver.sh '${nextRelease.version}' 'src/MockServerClientNet/MockServerClientNet.csproj'",
28+
"successCmd": "echo 'new_release_version=${nextRelease.version}' >> $GITHUB_OUTPUT"
2729
}
2830
],
2931
[

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "mockserver-client-net",
3+
"version": "0.0.0",
4+
"private": true
5+
}

semver.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/usr/bin/env bash
22

3-
echo "::set-output name=new_release_version::$1"
43
dotnet tool install -g dotnet-setversion > /dev/null 2>&1
54
setversion $1 $2 > /dev/null 2>&1
65

src/MockServerClientNet/MockServerClient.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ public MockServerClient(string host, int port, string contextPath = "",
5151
_httpClient = new HttpClient(httpHandler ?? new HttpClientHandler());
5252
}
5353

54+
public MockServerClient(string host, int port, HttpClient httpClient, string contextPath = "",
55+
HttpScheme httpScheme = HttpScheme.Http)
56+
{
57+
_host = host;
58+
_port = port;
59+
_contextPath = contextPath;
60+
_httpScheme = httpScheme;
61+
_httpClient = httpClient;
62+
}
63+
5464
public void Dispose()
5565
{
5666
_httpClient.Dispose();
@@ -302,4 +312,4 @@ private string FullPath(string endpoint)
302312
.PrefixWith("/");
303313
}
304314
}
305-
}
315+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using System.Net;
3+
using System.Net.Http;
4+
using System.Threading.Tasks;
5+
using MockServerClientNet.Model;
6+
using Xunit;
7+
using static MockServerClientNet.Model.HttpRequest;
8+
using static MockServerClientNet.Model.HttpResponse;
9+
10+
namespace MockServerClientNet.Tests
11+
{
12+
public class CustomHttpClientTest(MockServerFixture fixture) : MockServerClientTest(fixture, HttpClient)
13+
{
14+
private static readonly HttpClient HttpClient = GetHttpClient();
15+
16+
[Fact]
17+
public async Task ShouldRespondToHttpsRequest()
18+
{
19+
// arrange
20+
await SetupExpectation(MockServerClient, true);
21+
22+
// act
23+
var response = await SendHello(HttpScheme.Https);
24+
25+
// assert
26+
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
27+
Assert.Equal("{\"message\": \"hello\"}", await response.Content.ReadAsStringAsync());
28+
}
29+
30+
[Fact]
31+
public async Task ShouldNotMatchHttpsRequestWhenSecureIsFalse()
32+
{
33+
// arrange
34+
await SetupExpectation(MockServerClient, false);
35+
36+
// act
37+
var response = await SendHello(HttpScheme.Https);
38+
39+
// assert
40+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
41+
}
42+
43+
[Fact]
44+
public async Task ShouldNotMatchHttpRequestWhenSecureIsTrue()
45+
{
46+
// arrange
47+
await SetupExpectation(MockServerClient, true);
48+
49+
// act
50+
var response = await SendHello(HttpScheme.Http);
51+
52+
// assert
53+
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
54+
}
55+
56+
private static HttpClient GetHttpClient()
57+
{
58+
return new HttpClient(new HttpClientHandler
59+
{
60+
ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) =>
61+
{
62+
Assert.Contains("O=MockServer", cert.Issuer);
63+
return true;
64+
}
65+
}, false);
66+
}
67+
68+
private static async Task SetupExpectation(MockServerClient mockServerClient, bool secure)
69+
{
70+
await mockServerClient.ResetAsync();
71+
72+
await mockServerClient.When(Request()
73+
.WithSecure(secure)
74+
.WithMethod(HttpMethod.Get)
75+
.WithPath("/hello"),
76+
Times.Unlimited()
77+
).RespondAsync(Response()
78+
.WithDelay(TimeSpan.FromSeconds(0))
79+
.WithStatusCode(200)
80+
.WithBody("{\"message\": \"hello\"}"));
81+
}
82+
83+
private async Task<HttpResponseMessage> SendHello(HttpScheme scheme)
84+
{
85+
var host = MockServerClient.ServerAddress().Host;
86+
var port = MockServerClient.ServerAddress().Port;
87+
return await HttpClient.GetAsync(new Uri($"{scheme}://{host}:{port}/hello"));
88+
}
89+
}
90+
}

tests/MockServerClientNet.Tests/MockServerClientTest.cs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,40 @@
99
namespace MockServerClientNet.Tests
1010
{
1111
[Collection(nameof(MockServerCollection))]
12-
public class MockServerClientTest(
13-
MockServerFixture fixture,
14-
HttpScheme scheme = HttpScheme.Http,
15-
HttpClientHandler handler = null
16-
) : IClassFixture<MockServerFixture>, IDisposable
12+
public class MockServerClientTest : IClassFixture<MockServerFixture>, IDisposable
1713
{
18-
protected readonly MockServerClient MockServerClient = new(
19-
host: fixture.Host,
20-
port: fixture.Port,
21-
httpScheme: scheme,
22-
httpHandler: handler
23-
);
14+
protected readonly MockServerClient MockServerClient;
15+
protected readonly string HostHeader;
2416

25-
protected string HostHeader => $"{fixture.Host}:{fixture.Port}";
17+
protected MockServerClientTest(
18+
MockServerFixture fixture,
19+
HttpScheme scheme = HttpScheme.Http,
20+
HttpClientHandler handler = null
21+
)
22+
{
23+
MockServerClient = new(
24+
host: fixture.Host,
25+
port: fixture.Port,
26+
httpScheme: scheme,
27+
httpHandler: handler
28+
);
29+
HostHeader = fixture.HostHeader;
30+
}
31+
32+
protected MockServerClientTest(
33+
MockServerFixture fixture,
34+
HttpClient httpClient,
35+
HttpScheme scheme = HttpScheme.Http
36+
)
37+
{
38+
MockServerClient = new(
39+
host: fixture.Host,
40+
port: fixture.Port,
41+
httpScheme: scheme,
42+
httpClient: httpClient
43+
);
44+
HostHeader = fixture.HostHeader;
45+
}
2646

2747
public void Dispose()
2848
{
@@ -39,10 +59,8 @@ protected static void SendRequest(HttpRequestMessage request, out string respons
3959

4060
protected static async Task<HttpResponseMessage> SendRequestAsync(HttpRequestMessage request)
4161
{
42-
using (var client = new HttpClient())
43-
{
44-
return await client.SendAsync(request);
45-
}
62+
using var client = new HttpClient();
63+
return await client.SendAsync(request);
4664
}
4765

4866
protected HttpRequestMessage BuildRequest(HttpMethod method, string path, string body)
@@ -68,4 +86,4 @@ protected HttpRequestMessage BuildGetRequest(string path)
6886
return BuildRequest(HttpMethod.Get, path, string.Empty);
6987
}
7088
}
71-
}
89+
}

tests/MockServerClientNet.Tests/MockServerFixture.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public class MockServerFixture : IAsyncLifetime
2626
public int Port => int.Parse(Environment.GetEnvironmentVariable("MOCKSERVER_TEST_PORT")
2727
?? _container.GetMappedPublicPort(1080).ToString());
2828

29+
public string HostHeader => $"{Host}:{Port}";
30+
2931
public Task InitializeAsync()
3032
=> _container.StartAsync();
3133

0 commit comments

Comments
 (0)