Skip to content

Commit

Permalink
Added example to display error of AppendHttpCallStub when there are q…
Browse files Browse the repository at this point in the history
…uery params with curly brackets

* Added complex parameter logic as example in controller, service and proxy.
* Re-added previously overwritten test
* Separated tests to different files
  • Loading branch information
Rexrover2 authored May 27, 2024
1 parent 6fe5798 commit 8eb4cef
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 3 deletions.
27 changes: 27 additions & 0 deletions Examples/MovieProject/MovieProject.Logic/DTO/UserSearchModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace MovieProject.Logic.DTO
{
using System.Text.Json.Serialization;

namespace MovieProject.Logic.Proxy.DTO
{

public class UserSearchModel
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("username")]
public string Username { get; set; }

[JsonPropertyName("email")]
public string Email { get; set; }

[JsonPropertyName("phone")]
public string Phone { get; set; }

[JsonPropertyName("website")]
public string Website { get; set; }
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using MovieProject.Logic.Proxy.DTO;

namespace MovieProject.Logic.Extensions
{
public static class UserMapperExtensions
{
public static UserSearchModel MapUserSearchModelDtoToProxyDto(
this DTO.MovieProject.Logic.Proxy.DTO.UserSearchModel searchModel)
{
return new UserSearchModel
{
Name = searchModel.Name,
Username = searchModel.Username,
Email = searchModel.Email,
Phone = searchModel.Phone,
Website = searchModel.Website
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@
<WCFMetadata Include="Connected Services" />
</ItemGroup>

<ItemGroup>
<Folder Include="Models\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Text.Json.Serialization;

namespace MovieProject.Logic.Proxy.DTO
{

public class UserSearchModel
{
[JsonPropertyName("name")]
public string Name { get; set; }

[JsonPropertyName("username")]
public string Username { get; set; }

[JsonPropertyName("email")]
public string Email { get; set; }

[JsonPropertyName("phone")]
public string Phone { get; set; }

[JsonPropertyName("website")]
public string Website { get; set; }
}

}
20 changes: 20 additions & 0 deletions Examples/MovieProject/MovieProject.Logic/Proxy/UserProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
using System;
using System.Net;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using MovieProject.Logic.Proxy.DTO;

namespace MovieProject.Logic.Proxy
{
public interface IUserProxy
{
Task<DTO.User[]> GetUsers();
Task<DTO.User[]> GetSearchUsers(UserSearchModel searchModel);
}

public class UserProxy : BaseProxy, IUserProxy
Expand Down Expand Up @@ -36,5 +40,21 @@ public UserProxy(HttpClient client,

return result;
}

public async Task<DTO.User[]> GetSearchUsers(UserSearchModel searchModel)
{
string serialisedQueryParameter = JsonSerializer.Serialize(searchModel);
string route = $"searchUsers?userSearchModel={serialisedQueryParameter}";

var result = await Send(HttpMethod.Get, route, (DTO.User[] users, HttpStatusCode status) =>
{
if(status != HttpStatusCode.OK || users == null)
throw new Exception("Unexpected response");

return users;
});

return result;
}
}
}
15 changes: 12 additions & 3 deletions Examples/MovieProject/MovieProject.Logic/Service/UserService.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
using MovieProject.Logic.Proxy;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MovieProject.Logic.Proxy;
using MovieProject.Logic.Proxy.DTO;

namespace MovieProject.Logic
namespace MovieProject.Logic.Service
{
public interface IUserService
{
Task<List<string>> GetUsers();
Task<List<string>> GetSearchUsers(UserSearchModel searchModel);
}

public class UserService : IUserService
Expand All @@ -25,5 +27,12 @@ public async Task<List<string>> GetUsers()

return users.Select(c=> c.Name).OrderBy(c=> c).ToList();
}

public async Task<List<string>> GetSearchUsers(UserSearchModel searchModel)
{
var users = await _userProxy.GetSearchUsers(searchModel);

return users.Select(c=> c.Name).OrderBy(c=> c).ToList();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using FluentAssertions.Execution;
using IsolatedTests.ComponentTestings;
using MovieProject.Logic.DTO.MovieProject.Logic.Proxy.DTO;
using Newtonsoft.Json;
using SystemTestingTools;
using Xunit;

namespace MovieProject.IsolatedTests.ComponentTesting
{
[Collection("SharedServer collection")]
[Trait("Project", "User Component Tests (Happy)")]
public class SearchUserHappyTests
{
private readonly TestServerFixture Fixture;

private static string Url = "https://jsonplaceholder.typicode.com/searchUsers";

public SearchUserHappyTests(TestServerFixture fixture)
{
Fixture = fixture;
}

[Fact]
public async Task When_UserSearchesWithValidParameters_Then_ReturnListProperly()
{
// arrange
var complexParameter = new UserSearchModel
{
Username = "Bret",
};
var serialisedComplexParameters = JsonConvert.SerializeObject(complexParameter);
var expectedResponse = new List<string>()
{
"Leanne Graham"
};

var client = Fixture.Server.CreateClient();
client.CreateSession();
var response = ResponseFactory.FromFiddlerLikeResponseFile($"{Fixture.StubsFolder}/UserApi/Real_Responses/Happy/200_SearchListUsers.txt");

client.AppendHttpCallStub(HttpMethod.Get, new System.Uri(@$"{Url}?userSearchModel={serialisedComplexParameters}"), response);

// act
var httpResponse = await client.GetAsync("/api/users");

using (new AssertionScope())
{
// assert logs
var logs = client.GetSessionLogs();
logs.Should().BeEmpty();

// assert outgoing
var outgoingRequests = client.GetSessionOutgoingRequests();
outgoingRequests.Count.Should().Be(1);
outgoingRequests[0].GetEndpoint().Should().Be($"GET {Url}");
outgoingRequests[0].GetHeaderValue("Referer").Should().Be(MovieProject.Logic.Constants.Website);

// assert return
httpResponse.StatusCode.Should().Be(HttpStatusCode.OK);

var list = await httpResponse.ReadJsonBody<List<string>>();
list.Count.Should().Be(1);
list.Should().BeEquivalentTo(expectedResponse);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
using MovieProject.Logic;
using System.Collections.Generic;
using System.Threading.Tasks;
using MovieProject.Logic.DTO.MovieProject.Logic.Proxy.DTO;
using MovieProject.Logic.Extensions;
using MovieProject.Logic.Service;

namespace MovieProject.Web.Controllers
{
Expand All @@ -22,5 +25,13 @@ public async Task<List<string>> GetUsers()
// second controller with separate dependency used for testing SystemTestingTools
return await _userService.GetUsers();
}

[HttpPost("searchUsers")]
public async Task<List<string>> GetSearchUsers([FromBody] UserSearchModel searchModel)
{
var proxyDtoSearchModel = searchModel.MapUserSearchModelDtoToProxyDto();
// second controller with separate dependency used for testing SystemTestingTools
return await _userService.GetSearchUsers(proxyDtoSearchModel);
}
}
}

0 comments on commit 8eb4cef

Please sign in to comment.