Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExchangeRateUpdater - Mews Backend Developer Task #667

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
400 changes: 400 additions & 0 deletions jobs/Backend/Task/.gitignore

Large diffs are not rendered by default.

20 changes: 0 additions & 20 deletions jobs/Backend/Task/Currency.cs

This file was deleted.

23 changes: 0 additions & 23 deletions jobs/Backend/Task/ExchangeRate.cs

This file was deleted.

19 changes: 0 additions & 19 deletions jobs/Backend/Task/ExchangeRateProvider.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="Reqnroll.NUnit" Version="2.2.1" />
<PackageReference Include="nunit" Version="4.3.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="FluentAssertions" Version="7.0.0" />
<PackageReference Include="System.Management" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
<Folder Include="Drivers\" />
<Folder Include="Support\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ExchangeRateUpdater.Infrastructure\ExchangeRateUpdater.Infrastructure.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Feature: ExchangeRateUpdater

ExchangeRateUpdater is an API that allows retrieving exchange rates from the Czech National Bank

Scenario: ExchangeRateUpdater returns today's exchange rates
Given we have the ExchangeRateUpdater Api running
When we call the api/exchange-rates endpoint
Then the result should be today's exchange rates

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
global using FluentAssertions;
global using Reqnroll;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Diagnostics;
using System.Management;

namespace ExchangeRateUpdater.AcceptanceTests
{
internal class ProcessHelpers
{
internal static void KillProcessAndChildren(int processId)
{
var searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessId=" + processId);
var managementObjects = searcher.Get();
foreach (var managementObject in managementObjects)
{
KillProcessAndChildren(Convert.ToInt32(managementObject["ProcessId"]));
}

try
{
Process process = Process.GetProcessById(processId);
process.Kill();
process.WaitForExit(); // Optionally wait for the process to exit
}
catch (ArgumentException)
{
// Process already exited
}
catch (InvalidOperationException)
{
// Process already exited
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using ExchangeRateUpdater.Domain;
using ExchangeRateUpdater.Infrastructure.Data.Repositories;
using ExchangeRateUpdater.Infrastructure.HttpClients;
using Newtonsoft.Json;

namespace ExchangeRateUpdater.AcceptanceTests.StepDefinitions
{
[Binding]
public class ExchangeRateUpdaterStepDefinitions
{
IEnumerable<ExchangeRate>? _obtainedExchangeRates;
System.Diagnostics.Process? _process;


[Given("we have the ExchangeRateUpdater Api running")]
public void GivenWeHaveTheExchangeRateUpdaterApiRunning()
{
LaunchExchangeRateUpdaterApi();
}

private void LaunchExchangeRateUpdaterApi()
{
_process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = @"/C cd ..\..\..\..\ExchangeRateUpdater.Api\ && dotnet run";
_process.StartInfo = startInfo;
_process.Start();
}

[When("we call the api\\/exchange-rates endpoint")]
public void WhenWeCallTheApiExchange_RatesEndpoint()
{
using var httpClient = new HttpClient();
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, $" http://localhost:5129/api/exchange-rates");

var response = httpClient.SendAsync(httpRequestMessage);
response.Wait(30000);

if (response.Result.IsSuccessStatusCode)
{
var ratesTask = response.Result.Content.ReadAsStringAsync();
ratesTask.Wait(30000);

_obtainedExchangeRates = JsonConvert.DeserializeObject<IEnumerable<ExchangeRate>>(ratesTask.Result);
}
}

[Then("the result should be today's exchange rates")]
public void ThenTheResultShouldBeTodaysExchangeRates()
{
using var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://api.cnb.cz");

var cnbExchangeRates = (new CnbExchangeRateRepository(new CnbApiClient(httpClient))).GetTodayExchangeRatesAsync();
cnbExchangeRates.Wait(30000);

_obtainedExchangeRates.Should().NotBeNull();
_obtainedExchangeRates.Should().BeEquivalentTo(cnbExchangeRates.Result);

ProcessHelpers.KillProcessAndChildren(_process!.Id);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using ExchangeRateUpdater.ApplicationServices.ExchangeRates;
using ExchangeRateUpdater.ApplicationServices.ExchangeRates.Dto;
using Microsoft.AspNetCore.Mvc;

namespace ExchangeRateUpdater.Api.Controllers;

/// <summary>
/// Exchange Rates Controller
/// </summary>
/// <seealso cref="Microsoft.AspNetCore.Mvc.ControllerBase" />
[Route("api/exchange-rates")]
[ApiController]
public class ExchangeRatesController: ControllerBase
{
private readonly IExchangeRateService _exchangeRateService;

/// <summary>
/// Initializes a new instance of the <see cref="ExchangeRatesController"/> class.
/// </summary>
/// <param name="exchangeRateAppService">The exchange rate application service.</param>
public ExchangeRatesController(IExchangeRateService exchangeRateAppService)
{
_exchangeRateService = exchangeRateAppService;
}

/// <summary>
/// Gets the exchange rates.
/// </summary>
/// <returns>A Http status code 200 response containing the exchange rates for today's date.</returns>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesDefaultResponseType]
public async Task<ActionResult<IEnumerable<ExchangeRateDto>>> GetExchangeRates()
{
return (await _exchangeRateService.GetTodayExchangeRatesAsync()).ToList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ExchangeRateUpdater.ApplicationServices\ExchangeRateUpdater.ApplicationServices.csproj" />
<ProjectReference Include="..\ExchangeRateUpdater.Infrastructure\ExchangeRateUpdater.Infrastructure.csproj" />
</ItemGroup>

</Project>
Loading