Skip to content
Open
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 @@ -6,7 +6,7 @@
<Copyright>Copyright (c) 2020, nventive</Copyright>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<Product>HttpRecorder</Product>
<LangVersion>8.0</LangVersion>
<LangVersion>10.0</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />
<NoWarn>1701;1702;1998</NoWarn>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
Expand Down Expand Up @@ -34,8 +33,8 @@ public async Task ItShouldAnonymizeRequestQueryStringParameter()
.AnonymizeRequestQueryStringParameter("key");

var result = await anonymizer.Anonymize(interaction);
result.Messages[0].Response.RequestMessage.RequestUri.ToString().Should().Be("http://first/");
result.Messages[1].Response.RequestMessage.RequestUri.ToString().Should().Be($"https://second/?key={RulesInteractionAnonymizer.DefaultAnonymizerReplaceValue}&value=bar");
result.Messages[0].Response.RequestMessage!.RequestUri!.ToString().Should().Be("http://first/");
result.Messages[1].Response.RequestMessage!.RequestUri!.ToString().Should().Be($"https://second/?key={RulesInteractionAnonymizer.DefaultAnonymizerReplaceValue}&value=bar");
}

[Fact]
Expand All @@ -51,10 +50,10 @@ public async Task ItShouldAnonymizeRequestHeader()
.AnonymizeRequestHeader("X-RequestHeader");

var result = await anonymizer.Anonymize(interaction);
result.Messages[0].Response.RequestMessage.Headers.GetValues("X-RequestHeader").First().Should().Be(RulesInteractionAnonymizer.DefaultAnonymizerReplaceValue);
result.Messages[0].Response.RequestMessage!.Headers.GetValues("X-RequestHeader").First().Should().Be(RulesInteractionAnonymizer.DefaultAnonymizerReplaceValue);
}

private Interaction BuildInteraction(params HttpRequestMessage[] requests)
private static Interaction BuildInteraction(params HttpRequestMessage[] requests)
{
return new Interaction(
"test",
Expand Down
16 changes: 8 additions & 8 deletions HttpRecorder.Tests/ContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public async Task ItShouldWorkWithHttpRecorderContext()
options.BaseAddress = _fixture.ServerUri;
});

HttpResponseMessage passthroughResponse = null;
using (var context = new HttpRecorderContext((sp, builder) => new HttpRecorderConfiguration
HttpResponseMessage passthroughResponse;
using (new HttpRecorderContext((_, _) => new HttpRecorderConfiguration
{
Mode = HttpRecorderMode.Record,
InteractionName = nameof(ItShouldWorkWithHttpRecorderContext),
Expand All @@ -44,7 +44,7 @@ public async Task ItShouldWorkWithHttpRecorderContext()
passthroughResponse.EnsureSuccessStatusCode();
}

using (var context = new HttpRecorderContext((sp, builder) => new HttpRecorderConfiguration
using (new HttpRecorderContext((_, _) => new HttpRecorderConfiguration
{
Mode = HttpRecorderMode.Replay,
InteractionName = nameof(ItShouldWorkWithHttpRecorderContext),
Expand All @@ -70,8 +70,8 @@ public async Task ItShouldWorkWithHttpRecorderContextWhenNotRecording()
options.BaseAddress = _fixture.ServerUri;
});

HttpResponseMessage passthroughResponse = null;
using (var context = new HttpRecorderContext((sp, builder) => new HttpRecorderConfiguration
HttpResponseMessage passthroughResponse;
using (new HttpRecorderContext((_, _) => new HttpRecorderConfiguration
{
Enabled = false,
Mode = HttpRecorderMode.Record,
Expand All @@ -83,23 +83,23 @@ public async Task ItShouldWorkWithHttpRecorderContextWhenNotRecording()
passthroughResponse.EnsureSuccessStatusCode();
}

using (var context = new HttpRecorderContext((sp, builder) => new HttpRecorderConfiguration
using (new HttpRecorderContext((_, _) => new HttpRecorderConfiguration
{
Mode = HttpRecorderMode.Replay,
InteractionName = nameof(ItShouldWorkWithHttpRecorderContextWhenNotRecording),
}))
{
var client = services.BuildServiceProvider().GetRequiredService<IHttpClientFactory>().CreateClient("TheClient");
Func<Task> act = async () => await client.GetAsync(ApiController.JsonUri);
act.Should().Throw<HttpRecorderException>();
await act.Should().ThrowAsync<HttpRecorderException>();
}
}

[Fact]
public void ItShouldNotAllowMultipleContexts()
{
using var context = new HttpRecorderContext();
Action act = () => { var ctx2 = new HttpRecorderContext(); };
Action act = () => { _ = new HttpRecorderContext(); };
act.Should().Throw<HttpRecorderException>().WithMessage("*multiple*");
}
}
Expand Down
4 changes: 1 addition & 3 deletions HttpRecorder.Tests/HttpClientFactoryTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using HttpRecorder.Tests.Server;
Expand Down
14 changes: 6 additions & 8 deletions HttpRecorder.Tests/HttpRecorder.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.6.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="Moq" Version="4.10.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0" />
</ItemGroup>

<ItemGroup>
Expand Down
82 changes: 40 additions & 42 deletions HttpRecorder.Tests/HttpRecorderIntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -38,13 +40,13 @@ await ExecuteModeIterations(async (client, mode) =>
{
var response = await client.GetAsync(ApiController.JsonUri);

response.EnsureSuccessStatusCode();
response.Should().BeSuccessful();
response.Headers.Remove("Date");
if (mode == HttpRecorderMode.Passthrough)
{
passthroughResponse = response;
var result = await response.Content.ReadAsAsync<SampleModel>();
result.Name.Should().Be(SampleModel.DefaultName);
var result = await response.Content.ReadFromJsonAsync<SampleModel>();
result!.Name.Should().Be(SampleModel.DefaultName);
}
else
{
Expand All @@ -63,13 +65,13 @@ await ExecuteModeIterations(async (client, mode) =>
{
var response = await client.GetAsync($"{ApiController.JsonUri}?name={name}");

response.EnsureSuccessStatusCode();
response.Should().BeSuccessful();
response.Headers.Remove("Date");
if (mode == HttpRecorderMode.Passthrough)
{
passthroughResponse = response;
var result = await response.Content.ReadAsAsync<SampleModel>();
result.Name.Should().Be(name);
var result = await response.Content.ReadFromJsonAsync<SampleModel>();
result!.Name.Should().Be(name);
}
else
{
Expand All @@ -88,14 +90,14 @@ await ExecuteModeIterations(async (client, mode) =>
{
var response = await client.PostAsJsonAsync(ApiController.JsonUri, sampleModel);

response.EnsureSuccessStatusCode();
response.Should().BeSuccessful();
response.Headers.Remove("Date");

if (mode == HttpRecorderMode.Passthrough)
{
passthroughResponse = response;
var result = await response.Content.ReadAsAsync<SampleModel>();
result.Name.Should().Be(sampleModel.Name);
var result = await response.Content.ReadFromJsonAsync<SampleModel>();
result!.Name.Should().Be(sampleModel.Name);
}
else
{
Expand All @@ -119,13 +121,13 @@ await ExecuteModeIterations(async (client, mode) =>

var response = await client.PostAsync(ApiController.FormDataUri, formContent);

response.EnsureSuccessStatusCode();
response.Should().BeSuccessful();
response.Headers.Remove("Date");
if (mode == HttpRecorderMode.Passthrough)
{
passthroughResponse = response;
var result = await response.Content.ReadAsAsync<SampleModel>();
result.Name.Should().Be(sampleModel.Name);
var result = await response.Content.ReadFromJsonAsync<SampleModel>();
result!.Name.Should().Be(sampleModel.Name);
}
else
{
Expand Down Expand Up @@ -161,9 +163,9 @@ await ExecuteModeIterations(async (client, mode) =>
for (var i = 0; i < Concurrency; i++)
{
var response = responses[i];
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsAsync<SampleModel>();
result.Name.Should().Be($"{i}");
response.Should().BeSuccessful();
var result = await response.Content.ReadFromJsonAsync<SampleModel>();
result!.Name.Should().Be($"{i}");
}
}
else
Expand All @@ -183,21 +185,17 @@ public async Task ItShouldExecuteMultipleRequestsInSequenceWithRecorderModeAuto(
File.Delete(recordedFileName);
}

var client = CreateHttpClient(
HttpRecorderMode.Auto,
nameof(ItShouldExecuteMultipleRequestsInSequenceWithRecorderModeAuto));
var client = CreateHttpClient(HttpRecorderMode.Auto);
var response1 = await client.GetAsync($"{ApiController.JsonUri}?name=1");
var response2 = await client.GetAsync($"{ApiController.JsonUri}?name=2");
var result1 = await response1.Content.ReadAsAsync<SampleModel>();
result1.Name.Should().Be("1");
var result1 = await response1.Content.ReadFromJsonAsync<SampleModel>();
result1!.Name.Should().Be("1");

var result2 = await response2.Content.ReadAsAsync<SampleModel>();
result2.Name.Should().Be("2");
var result2 = await response2.Content.ReadFromJsonAsync<SampleModel>();
result2!.Name.Should().Be("2");

// We resolve to replay at this point.
client = CreateHttpClient(
HttpRecorderMode.Auto,
nameof(ItShouldExecuteMultipleRequestsInSequenceWithRecorderModeAuto));
client = CreateHttpClient(HttpRecorderMode.Auto);
var response2_1 = await client.GetAsync($"{ApiController.JsonUri}?name=1");
var response2_2 = await client.GetAsync($"{ApiController.JsonUri}?name=2");

Expand All @@ -215,7 +213,7 @@ await ExecuteModeIterations(async (client, mode) =>
{
var response = await client.GetAsync(ApiController.BinaryUri);

response.EnsureSuccessStatusCode();
response.Should().BeSuccessful();
response.Headers.Remove("Date");

if (mode == HttpRecorderMode.Passthrough)
Expand All @@ -239,7 +237,7 @@ public async Task ItShouldThrowIfDoesNotFindFile()

Func<Task> act = async () => await client.GetAsync(ApiController.JsonUri);

act.Should().Throw<HttpRecorderException>()
await act.Should().ThrowAsync<HttpRecorderException>()
.WithMessage($"*{TestFile}*");
}

Expand All @@ -251,7 +249,7 @@ public async Task ItShouldThrowIfFileIsCorrupted()

Func<Task> act = async () => await client.GetAsync(ApiController.JsonUri);

act.Should().Throw<HttpRecorderException>()
await act.Should().ThrowAsync<HttpRecorderException>()
.WithMessage($"*{file}*");
}

Expand All @@ -268,25 +266,25 @@ public async Task ItShouldThrowIfNoRequestCanBeMatched()

Func<Task> act = async () => await client.GetAsync(ApiController.JsonUri);

act.Should().Throw<HttpRecorderException>()
await act.Should().ThrowAsync<HttpRecorderException>()
.WithMessage($"*{ApiController.JsonUri}*");
}

[Theory]
[InlineData(202)]
[InlineData(301)]
[InlineData(303)]
[InlineData(404)]
[InlineData(500)]
[InlineData(502)]
public async Task ItShouldGetStatus(int statusCode)
[InlineData(HttpStatusCode.Accepted)]
[InlineData(HttpStatusCode.MovedPermanently)]
[InlineData(HttpStatusCode.RedirectMethod)]
[InlineData(HttpStatusCode.NotFound)]
[InlineData(HttpStatusCode.InternalServerError)]
[InlineData(HttpStatusCode.BadGateway)]
public async Task ItShouldGetStatus(HttpStatusCode statusCode)
{
HttpResponseMessage passthroughResponse = null;

await ExecuteModeIterations(async (client, mode) =>
{
var response = await client.GetAsync($"{ApiController.StatusCodeUri}?statusCode={statusCode}");
response.StatusCode.Should().Be(statusCode);
var response = await client.GetAsync($"{ApiController.StatusCodeUri}?statusCode={(int)statusCode}");
response.Should().HaveStatusCode(statusCode);
response.Headers.Remove("Date");

if (mode == HttpRecorderMode.Passthrough)
Expand All @@ -310,7 +308,7 @@ public async Task ItShouldOverrideModeWithEnvironmentVariable()

Func<Task> act = () => client.GetAsync(ApiController.JsonUri);

act.Should().Throw<HttpRecorderException>();
await act.Should().ThrowAsync<HttpRecorderException>();
}
finally
{
Expand All @@ -326,8 +324,8 @@ public async Task ItShouldAnonymize()
HttpRecorderMode.Record,
repository: repositoryMock.Object,
anonymizer: RulesInteractionAnonymizer.Default.AnonymizeRequestQueryStringParameter("key"));
Func<Task> act = async () => await client.GetAsync($"{ApiController.JsonUri}?key=foo");
act.Should().Throw<InvalidOperationException>(); // Because we don't act on the stream in the repository. That's fine.

await client.GetAsync($"{ApiController.JsonUri}?key=foo");

repositoryMock.Verify(
x => x.StoreAsync(
Expand Down
Loading