Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System.Threading.Tasks;
using AutoFixture;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NSubstitute;
using Paymentsense.Coding.Challenge.Api.Controllers;
using Paymentsense.Coding.Challenge.Api.Models;
using Paymentsense.Coding.Challenge.Api.Parameters;
using Paymentsense.Coding.Challenge.Api.Services;
using Xunit;

namespace Paymentsense.Coding.Challenge.Api.Tests.Controllers
{
public class CountriesControllerTests
{
private readonly Fixture _fixture;

private readonly ICountriesRestService _countriesRestService;

private readonly CountriesController _controller;

public CountriesControllerTests()
{
_fixture = new Fixture();

_countriesRestService = Substitute.For<ICountriesRestService>();
_controller = new CountriesController(_countriesRestService);
}

[Fact]
public async Task Get_Pagination_OnInvoke_ReturnsExpectedMessage()
{
var queryParams = new GetCountriesQueryParameters
{
Page = 0,
Take = 10
};

var expectedResponse = _fixture.Create<CountryForPaginationResponse>();

_countriesRestService.GetAllForPagination(queryParams.Page, queryParams.Take).Returns(expectedResponse);

var response = await _controller.GetAllCountriesForPagination(queryParams);

var result = response.Result as OkObjectResult;
result.StatusCode.Should().Be(StatusCodes.Status200OK);
result.Value.Should().Be(expectedResponse);
}

[Fact]
public async Task Get_GetByCode_OnInvoke_ReturnsExpectedMessage()
{
var code = "Code";

var expectedResponse = _fixture.Create<Country>();

_countriesRestService.GetByCode(code).Returns(expectedResponse);

var response = await _controller.GetByCode(code);

var result = response.Result as OkObjectResult;
result.StatusCode.Should().Be(StatusCodes.Status200OK);
result.Value.Should().Be(expectedResponse);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using FluentAssertions;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;

namespace Paymentsense.Coding.Challenge.Api.Tests.Integration
{
public class CountriesTests
{
private readonly HttpClient _client;

public CountriesTests()
{
var builder = new WebHostBuilder().UseStartup<Startup>();
var testServer = new TestServer(builder);
_client = testServer.CreateClient();
}

[Fact]
public async Task Countries_Pagination_OnInvoke_ReturnsValidResponse()
{
var response = await _client.GetAsync("countries/pagination?page=1&take=10");
var responseString = await response.Content.ReadAsStringAsync();

response.StatusCode.Should().Be(StatusCodes.Status200OK);
responseString.Should().NotBeNull();
}

[Fact]
public async Task Countries_Pagination_OnInvoke_ReturnsBadRequest()
{
var response = await _client.GetAsync("countries/pagination?page=1;take=0");

response.StatusCode.Should().Be(StatusCodes.Status400BadRequest);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Threading.Tasks;
using Xunit;

namespace Paymentsense.Coding.Challenge.Api.Tests
namespace Paymentsense.Coding.Challenge.Api.Tests.Integration
{
public class HealthcheckTests
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using FluentAssertions;
using Paymentsense.Coding.Challenge.Api.Parameters;
using Xunit;

namespace Paymentsense.Coding.Challenge.Api.Tests.Parameters
{
public class GetCountriesQueryParametersTests
{
private readonly List<Tuple<GetCountriesQueryParameters, string>> InvalidTestCases = new List<Tuple<GetCountriesQueryParameters, string>>
{
new Tuple<GetCountriesQueryParameters, string>
(
new GetCountriesQueryParameters
{
Page = 0,
Take = 1
},
"Please enter a value larger or equal to 1"
),
new Tuple<GetCountriesQueryParameters, string>
(
new GetCountriesQueryParameters
{
Page = 1,
Take = 0
},
"Please enter a value larger or equal to 1"
)
};

[Fact]
public void GetCountriesQueryParameters_Should_Be_Valid()
{
var model = new GetCountriesQueryParameters
{
Page = 1,
Take = 1
};

var results = ValidateModel(model);

results.Count.Should().Be(0);
}

[Theory]
[InlineData(0)]
[InlineData(1)]
public void GetCountriesQueryParameters_Should_Be_InValid(int index)
{
var testCase = InvalidTestCases[index];

var model = testCase.Item1;

var results = ValidateModel(model);

results[0].ErrorMessage.Should().Be(testCase.Item2);
}

private List<ValidationResult> ValidateModel<T>(T model)
{
var validationResults = new List<ValidationResult>();
var ctx = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, ctx, validationResults, true);
return validationResults;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AutoFixture" Version="4.15.0" />
<PackageReference Include="FluentAssertions" Version="5.9.0" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="NSubstitute" Version="4.2.2" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
Expand All @@ -21,10 +23,6 @@
</PackageReference>
</ItemGroup>

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

<ItemGroup>
<ProjectReference Include="..\Paymentsense.Coding.Challenge.Api\Paymentsense.Coding.Challenge.Api.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<ProjectConfiguration>
<Settings>
<HiddenComponentWarnings>
<Value>AspNetTestHostCompatibility</Value>
</HiddenComponentWarnings>
</Settings>
</ProjectConfiguration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using AutoFixture;
using FluentAssertions;
using MemoryCache.Testing.NSubstitute;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using Paymentsense.Coding.Challenge.Api.Models;
using Paymentsense.Coding.Challenge.Api.Services;
using Paymentsense.Coding.Challenge.Api.Tests.TestUtilities;
using Xunit;

namespace Paymentsense.Coding.Challenge.Api.Tests.Services
{
public class CountriesRestServiceTests
{
private readonly Fixture _fixture;

private readonly MockHttpMessageHandler _mockHttpMessageHandler;
private readonly HttpClient _httpClient;
private readonly IMemoryCache _memoryCache;

private readonly CountriesRestService _sut;

public CountriesRestServiceTests()
{
_fixture = new Fixture();

_mockHttpMessageHandler = new MockHttpMessageHandler();
_httpClient = new HttpClient(_mockHttpMessageHandler);

_memoryCache = Create.MockedMemoryCache();

_sut = new CountriesRestService(_httpClient, _memoryCache);
}

[Fact]
public async Task GetAllForPagination_OnInvoke_Returns_ResponseObject()
{
int page = 1;
int take = 10;

var returnedCountries = _fixture.CreateMany<CountryForPagination>(2);

_mockHttpMessageHandler.ResponseContent = JsonConvert.SerializeObject(returnedCountries);

var expectedResponse = new CountryForPaginationResponse
{
Countries = returnedCountries,
Meta = new PaginationMeta
{
Page = 1,
Take = 10,
MaxPage = 1,
TotalItems = 2
}
};

var result = await _sut.GetAllForPagination(page, take);

result.Should().BeEquivalentTo(expectedResponse);
}

[Fact]
public async Task GetAllForPagination_OnInvoke_Returns_ResponseObject_FromMemory()
{
int page = 1;
int take = 10;

var returnedCountries = _fixture.CreateMany<CountryForPagination>(2);

_memoryCache.Set("COUNTRIES_CACHE_KEY", returnedCountries);

var expectedResponse = new CountryForPaginationResponse
{
Countries = returnedCountries,
Meta = new PaginationMeta
{
Page = 1,
Take = 10,
MaxPage = 1,
TotalItems = 2
}
};

var result = await _sut.GetAllForPagination(page, take);

result.Should().BeEquivalentTo(expectedResponse);
}

[Fact]
public async Task GetAllForPagination_OnInvoke_Returns_ResponseObject_WithCorrectPageTake()
{
int page = 2;
int take = 10;

var returnedCountries = _fixture.CreateMany<CountryForPagination>(25);

_mockHttpMessageHandler.ResponseContent = JsonConvert.SerializeObject(returnedCountries);

var expectedResponse = new CountryForPaginationResponse
{
Countries = returnedCountries.Skip((page-1) * take).Take(take),
Meta = new PaginationMeta
{
Page = 2,
Take = 10,
MaxPage = 3,
TotalItems = 25
}
};

var result = await _sut.GetAllForPagination(page, take);

result.Should().BeEquivalentTo(expectedResponse);
}

[Fact]
public async Task GetByCode_OnInvoke_Returns_ResponseObject()
{
string code = "AAA";

var expectedResponse = _fixture.Create<Country>();

_mockHttpMessageHandler.ResponseContent = JsonConvert.SerializeObject(expectedResponse);

var result = await _sut.GetByCode(code);

result.Should().BeEquivalentTo(expectedResponse);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Paymentsense.Coding.Challenge.Api.Tests.TestUtilities
{
public class MockHttpMessageHandler : HttpMessageHandler
{
public string ResponseContent { get; set; }

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(ResponseContent)
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<SolutionConfiguration>
<Settings>
<AllowParallelTestExecution>False</AllowParallelTestExecution>
<SolutionConfigured>True</SolutionConfigured>
</Settings>
</SolutionConfiguration>
Loading