From fd1bb04c65aca90c2a632afe79c1dd12b36037e1 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Wed, 24 Jul 2024 08:14:12 +0200 Subject: [PATCH] fix(dim): fix callback logic for dim requests (#863) Refs: #862 Co-authored-by: Norbert Truchsess Reviewed-By: Evelyn Gurschler Reviewed-By: Norbert Truchsess --- .../BusinessLogic/DimBusinessLogic.cs | 10 ++++++---- .../Repositories/CompanyRepository.cs | 7 +++---- .../Repositories/ICompanyRepository.cs | 2 +- .../DimBusinessLogicTests.cs | 20 +++++++++---------- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/externalsystems/Dim.Library/BusinessLogic/DimBusinessLogic.cs b/src/externalsystems/Dim.Library/BusinessLogic/DimBusinessLogic.cs index be307c7423..34cf42c3a1 100644 --- a/src/externalsystems/Dim.Library/BusinessLogic/DimBusinessLogic.cs +++ b/src/externalsystems/Dim.Library/BusinessLogic/DimBusinessLogic.cs @@ -103,20 +103,22 @@ private async Task CreateWalletInternal(Guid applicationId, CancellationToken ca public async Task ProcessDimResponse(string bpn, DimWalletData data, CancellationToken cancellationToken) { - var (exists, companyId, companyApplicationStatusIds) = await _portalRepositories.GetInstance().GetCompanyIdByBpn(bpn).ConfigureAwait(ConfigureAwaitOptions.None); - if (!exists) + var companySubmittedApplicationIds = await _portalRepositories.GetInstance().GetCompanySubmittedApplicationIdsByBpn(bpn).ToListAsync(cancellationToken).ConfigureAwait(false); + if (companySubmittedApplicationIds.Count == 0) { throw new NotFoundException($"No company found for bpn {bpn}"); } - if (companyApplicationStatusIds.Count() != 1) + var companyApplicationIds = companySubmittedApplicationIds.SelectMany(x => x.SubmittedApplicationIds.Select(applicationId => (x.CompanyId, ApplicationId: applicationId))); + if (companyApplicationIds.Count() != 1) { throw new ConflictException($"There must be exactly one company application in state {CompanyApplicationStatusId.SUBMITTED}"); } + var (companyId, applicationId) = companyApplicationIds.First(); var context = await _checklistService .VerifyChecklistEntryAndProcessSteps( - companyApplicationStatusIds.Single(), + applicationId, ApplicationChecklistEntryTypeId.IDENTITY_WALLET, [ApplicationChecklistEntryStatusId.IN_PROGRESS], ProcessStepTypeId.AWAIT_DIM_RESPONSE, diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs index 80b2e19b8c..c15224fb1f 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/CompanyRepository.cs @@ -367,16 +367,15 @@ public void CreateWalletData(Guid companyId, string did, JsonDocument didDocumen .Select(x => new ValueTuple(true, x.DidDocument)) .SingleOrDefaultAsync(); - public Task<(bool Exists, Guid CompanyId, IEnumerable SubmittedCompanyApplicationId)> GetCompanyIdByBpn(string bpn) => + public IAsyncEnumerable<(Guid CompanyId, IEnumerable SubmittedApplicationIds)> GetCompanySubmittedApplicationIdsByBpn(string bpn) => context.Companies .Where(x => x.BusinessPartnerNumber == bpn) - .Select(x => new ValueTuple>( - true, + .Select(x => new ValueTuple>( x.Id, x.CompanyApplications .Where(ca => ca.ApplicationStatusId == CompanyApplicationStatusId.SUBMITTED) .Select(ca => ca.Id))) - .SingleOrDefaultAsync(); + .ToAsyncEnumerable(); public Task<(string? Bpn, string? Did, string? WalletUrl)> GetDimServiceUrls(Guid companyId) => context.Companies.Where(x => x.Id == companyId) diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs index d77170ded7..e8d44c0a9e 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/ICompanyRepository.cs @@ -175,7 +175,7 @@ public interface ICompanyRepository Task CheckBpnExists(string bpn); void CreateWalletData(Guid companyId, string did, JsonDocument didDocument, string clientId, byte[] clientSecret, byte[]? initializationVector, int encryptionMode, string authenticationServiceUrl); Task<(bool Exists, JsonDocument DidDocument)> GetDidDocumentById(string bpn); - Task<(bool Exists, Guid CompanyId, IEnumerable SubmittedCompanyApplicationId)> GetCompanyIdByBpn(string bpn); + IAsyncEnumerable<(Guid CompanyId, IEnumerable SubmittedApplicationIds)> GetCompanySubmittedApplicationIdsByBpn(string bpn); Task<(string? Bpn, string? Did, string? WalletUrl)> GetDimServiceUrls(Guid companyId); Task<(string? Holder, string? BusinessPartnerNumber, WalletInformation? WalletInformation)> GetWalletData(Guid identityId); void RemoveProviderCompanyDetails(Guid providerCompanyDetailId); diff --git a/tests/externalsystems/Dim.Library.Tests/DimBusinessLogicTests.cs b/tests/externalsystems/Dim.Library.Tests/DimBusinessLogicTests.cs index 42bb772b01..797e7abf79 100644 --- a/tests/externalsystems/Dim.Library.Tests/DimBusinessLogicTests.cs +++ b/tests/externalsystems/Dim.Library.Tests/DimBusinessLogicTests.cs @@ -259,8 +259,8 @@ public async Task ProcessDimResponse_NoCompanyForBpn_ThrowsNotFoundException() { // Arrange var data = _fixture.Create(); - A.CallTo(() => _companyRepository.GetCompanyIdByBpn(BPN)) - .Returns(new ValueTuple>(false, default, Enumerable.Empty())); + A.CallTo(() => _companyRepository.GetCompanySubmittedApplicationIdsByBpn(BPN)) + .Returns(Enumerable.Empty>>().ToAsyncEnumerable()); async Task Act() => await _logic.ProcessDimResponse(BPN, data, CancellationToken.None); // Act @@ -277,8 +277,8 @@ public async Task ProcessDimResponse_WithMultipleSubmittedApplications_ThrowsCon { // Arrange var data = _fixture.Create(); - A.CallTo(() => _companyRepository.GetCompanyIdByBpn(BPN)) - .Returns(new ValueTuple>(true, default, _fixture.CreateMany(2))); + A.CallTo(() => _companyRepository.GetCompanySubmittedApplicationIdsByBpn(BPN)) + .Returns(Enumerable.Repeat(new ValueTuple>(default, _fixture.CreateMany(2)), 1).ToAsyncEnumerable()); async Task Act() => await _logic.ProcessDimResponse(BPN, data, CancellationToken.None); // Act @@ -304,8 +304,8 @@ public async Task ProcessDimResponse_WithDidSchemaInvalid_CallsExpected() .With(x => x.Did, "did:web:test.com:BPNL0000000000XX") .Create(); var companyId = Guid.NewGuid(); - A.CallTo(() => _companyRepository.GetCompanyIdByBpn(BPN)) - .Returns(new ValueTuple>(true, companyId, Enumerable.Repeat(ApplicationId, 1))); + A.CallTo(() => _companyRepository.GetCompanySubmittedApplicationIdsByBpn(BPN)) + .Returns(Enumerable.Repeat(new ValueTuple>(companyId, Enumerable.Repeat(ApplicationId, 1)), 1).ToAsyncEnumerable()); A.CallTo(() => _checklistService.VerifyChecklistEntryAndProcessSteps(ApplicationId, ApplicationChecklistEntryTypeId.IDENTITY_WALLET, A>._, ProcessStepTypeId.AWAIT_DIM_RESPONSE, A?>._, A?>._)) .Returns(context); @@ -330,8 +330,8 @@ public async Task ProcessDimResponse_WithFailingSchemaValidation_CallsExpected() var didDocument = JsonDocument.Parse("{\n \"@context\": [\n \"abc\" ],\n \"id\": \"did:web:example.org:did:BPNL0000000000XX\",\n \"verificationMethod\": [\n {\n \"id\": [\"did:web:example.com:did:BPNL0000000000XX#key-0\"],\n \"publicKeyJwk\": {\n \"kty\": \"JsonWebKey2020\",\n \"crv\": \"Ed25519\",\n \"x\": \"3534354354353\"\n }\n }\n ],\n \"services\": [\n {\n \"id\": [\"did:web:example.com:did:BPNL0000000000XX#key-0\"],\n \"serviceEndpoint\": \"test.org:123\"\n }\n ]\n}"); var data = _fixture.Build().With(x => x.DidDocument, didDocument).With(x => x.Did, "did:web:example.org:did:BPNL0000000000XX").Create(); var companyId = Guid.NewGuid(); - A.CallTo(() => _companyRepository.GetCompanyIdByBpn(BPN)) - .Returns(new ValueTuple>(true, companyId, Enumerable.Repeat(ApplicationId, 1))); + A.CallTo(() => _companyRepository.GetCompanySubmittedApplicationIdsByBpn(BPN)) + .Returns(Enumerable.Repeat(new ValueTuple>(companyId, Enumerable.Repeat(ApplicationId, 1)), 1).ToAsyncEnumerable()); A.CallTo(() => _checklistService.VerifyChecklistEntryAndProcessSteps(ApplicationId, ApplicationChecklistEntryTypeId.IDENTITY_WALLET, A>._, ProcessStepTypeId.AWAIT_DIM_RESPONSE, A?>._, A?>._)) .Returns(context); @@ -390,8 +390,8 @@ public async Task ProcessDimResponse_WithValid_CallsExpected() .With(x => x.Did, "did:web:example.org:did:BPNL0000000000XX") .Create(); var companyId = Guid.NewGuid(); - A.CallTo(() => _companyRepository.GetCompanyIdByBpn(BPN)) - .Returns(new ValueTuple>(true, companyId, Enumerable.Repeat(ApplicationId, 1))); + A.CallTo(() => _companyRepository.GetCompanySubmittedApplicationIdsByBpn(BPN)) + .Returns(Enumerable.Repeat(new ValueTuple>(companyId, Enumerable.Repeat(ApplicationId, 1)), 1).ToAsyncEnumerable()); A.CallTo(() => _checklistService.VerifyChecklistEntryAndProcessSteps(ApplicationId, ApplicationChecklistEntryTypeId.IDENTITY_WALLET, A>._, ProcessStepTypeId.AWAIT_DIM_RESPONSE, A?>._, A?>._)) .Returns(context); byte[]? encrypted = null;