From 637fd70cb24a4bcdd3042d6bcef016399849808d Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Tue, 6 Dec 2022 15:17:44 +0100 Subject: [PATCH] remove NodaTime dependency and refactor to System.DateTimeOffset --- .../Accounts/Account.cs | 4 +- .../Accounts/AccountClient.cs | 5 ++- .../Accounts/Balance.cs | 3 +- .../Accounts/BookedTransaction.cs | 4 +- .../Accounts/IAccountClient.cs | 5 ++- .../Accounts/Transaction.cs | 3 +- .../Agreements/EndUserAgreement.cs | 6 +-- .../Requisitions/Requisition.cs | 2 +- source/VMelnalksnis.NordigenDotNet/Routes.cs | 20 +++++++--- .../NordigenJsonSerializerOptions.cs | 8 +--- .../Tokens/AccessToken.cs | 2 +- .../Tokens/NordigenTokenCache.cs | 37 +++++++++---------- .../Tokens/Token.cs | 2 +- .../VMelnalksnis.NordigenDotNet.csproj | 5 --- .../ServiceCollectionExtensionsTests.cs | 2 - .../Accounts/AccountClientTests.cs | 22 +++++------ .../Agreements/AgreementClientTests.cs | 5 +-- .../Requisitions/RequisitionsClientTests.cs | 5 +-- .../RoutesTests.cs | 5 ++- .../TransactionsUriTestData.cs | 6 +-- 20 files changed, 75 insertions(+), 76 deletions(-) diff --git a/source/VMelnalksnis.NordigenDotNet/Accounts/Account.cs b/source/VMelnalksnis.NordigenDotNet/Accounts/Account.cs index 809ef8a..e8a0ec9 100644 --- a/source/VMelnalksnis.NordigenDotNet/Accounts/Account.cs +++ b/source/VMelnalksnis.NordigenDotNet/Accounts/Account.cs @@ -18,11 +18,11 @@ public record Account public Guid Id { get; set; } /// Gets or sets the point in time when the account object was created. - public Instant Created { get; set; } + public DateTimeOffset Created { get; set; } /// Gets or sets the point in time when the account object was last accessed. [JsonPropertyName("last_accessed")] - public Instant LastAccessed { get; set; } + public DateTimeOffset LastAccessed { get; set; } /// Gets or sets the account IBAN. public string Iban { get; set; } = null!; diff --git a/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs b/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs index a07e687..d7f5e4b 100644 --- a/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs +++ b/source/VMelnalksnis.NordigenDotNet/Accounts/AccountClient.cs @@ -60,11 +60,12 @@ public sealed class AccountClient : IAccountClient /// public async Task GetTransactions( Guid id, - Interval? interval = null, + DateTimeOffset? dateFrom = null, + DateTimeOffset? dateTo = null, CancellationToken cancellationToken = default) { var transactions = await _httpClient - .GetFromJsonAsync(Routes.Accounts.TransactionsUri(id, interval), _context.TransactionsWrapper, cancellationToken) + .GetFromJsonAsync(Routes.Accounts.TransactionsUri(id, dateFrom, dateTo), _context.TransactionsWrapper, cancellationToken) .ConfigureAwait(false); return transactions!.Transactions; diff --git a/source/VMelnalksnis.NordigenDotNet/Accounts/Balance.cs b/source/VMelnalksnis.NordigenDotNet/Accounts/Balance.cs index cd5e578..d0b4696 100644 --- a/source/VMelnalksnis.NordigenDotNet/Accounts/Balance.cs +++ b/source/VMelnalksnis.NordigenDotNet/Accounts/Balance.cs @@ -2,6 +2,7 @@ // 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 NodaTime; @@ -21,7 +22,7 @@ public record Balance public bool CreditLimitIncluded { get; set; } /// Gets or sets the date on which the balance was calculated. - public LocalDate? ReferenceDate { get; set; } + public DateTimeOffset? ReferenceDate { get; set; } } internal class BalancesWrapper diff --git a/source/VMelnalksnis.NordigenDotNet/Accounts/BookedTransaction.cs b/source/VMelnalksnis.NordigenDotNet/Accounts/BookedTransaction.cs index 80c58b2..fcbbb52 100644 --- a/source/VMelnalksnis.NordigenDotNet/Accounts/BookedTransaction.cs +++ b/source/VMelnalksnis.NordigenDotNet/Accounts/BookedTransaction.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License 2.0. // See LICENSE file in the project root for full license information. +using System; + using NodaTime; using VMelnalksnis.NordigenDotNet.Institutions; @@ -15,7 +17,7 @@ public record BookedTransaction : Transaction public string TransactionId { get; set; } = null!; /// Gets or sets the date when an entry is posted to an account on the account servicer's books. - public LocalDate BookingDate { get; set; } + public DateTimeOffset BookingDate { get; set; } /// Gets or sets the name of the counterparty that sends during the transaction. public string? DebtorName { get; set; } diff --git a/source/VMelnalksnis.NordigenDotNet/Accounts/IAccountClient.cs b/source/VMelnalksnis.NordigenDotNet/Accounts/IAccountClient.cs index b5dcdfa..75c6683 100644 --- a/source/VMelnalksnis.NordigenDotNet/Accounts/IAccountClient.cs +++ b/source/VMelnalksnis.NordigenDotNet/Accounts/IAccountClient.cs @@ -34,8 +34,9 @@ public interface IAccountClient /// Gets all transactions for the account within the specified interval. /// The id of the account. - /// The interval for which to get the transactions. + /// The start date for which to get the transactions. + /// The end date for which to get the transactions. /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// All transactions for the specified account and interval. - Task GetTransactions(Guid id, Interval? interval = null, CancellationToken cancellationToken = default); + Task GetTransactions(Guid id, DateTimeOffset? dateFrom = null, DateTimeOffset? dateTo = null, CancellationToken cancellationToken = default); } diff --git a/source/VMelnalksnis.NordigenDotNet/Accounts/Transaction.cs b/source/VMelnalksnis.NordigenDotNet/Accounts/Transaction.cs index 6554f09..51b5e6e 100644 --- a/source/VMelnalksnis.NordigenDotNet/Accounts/Transaction.cs +++ b/source/VMelnalksnis.NordigenDotNet/Accounts/Transaction.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License 2.0. // See LICENSE file in the project root for full license information. +using System; using System.Text.Json.Serialization; using NodaTime; @@ -19,5 +20,5 @@ public abstract record Transaction public string UnstructuredInformation { get; set; } = null!; /// Gets or sets the date when the transaction was valued at. - public LocalDate? ValueDate { get; set; } + public DateTimeOffset? ValueDate { get; set; } } diff --git a/source/VMelnalksnis.NordigenDotNet/Agreements/EndUserAgreement.cs b/source/VMelnalksnis.NordigenDotNet/Agreements/EndUserAgreement.cs index be16c9c..962f108 100644 --- a/source/VMelnalksnis.NordigenDotNet/Agreements/EndUserAgreement.cs +++ b/source/VMelnalksnis.NordigenDotNet/Agreements/EndUserAgreement.cs @@ -19,7 +19,7 @@ public record EndUserAgreement public Guid Id { get; set; } /// Gets or sets the point in time when the agreement was created. - public Instant Created { get; set; } + public DateTimeOffset Created { get; set; } /// Gets or sets maximum number of days of transaction data to retrieve. [JsonPropertyName("max_historical_days")] @@ -37,6 +37,6 @@ public record EndUserAgreement [JsonPropertyName("institution_id")] public string InstitutionId { get; set; } = null!; - /// Gets or sets the point int time when the end user accepted the agreement. - public Instant? Accepted { get; set; } + /// Gets or sets the point in time when the end user accepted the agreement. + public DateTimeOffset? Accepted { get; set; } } diff --git a/source/VMelnalksnis.NordigenDotNet/Requisitions/Requisition.cs b/source/VMelnalksnis.NordigenDotNet/Requisitions/Requisition.cs index 7b376ec..2984172 100644 --- a/source/VMelnalksnis.NordigenDotNet/Requisitions/Requisition.cs +++ b/source/VMelnalksnis.NordigenDotNet/Requisitions/Requisition.cs @@ -17,7 +17,7 @@ public record Requisition public Guid Id { get; set; } /// Gets or sets the point in time when the requisition was created. - public Instant Created { get; set; } + public DateTimeOffset Created { get; set; } /// Gets or sets the URI to which the user will be redirected after authorizing access. public Uri Redirect { get; set; } = null!; diff --git a/source/VMelnalksnis.NordigenDotNet/Routes.cs b/source/VMelnalksnis.NordigenDotNet/Routes.cs index 2071ee0..04d11c7 100644 --- a/source/VMelnalksnis.NordigenDotNet/Routes.cs +++ b/source/VMelnalksnis.NordigenDotNet/Routes.cs @@ -4,8 +4,6 @@ using System; -using NodaTime; - namespace VMelnalksnis.NordigenDotNet; internal static class Routes @@ -33,9 +31,21 @@ internal static class Routes internal static string DetailsUri(Guid id) => $"{IdUri(id)}details/"; - 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}"; + internal static string TransactionsUri(Guid id, DateTimeOffset? dateFrom, DateTimeOffset? dateTo) + { + var uri = TransactionsUri(id); + + if (dateFrom.HasValue) + { + uri += $"?date_from={dateFrom.Value:yyyy-MM-dd}"; + } + if (dateTo.HasValue) + { + uri += $"{(dateFrom.HasValue ? '&' : '?')}date_to={dateTo.Value:yyyy-MM-dd}"; + } + + return uri; + } private static string TransactionsUri(Guid id) => $"{IdUri(id)}transactions/"; } diff --git a/source/VMelnalksnis.NordigenDotNet/Serialization/NordigenJsonSerializerOptions.cs b/source/VMelnalksnis.NordigenDotNet/Serialization/NordigenJsonSerializerOptions.cs index 89801a2..07dbe03 100644 --- a/source/VMelnalksnis.NordigenDotNet/Serialization/NordigenJsonSerializerOptions.cs +++ b/source/VMelnalksnis.NordigenDotNet/Serialization/NordigenJsonSerializerOptions.cs @@ -5,22 +5,18 @@ using System.Text.Json; using System.Text.Json.Serialization; -using NodaTime; -using NodaTime.Serialization.SystemTextJson; - namespace VMelnalksnis.NordigenDotNet.Serialization; /// for . public sealed class NordigenJsonSerializerOptions { /// Initializes a new instance of the class. - /// Time zone provider for date and time serialization. - public NordigenJsonSerializerOptions(IDateTimeZoneProvider dateTimeZoneProvider) + public NordigenJsonSerializerOptions() { var options = new JsonSerializerOptions(JsonSerializerDefaults.Web) { Converters = { new JsonStringEnumConverter() }, - }.ConfigureForNodaTime(dateTimeZoneProvider); + }; Context = new(options); } diff --git a/source/VMelnalksnis.NordigenDotNet/Tokens/AccessToken.cs b/source/VMelnalksnis.NordigenDotNet/Tokens/AccessToken.cs index b884d45..ba28e51 100644 --- a/source/VMelnalksnis.NordigenDotNet/Tokens/AccessToken.cs +++ b/source/VMelnalksnis.NordigenDotNet/Tokens/AccessToken.cs @@ -6,7 +6,7 @@ using System.Text.Json.Serialization; namespace VMelnalksnis.NordigenDotNet.Tokens; -internal class AccessToken +public class AccessToken { [JsonConstructor] public AccessToken(string access, int accessExpires) diff --git a/source/VMelnalksnis.NordigenDotNet/Tokens/NordigenTokenCache.cs b/source/VMelnalksnis.NordigenDotNet/Tokens/NordigenTokenCache.cs index 3415302..e9d5aa2 100644 --- a/source/VMelnalksnis.NordigenDotNet/Tokens/NordigenTokenCache.cs +++ b/source/VMelnalksnis.NordigenDotNet/Tokens/NordigenTokenCache.cs @@ -2,6 +2,8 @@ // Licensed under the Apache License 2.0. // See LICENSE file in the project root for full license information. +using System; + using NodaTime; namespace VMelnalksnis.NordigenDotNet.Tokens; @@ -10,50 +12,47 @@ namespace VMelnalksnis.NordigenDotNet.Tokens; public class NordigenTokenCache { private readonly NordigenOptions _nordigenOptions; - private readonly IClock _clock; /// Initializes a new instance of the class. /// Options for connection to the Nordigen API. - /// Clock for accessing the current time. - public NordigenTokenCache(NordigenOptions nordigenOptions, IClock clock) + public NordigenTokenCache(NordigenOptions nordigenOptions) { _nordigenOptions = nordigenOptions; - _clock = clock; } - internal AccessToken? AccessToken { get; private set; } + public AccessToken? AccessToken { get; private set; } - internal bool IsAccessExpired => + public bool IsAccessExpired => AccessToken is not null && AccessExpiresAt is not null && - _clock.GetCurrentInstant() > AccessExpiresAt; + DateTimeOffset.Now > AccessExpiresAt; - internal Token? Token { get; private set; } + public Token? Token { get; private set; } - internal bool IsRefreshExpired => + public bool IsRefreshExpired => Token is not null && RefreshExpiresAt is not null && - _clock.GetCurrentInstant() > RefreshExpiresAt; + DateTimeOffset.Now > RefreshExpiresAt; - private Instant? AccessExpiresAt { get; set; } + public DateTimeOffset? AccessExpiresAt { get; set; } - private Instant? RefreshExpiresAt { get; set; } + public DateTimeOffset? RefreshExpiresAt { get; set; } - internal void SetToken(Token token) + public void SetToken(Token token) { Token = token; AccessToken = token; - var currentInstant = _clock.GetCurrentInstant(); + var now = DateTimeOffset.Now; var factor = _nordigenOptions.ExpirationFactor; - AccessExpiresAt = currentInstant + Duration.FromSeconds(token.AccessExpires / factor); - RefreshExpiresAt = currentInstant + Duration.FromSeconds(token.RefreshExpires / factor); + AccessExpiresAt = now.AddSeconds(token.AccessExpires / factor); + RefreshExpiresAt = now.AddSeconds(token.RefreshExpires / factor); } - internal void SetAccessToken(AccessToken accessToken) + public void SetAccessToken(AccessToken accessToken) { AccessToken = accessToken; - var currentInstant = _clock.GetCurrentInstant(); + var now = DateTimeOffset.Now; var factor = _nordigenOptions.ExpirationFactor; - AccessExpiresAt = currentInstant + Duration.FromSeconds(accessToken.AccessExpires / factor); + AccessExpiresAt = now.AddSeconds(accessToken.AccessExpires / factor); } } diff --git a/source/VMelnalksnis.NordigenDotNet/Tokens/Token.cs b/source/VMelnalksnis.NordigenDotNet/Tokens/Token.cs index bbe1b82..7a07102 100644 --- a/source/VMelnalksnis.NordigenDotNet/Tokens/Token.cs +++ b/source/VMelnalksnis.NordigenDotNet/Tokens/Token.cs @@ -6,7 +6,7 @@ using System.Text.Json.Serialization; namespace VMelnalksnis.NordigenDotNet.Tokens; -internal class Token : AccessToken +public class Token : AccessToken { [JsonConstructor] public Token(string access, int accessExpires, string refresh, int refreshExpires) diff --git a/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj b/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj index 0dbba2b..6cdde71 100644 --- a/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj +++ b/source/VMelnalksnis.NordigenDotNet/VMelnalksnis.NordigenDotNet.csproj @@ -13,11 +13,6 @@ key.snk - - - - - diff --git a/tests/VMelnalksnis.NordigenDotNet.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs b/tests/VMelnalksnis.NordigenDotNet.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs index bb19eb8..8d20b6f 100644 --- a/tests/VMelnalksnis.NordigenDotNet.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs +++ b/tests/VMelnalksnis.NordigenDotNet.DependencyInjection.Tests/ServiceCollectionExtensionsTests.cs @@ -28,8 +28,6 @@ public sealed class ServiceCollectionExtensionsTests var serviceCollection = new ServiceCollection(); serviceCollection - .AddSingleton(SystemClock.Instance) - .AddSingleton(DateTimeZoneProviders.Tzdb) .AddNordigenDotNet(configuration); var serviceProvider = serviceCollection.BuildServiceProvider(); diff --git a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs index 854d1ae..e97767f 100644 --- a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs +++ b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Accounts/AccountClientTests.cs @@ -6,8 +6,6 @@ using System; using System.Linq; using System.Threading.Tasks; -using NodaTime; - using VMelnalksnis.NordigenDotNet.Requisitions; using Xunit.Abstractions; @@ -41,12 +39,12 @@ public sealed class AccountClientTests : IClassFixture, _requisition.Accounts.Should().HaveCount(2); var account = await _nordigenClient.Accounts.Get(_accountId); - var currentInstant = SystemClock.Instance.GetCurrentInstant(); + var now = DateTimeOffset.Now; using (new AssertionScope()) { account.Id.Should().Be(_accountId); - account.Created.Should().BeLessThan(account.LastAccessed).And.BeLessThan(currentInstant); - account.LastAccessed.Should().BeGreaterThan(currentInstant - Duration.FromMinutes(1)); + account.Created.Should().BeBefore(account.LastAccessed).And.BeBefore(now); + account.LastAccessed.Should().BeAfter(now.AddMinutes(-1)); account.Iban.Should().Be("GL3343697694912188"); account.InstitutionId.Should().Be(IntegrationInstitutionId); account.Status.Should().BeDefined(); @@ -90,13 +88,11 @@ public sealed class AccountClientTests : IClassFixture, [Fact] public async Task GetTransactions_ShouldReturnExpected() { - var currentInstant = SystemClock.Instance.GetCurrentInstant(); - var currentZone = DateTimeZoneProviders.Tzdb.GetSystemDefault(); - var currentDate = currentInstant.InZone(currentZone).Date; + var now = DateTimeOffset.Now; - var dateTo = currentInstant; - var dateFrom = dateTo - Duration.FromDays(7); - var transactions = await _nordigenClient.Accounts.GetTransactions(_accountId, new Interval(dateFrom, dateTo)); + var dateTo = now; + var dateFrom = dateTo.AddDays(-7); + var transactions = await _nordigenClient.Accounts.GetTransactions(_accountId, dateFrom, dateTo); var allTransactions = await _nordigenClient.Accounts.GetTransactions(_accountId); using (new AssertionScope()) @@ -109,9 +105,9 @@ public sealed class AccountClientTests : IClassFixture, pendingTransaction.TransactionAmount.Currency.Should().Be("EUR"); pendingTransaction.TransactionAmount.Amount.Should().Be(10m); pendingTransaction.UnstructuredInformation.Should().Be("Reserved PAYMENT Emperor's Burgers"); - pendingTransaction.ValueDate.Should().Be(currentDate - Period.FromDays(2)); + pendingTransaction.ValueDate.Should().Be(now.AddDays(-2)); - var date = currentDate - Period.FromDays(1); + var date = now.AddDays(-1); var transactionId = $"{date:yyyyMMdd}01927908-1"; var bookedTransaction = transactions.Booked.First(transaction => transaction.TransactionId == transactionId); bookedTransaction.TransactionAmount.Currency.Should().Be("EUR"); diff --git a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Agreements/AgreementClientTests.cs b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Agreements/AgreementClientTests.cs index 0ff1ac0..4963af0 100644 --- a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Agreements/AgreementClientTests.cs +++ b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Agreements/AgreementClientTests.cs @@ -2,12 +2,11 @@ // Licensed under the Apache License 2.0. // See LICENSE file in the project root for full license information. +using System; using System.Linq; using System.Net.Http; using System.Threading.Tasks; -using NodaTime; - using VMelnalksnis.NordigenDotNet.Agreements; using Xunit.Abstractions; @@ -39,7 +38,7 @@ public sealed class AgreementClientTests : IClassFixture using (new AssertionScope()) { - createdAgreement.Created.Should().BeGreaterThan(SystemClock.Instance.GetCurrentInstant() - Duration.FromSeconds(5)); + createdAgreement.Created.Should().BeAfter(DateTimeOffset.Now.AddSeconds(-5)); createdAgreement.Accepted.Should().BeNull(); createdAgreement.MaxHistoricalDays.Should().Be(90); createdAgreement.AccessValidForDays.Should().Be(90); diff --git a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Requisitions/RequisitionsClientTests.cs b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Requisitions/RequisitionsClientTests.cs index 81bcf10..8529fc6 100644 --- a/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Requisitions/RequisitionsClientTests.cs +++ b/tests/VMelnalksnis.NordigenDotNet.Tests.Integration/Requisitions/RequisitionsClientTests.cs @@ -2,14 +2,13 @@ // 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.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using NodaTime; - using VMelnalksnis.NordigenDotNet.Requisitions; using Xunit.Abstractions; @@ -66,7 +65,7 @@ public sealed class RequisitionsClientTests : IClassFixture { 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 dateFrom = new DateTimeOffset(2022, 05, 01, 12, 00, 00, TimeSpan.Zero); + var dateTo = new DateTimeOffset(2022, 05, 12, 13, 00, 00, TimeSpan.Zero); 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 }; + yield return new object?[] { Guid.NewGuid(), dateFrom, dateTo, collection }; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();