From 0fd5700245e75333ddaee0c23ec3eab2a8af76b4 Mon Sep 17 00:00:00 2001 From: Vincent Kok Date: Tue, 26 Sep 2023 19:49:44 +0200 Subject: [PATCH] Remove non existing include parameters from InvoiceClient (#329) --- .../Client/Abstract/IInvoicesClient.cs | 6 +- src/Mollie.Api/Client/InvoicesClient.cs | 33 ++-- src/Mollie.Api/Mollie.Api.csproj | 8 +- .../Client/InvoiceClientTests.cs | 175 ++++++++++++++++++ 4 files changed, 193 insertions(+), 29 deletions(-) create mode 100644 tests/Mollie.Tests.Unit/Client/InvoiceClientTests.cs diff --git a/src/Mollie.Api/Client/Abstract/IInvoicesClient.cs b/src/Mollie.Api/Client/Abstract/IInvoicesClient.cs index fc3a3a40..b99d9981 100644 --- a/src/Mollie.Api/Client/Abstract/IInvoicesClient.cs +++ b/src/Mollie.Api/Client/Abstract/IInvoicesClient.cs @@ -7,10 +7,10 @@ namespace Mollie.Api.Client.Abstract { public interface IInvoicesClient : IDisposable { - Task GetInvoiceAsync(string invoiceId, bool includeLines = false, bool includeSettlements = false); + Task GetInvoiceAsync(string invoiceId); Task GetInvoiceAsync(UrlObjectLink url); - Task> GetInvoiceListAsync(string reference = null, int? year = null, - string from = null, int? limit = null, bool includeLines = false, bool includeSettlements = false); + Task> GetInvoiceListAsync( + string reference = null, int? year = null, string from = null, int? limit = null); Task> GetInvoiceListAsync(UrlObjectLink> url); } } \ No newline at end of file diff --git a/src/Mollie.Api/Client/InvoicesClient.cs b/src/Mollie.Api/Client/InvoicesClient.cs index 5767ebe9..b83ed84f 100644 --- a/src/Mollie.Api/Client/InvoicesClient.cs +++ b/src/Mollie.Api/Client/InvoicesClient.cs @@ -14,44 +14,33 @@ public class InvoicesClient : OauthBaseMollieClient, IInvoicesClient { public InvoicesClient(string oauthAccessToken, HttpClient httpClient = null) : base(oauthAccessToken, httpClient) { } - public async Task GetInvoiceAsync(string invoiceId, bool includeLines = false, bool includeSettlements = false) { + public async Task GetInvoiceAsync(string invoiceId) { this.ValidateRequiredUrlParameter(nameof(invoiceId), invoiceId); - var includes = this.BuildIncludeParameter(includeLines, includeSettlements); - return await this.GetAsync($"invoices/{invoiceId}{includes.ToQueryString()}").ConfigureAwait(false); + return await this.GetAsync($"invoices/{invoiceId}").ConfigureAwait(false); } public async Task GetInvoiceAsync(UrlObjectLink url) { return await this.GetAsync(url).ConfigureAwait(false); } - public async Task> GetInvoiceListAsync(string reference = null, int? year = null, string from = null, int? limit = null, bool includeLines = false, bool includeSettlements = false) { - var parameters = this.BuildIncludeParameter(includeLines, includeSettlements); + public async Task> GetInvoiceListAsync( + string reference = null, int? year = null, string from = null, int? limit = null) { + var parameters = new Dictionary(); parameters.AddValueIfNotNullOrEmpty(nameof(reference), reference); parameters.AddValueIfNotNullOrEmpty(nameof(year), Convert.ToString(year)); - return await this.GetListAsync>($"invoices", from, limit, parameters).ConfigureAwait(false); + return await this.GetListAsync>($"invoices", from, limit, parameters) + .ConfigureAwait(false); } public async Task> GetInvoiceListAsync(UrlObjectLink> url) { return await this.GetAsync(url).ConfigureAwait(false); } - - private Dictionary BuildIncludeParameter(bool includeLines = false, bool includeSettlements = false) { + + private Dictionary BuildQueryParameters(string profileId, bool testmode) { var result = new Dictionary(); - - var includeList = new List(); - if (includeLines) { - includeList.Add("lines"); - } - - if (includeSettlements) { - includeList.Add("settlements"); - } - - if (includeList.Any()) { - result.Add("include", string.Join(",", includeList)); - } - + result.AddValueIfNotNullOrEmpty("profileId", profileId); + result.AddValueIfTrue("testmode", testmode); return result; } } diff --git a/src/Mollie.Api/Mollie.Api.csproj b/src/Mollie.Api/Mollie.Api.csproj index 523a0b60..d46299be 100644 --- a/src/Mollie.Api/Mollie.Api.csproj +++ b/src/Mollie.Api/Mollie.Api.csproj @@ -1,7 +1,7 @@  - 3.3.0.0 + 3.4.0.0 True Vincent Kok This is a wrapper for the Mollie REST webservice. All payment methods and webservice calls are supported. @@ -9,9 +9,9 @@ Mollie Payment API https://github.com/Viincenttt/MollieApi Mollie - 3.3.0.0 - 3.3.0.0 - 3.3.0.0 + 3.4.0.0 + 3.4.0.0 + 3.4.0.0 netstandard2.0 README.md LICENSE diff --git a/tests/Mollie.Tests.Unit/Client/InvoiceClientTests.cs b/tests/Mollie.Tests.Unit/Client/InvoiceClientTests.cs new file mode 100644 index 00000000..1aba907a --- /dev/null +++ b/tests/Mollie.Tests.Unit/Client/InvoiceClientTests.cs @@ -0,0 +1,175 @@ +using System.Net.Http; +using System.Threading.Tasks; +using FluentAssertions; +using Mollie.Api.Client; +using RichardSzalay.MockHttp; +using Xunit; + +namespace Mollie.Tests.Unit.Client; + +public class InvoiceClientTests : BaseClientTests +{ + [Fact] + public async Task GetInvoiceAsync_DefaultBehaviour_ResponseIsParsed() + { + // Given + const string invoiceId = "inv_xBEbP9rvAq"; + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When($"{BaseMollieClient.ApiEndPoint}invoices/{invoiceId}") + .Respond("application/json", defaultInvoice); + HttpClient httpClient = mockHttp.ToHttpClient(); + using InvoicesClient invoicesClient = new InvoicesClient("access_abcde", httpClient); + + // When + var result = await invoicesClient.GetInvoiceAsync(invoiceId); + + // Then + mockHttp.VerifyNoOutstandingExpectation(); + result.Should().NotBeNull(); + result.Resource.Should().Be("invoice"); + result.Id.Should().Be(invoiceId); + result.Reference.Should().Be("2016.10000"); + result.VatNumber.Should().Be("NL001234567B01"); + result.Status.Should().Be("open"); + } + + [Theory] + [InlineData(null, null, null, null, "")] + [InlineData("my-reference", null, null, null, "?reference=my-reference")] + [InlineData("my-reference", 2023, null, null, "?reference=my-reference&year=2023")] + [InlineData("my-reference", 2023, "abcde", null, "?reference=my-reference&year=2023&from=abcde")] + [InlineData("my-reference", 2023, "abcde", 10, "?reference=my-reference&year=2023&from=abcde&limit=10")] + public async Task GetInvoiceListAsync_WithVariousParameters_QueryStringMatchesExpectedValue( + string reference, int? year, string from, int? limit, string expectedQueryString) { + // Given: We retrieve a list of customers + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When($"{BaseMollieClient.ApiEndPoint}invoices{expectedQueryString}") + .Respond("application/json", defaultInvoiceList); + HttpClient httpClient = mockHttp.ToHttpClient(); + using InvoicesClient invoicesClient = new InvoicesClient("access_abcde", httpClient); + + // When: We send the request + var result = await invoicesClient.GetInvoiceListAsync( + reference, year, from, limit); + + // Then + mockHttp.VerifyNoOutstandingExpectation(); + result.Should().NotBeNull(); + } + + private const string defaultInvoice = @"{ + ""resource"": ""invoice"", + ""id"": ""inv_xBEbP9rvAq"", + ""reference"": ""2016.10000"", + ""vatNumber"": ""NL001234567B01"", + ""status"": ""open"", + ""issuedAt"": ""2016-08-31"", + ""dueAt"": ""2016-09-14"", + ""netAmount"": { + ""value"": ""45.00"", + ""currency"": ""EUR"" + }, + ""vatAmount"": { + ""value"": ""9.45"", + ""currency"": ""EUR"" + }, + ""grossAmount"": { + ""value"": ""54.45"", + ""currency"": ""EUR"" + }, + ""lines"":[ + { + ""period"": ""2016-09"", + ""description"": ""iDEAL transactiekosten"", + ""count"": 100, + ""vatPercentage"": 21, + ""amount"": { + ""value"": ""45.00"", + ""currency"": ""EUR"" + } + } + ], + ""_links"": { + ""self"": { + ""href"": ""https://api.mollie.com/v2/invoices/inv_xBEbP9rvAq"", + ""type"": ""application/hal+json"" + }, + ""pdf"": { + ""href"": ""https://www.mollie.com/merchant/download/invoice/xBEbP9rvAq/2ab44d60b35b1d06090bba955fa2c602"", + ""type"": ""application/pdf"", + ""expiresAt"": ""2018-11-09T14:10:36+00:00"" + } + } +}"; + + private const string defaultInvoiceList = @"{ + ""count"": 5, + ""_embedded"": { + ""invoices"": [ + { + ""resource"": ""invoice"", + ""id"": ""inv_xBEbP9rvAq"", + ""reference"": ""2016.10000"", + ""vatNumber"": ""NL001234567B01"", + ""status"": ""open"", + ""issuedAt"": ""2016-08-31"", + ""dueAt"": ""2016-09-14"", + ""netAmount"": { + ""value"": ""45.00"", + ""currency"": ""EUR"" + }, + ""vatAmount"": { + ""value"": ""9.45"", + ""currency"": ""EUR"" + }, + ""grossAmount"": { + ""value"": ""54.45"", + ""currency"": ""EUR"" + }, + ""lines"":[ + { + ""period"": ""2016-09"", + ""description"": ""iDEAL transactiekosten"", + ""count"": 100, + ""vatPercentage"": 21, + ""amount"": { + ""value"": ""45.00"", + ""currency"": ""EUR"" + } + } + ], + ""_links"": { + ""self"": { + ""href"": ""https://api.mollie.com/v2/invoices/inv_xBEbP9rvAq"", + ""type"": ""application/hal+json"" + }, + ""pdf"": { + ""href"": ""https://www.mollie.com/merchant/download/invoice/xBEbP9rvAq/2ab44d60b35955fa2c602"", + ""type"": ""application/pdf"", + ""expiresAt"": ""2018-11-09T14:10:36+00:00"" + } + } + }, + { }, + { }, + { }, + { } + ] + }, + ""_links"": { + ""self"": { + ""href"": ""https://api.mollie.nl/v2/invoices?limit=5"", + ""type"": ""application/hal+json"" + }, + ""previous"": null, + ""next"": { + ""href"": ""https://api.mollie.nl/v2/invoices?from=inv_xBEbP9rvAq&limit=5"", + ""type"": ""application/hal+json"" + }, + ""documentation"": { + ""href"": ""https://docs.mollie.com/reference/v2/invoices-api/list-invoices"", + ""type"": ""text/html"" + } + } +}"; +} \ No newline at end of file