From 374394758f458c2861d6536a8dca0016f91e7afa Mon Sep 17 00:00:00 2001 From: Valters Melnalksnis Date: Tue, 21 Jun 2022 20:51:03 +0300 Subject: [PATCH] fix: Fix query for transactions within interval (#31) --- NordigenDotNet.sln | 7 +++ .../Accounts/AccountClient.cs | 6 +-- source/VMelnalksnis.NordigenDotNet/Routes.cs | 8 +++- .../VMelnalksnis.NordigenDotNet.csproj | 4 ++ .../Accounts/AccountClientTests.cs | 10 +++- .../RoutesTests.cs | 44 ++++++++++++++++++ .../VMelnalksnis.NordigenDotNet.Tests.csproj | 13 ++++++ .../VMelnalksnis.NordigenDotNet.Tests/key.snk | Bin 0 -> 1172 bytes 8 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 tests/VMelnalksnis.NordigenDotNet.Tests/RoutesTests.cs create mode 100644 tests/VMelnalksnis.NordigenDotNet.Tests/VMelnalksnis.NordigenDotNet.Tests.csproj create mode 100644 tests/VMelnalksnis.NordigenDotNet.Tests/key.snk diff --git a/NordigenDotNet.sln b/NordigenDotNet.sln index 1dada9d..fd82da9 100644 --- a/NordigenDotNet.sln +++ b/NordigenDotNet.sln @@ -36,6 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{ .github\workflows\release.yml = .github\workflows\release.yml EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VMelnalksnis.NordigenDotNet.Tests", "tests\VMelnalksnis.NordigenDotNet.Tests\VMelnalksnis.NordigenDotNet.Tests.csproj", "{B01186E2-7A80-4117-BC89-C345B0221ECE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -58,11 +60,16 @@ Global {10F5857A-33BE-483A-A96C-1903DFFDEFC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {10F5857A-33BE-483A-A96C-1903DFFDEFC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {10F5857A-33BE-483A-A96C-1903DFFDEFC3}.Release|Any CPU.Build.0 = Release|Any CPU + {B01186E2-7A80-4117-BC89-C345B0221ECE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B01186E2-7A80-4117-BC89-C345B0221ECE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B01186E2-7A80-4117-BC89-C345B0221ECE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B01186E2-7A80-4117-BC89-C345B0221ECE}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {98E15B27-7113-48B8-AA35-F65E4273B310} = {F9FD8772-AC85-42BE-B3B0-F03247F72E2A} {10F5857A-33BE-483A-A96C-1903DFFDEFC3} = {F9FD8772-AC85-42BE-B3B0-F03247F72E2A} {CA8D9082-D6CE-4568-8D61-862001E8241A} = {56CE37B2-286D-49AA-BCF4-E9AB51E7CC48} {F733A567-775B-4DD8-B900-005894E062B5} = {CA8D9082-D6CE-4568-8D61-862001E8241A} + {B01186E2-7A80-4117-BC89-C345B0221ECE} = {F9FD8772-AC85-42BE-B3B0-F03247F72E2A} EndGlobalSection EndGlobal diff --git a/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs b/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs index ec6afb5..18effb9 100644 --- a/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs +++ b/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs @@ -59,11 +59,7 @@ public sealed class AccountClient : IAccountClient Interval? interval = null, CancellationToken cancellationToken = default) { - var uri = Routes.Accounts.TransactionsUri(id); - if (interval is { } value) - { - uri += $"?date_from{value.Start:yyyy-MM-dd}&date_to={value.End:yyyy-MM-dd}"; - } + var uri = Routes.Accounts.TransactionsUri(id, interval); var transactions = await _nordigenHttpClient .GetAsJson(uri, cancellationToken) diff --git a/source/VMelnalksnis.NordigenDotNet/Routes.cs b/source/VMelnalksnis.NordigenDotNet/Routes.cs index 401f647..50dff09 100644 --- a/source/VMelnalksnis.NordigenDotNet/Routes.cs +++ b/source/VMelnalksnis.NordigenDotNet/Routes.cs @@ -4,6 +4,8 @@ using System; +using NodaTime; + namespace VMelnalksnis.NordigenDotNet; internal static class Routes @@ -27,7 +29,11 @@ internal static class Routes internal static string DetailsUri(Guid id) => $"{IdUri(id)}details/"; - internal static string TransactionsUri(Guid id) => $"{IdUri(id)}transactions/"; + internal static string TransactionsUri(Guid id, Interval? interval) => interval is null + ? TransactionsUri(id) + : $"{TransactionsUri(id)}?date_from={interval.Value.Start:yyyy-MM-dd}&date_to={interval.Value.End:yyyy-MM-dd}"; + + private static string TransactionsUri(Guid id) => $"{IdUri(id)}transactions/"; } internal static class Institutions diff --git a/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj b/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj index b60d9d8..e0a4c94 100644 --- a/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj +++ b/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj @@ -24,4 +24,8 @@ + + + + diff --git a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs index e4f91e4..880e3c1 100644 --- a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs +++ b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs @@ -5,6 +5,8 @@ using System.Linq; using System.Threading.Tasks; +using NodaTime; + namespace VMelnalksnis.NordigenDotNet.Tests.Integration.Accounts; public sealed class AccountClientTests : IClassFixture @@ -26,7 +28,13 @@ public sealed class AccountClientTests : IClassFixture await _nordigenClient.Accounts.Get(id); await _nordigenClient.Accounts.GetDetails(id); await _nordigenClient.Accounts.GetBalances(id); - await _nordigenClient.Accounts.GetTransactions(id); + + var dateTo = SystemClock.Instance.GetCurrentInstant(); + var dateFrom = dateTo - Duration.FromDays(7); + var transactions = await _nordigenClient.Accounts.GetTransactions(id, new Interval(dateFrom, dateTo)); + var allTransactions = await _nordigenClient.Accounts.GetTransactions(id); + + transactions.Booked.Should().BeSubsetOf(allTransactions.Booked); } } } diff --git a/tests/VMelnalksnis.NordigenDotNet.Tests/RoutesTests.cs b/tests/VMelnalksnis.NordigenDotNet.Tests/RoutesTests.cs new file mode 100644 index 0000000..5d661ac --- /dev/null +++ b/tests/VMelnalksnis.NordigenDotNet.Tests/RoutesTests.cs @@ -0,0 +1,44 @@ +// Copyright 2022 Valters Melnalksnis +// Licensed under the Apache License 2.0. +// See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web; + +using NodaTime; + +namespace VMelnalksnis.NordigenDotNet.Tests; + +public sealed class RoutesTests +{ + [Theory] + [MemberData(nameof(TestData))] + public void TransactionsUri_ShouldHaveExpectedQueryParameters( + Guid id, + Interval? interval, + NameValueCollection expectedParameters) + { + var uriValue = Routes.Accounts.TransactionsUri(id, interval); + var uriBuilder = new UriBuilder(uriValue); + + var queryDictionary = HttpUtility.ParseQueryString(uriBuilder.Query); + queryDictionary.Should().BeEquivalentTo(expectedParameters); + } + + internal static IEnumerable TestData() + { + yield return new object?[] { Guid.NewGuid(), null, new NameValueCollection() }; + + var dateFrom = Instant.FromUtc(2022, 05, 01, 12, 00); + var dateTo = Instant.FromUtc(2022, 05, 12, 13, 00); + var collection = new NameValueCollection + { + { "date_from", "2022-05-01" }, + { "date_to", "2022-05-12" }, + }; + + yield return new object?[] { Guid.NewGuid(), new Interval(dateFrom, dateTo), collection }; + } +} diff --git a/tests/VMelnalksnis.NordigenDotNet.Tests/VMelnalksnis.NordigenDotNet.Tests.csproj b/tests/VMelnalksnis.NordigenDotNet.Tests/VMelnalksnis.NordigenDotNet.Tests.csproj new file mode 100644 index 0000000..320cfe1 --- /dev/null +++ b/tests/VMelnalksnis.NordigenDotNet.Tests/VMelnalksnis.NordigenDotNet.Tests.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + true + key.snk + + + + + + + diff --git a/tests/VMelnalksnis.NordigenDotNet.Tests/key.snk b/tests/VMelnalksnis.NordigenDotNet.Tests/key.snk new file mode 100644 index 0000000000000000000000000000000000000000..f3d8a3fb248bf8e76a01ddf2520a22454eb0fff9 GIT binary patch literal 1172 zcmV;F1Z(>T0ssI2Bme+XQ$aES2mk;90098&4I)N|aoUncGl;%#3PvbLgcB0{&xpR- z+eXZpv3ku8;SS%AfxSZfr?Ce*;!&JcI@TJ!!%q=#?#|v|6JT~99QSIVVzrtv-wX9E zsVAzW1&G%M*5E~uw_hnBmN?~;<hA;TJ4&e_i#`XcrBV&n;4+;uundZ2| z0s=GLxUhq`6Xh;{q^5ml+8E zssWY5E+$(_?fn`2V=ycQ1*YL@wBuH1skXmb#*8l zo}6!natyFq3l`LkE}{}45W;OhkQFN^Dd<`qqCp;m7Y8(%wXZLb+>DIxC`KReMbI|Y z29KhgG)qQEy76!ETFov&5Ky4Kx?>MhD?T9a*C6E3g>a>x;}-#-Atze2q|r!WiI5eg zI-E;zS5D2mKZt*n9ioqCMHxR^#cwtu5(eHz1v3(#1^YmHhbi7x>BoANCWbhDWhRh8 zSdtc(40Kh&oI#&~9xujgGqoz;)h-H1l7K&M7-*tXU3E4IU2$D)HPcWTx|)0g%b{g_ z4bgts1^d7X4*J`|hD(W5>-2Ofu=__k0_tB~UuKj13VyB6XpQ_QKtr1H#g}zVKoi$c zf0(!y11_ciNbUXWd(`q8m6S){6_sfx$xIRINPh#O`7kntF(#@>UxZCfLKAb1Ga$2q zx22LcnmmI1YT-aebi2 z2>DdHAQpMRe)Ec^+bI$=Judae2%xU{ZHnlms05Q$F~Ewl)(EHJCD$&fZNG5Pkxgvy mUlA*}0=jp{6cNh@s3%oYWx>61TX4HtP%Rm-DlUisePj%X4k#S} literal 0 HcmV?d00001