From 89e7ce84497eab7e2999474317c6c0353e4351af Mon Sep 17 00:00:00 2001 From: Matthias Langhard Date: Fri, 21 May 2021 22:13:04 +0200 Subject: [PATCH] chore: refactoring some code to introduce a common base class for all api classes --- src/ClientContacts/ClientContactsApi.cs | 49 ++++++++ src/ClientContacts/IClientContactsApi.cs | 41 +++++++ src/ClientContacts/IPaymoClientContactsApi.cs | 20 ---- ...PaymoClientContact.cs => ClientContact.cs} | 2 +- .../Models/GetClientContactsResponse.cs | 2 +- src/ClientContacts/PaymoClientContactsApi.cs | 72 ------------ src/Clients/ClientsApi.cs | 49 ++++++++ src/Clients/IClientsApi.cs | 41 +++++++ src/Clients/IPaymoClientsApi.cs | 14 --- .../Models/{PaymoClient.cs => Client.cs} | 4 +- ...tClientsResponse.cs => ClientsResponse.cs} | 4 +- src/Clients/PaymoClientsApi.cs | 72 ------------ .../{PaymoApiException.cs => ApiException.cs} | 4 +- .../{PaymoApiOptions.cs => ApiOptions.cs} | 2 +- .../HttpResponseMessageExtensions.cs | 2 +- src/Extensions/PaymoApiExtensions.cs | 14 ++- .../{PaymoApiClient.cs => ApiClient.cs} | 4 +- src/Shared/BaseApi.cs | 80 +++++++++++++ .../{BasePaymoModel.cs => BaseModel.cs} | 2 +- .../{IPaymoApiClient.cs => IApiClient.cs} | 2 +- src/Shared/IBaseApi.cs | 41 +++++++ src/Tasks/IPaymoTasksApi.cs | 14 --- src/Tasks/ITasksApi.cs | 40 +++++++ src/Tasks/Models/{PaymoTask.cs => Task.cs} | 2 +- .../{GetTasksResponse.cs => TasksResponse.cs} | 4 +- src/Tasks/PaymoTasksApi.cs | 73 ------------ src/Tasks/TasksApi.cs | 53 +++++++++ tests/ClientContactsApiTests.cs | 91 +++++++++++++++ tests/ClientsApiTests.cs | 98 ++++++++++++++++ tests/DependencyFactory.cs | 8 +- tests/PaymoClientContactsApiTests.cs | 89 -------------- tests/PaymoClientsApiTests.cs | 81 ------------- tests/PaymoTasksApiTests.cs | 89 -------------- tests/TasksApiTests.cs | 109 ++++++++++++++++++ 34 files changed, 721 insertions(+), 551 deletions(-) create mode 100644 src/ClientContacts/ClientContactsApi.cs create mode 100644 src/ClientContacts/IClientContactsApi.cs delete mode 100644 src/ClientContacts/IPaymoClientContactsApi.cs rename src/ClientContacts/Models/{PaymoClientContact.cs => ClientContact.cs} (95%) delete mode 100644 src/ClientContacts/PaymoClientContactsApi.cs create mode 100644 src/Clients/ClientsApi.cs create mode 100644 src/Clients/IClientsApi.cs delete mode 100644 src/Clients/IPaymoClientsApi.cs rename src/Clients/Models/{PaymoClient.cs => Client.cs} (93%) rename src/Clients/Models/{GetClientsResponse.cs => ClientsResponse.cs} (60%) delete mode 100644 src/Clients/PaymoClientsApi.cs rename src/Exceptions/{PaymoApiException.cs => ApiException.cs} (52%) rename src/Extensions/{PaymoApiOptions.cs => ApiOptions.cs} (84%) rename src/Shared/{PaymoApiClient.cs => ApiClient.cs} (62%) create mode 100644 src/Shared/BaseApi.cs rename src/Shared/{BasePaymoModel.cs => BaseModel.cs} (86%) rename src/Shared/{IPaymoApiClient.cs => IApiClient.cs} (57%) create mode 100644 src/Shared/IBaseApi.cs delete mode 100644 src/Tasks/IPaymoTasksApi.cs create mode 100644 src/Tasks/ITasksApi.cs rename src/Tasks/Models/{PaymoTask.cs => Task.cs} (96%) rename src/Tasks/Models/{GetTasksResponse.cs => TasksResponse.cs} (61%) delete mode 100644 src/Tasks/PaymoTasksApi.cs create mode 100644 src/Tasks/TasksApi.cs create mode 100644 tests/ClientContactsApiTests.cs create mode 100644 tests/ClientsApiTests.cs delete mode 100644 tests/PaymoClientContactsApiTests.cs delete mode 100644 tests/PaymoClientsApiTests.cs delete mode 100644 tests/PaymoTasksApiTests.cs create mode 100644 tests/TasksApiTests.cs diff --git a/src/ClientContacts/ClientContactsApi.cs b/src/ClientContacts/ClientContactsApi.cs new file mode 100644 index 0000000..fd5cfc7 --- /dev/null +++ b/src/ClientContacts/ClientContactsApi.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Novaloop.PaymoApi.ClientContacts.Models; +using Novaloop.PaymoApi.Shared; + +namespace Novaloop.PaymoApi.ClientContacts +{ + public class ClientContactsApi : IClientContactsApi + { + private readonly IBaseApi _baseApi; + + public ClientContactsApi(IBaseApi baseApi) + { + _baseApi = baseApi; + _baseApi.ResourceUri = "clientcontacts"; + } + + /// + public async Task> GetClientContacts() + { + return (await _baseApi.GetAll()).ClientContacts; + } + + /// + public async Task GetClientContact(int clientContactId) + { + return (await _baseApi.Get(clientContactId)).ClientContacts.Single(); + } + + /// + public async Task CreateClientContact(ClientContact clientContact) + { + return (await _baseApi.Create(clientContact)).ClientContacts.Single(); + } + + /// + public async Task DeleteClientContact(int clientContactId) + { + await _baseApi.Delete(clientContactId); + } + + /// + public async Task UpdateClientContact(ClientContact clientContact, int clientContactId) + { + await _baseApi.Update(clientContact, clientContactId); + } + } +} \ No newline at end of file diff --git a/src/ClientContacts/IClientContactsApi.cs b/src/ClientContacts/IClientContactsApi.cs new file mode 100644 index 0000000..e4c0660 --- /dev/null +++ b/src/ClientContacts/IClientContactsApi.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Novaloop.PaymoApi.ClientContacts.Models; + +namespace Novaloop.PaymoApi.ClientContacts +{ + public interface IClientContactsApi + { + /// + /// Receive all existing client contacts + /// + Task> GetClientContacts(); + + /// + /// Retrieve an existing client contact by id + /// + /// id of the contact + /// + Task GetClientContact(int clientContactId); + + /// + /// Create a new client contact + /// + Task CreateClientContact(ClientContact clientContact); + + /// + /// Delete a client contact + /// + /// + /// + Task DeleteClientContact(int clientContactId); + + /// + /// Update an existing client contact + /// + /// + /// + /// + Task UpdateClientContact(ClientContact clientContact, int clientContactId); + } +} \ No newline at end of file diff --git a/src/ClientContacts/IPaymoClientContactsApi.cs b/src/ClientContacts/IPaymoClientContactsApi.cs deleted file mode 100644 index 8259570..0000000 --- a/src/ClientContacts/IPaymoClientContactsApi.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Novaloop.PaymoApi.ClientContacts.Models; - -namespace Novaloop.PaymoApi.ClientContacts -{ - public interface IPaymoClientContactsApi - { - Task> GetClientContacts(); - Task GetClientContact(int contactId); - Task CreateClientContact(PaymoClientContact clientContact); - - /// - /// Deleta a client contact - /// - /// - /// - Task DeleteClientContact(int clientContactId); - } -} \ No newline at end of file diff --git a/src/ClientContacts/Models/PaymoClientContact.cs b/src/ClientContacts/Models/ClientContact.cs similarity index 95% rename from src/ClientContacts/Models/PaymoClientContact.cs rename to src/ClientContacts/Models/ClientContact.cs index eb64528..08f8ebb 100644 --- a/src/ClientContacts/Models/PaymoClientContact.cs +++ b/src/ClientContacts/Models/ClientContact.cs @@ -3,7 +3,7 @@ using Novaloop.PaymoApi.Shared; namespace Novaloop.PaymoApi.ClientContacts.Models { - public class PaymoClientContact : BasePaymoModel + public class ClientContact : BaseModel { [JsonProperty("client_id")] public int ClientId { get; set; } diff --git a/src/ClientContacts/Models/GetClientContactsResponse.cs b/src/ClientContacts/Models/GetClientContactsResponse.cs index 5cccc00..29b1ada 100644 --- a/src/ClientContacts/Models/GetClientContactsResponse.cs +++ b/src/ClientContacts/Models/GetClientContactsResponse.cs @@ -6,6 +6,6 @@ namespace Novaloop.PaymoApi.ClientContacts.Models public class GetClientContactsResponse { [JsonProperty("clientcontacts")] - public IEnumerable ClientContacts { get; set; } + public IEnumerable ClientContacts { get; set; } } } \ No newline at end of file diff --git a/src/ClientContacts/PaymoClientContactsApi.cs b/src/ClientContacts/PaymoClientContactsApi.cs deleted file mode 100644 index 06d32ac..0000000 --- a/src/ClientContacts/PaymoClientContactsApi.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Options; -using Novaloop.PaymoApi.ClientContacts.Models; -using Novaloop.PaymoApi.Extensions; -using Novaloop.PaymoApi.Shared; - -namespace Novaloop.PaymoApi.ClientContacts -{ - public class PaymoClientContactsApi : IPaymoClientContactsApi - { - private readonly PaymoApiOptions _options; - private readonly HttpClient _client; - private const string ResourceUri = "clientcontacts"; - - public PaymoClientContactsApi(PaymoApiClient paymoApiClient, IOptions options) - { - _options = options.Value; - _client = paymoApiClient.Client; - } - - /// - /// Receive all existing client contacts - /// - public async Task> GetClientContacts() - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.GetAsync($"api/{ResourceUri}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).ClientContacts; - } - - /// - /// Retrieve an existing client contact by id - /// - /// id of the contact - /// - public async Task GetClientContact(int clientContactId) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.GetAsync($"api/{ResourceUri}/{clientContactId}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).ClientContacts.Single(); - } - - - /// - /// Create a new client contact - /// - public async Task CreateClientContact(PaymoClientContact clientContact) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.PostAsJsonAsync($"api/{ResourceUri}", clientContact); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).ClientContacts.Single(); - } - - /// - /// Deleta a client contact - /// - /// - /// - public async Task DeleteClientContact(int clientContactId) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.DeleteAsync($"api/{ResourceUri}/{clientContactId}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - } - } -} \ No newline at end of file diff --git a/src/Clients/ClientsApi.cs b/src/Clients/ClientsApi.cs new file mode 100644 index 0000000..e688974 --- /dev/null +++ b/src/Clients/ClientsApi.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Novaloop.PaymoApi.Clients.Models; +using Novaloop.PaymoApi.Shared; + +namespace Novaloop.PaymoApi.Clients +{ + public class ClientsApi : IClientsApi + { + private readonly IBaseApi _baseApi; + + public ClientsApi(IBaseApi baseApi) + { + _baseApi = baseApi; + _baseApi.ResourceUri = "clients"; + } + + /// + public async Task> GetClients() + { + return (await _baseApi.GetAll()).Clients; + } + + /// + public async Task GetClient(int clientId) + { + return (await _baseApi.Get(clientId)).Clients.Single(); + } + + /// + public async Task CreateClient(Client client) + { + return (await _baseApi.Create(client)).Clients.Single(); + } + + /// + public async Task DeleteClient(int clientId) + { + await _baseApi.Delete(clientId); + } + + /// + public async Task UpdateClient(Client client, int clientId) + { + await _baseApi.Update(client, clientId); + } + } +} \ No newline at end of file diff --git a/src/Clients/IClientsApi.cs b/src/Clients/IClientsApi.cs new file mode 100644 index 0000000..b6d45c6 --- /dev/null +++ b/src/Clients/IClientsApi.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Novaloop.PaymoApi.Clients.Models; + +namespace Novaloop.PaymoApi.Clients +{ + public interface IClientsApi + { + /// + /// Receive all existing clients + /// + Task> GetClients(); + + /// + /// Retrieve an existing client by id + /// + /// id of the contact + /// + Task GetClient(int clientId); + + /// + /// Create a new client + /// + Task CreateClient(Client client); + + /// + /// Delete a client + /// + /// + /// + Task DeleteClient(int clientId); + + /// + /// Update an existing client + /// + /// + /// + /// + Task UpdateClient(Client client, int clientId); + } +} \ No newline at end of file diff --git a/src/Clients/IPaymoClientsApi.cs b/src/Clients/IPaymoClientsApi.cs deleted file mode 100644 index 2d9e462..0000000 --- a/src/Clients/IPaymoClientsApi.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Novaloop.PaymoApi.Clients.Models; - -namespace Novaloop.PaymoApi.Clients -{ - public interface IPaymoClientsApi - { - Task> GetClients(); - Task GetClient(int clientId); - Task CreateClient(PaymoClient client); - Task DeleteClient(int clientId); - } -} \ No newline at end of file diff --git a/src/Clients/Models/PaymoClient.cs b/src/Clients/Models/Client.cs similarity index 93% rename from src/Clients/Models/PaymoClient.cs rename to src/Clients/Models/Client.cs index 1c58cbf..828cc95 100644 --- a/src/Clients/Models/PaymoClient.cs +++ b/src/Clients/Models/Client.cs @@ -3,7 +3,7 @@ using Novaloop.PaymoApi.Shared; namespace Novaloop.PaymoApi.Clients.Models { - public class PaymoClient : BasePaymoModel + public class Client : BaseModel { [JsonProperty("name")] public string Name { get; set; } @@ -42,7 +42,7 @@ namespace Novaloop.PaymoApi.Clients.Models public string FiscalInformation { get; set; } [JsonProperty("active")] - public bool Active { get; set; } + public bool Active { get; set; } = true; public override string ToString() { diff --git a/src/Clients/Models/GetClientsResponse.cs b/src/Clients/Models/ClientsResponse.cs similarity index 60% rename from src/Clients/Models/GetClientsResponse.cs rename to src/Clients/Models/ClientsResponse.cs index b5b4996..e391b9a 100644 --- a/src/Clients/Models/GetClientsResponse.cs +++ b/src/Clients/Models/ClientsResponse.cs @@ -3,9 +3,9 @@ using Newtonsoft.Json; namespace Novaloop.PaymoApi.Clients.Models { - public class GetClientsResponse + public class ClientsResponse { [JsonProperty("clients")] - public IEnumerable Clients { get; set; } + public IEnumerable Clients { get; set; } } } \ No newline at end of file diff --git a/src/Clients/PaymoClientsApi.cs b/src/Clients/PaymoClientsApi.cs deleted file mode 100644 index 8f351c7..0000000 --- a/src/Clients/PaymoClientsApi.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Options; -using Novaloop.PaymoApi.Clients.Models; -using Novaloop.PaymoApi.Extensions; -using Novaloop.PaymoApi.Shared; - -namespace Novaloop.PaymoApi.Clients -{ - public class PaymoClientsApi : IPaymoClientsApi - { - private readonly PaymoApiOptions _options; - private readonly HttpClient _client; - private const string ResourceUri = "clients"; - - public PaymoClientsApi(PaymoApiClient paymoApiClient, IOptions options) - { - _options = options.Value; - _client = paymoApiClient.Client; - } - - /// - /// Receive all existing clients - /// - public async Task> GetClients() - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.GetAsync($"api/{ResourceUri}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).Clients; - } - - /// - /// Retrieve an existing client by id - /// - /// id of the contact - /// - public async Task GetClient(int clientId) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.GetAsync($"api/{ResourceUri}/{clientId}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).Clients.Single(); - } - - - /// - /// Create a new client - /// - public async Task CreateClient(PaymoClient client) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.PostAsJsonAsync($"api/{ResourceUri}", client); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).Clients.Single(); - } - - /// - /// Delete a client - /// - /// - /// - public async Task DeleteClient(int clientId) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.DeleteAsync($"api/{ResourceUri}/{clientId}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - } - } -} \ No newline at end of file diff --git a/src/Exceptions/PaymoApiException.cs b/src/Exceptions/ApiException.cs similarity index 52% rename from src/Exceptions/PaymoApiException.cs rename to src/Exceptions/ApiException.cs index f0f7fb8..d650db6 100644 --- a/src/Exceptions/PaymoApiException.cs +++ b/src/Exceptions/ApiException.cs @@ -2,9 +2,9 @@ using System; namespace Novaloop.PaymoApi.Exceptions { - public class PaymoApiException : Exception + public class ApiException : Exception { - public PaymoApiException(int statusCode, string message) : base($"[{statusCode}]: {message})") + public ApiException(int statusCode, string message) : base($"[{statusCode}]: {message})") { StatusCode = statusCode; } diff --git a/src/Extensions/PaymoApiOptions.cs b/src/Extensions/ApiOptions.cs similarity index 84% rename from src/Extensions/PaymoApiOptions.cs rename to src/Extensions/ApiOptions.cs index 81f66fe..ba19c92 100644 --- a/src/Extensions/PaymoApiOptions.cs +++ b/src/Extensions/ApiOptions.cs @@ -1,6 +1,6 @@ namespace Novaloop.PaymoApi.Extensions { - public class PaymoApiOptions + public class ApiOptions { public string BaseUrl { get; set; } = "https://app.paymoapp.com/"; public string ApiToken { get; set; } diff --git a/src/Extensions/HttpResponseMessageExtensions.cs b/src/Extensions/HttpResponseMessageExtensions.cs index 84cf220..ec9b6e3 100644 --- a/src/Extensions/HttpResponseMessageExtensions.cs +++ b/src/Extensions/HttpResponseMessageExtensions.cs @@ -10,7 +10,7 @@ namespace Novaloop.PaymoApi.Extensions { if (!response.IsSuccessStatusCode) { - throw new PaymoApiException((int) response.StatusCode, await response.Content.ReadAsStringAsync()); + throw new ApiException((int) response.StatusCode, await response.Content.ReadAsStringAsync()); } } } diff --git a/src/Extensions/PaymoApiExtensions.cs b/src/Extensions/PaymoApiExtensions.cs index b0217f8..899cdcc 100644 --- a/src/Extensions/PaymoApiExtensions.cs +++ b/src/Extensions/PaymoApiExtensions.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Novaloop.PaymoApi.ClientContacts; using Novaloop.PaymoApi.Clients; +using Novaloop.PaymoApi.Clients.Models; using Novaloop.PaymoApi.Shared; using Novaloop.PaymoApi.Tasks; @@ -10,14 +11,15 @@ namespace Novaloop.PaymoApi.Extensions { public static class PaymoApiExtensions { - public static IServiceCollection AddPaymoApi(this IServiceCollection services, Action options) + public static IServiceCollection AddPaymoApi(this IServiceCollection services, Action options) { services.Configure(options); - var resolvedOptions = (IOptions) services.BuildServiceProvider().GetService(typeof(IOptions)); - services.AddHttpClient(client => { client.BaseAddress = new Uri(resolvedOptions.Value.BaseUrl); }); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + var resolvedOptions = (IOptions) services.BuildServiceProvider().GetService(typeof(IOptions)); + services.AddHttpClient(client => { client.BaseAddress = new Uri(resolvedOptions.Value.BaseUrl); }); + services.AddTransient, BaseApi>(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); return services; } } diff --git a/src/Shared/PaymoApiClient.cs b/src/Shared/ApiClient.cs similarity index 62% rename from src/Shared/PaymoApiClient.cs rename to src/Shared/ApiClient.cs index 6ad3f46..0f0c13e 100644 --- a/src/Shared/PaymoApiClient.cs +++ b/src/Shared/ApiClient.cs @@ -2,9 +2,9 @@ using System.Net.Http; namespace Novaloop.PaymoApi.Shared { - public class PaymoApiClient : IPaymoApiClient + public class ApiClient : IApiClient { - public PaymoApiClient(HttpClient client) + public ApiClient(HttpClient client) { Client = client; } diff --git a/src/Shared/BaseApi.cs b/src/Shared/BaseApi.cs new file mode 100644 index 0000000..424b880 --- /dev/null +++ b/src/Shared/BaseApi.cs @@ -0,0 +1,80 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Novaloop.PaymoApi.Extensions; + +namespace Novaloop.PaymoApi.Shared +{ + public class BaseApi : IBaseApi + { + public string ResourceUri { get; set; } + private readonly ApiOptions _options; + private readonly HttpClient _client; + + public BaseApi(ApiClient apiClient, IOptions options) + { + _options = options.Value; + _client = apiClient.Client; + } + + /// + /// Receive all entities + /// + public async Task GetAll() + { + _client.SetApiKeyHeader(_options.ApiToken); + var response = await _client.GetAsync($"api/{ResourceUri}"); + await response.ThrowExceptionWithDetailsIfUnsuccessful(); + return await response.Content.ReadAsAsync(); + } + + /// + /// Retrieve an existing entity + /// + /// id of the entity + /// + public async Task Get(int entityId) + { + _client.SetApiKeyHeader(_options.ApiToken); + var response = await _client.GetAsync($"api/{ResourceUri}/{entityId}"); + await response.ThrowExceptionWithDetailsIfUnsuccessful(); + return await response.Content.ReadAsAsync(); + } + + /// + /// Create a new entity + /// + public async Task Create(TCreatType entity) + { + _client.SetApiKeyHeader(_options.ApiToken); + var response = await _client.PostAsJsonAsync($"api/{ResourceUri}", entity); + await response.ThrowExceptionWithDetailsIfUnsuccessful(); + return await response.Content.ReadAsAsync(); + } + + /// + /// Delete an entity + /// + /// id of the entity + /// + public async Task Delete(int entityId) + { + _client.SetApiKeyHeader(_options.ApiToken); + var response = await _client.DeleteAsync($"api/{ResourceUri}/{entityId}"); + await response.ThrowExceptionWithDetailsIfUnsuccessful(); + } + + /// + /// Update an entity + /// + /// entity information to update the entity with + /// id of the entity to update + /// + public async Task Update(TCreatType entity, int id) + { + _client.SetApiKeyHeader(_options.ApiToken); + var response = await _client.PutAsJsonAsync($"api/{ResourceUri}/{id}", entity); + await response.ThrowExceptionWithDetailsIfUnsuccessful(); + } + } +} \ No newline at end of file diff --git a/src/Shared/BasePaymoModel.cs b/src/Shared/BaseModel.cs similarity index 86% rename from src/Shared/BasePaymoModel.cs rename to src/Shared/BaseModel.cs index 048577b..501f3a5 100644 --- a/src/Shared/BasePaymoModel.cs +++ b/src/Shared/BaseModel.cs @@ -2,7 +2,7 @@ using System; namespace Novaloop.PaymoApi.Shared { - public class BasePaymoModel + public class BaseModel { public int Id { get; set; } public DateTime CreatedOn { get; set; } diff --git a/src/Shared/IPaymoApiClient.cs b/src/Shared/IApiClient.cs similarity index 57% rename from src/Shared/IPaymoApiClient.cs rename to src/Shared/IApiClient.cs index c35a3d5..c18bcab 100644 --- a/src/Shared/IPaymoApiClient.cs +++ b/src/Shared/IApiClient.cs @@ -1,6 +1,6 @@ namespace Novaloop.PaymoApi.Shared { - public interface IPaymoApiClient + public interface IApiClient { } } \ No newline at end of file diff --git a/src/Shared/IBaseApi.cs b/src/Shared/IBaseApi.cs new file mode 100644 index 0000000..fbf7b58 --- /dev/null +++ b/src/Shared/IBaseApi.cs @@ -0,0 +1,41 @@ +using System.Threading.Tasks; + +namespace Novaloop.PaymoApi.Shared +{ + public interface IBaseApi + { + string ResourceUri { get; set; } + + /// + /// Receive all entities + /// + Task GetAll(); + + /// + /// Retrieve an existing entity + /// + /// id of the entity + /// + Task Get(int entityId); + + /// + /// Create a new entity + /// + Task Create( TCreatType entity); + + /// + /// Delete an entity + /// + /// id of the entity + /// + Task Delete(int entityId); + + /// + /// Update an entity + /// + /// entity information to update the entity with + /// id of the entity to update + /// + Task Update( TCreatType entity, int id); + } +} \ No newline at end of file diff --git a/src/Tasks/IPaymoTasksApi.cs b/src/Tasks/IPaymoTasksApi.cs deleted file mode 100644 index 1f28dfb..0000000 --- a/src/Tasks/IPaymoTasksApi.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Novaloop.PaymoApi.Tasks.Models; - -namespace Novaloop.PaymoApi.Tasks -{ - public interface IPaymoTasksApi - { - Task> GetTasks(); - Task GetTask(int taskId); - Task CreateTask(PaymoTask task); - Task DeleteTask(int taskId); - } -} \ No newline at end of file diff --git a/src/Tasks/ITasksApi.cs b/src/Tasks/ITasksApi.cs new file mode 100644 index 0000000..7aed1d6 --- /dev/null +++ b/src/Tasks/ITasksApi.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Novaloop.PaymoApi.Tasks +{ + public interface ITasksApi + { + /// + /// Receive all existing tasks + /// + Task> GetTasks(); + + /// + /// Retrieve an existing Task by id + /// + /// id of the task + /// + Task GetTask(int taskId); + + /// + /// Create a new Task + /// + Task CreateTask(Novaloop.PaymoApi.Tasks.Models.Task task); + + /// + /// Delete a task + /// + /// + /// + Task DeleteTask(int taskId); + + /// + /// Update an existing task + /// + /// + /// + /// + Task UpdateTask(Novaloop.PaymoApi.Tasks.Models.Task task, int taskId); + } +} \ No newline at end of file diff --git a/src/Tasks/Models/PaymoTask.cs b/src/Tasks/Models/Task.cs similarity index 96% rename from src/Tasks/Models/PaymoTask.cs rename to src/Tasks/Models/Task.cs index 1cdcc04..49072cc 100644 --- a/src/Tasks/Models/PaymoTask.cs +++ b/src/Tasks/Models/Task.cs @@ -4,7 +4,7 @@ using Novaloop.PaymoApi.Shared; namespace Novaloop.PaymoApi.Tasks.Models { - public class PaymoTask : BasePaymoModel + public class Task : BaseModel { [JsonProperty("name")] public string Name { get; set; } diff --git a/src/Tasks/Models/GetTasksResponse.cs b/src/Tasks/Models/TasksResponse.cs similarity index 61% rename from src/Tasks/Models/GetTasksResponse.cs rename to src/Tasks/Models/TasksResponse.cs index 935346a..2e7fea5 100644 --- a/src/Tasks/Models/GetTasksResponse.cs +++ b/src/Tasks/Models/TasksResponse.cs @@ -3,9 +3,9 @@ using Newtonsoft.Json; namespace Novaloop.PaymoApi.Tasks.Models { - public class GetTasksResponse + public class TasksResponse { [JsonProperty("tasks")] - public IEnumerable Tasks { get; set; } + public IEnumerable Tasks { get; set; } } } \ No newline at end of file diff --git a/src/Tasks/PaymoTasksApi.cs b/src/Tasks/PaymoTasksApi.cs deleted file mode 100644 index 7da1cac..0000000 --- a/src/Tasks/PaymoTasksApi.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; -using Microsoft.Extensions.Options; -using Novaloop.PaymoApi.Extensions; -using Novaloop.PaymoApi.Shared; -using Novaloop.PaymoApi.Tasks.Models; - -namespace Novaloop.PaymoApi.Tasks -{ - public class PaymoTasksApi : IPaymoTasksApi - { - private readonly PaymoApiOptions _options; - private readonly HttpClient _client; - private const string ResourceUri = "tasks"; - - - public PaymoTasksApi(PaymoApiClient paymoApiClient, IOptions options) - { - _options = options.Value; - _client = paymoApiClient.Client; - } - - /// - /// Receive all existing tasks - /// - public async Task> GetTasks() - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.GetAsync($"api/{ResourceUri}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).Tasks; - } - - /// - /// Retrieve an existing Task by id - /// - /// id of the task - /// - public async Task GetTask(int taskId) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.GetAsync($"api/{ResourceUri}/{taskId}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).Tasks.Single(); - } - - - /// - /// Creates a new Task - /// - public async Task CreateTask(PaymoTask task) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.PostAsJsonAsync($"api/{ResourceUri}", task); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - return (await response.Content.ReadAsAsync()).Tasks.Single(); - } - - /// - /// Delete a task - /// - /// - /// - public async Task DeleteTask(int taskId) - { - _client.SetApiKeyHeader(_options.ApiToken); - var response = await _client.DeleteAsync($"api/{ResourceUri}/{taskId}"); - await response.ThrowExceptionWithDetailsIfUnsuccessful(); - } - } -} \ No newline at end of file diff --git a/src/Tasks/TasksApi.cs b/src/Tasks/TasksApi.cs new file mode 100644 index 0000000..103506c --- /dev/null +++ b/src/Tasks/TasksApi.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Novaloop.PaymoApi.Shared; +using Novaloop.PaymoApi.Tasks.Models; +using Task = System.Threading.Tasks.Task; + +namespace Novaloop.PaymoApi.Tasks +{ + public class TasksApi : ITasksApi + { + private readonly IBaseApi _baseApi; + + public TasksApi(IBaseApi baseApi) + { + _baseApi = baseApi; + _baseApi.ResourceUri = "tasks"; + } + + + /// + public async Task> GetTasks() + { + return (await _baseApi.GetAll()).Tasks; + } + + /// + public async Task GetTask(int taskId) + { + return (await _baseApi.Get(taskId)).Tasks.Single(); + } + + + /// + public async Task CreateTask(Novaloop.PaymoApi.Tasks.Models.Task task) + { + return (await _baseApi.Create(task)).Tasks.Single(); + } + + /// + public async Task DeleteTask(int taskId) + { + await _baseApi.Delete(taskId); + } + + + /// + public async Task UpdateTask(Novaloop.PaymoApi.Tasks.Models.Task task, int taskId) + { + await _baseApi.Update(task, taskId); + } + } +} \ No newline at end of file diff --git a/tests/ClientContactsApiTests.cs b/tests/ClientContactsApiTests.cs new file mode 100644 index 0000000..dab9473 --- /dev/null +++ b/tests/ClientContactsApiTests.cs @@ -0,0 +1,91 @@ +using System.Linq; +using Novaloop.PaymoApi.ClientContacts; +using Novaloop.PaymoApi.ClientContacts.Models; +using Novaloop.PaymoApi.Clients; +using Novaloop.PaymoApi.Clients.Models; +using Novaloop.PaymoApi.Shared; +using Xunit; + +namespace Novaloop.PaymoApi.Tests +{ + public class ClientContactsApiTests + { + private readonly ClientContactsApi _clientContactsApi; + private readonly ClientsApi _clientsApi; + + private readonly ClientContact _testClientContact = new ClientContact + { + Name = "Testclient", + Email = "test@client.de" + }; + + + public ClientContactsApiTests() + { + _clientContactsApi = new ClientContactsApi(new BaseApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions())); + _clientsApi = new ClientsApi(new BaseApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions())); + } + + + [Fact] + public async void GetClientContacts() + { + // Arrange + + // Act + var clientContacts = (await _clientContactsApi.GetClientContacts()).ToList(); + + // Assert + Assert.NotEmpty(clientContacts); + } + + [Fact] + public async void GetClientContact() + { + // Arrange + + // Act + var clientContacts = (await _clientContactsApi.GetClientContacts()).ToList(); + var clientContact = await _clientContactsApi.GetClientContact(clientContacts.First().Id); + + // Assert + Assert.NotNull(clientContact); + } + + [Fact] + public async void CreateClientContact() + { + // Arrange + var existingClientContact = (await _clientsApi.GetClients()).First(); + + // Act + _testClientContact.ClientId = existingClientContact.Id; + var createdClientContact = await _clientContactsApi.CreateClientContact(_testClientContact); + var clientContact = await _clientContactsApi.GetClientContact(createdClientContact.Id); + + // Assert + Assert.Equal(_testClientContact.Name, clientContact.Name); + Assert.Equal(_testClientContact.Email, clientContact.Email); + + // Cleanup + await _clientContactsApi.DeleteClientContact(createdClientContact.Id); + } + + [Fact] + public async void DeleteClientContact() + { + // Arrange + var existingClientContact = (await _clientsApi.GetClients()).First(); + _testClientContact.ClientId = existingClientContact.Id; + var createdClientContact = await _clientContactsApi.CreateClientContact(_testClientContact); + + // Act + await _clientContactsApi.DeleteClientContact(createdClientContact.Id); + var clientContacts = (await _clientContactsApi.GetClientContacts()).ToList(); + + + // Assert + Assert.Empty(clientContacts.Where(c => c.Id == createdClientContact.Id)); + } + } +} \ No newline at end of file diff --git a/tests/ClientsApiTests.cs b/tests/ClientsApiTests.cs new file mode 100644 index 0000000..d60e24a --- /dev/null +++ b/tests/ClientsApiTests.cs @@ -0,0 +1,98 @@ +using System.Linq; +using Novaloop.PaymoApi.Clients; +using Novaloop.PaymoApi.Clients.Models; +using Novaloop.PaymoApi.Shared; +using Xunit; + +namespace Novaloop.PaymoApi.Tests +{ + public class ClientsApiTests + { + private readonly ClientsApi _clientsApi; + + private readonly Client _testClient = new Client + { + Name = "Testclient", + Email = "test@client.de" + }; + + public ClientsApiTests() + { + _clientsApi = new ClientsApi(new BaseApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions())); + } + + + [Fact] + public async void GetClients() + { + // Arrange + + // Act + var clients = (await _clientsApi.GetClients()).ToList(); + + // Assert + Assert.NotEmpty(clients); + } + + [Fact] + public async void GetClient() + { + // Arrange + + // Act + var clients = (await _clientsApi.GetClients()).ToList(); + var client = await _clientsApi.GetClient(clients.First().Id); + + // Assert + Assert.NotNull(client); + } + + [Fact] + public async void CreateClient() + { + // Arrange + + // Act + var createdClient = await _clientsApi.CreateClient(_testClient); + var client = await _clientsApi.GetClient(createdClient.Id); + + // Assert + Assert.Equal(_testClient.Name, client.Name); + Assert.Equal(_testClient.Email, client.Email); + + // Cleanup + await _clientsApi.DeleteClient(createdClient.Id); + } + + [Fact] + public async void DeleteClient() + { + // Arrange + var createdClient = await _clientsApi.CreateClient(_testClient); + + // Act + await _clientsApi.DeleteClient(createdClient.Id); + var clients = (await _clientsApi.GetClients()).ToList(); + + + // Assert + Assert.Empty(clients.Where(c => c.Id == createdClient.Id)); + } + + [Fact] + public async void UpdateClient() + { + // Arrange + var createdClient = await _clientsApi.CreateClient(_testClient); + var clientUpdateInfo = new Client {Name = "Updated"}; + + // Act + await _clientsApi.UpdateClient(clientUpdateInfo, createdClient.Id); + var updatedClient = await _clientsApi.GetClient(createdClient.Id); + + + // Assert + Assert.Equal(clientUpdateInfo.Name, updatedClient.Name); + } + } +} \ No newline at end of file diff --git a/tests/DependencyFactory.cs b/tests/DependencyFactory.cs index cea5287..a93fe9a 100644 --- a/tests/DependencyFactory.cs +++ b/tests/DependencyFactory.cs @@ -9,12 +9,12 @@ namespace Novaloop.PaymoApi.Tests { public static class DependencyFactory { - public static PaymoApiClient GeneratePaymoApiClient() + public static ApiClient GeneratePaymoApiClient() { - return new PaymoApiClient(new HttpClient {BaseAddress = new Uri("https://app.paymoapp.com/")}); + return new ApiClient(new HttpClient {BaseAddress = new Uri("https://app.paymoapp.com/")}); } - public static IOptions GenerateOptions() + public static IOptions GenerateOptions() { var paymoToken = new ConfigurationBuilder() .SetBasePath(AppContext.BaseDirectory) @@ -28,7 +28,7 @@ namespace Novaloop.PaymoApi.Tests throw new ArgumentException("Please set the environment variable 'PAYMOAPIINTEGRATIONTESTS__PAYMOTESTPROJECTTOKEN' with the token of your paymo test-project. Look inside Bitwarden if you work @ Novaloop."); } - return Options.Create(new PaymoApiOptions {ApiToken = paymoToken}); + return Options.Create(new ApiOptions {ApiToken = paymoToken}); } } } \ No newline at end of file diff --git a/tests/PaymoClientContactsApiTests.cs b/tests/PaymoClientContactsApiTests.cs deleted file mode 100644 index f3b085f..0000000 --- a/tests/PaymoClientContactsApiTests.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Linq; -using Novaloop.PaymoApi.ClientContacts; -using Novaloop.PaymoApi.ClientContacts.Models; -using Novaloop.PaymoApi.Clients; -using Xunit; - -namespace Novaloop.PaymoApi.Tests -{ - public class PaymoClientContactsApiTests - { - private readonly PaymoClientContactsApi _paymoClientContactsApi; - private readonly PaymoClientsApi _paymoClientsApi; - - private readonly PaymoClientContact _testClientContact = new PaymoClientContact - { - Name = "Testclient", - Email = "test@client.de" - }; - - - public PaymoClientContactsApiTests() - { - _paymoClientContactsApi = new PaymoClientContactsApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions()); - _paymoClientsApi = new PaymoClientsApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions()); - } - - - [Fact] - public async void GetClientContacts() - { - // Arrange - - // Act - var clientContacts = (await _paymoClientContactsApi.GetClientContacts()).ToList(); - - // Assert - Assert.NotEmpty(clientContacts); - } - - [Fact] - public async void GetClientContact() - { - // Arrange - - // Act - var clientContacts = (await _paymoClientContactsApi.GetClientContacts()).ToList(); - var clientContact = await _paymoClientContactsApi.GetClientContact(clientContacts.First().Id); - - // Assert - Assert.NotNull(clientContact); - } - - [Fact] - public async void CreateClientContact() - { - // Arrange - var existingClientContact = (await _paymoClientsApi.GetClients()).First(); - - // Act - _testClientContact.ClientId = existingClientContact.Id; - var createdClientContact = await _paymoClientContactsApi.CreateClientContact(_testClientContact); - var clientContact = await _paymoClientContactsApi.GetClientContact(createdClientContact.Id); - - // Assert - Assert.Equal(_testClientContact.Name, clientContact.Name); - Assert.Equal(_testClientContact.Email, clientContact.Email); - - // Cleanup - await _paymoClientContactsApi.DeleteClientContact(createdClientContact.Id); - } - - [Fact] - public async void DeleteClientContact() - { - // Arrange - var existingClientContact = (await _paymoClientsApi.GetClients()).First(); - _testClientContact.ClientId = existingClientContact.Id; - var createdClientContact = await _paymoClientContactsApi.CreateClientContact(_testClientContact); - - // Act - await _paymoClientContactsApi.DeleteClientContact(createdClientContact.Id); - var clientContacts = (await _paymoClientContactsApi.GetClientContacts()).ToList(); - - - // Assert - Assert.Empty(clientContacts.Where(c => c.Id == createdClientContact.Id)); - } - } -} \ No newline at end of file diff --git a/tests/PaymoClientsApiTests.cs b/tests/PaymoClientsApiTests.cs deleted file mode 100644 index b3543d8..0000000 --- a/tests/PaymoClientsApiTests.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Linq; -using Novaloop.PaymoApi.Clients; -using Novaloop.PaymoApi.Clients.Models; -using Xunit; - -namespace Novaloop.PaymoApi.Tests -{ - public class PaymoClientsApiTests - { - private readonly PaymoClientsApi _paymoClientsApi; - - private readonly PaymoClient _testClient = new PaymoClient - { - Name = "Testclient", - Email = "test@client.de" - }; - - public PaymoClientsApiTests() - { - _paymoClientsApi = new PaymoClientsApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions()); - } - - - [Fact] - public async void GetClients() - { - // Arrange - - // Act - var clients = (await _paymoClientsApi.GetClients()).ToList(); - - // Assert - Assert.NotEmpty(clients); - } - - [Fact] - public async void GetClient() - { - // Arrange - - // Act - var clients = (await _paymoClientsApi.GetClients()).ToList(); - var client = await _paymoClientsApi.GetClient(clients.First().Id); - - // Assert - Assert.NotNull(client); - } - - [Fact] - public async void CreateClient() - { - // Arrange - - // Act - var createdClient = await _paymoClientsApi.CreateClient(_testClient); - var client = await _paymoClientsApi.GetClient(createdClient.Id); - - // Assert - Assert.Equal(_testClient.Name, client.Name); - Assert.Equal(_testClient.Email, client.Email); - - // Cleanup - await _paymoClientsApi.DeleteClient(createdClient.Id); - } - - [Fact] - public async void DeleteClient() - { - // Arrange - var createdClient = await _paymoClientsApi.CreateClient(_testClient); - - // Act - await _paymoClientsApi.DeleteClient(createdClient.Id); - var clients = (await _paymoClientsApi.GetClients()).ToList(); - - - // Assert - Assert.Empty(clients.Where(c => c.Id == createdClient.Id)); - } - } -} \ No newline at end of file diff --git a/tests/PaymoTasksApiTests.cs b/tests/PaymoTasksApiTests.cs deleted file mode 100644 index 9bbf56e..0000000 --- a/tests/PaymoTasksApiTests.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Linq; -using Novaloop.PaymoApi.Tasks; -using Novaloop.PaymoApi.Tasks.Models; -using Xunit; -using Xunit.Abstractions; - -namespace Novaloop.PaymoApi.Tests -{ - public class PaymoTasksApiTests - { - private readonly ITestOutputHelper _testOutputHelper; - private readonly PaymoTasksApi _paymoTasksApi; - private readonly PaymoTask _testTask; - - public PaymoTasksApiTests(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - _paymoTasksApi = new PaymoTasksApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions()); - _testTask = new PaymoTask - { - Name = "Testtask", - Description = "Just a little task" - }; - } - - - [Fact] - public async void GetTasks() - { - // Arrange - - // Act - var tasks = (await _paymoTasksApi.GetTasks()).ToList(); - - // Assert - Assert.NotEmpty(tasks); - _testOutputHelper.WriteLine(string.Join(",", tasks)); - } - - [Fact] - public async void GetTask() - { - // Arrange - - // Act - var tasks = (await _paymoTasksApi.GetTasks()).ToList(); - var task = await _paymoTasksApi.GetTask(tasks.First().Id); - - // Assert - Assert.NotNull(task); - } - - [Fact] - public async void CreateTask() - { - // Arrange - var existingTaskListId = (await _paymoTasksApi.GetTasks()).First().TasklistId; - - // Act - _testTask.TasklistId = existingTaskListId; - var createdTask = await _paymoTasksApi.CreateTask(_testTask); - var task = await _paymoTasksApi.GetTask(createdTask.Id); - - // Assert - Assert.Equal(_testTask.Name, task.Name); - Assert.Equal(_testTask.Description, task.Description); - - // Cleanup - await _paymoTasksApi.DeleteTask(createdTask.Id); - } - - [Fact] - public async void DeleteTask() - { - // Arrange - var existingTaskListId = (await _paymoTasksApi.GetTasks()).First().TasklistId; - _testTask.TasklistId = existingTaskListId; - var createdTask = await _paymoTasksApi.CreateTask(_testTask); - - // Act - await _paymoTasksApi.DeleteTask(createdTask.Id); - var tasks = (await _paymoTasksApi.GetTasks()).ToList(); - - - // Assert - Assert.Empty(tasks.Where(c => c.Id == createdTask.Id)); - } - } -} \ No newline at end of file diff --git a/tests/TasksApiTests.cs b/tests/TasksApiTests.cs new file mode 100644 index 0000000..566a929 --- /dev/null +++ b/tests/TasksApiTests.cs @@ -0,0 +1,109 @@ +using System.Linq; +using Novaloop.PaymoApi.Shared; +using Novaloop.PaymoApi.Tasks; +using Novaloop.PaymoApi.Tasks.Models; +using Xunit; +using Xunit.Abstractions; + +namespace Novaloop.PaymoApi.Tests +{ + public class TasksApiTests + { + private readonly ITestOutputHelper _testOutputHelper; + private readonly TasksApi _tasksApi; + private readonly Task _testTask; + + public TasksApiTests(ITestOutputHelper testOutputHelper) + { + _testOutputHelper = testOutputHelper; + _tasksApi = new TasksApi(new BaseApi(DependencyFactory.GeneratePaymoApiClient(), DependencyFactory.GenerateOptions())); + + _testTask = new Task + { + Name = "Testtask", + Description = "Just a little task" + }; + } + + + [Fact] + public async void GetTasks() + { + // Arrange + + // Act + var tasks = (await _tasksApi.GetTasks()).ToList(); + + // Assert + Assert.NotEmpty(tasks); + _testOutputHelper.WriteLine(string.Join(",", tasks)); + } + + [Fact] + public async void GetTask() + { + // Arrange + + // Act + var tasks = (await _tasksApi.GetTasks()).ToList(); + var task = await _tasksApi.GetTask(tasks.First().Id); + + // Assert + Assert.NotNull(task); + } + + [Fact] + public async void CreateTask() + { + // Arrange + var existingTaskListId = (await _tasksApi.GetTasks()).First().TasklistId; + + // Act + _testTask.TasklistId = existingTaskListId; + var createdTask = await _tasksApi.CreateTask(_testTask); + var task = await _tasksApi.GetTask(createdTask.Id); + + // Assert + Assert.Equal(_testTask.Name, task.Name); + Assert.Equal(_testTask.Description, task.Description); + + // Cleanup + await _tasksApi.DeleteTask(createdTask.Id); + } + + [Fact] + public async void DeleteTask() + { + // Arrange + var existingTaskListId = (await _tasksApi.GetTasks()).First().TasklistId; + _testTask.TasklistId = existingTaskListId; + var createdTask = await _tasksApi.CreateTask(_testTask); + + // Act + await _tasksApi.DeleteTask(createdTask.Id); + var tasks = (await _tasksApi.GetTasks()).ToList(); + + + // Assert + Assert.Empty(tasks.Where(c => c.Id == createdTask.Id)); + } + + [Fact] + public async void UpdateTask() + { + // Arrange + var existingTaskListId = (await _tasksApi.GetTasks()).First().TasklistId; + _testTask.TasklistId = existingTaskListId; + var createdTask = await _tasksApi.CreateTask(_testTask); + var taskUpdateInfo = new Task {Name = "Updated", TasklistId = _testTask.TasklistId}; + + // Act + await _tasksApi.UpdateTask(taskUpdateInfo, createdTask.Id); + var updatedTask = await _tasksApi.GetTask(createdTask.Id); + + + // Assert + Assert.Equal(taskUpdateInfo.Name, updatedTask.Name); + } + } +} \ No newline at end of file