From 8f9c4b6ddeaab96440c530e9a6460daccf2bf994 Mon Sep 17 00:00:00 2001 From: Luciana Regina Lino Date: Wed, 10 Jul 2024 12:36:47 -0300 Subject: [PATCH] feat: changes OdataRepository implementation to obtain context service authentication token. --- src/Liquid.Core/Liquid.Core.csproj | 4 +- .../Extensions/ILiquidRepositoryExtension.cs | 33 ------- .../Extensions/IServiceCollectionExtension.cs | 2 + .../IODataClientFactory.cs | 3 +- .../Liquid.Repository.OData.csproj | 2 +- .../ODataClientFactory.cs | 18 +++- .../ODataRepository.cs | 53 ++--------- .../IServiceCollectionExtensionTests.cs | 3 +- .../ODataClientFactoryTests.cs | 49 ++++++++-- .../ODataRepositoryTests.cs | 90 +------------------ 10 files changed, 74 insertions(+), 183 deletions(-) delete mode 100644 src/Liquid.Repository.OData/Extensions/ILiquidRepositoryExtension.cs diff --git a/src/Liquid.Core/Liquid.Core.csproj b/src/Liquid.Core/Liquid.Core.csproj index 32107ed..13796ad 100644 --- a/src/Liquid.Core/Liquid.Core.csproj +++ b/src/Liquid.Core/Liquid.Core.csproj @@ -10,7 +10,7 @@ Avanade 2019 https://github.com/Avanade/Liquid-Application-Framework logo.png - 8.0.0-beta-06 + 8.0.0-beta-07 true {C33A89FC-4F4D-4274-8D0F-29456BA8F76B} true @@ -28,7 +28,7 @@ - + diff --git a/src/Liquid.Repository.OData/Extensions/ILiquidRepositoryExtension.cs b/src/Liquid.Repository.OData/Extensions/ILiquidRepositoryExtension.cs deleted file mode 100644 index 9a6d654..0000000 --- a/src/Liquid.Repository.OData/Extensions/ILiquidRepositoryExtension.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Liquid.Core.Entities; -using Liquid.Core.Interfaces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Liquid.Repository.OData.Extensions -{ - /// - /// Extension methods for . - /// - public static class ILiquidRepositoryExtension - { - /// - /// Set the token to perform operations. - /// - /// - /// - /// - /// - /// - public static ILiquidRepository SetODataAuthenticationHeader(this ILiquidRepository repository, string token) where TEntity : LiquidEntity, new() - { - var oDataRepository = repository as ODataRepository; - - oDataRepository.SetToken(token); - - return repository; - } - } -} diff --git a/src/Liquid.Repository.OData/Extensions/IServiceCollectionExtension.cs b/src/Liquid.Repository.OData/Extensions/IServiceCollectionExtension.cs index 3ee5487..a623fae 100644 --- a/src/Liquid.Repository.OData/Extensions/IServiceCollectionExtension.cs +++ b/src/Liquid.Repository.OData/Extensions/IServiceCollectionExtension.cs @@ -1,5 +1,6 @@ using Liquid.Core.Entities; using Liquid.Core.Extensions.DependencyInjection; +using Liquid.Core.Implementations; using Liquid.Core.Interfaces; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -30,6 +31,7 @@ public static IServiceCollection AddLiquidOdataRepository( where TEntity : LiquidEntity, new() { services.TryAddSingleton(); + services.TryAddSingleton(); services.AddOptions() .Configure((settings, configuration) => diff --git a/src/Liquid.Repository.OData/IODataClientFactory.cs b/src/Liquid.Repository.OData/IODataClientFactory.cs index 5d69fc5..8385907 100644 --- a/src/Liquid.Repository.OData/IODataClientFactory.cs +++ b/src/Liquid.Repository.OData/IODataClientFactory.cs @@ -16,7 +16,6 @@ public interface IODataClientFactory /// Create an OData client. /// /// The entity name. - /// Authorization token. - IODataClient CreateODataClientAsync(string entityName, string token); + IODataClient CreateODataClientAsync(string entityName); } } diff --git a/src/Liquid.Repository.OData/Liquid.Repository.OData.csproj b/src/Liquid.Repository.OData/Liquid.Repository.OData.csproj index d8315fd..8a64ddc 100644 --- a/src/Liquid.Repository.OData/Liquid.Repository.OData.csproj +++ b/src/Liquid.Repository.OData/Liquid.Repository.OData.csproj @@ -13,7 +13,7 @@ Avanade 2019 https://github.com/Avanade/Liquid-Application-Framework logo.png - 8.0.0-beta-02 + 8.0.0-beta-03 true true Full diff --git a/src/Liquid.Repository.OData/ODataClientFactory.cs b/src/Liquid.Repository.OData/ODataClientFactory.cs index 999f893..8a82817 100644 --- a/src/Liquid.Repository.OData/ODataClientFactory.cs +++ b/src/Liquid.Repository.OData/ODataClientFactory.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Options; +using Liquid.Core.Interfaces; +using Microsoft.Extensions.Options; using Simple.OData.Client; namespace Liquid.Repository.OData @@ -7,19 +8,30 @@ namespace Liquid.Repository.OData public class ODataClientFactory : IODataClientFactory { private readonly IOptions _options; + private readonly ILiquidContext _context; /// /// Initialize a new instance of /// /// - public ODataClientFactory(IOptions options) + /// + public ODataClientFactory(IOptions options, ILiquidContext context) { _options = options ?? throw new ArgumentNullException(nameof(options)); + _context = context ?? throw new ArgumentNullException(nameof(context)); } /// - public IODataClient CreateODataClientAsync(string entityName, string token) + public IODataClient CreateODataClientAsync(string entityName) { + var token = _context.Get("OdataToken").ToString(); + + if (string.IsNullOrEmpty(token)) + { + throw new InvalidOperationException("Token is required to perform this operation. The 'OdataToken' variable" + + " must be declared in the LiquidContext service."); + } + var settings = _options?.Value?.Settings.FirstOrDefault(x => x.EntityName == entityName); if (settings == null) diff --git a/src/Liquid.Repository.OData/ODataRepository.cs b/src/Liquid.Repository.OData/ODataRepository.cs index c771ac2..0049617 100644 --- a/src/Liquid.Repository.OData/ODataRepository.cs +++ b/src/Liquid.Repository.OData/ODataRepository.cs @@ -1,6 +1,5 @@ using Liquid.Core.Entities; using Liquid.Core.Interfaces; -using Simple.OData.Client; using System.Linq.Expressions; namespace Liquid.Repository.OData @@ -13,7 +12,6 @@ namespace Liquid.Repository.OData private readonly IODataClientFactory _clientFactory; private readonly string _entityName; - private string _token; /// /// Initialize a new instance of @@ -27,24 +25,11 @@ public ODataRepository(IODataClientFactory clientFactory, string entityName) _entityName = entityName ?? throw new ArgumentNullException(nameof(entityName)); } - /// - /// Set the token to perform operations. - /// - /// Token to be set. - public void SetToken(string token) - { - _token = token; - } /// public async Task AddAsync(TEntity entity) - { - if (string.IsNullOrEmpty(_token)) - { - throw new InvalidOperationException("Token is required to perform this operation."); - } - - var client = _clientFactory.CreateODataClientAsync(_entityName, _token); + { + var client = _clientFactory.CreateODataClientAsync(_entityName); await client.For().Set(entity).InsertEntryAsync(); } @@ -52,12 +37,7 @@ public async Task AddAsync(TEntity entity) /// public async Task> FindAllAsync() { - if (string.IsNullOrEmpty(_token)) - { - throw new InvalidOperationException("Token is required to perform this operation."); - } - - var client = _clientFactory.CreateODataClientAsync(_entityName, _token); + var client = _clientFactory.CreateODataClientAsync(_entityName); return await client.For().FindEntriesAsync(); } @@ -65,11 +45,7 @@ public async Task> FindAllAsync() /// public async Task FindByIdAsync(TIdentifier id) { - if (string.IsNullOrEmpty(_token)) - { - throw new InvalidOperationException("Token is required to perform this operation."); - } - var client = _clientFactory.CreateODataClientAsync(_entityName, _token); + var client = _clientFactory.CreateODataClientAsync(_entityName); return await client.For().Key(id).FindEntryAsync(); } @@ -77,12 +53,7 @@ public async Task FindByIdAsync(TIdentifier id) /// public async Task RemoveByIdAsync(TIdentifier id) { - if (string.IsNullOrEmpty(_token)) - { - throw new InvalidOperationException("Token is required to perform this operation."); - } - - var client = _clientFactory.CreateODataClientAsync(_entityName, _token); + var client = _clientFactory.CreateODataClientAsync(_entityName); await client.For().Key(id).DeleteEntryAsync(); } @@ -90,12 +61,7 @@ public async Task RemoveByIdAsync(TIdentifier id) /// public async Task UpdateAsync(TEntity entity) { - if (string.IsNullOrEmpty(_token)) - { - throw new InvalidOperationException("Token is required to perform this operation."); - } - - var client = _clientFactory.CreateODataClientAsync(_entityName, _token); + var client = _clientFactory.CreateODataClientAsync(_entityName); await client.For().Set(entity).UpdateEntryAsync(); } @@ -103,12 +69,7 @@ public async Task UpdateAsync(TEntity entity) /// public async Task> WhereAsync(Expression> whereClause) { - if (string.IsNullOrEmpty(_token)) - { - throw new InvalidOperationException("Token is required to perform this operation."); - } - - var client = _clientFactory.CreateODataClientAsync(_entityName, _token); + var client = _clientFactory.CreateODataClientAsync(_entityName); return await client.For().Filter(whereClause).FindEntriesAsync(); } diff --git a/test/Liquid.Repository.OData.Tests/IServiceCollectionExtensionTests.cs b/test/Liquid.Repository.OData.Tests/IServiceCollectionExtensionTests.cs index d8a9208..e842fda 100644 --- a/test/Liquid.Repository.OData.Tests/IServiceCollectionExtensionTests.cs +++ b/test/Liquid.Repository.OData.Tests/IServiceCollectionExtensionTests.cs @@ -1,4 +1,5 @@ -using Liquid.Core.Interfaces; +using Liquid.Core.Implementations; +using Liquid.Core.Interfaces; using Liquid.Repository.OData.Extensions; using Liquid.Repository.OData.Tests.Mock; using Microsoft.Extensions.Configuration; diff --git a/test/Liquid.Repository.OData.Tests/ODataClientFactoryTests.cs b/test/Liquid.Repository.OData.Tests/ODataClientFactoryTests.cs index 1b93dcb..d2e3406 100644 --- a/test/Liquid.Repository.OData.Tests/ODataClientFactoryTests.cs +++ b/test/Liquid.Repository.OData.Tests/ODataClientFactoryTests.cs @@ -1,3 +1,4 @@ +using Liquid.Core.Interfaces; using Microsoft.Extensions.Options; using NSubstitute; @@ -7,6 +8,7 @@ public class ODataClientFactoryTests { private IODataClientFactory _sut; private IOptions _options; + private ILiquidContext _context; public ODataClientFactoryTests() { @@ -26,26 +28,29 @@ public ODataClientFactoryTests() _options.Value.Returns(settings); - _sut = new ODataClientFactory(_options); + _context = Substitute.For(); + _context.Get("OdataToken").Returns("token"); + + _sut = new ODataClientFactory(_options, _context); } [Fact] public void ODataClientFactory_WhenEntityNameIsNotFound_ThrowException() { - Assert.Throws(() => _sut.CreateODataClientAsync("TestEntities2", "token")); + Assert.Throws(() => _sut.CreateODataClientAsync("TestEntities2")); } [Fact] public void ODataClientFactory_WhenEntityNameIsNull_ThrowException() { - Assert.Throws(() => _sut.CreateODataClientAsync(null, "token")); + Assert.Throws(() => _sut.CreateODataClientAsync(null)); } [Fact] public void OdataClientFactory_WhenValidateCertIsFalse_ReturnClient() { - var client = _sut.CreateODataClientAsync("TestEntities", "token"); + var client = _sut.CreateODataClientAsync("TestEntities"); Assert.NotNull(client); } @@ -65,12 +70,44 @@ public void OdataClientFactory_WhenValidateCertIsTrue_ReturnClient() Settings = new List() { settings } }); - var sut = new ODataClientFactory(_options); + var sut = new ODataClientFactory(_options, _context); - var client = sut.CreateODataClientAsync("TestEntities", "token"); + var client = sut.CreateODataClientAsync("TestEntities"); Assert.NotNull(client); } + [Fact] + public void OdataClientFactory_WhenTokenIsNotSet_ThrowException() + { + _context.Get("OdataToken").Returns(""); + + Assert.Throws(() => _sut.CreateODataClientAsync("TestEntities")); + } + [Fact] + public void OdataClientFactory_WhenTokenIsNull_ThrowException() + { + var context = Substitute.For(); + + var sut = new ODataClientFactory(_options, context); + + Assert.Throws(() => sut.CreateODataClientAsync("TestEntities")); + } + + [Fact] + public void OdataClientFactory_WhenOptionsIsNull_ThrowException() + { + _options = null; + + Assert.Throws(() => new ODataClientFactory(_options, _context)); + } + + [Fact] + public void OdataClientFactory_WhenContextIsNull_ThrowException() + { + _context = null; + + Assert.Throws(() => new ODataClientFactory(_options, _context)); + } } } \ No newline at end of file diff --git a/test/Liquid.Repository.OData.Tests/ODataRepositoryTests.cs b/test/Liquid.Repository.OData.Tests/ODataRepositoryTests.cs index 3ed402e..face358 100644 --- a/test/Liquid.Repository.OData.Tests/ODataRepositoryTests.cs +++ b/test/Liquid.Repository.OData.Tests/ODataRepositoryTests.cs @@ -20,7 +20,7 @@ public OdataRepositoryTests() _client = Substitute.For(); - factory.CreateODataClientAsync(Arg.Any(), Arg.Any()).Returns(_client); + factory.CreateODataClientAsync(Arg.Any()).Returns(_client); _sut = new ODataRepository(factory, "People"); @@ -43,143 +43,55 @@ public async Task AddAsync_WhenActionIsSuccessful_CallClient() { var entity = new People(); - _sut.SetODataAuthenticationHeader("token"); - await _sut.AddAsync(entity); await _client.Received(1).For().Set(entity).InsertEntryAsync(); } - [Fact] - public async Task AddAsync_WhenTokenIsNotSet_ThrowException() - { - var entity = new People(); - - _sut.SetODataAuthenticationHeader(""); - - await Assert.ThrowsAsync(() => _sut.AddAsync(entity)); - } - [Fact] public async Task FindAllAsync_WhenActionIsSuccessful_CallClient() { - _sut.SetODataAuthenticationHeader("token"); await _sut.FindAllAsync(); await _client.Received(1).For().FindEntriesAsync(); } - [Fact] - public async Task FindAllAsync_WhenTokenIsNotSet_ThrowException() - { - _sut.SetODataAuthenticationHeader(""); - - await Assert.ThrowsAsync(() => _sut.FindAllAsync()); - } - [Fact] public async Task FindByIdAsync_WhenActionIsSuccessful_CallClient() { - _sut.SetODataAuthenticationHeader("token"); - await _sut.FindByIdAsync("id"); await _client.Received(1).For().Key("id").FindEntryAsync(); } - [Fact] - public async Task FindByIdAsync_WhenTokenIsNotSet_ThrowException() - { - _sut.SetODataAuthenticationHeader(""); - - await Assert.ThrowsAsync(() => _sut.FindByIdAsync("id")); - } - [Fact] public async Task RemoveByIdAsync_WhenActionIsSuccessful_CallClient() { - _sut.SetODataAuthenticationHeader("token"); - await _sut.RemoveByIdAsync("id"); await _client.Received(1).For().Key("id").DeleteEntryAsync(); } - [Fact] - public async Task RemoveByIdAsync_WhenTokenIsNotSet_ThrowException() - { - _sut.SetODataAuthenticationHeader(""); - - await Assert.ThrowsAsync(() => _sut.RemoveByIdAsync("id")); - } - [Fact] public async Task UpdateAsync_WhenActionIsSuccessful_CallClient() { var entity = new People(); - _sut.SetODataAuthenticationHeader("token"); - await _sut.UpdateAsync(entity); await _client.Received(1).For().Set(entity).UpdateEntryAsync(); } - [Fact] - public async Task UpdateAsync_WhenTokenIsNotSet_ThrowException() - { - var entity = new People(); - - _sut.SetODataAuthenticationHeader(""); - - await Assert.ThrowsAsync(() => _sut.UpdateAsync(entity)); - } - - [Fact] - public async Task SetODataAuthenticationHeader_WhenTokenIsSet_ReturnClient() - { - _sut.SetODataAuthenticationHeader("token"); - - Assert.NotNull(_sut); - } - [Fact] public async Task WhereAsync_WhenActionIsSuccessful_CallClient() { - _sut.SetODataAuthenticationHeader("token"); - Expression> expression = e => e.Id.Equals("id"); await _sut.WhereAsync(expression); await _client.Received(1).For().Filter(expression).FindEntriesAsync(); } - - [Fact] - public async Task WhereAsync_WhenTokenIsNotSet_ThrowException() - { - _sut.SetODataAuthenticationHeader(""); - - await Assert.ThrowsAsync(() => _sut.WhereAsync(e => e.Id.Equals("id"))); - } - - - [Fact] - public async Task SetODataAuthenticationHeader_WhenTokenIsNotSet_ThrowException() - { - _sut.SetODataAuthenticationHeader(""); - - await Assert.ThrowsAsync(() => _sut.FindAllAsync()); - } - - [Fact] - public async Task SetODataAuthenticationHeader_WhenTokenIsNull_ThrowException() - { - _sut.SetODataAuthenticationHeader(null); - - await Assert.ThrowsAsync(() => _sut.FindAllAsync()); - } } }