Skip to content

Commit

Permalink
Cleaning up fixtures
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyzimarev committed Apr 3, 2024
1 parent 3165eaf commit 3e09a51
Show file tree
Hide file tree
Showing 25 changed files with 216 additions and 491 deletions.
1 change: 1 addition & 0 deletions Directory.Packages.props
Expand Up @@ -15,6 +15,7 @@
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="CsvHelper" Version="30.0.1" />
<PackageVersion Include="System.Text.Json" Version="8.0.3" />
<PackageVersion Include="WireMock.Net" Version="1.5.51" />
<PackageVersion Include="WireMock.Net.FluentAssertions" Version="1.5.51" />
</ItemGroup>
<ItemGroup Label="Compile dependencies">
Expand Down
18 changes: 6 additions & 12 deletions src/RestSharp.Serializers.CsvHelper/CsvHelperSerializer.cs
Expand Up @@ -5,26 +5,20 @@

namespace RestSharp.Serializers.CsvHelper;

public class CsvHelperSerializer : IDeserializer, IRestSerializer, ISerializer {
const string TextCsvContentType = "text/csv";

readonly CsvConfiguration _configuration;

public class CsvHelperSerializer(CsvConfiguration configuration) : IDeserializer, IRestSerializer, ISerializer {
public ISerializer Serializer => this;

public IDeserializer Deserializer => this;

public string[] AcceptedContentTypes => new[] { TextCsvContentType, "application/x-download" };
public string[] AcceptedContentTypes => [ContentType.Csv, "application/x-download"];

public SupportsContentType SupportsContentType => x => Array.IndexOf(AcceptedContentTypes, x) != -1 || x.Value.Contains("csv");

public DataFormat DataFormat => DataFormat.None;

public ContentType ContentType { get; set; } = TextCsvContentType;

public CsvHelperSerializer() => _configuration = new CsvConfiguration(CultureInfo.InvariantCulture);
public ContentType ContentType { get; set; } = ContentType.Csv;

public CsvHelperSerializer(CsvConfiguration configuration) => _configuration = configuration;
public CsvHelperSerializer() : this(new CsvConfiguration(CultureInfo.InvariantCulture)) { }

public T? Deserialize<T>(RestResponse response) {
try {
Expand All @@ -33,7 +27,7 @@ public class CsvHelperSerializer : IDeserializer, IRestSerializer, ISerializer {

using var stringReader = new StringReader(response.Content);

using var csvReader = new CsvReader(stringReader, _configuration);
using var csvReader = new CsvReader(stringReader, configuration);

var @interface = typeof(T).GetInterface("IEnumerable`1");

Expand Down Expand Up @@ -81,7 +75,7 @@ public class CsvHelperSerializer : IDeserializer, IRestSerializer, ISerializer {

using var stringWriter = new StringWriter();

using var csvWriter = new CsvWriter(stringWriter, _configuration);
using var csvWriter = new CsvWriter(stringWriter, configuration);

if (obj is IEnumerable records) {
csvWriter.WriteRecords(records);
Expand Down
3 changes: 2 additions & 1 deletion src/RestSharp/ContentType.cs
Expand Up @@ -29,6 +29,7 @@ public class ContentType : IEquatable<ContentType> {
public static readonly ContentType Json = "application/json";
public static readonly ContentType Xml = "application/xml";
public static readonly ContentType Plain = "text/plain";
public static readonly ContentType Csv = "text/csv";
public static readonly ContentType Binary = "application/octet-stream";
public static readonly ContentType GZip = "application/x-gzip";
public static readonly ContentType FormUrlEncoded = "application/x-www-form-urlencoded";
Expand Down Expand Up @@ -84,4 +85,4 @@ public class ContentType : IEquatable<ContentType> {
}

public override int GetHashCode() => _value.GetHashCode();
}
}
1 change: 1 addition & 0 deletions test/RestSharp.Tests.Integrated/DefaultParameterTests.cs
@@ -1,5 +1,6 @@
using RestSharp.Tests.Integrated.Fixtures;
using RestSharp.Tests.Integrated.Server;
using RestSharp.Tests.Shared.Fixtures;

namespace RestSharp.Tests.Integrated;

Expand Down
77 changes: 34 additions & 43 deletions test/RestSharp.Tests.Integrated/DownloadFileTests.cs
@@ -1,64 +1,56 @@
using System.Net;
using System.Text;
using RestSharp.Tests.Shared.Fixtures;
using System.Text;

namespace RestSharp.Tests.Integrated;

public sealed class DownloadFileTests : IDisposable {
const string LocalPath = "Assets/Koala.jpg";

public DownloadFileTests() {
_server = HttpServerFixture.StartServer("Assets/Koala.jpg", FileHandler);
var options = new RestClientOptions(_server.Url) { ThrowOnAnyError = true };
// _server = HttpServerFixture.StartServer("Assets/Koala.jpg", FileHandler);

var pathToFile = Path.Combine(_path, Path.Combine(LocalPath.Split('/')));

_server
.Given(Request.Create().WithPath($"/{LocalPath}"))
.RespondWith(Response.Create().WithBodyFromFile(pathToFile));
var options = new RestClientOptions($"{_server.Url}/{LocalPath}") { ThrowOnAnyError = true };
_client = new RestClient(options);
}

public void Dispose() => _server.Dispose();

void FileHandler(HttpListenerRequest request, HttpListenerResponse response) {
var pathToFile = Path.Combine(
_path,
Path.Combine(
request.Url!.Segments.Select(s => s.Replace("/", "")).ToArray()
)
);

using var reader = new StreamReader(pathToFile);

reader.BaseStream.CopyTo(response.OutputStream);
}

readonly HttpServerFixture _server;
readonly RestClient _client;
readonly string _path = AppDomain.CurrentDomain.BaseDirectory;
readonly WireMockServer _server = WireMockServer.Start();
readonly RestClient _client;
readonly string _path = AppDomain.CurrentDomain.BaseDirectory;

[Fact]
public async Task AdvancedResponseWriter_without_ResponseWriter_reads_stream() {
var tag = string.Empty;

// ReSharper disable once UseObjectOrCollectionInitializer
var rr = new RestRequest("Assets/Koala.jpg");

rr.AdvancedResponseWriter = (response, request) => {
var buf = new byte[16];
// ReSharper disable once MustUseReturnValue
response.Content.ReadAsStream().Read(buf, 0, buf.Length);
tag = Encoding.ASCII.GetString(buf, 6, 4);
return new RestResponse(request);
var rr = new RestRequest("") {
AdvancedResponseWriter = (response, request) => {
var buf = new byte[16];
// ReSharper disable once MustUseReturnValue
response.Content.ReadAsStream().Read(buf, 0, buf.Length);
tag = Encoding.ASCII.GetString(buf, 6, 4);
return new RestResponse(request);
}
};

await _client.ExecuteAsync(rr);
Assert.True(string.Compare("JFIF", tag, StringComparison.Ordinal) == 0);
Assert.Equal(0, string.Compare("JFIF", tag, StringComparison.Ordinal));
}

[Fact]
public async Task Handles_File_Download_Failure() {
var request = new RestRequest("Assets/Koala1.jpg");
var request = new RestRequest("");
var task = () => _client.DownloadDataAsync(request);
await task.Should().ThrowAsync<HttpRequestException>().WithMessage("Request failed with status code NotFound");
}

[Fact]
public async Task Handles_Binary_File_Download() {
var request = new RestRequest("Assets/Koala.jpg");
var request = new RestRequest("");
var response = await _client.DownloadDataAsync(request);
var expected = await File.ReadAllBytesAsync(Path.Combine(_path, "Assets", "Koala.jpg"));

Expand All @@ -69,22 +61,21 @@ public sealed class DownloadFileTests : IDisposable {
public async Task Writes_Response_To_Stream() {
var tempFile = Path.GetTempFileName();

// ReSharper disable once UseObjectOrCollectionInitializer
var request = new RestRequest("Assets/Koala.jpg");

request.ResponseWriter = responseStream => {
using var writer = File.OpenWrite(tempFile);
responseStream.CopyTo(writer);
return null;
var request = new RestRequest("") {
ResponseWriter = responseStream => {
using var writer = File.OpenWrite(tempFile);
responseStream.CopyTo(writer);
return null;
}
};

var response = await _client.DownloadDataAsync(request);

Assert.Null(response);

var fromTemp = await File.ReadAllBytesAsync(tempFile);
var expected = await File.ReadAllBytesAsync(Path.Combine(_path, "Assets", "Koala.jpg"));
var expected = await File.ReadAllBytesAsync(Path.Combine(_path, Path.Combine(LocalPath.Split('/'))));

Assert.Equal(expected, fromTemp);
}
}
}
1 change: 1 addition & 0 deletions test/RestSharp.Tests.Integrated/JsonBodyTests.cs
@@ -1,5 +1,6 @@
using System.Text.Json;
using RestSharp.Tests.Integrated.Fixtures;
using RestSharp.Tests.Shared.Fixtures;

namespace RestSharp.Tests.Integrated;

Expand Down
1 change: 1 addition & 0 deletions test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs
@@ -1,5 +1,6 @@
using HttpTracer;
using RestSharp.Tests.Integrated.Fixtures;
using RestSharp.Tests.Shared.Fixtures;

namespace RestSharp.Tests.Integrated;

Expand Down
6 changes: 3 additions & 3 deletions test/RestSharp.Tests.Integrated/ProxyTests.cs
Expand Up @@ -6,14 +6,14 @@ namespace RestSharp.Tests.Integrated;
public class ProxyTests {
[Fact]
public async Task Set_Invalid_Proxy_Fails() {
using var server = HttpServerFixture.StartServer((_, _) => { });
using var server = WireMockServer.Start();

var client = new RestClient(new RestClientOptions(server.Url) { Proxy = new WebProxy("non_existent_proxy", false) });
var client = new RestClient(new RestClientOptions(server.Url!) { Proxy = new WebProxy("non_existent_proxy", false) });
var request = new RestRequest();

var response = await client.ExecuteAsync(request);

Assert.False(response.IsSuccessful);
response.IsSuccessful.Should().BeFalse();
response.ErrorException.Should().BeOfType<HttpRequestException>();
}
}
1 change: 1 addition & 0 deletions test/RestSharp.Tests.Integrated/RequestBodyTests.cs
@@ -1,4 +1,5 @@
using RestSharp.Tests.Integrated.Fixtures;
using RestSharp.Tests.Shared.Fixtures;

namespace RestSharp.Tests.Integrated;

Expand Down
38 changes: 17 additions & 21 deletions test/RestSharp.Tests.Integrated/RootElementTests.cs
@@ -1,36 +1,32 @@
using System.Net;
using RestSharp.Serializers.Xml;
using RestSharp.Tests.Shared.Extensions;
using RestSharp.Tests.Shared.Fixtures;
using RestSharp.Serializers.Xml;

namespace RestSharp.Tests.Integrated;

public class RootElementTests {
[Fact]
public async Task Copy_RootElement_From_Request_To_IWithRootElement_Deserializer() {
using var server = HttpServerFixture.StartServer("success", Handle);

var client = new RestClient(server.Url, configureSerialization: cfg => cfg.UseXmlSerializer());
using var server = WireMockServer.Start();

const string xmlBody =
"""
<?xml version="1.0" encoding="utf-8" ?>
<Response>
<Success>
<Message>Works!</Message>
</Success>
</Response>
""";
server
.Given(Request.Create().WithPath("/success"))
.RespondWith(Response.Create().WithBody(xmlBody).WithHeader(KnownHeaders.ContentType, ContentType.Xml));

var client = new RestClient(server.Url!, configureSerialization: cfg => cfg.UseXmlSerializer());

var request = new RestRequest("success") { RootElement = "Success" };

var response = await client.ExecuteAsync<TestResponse>(request);

response.Data.Should().NotBeNull();
response.Data!.Message.Should().Be("Works!");

static void Handle(HttpListenerRequest req, HttpListenerResponse response) {
response.StatusCode = 200;
response.Headers.Add(KnownHeaders.ContentType, ContentType.Xml);

response.OutputStream.WriteStringUtf8(
@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<Response>
<Success>
<Message>Works!</Message>
</Success>
</Response>"
);
}
}
}
46 changes: 30 additions & 16 deletions test/RestSharp.Tests.Integrated/StructuredSyntaxSuffixTests.cs
@@ -1,15 +1,14 @@
using System.Net;
using System.Text;
using RestSharp.Serializers.Xml;
using RestSharp.Tests.Shared.Extensions;
using RestSharp.Tests.Shared.Fixtures;
using WireMock.Types;
using WireMock.Util;

// ReSharper disable UnusedAutoPropertyAccessor.Local

namespace RestSharp.Tests.Integrated;

public sealed class StructuredSyntaxSuffixTests : IDisposable {
readonly TestHttpServer _server;
readonly string _url;
readonly WireMockServer _server;

class Person {
public string Name { get; set; } = null!;
Expand All @@ -21,22 +20,37 @@ class Person {
const string JsonContent = @"{ ""name"":""Bob"", ""age"":50 }";

public StructuredSyntaxSuffixTests() {
_server = new TestHttpServer(0, "", HandleRequest);
_url = $"http://localhost:{_server.Port}";
_server = WireMockServer.Start();
_server.Given(Request.Create().WithPath("/").UsingGet()).RespondWith(Response.Create().WithCallback(Handle));
return;

static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> p) {
response.ContentType = request.QueryString["ct"];
response.OutputStream.WriteStringUtf8(request.QueryString["c"]);
response.StatusCode = 200;
static ResponseMessage Handle(IRequestMessage request) {
var response = new ResponseMessage {
Headers = new Dictionary<string, WireMockList<string>> {
[KnownHeaders.ContentType] = new(request.Query!["ct"])
},
StatusCode = 200,
BodyData = new BodyData {
BodyAsString = request.Query["c"].First(),
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.String
}
};
return response;
}

// static void HandleRequest(HttpListenerRequest request, HttpListenerResponse response, Dictionary<string, string> p) {
// response.ContentType = request.QueryString["ct"];
// response.OutputStream.WriteStringUtf8(request.QueryString["c"]);
// response.StatusCode = 200;
// }
}

public void Dispose() => _server.Dispose();

[Fact]
public async Task By_default_application_json_content_type_should_deserialize_as_JSON() {
var client = new RestClient(_url);
var client = new RestClient(_server.Url!);

var request = new RestRequest()
.AddParameter("ct", "application/json")
Expand All @@ -50,7 +64,7 @@ class Person {

[Fact]
public async Task By_default_content_types_with_JSON_structured_syntax_suffix_should_deserialize_as_JSON() {
var client = new RestClient(_url);
var client = new RestClient(_server.Url!);

var request = new RestRequest()
.AddParameter("ct", "application/vnd.somebody.something+json")
Expand All @@ -64,7 +78,7 @@ class Person {

[Fact]
public async Task By_default_content_types_with_XML_structured_syntax_suffix_should_deserialize_as_XML() {
var client = new RestClient(_url, configureSerialization: cfg => cfg.UseXmlSerializer());
var client = new RestClient(_server.Url!, configureSerialization: cfg => cfg.UseXmlSerializer());

var request = new RestRequest()
.AddParameter("ct", "application/vnd.somebody.something+xml")
Expand All @@ -78,7 +92,7 @@ class Person {

[Fact]
public async Task By_default_text_xml_content_type_should_deserialize_as_XML() {
var client = new RestClient(_url, configureSerialization: cfg => cfg.UseXmlSerializer());
var client = new RestClient(_server.Url!, configureSerialization: cfg => cfg.UseXmlSerializer());

var request = new RestRequest()
.AddParameter("ct", "text/xml")
Expand All @@ -89,4 +103,4 @@ class Person {
Assert.Equal("Bob", response.Data!.Name);
Assert.Equal(50, response.Data.Age);
}
}
}

0 comments on commit 3e09a51

Please sign in to comment.