diff --git a/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs index 5cd25e284d..cd6dbd3e40 100644 --- a/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs @@ -63,32 +63,12 @@ public ConnectorsBusinessLogic(IPortalRepositories portalRepositories, IOptions< } /// - public Task> GetAllCompanyConnectorDatas(int page, int size) - { - var connectors = _portalRepositories.GetInstance().GetAllCompanyConnectorsForCompanyId(_identityService.IdentityData.CompanyId); - - return Pagination.CreateResponseAsync(page, size, _settings.MaxPageSize, (skip, take) => - new Pagination.AsyncSource - ( - connectors.CountAsync(), - connectors.OrderByDescending(connector => connector.Name) - .Skip(skip) - .Take(take) - .Select(c => - new ConnectorData( - c.Name, - c.Location!.Alpha2Code, - c.Id, - c.TypeId, - c.StatusId, - c.HostId, - c.Host!.Name, - c.SelfDescriptionDocumentId, - c.SelfDescriptionDocument!.DocumentName) - ).AsAsyncEnumerable() - ) - ); - } + public Task> GetAllCompanyConnectorDatas(int page, int size) => + Pagination.CreateResponseAsync( + page, + size, + _settings.MaxPageSize, + _portalRepositories.GetInstance().GetAllCompanyConnectorsForCompanyId(_identityService.IdentityData.CompanyId)); /// public Task> GetManagedConnectorForCompany(int page, int size) => diff --git a/src/portalbackend/PortalBackend.DBAccess/Models/ConnectorData.cs b/src/portalbackend/PortalBackend.DBAccess/Models/ConnectorData.cs index cfc428c9cd..8eec1152da 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Models/ConnectorData.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Models/ConnectorData.cs @@ -36,7 +36,9 @@ public record ConnectorData( Guid? HostId, string? HostCompanyName, Guid? SelfDescriptionDocumentId, - string? DocumentName); + string? DocumentName, + TechnicalUserData? TechnicalUser +); /// /// Connector information for the daps call. @@ -58,7 +60,8 @@ public record ManagedConnectorData( ConnectorTypeId Type, ConnectorStatusId Status, string? ProviderCompanyName, - Guid? SelfDescriptionDocumentId); + Guid? SelfDescriptionDocumentId, + TechnicalUserData? TechnicalUser); /// /// connector information to delete @@ -73,3 +76,5 @@ public record DeleteConnectorData( Guid? ServiceAccountId ); public record ConnectorOfferSubscription(Guid AssignedOfferSubscriptionIds, OfferSubscriptionStatusId OfferSubscriptionStatus); + +public record TechnicalUserData(Guid Id, string Name, string? ClientId, string Description); diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/ConnectorsRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/ConnectorsRepository.cs index f2e015ba54..a9aac08ea1 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/ConnectorsRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/ConnectorsRepository.cs @@ -42,10 +42,30 @@ public ConnectorsRepository(PortalDbContext portalDbContext) } /// - public IQueryable GetAllCompanyConnectorsForCompanyId(Guid companyId) => - _context.Connectors - .AsNoTracking() - .Where(x => x.ProviderId == companyId && x.StatusId != ConnectorStatusId.INACTIVE); + public Func?>> GetAllCompanyConnectorsForCompanyId(Guid companyId) => + (skip, take) => Pagination.CreateSourceQueryAsync( + skip, + take, + _context.Connectors.AsNoTracking() + .Where(x => x.ProviderId == companyId && x.StatusId != ConnectorStatusId.INACTIVE) + .GroupBy(c => c.HostId), + connector => connector.OrderByDescending(connector => connector.Name), + con => new ConnectorData( + con.Name, + con.Location!.Alpha2Code, + con.Id, + con.TypeId, + con.StatusId, + con.HostId, + con.Host!.Name, + con.SelfDescriptionDocumentId, + con.SelfDescriptionDocument!.DocumentName, + con.CompanyServiceAccountId == null ? null : new TechnicalUserData( + con.CompanyServiceAccount!.Id, + con.CompanyServiceAccount.Name, + con.CompanyServiceAccount.ClientId!, + con.CompanyServiceAccount.Description)) + ).SingleOrDefaultAsync(); /// public Func?>> GetManagedConnectorsForCompany(Guid companyId) => @@ -65,7 +85,12 @@ public IQueryable GetAllCompanyConnectorsForCompanyId(Guid companyId) c.TypeId, c.StatusId, c.Provider!.Name, - c.SelfDescriptionDocumentId) + c.SelfDescriptionDocumentId, + c.CompanyServiceAccountId == default ? null : new TechnicalUserData( + c.CompanyServiceAccount!.Id, + c.CompanyServiceAccount.Name, + c.CompanyServiceAccount.ClientId!, + c.CompanyServiceAccount.Description)) ).SingleOrDefaultAsync(); public Task<(ConnectorData ConnectorData, bool IsProviderCompany)> GetConnectorByIdForCompany(Guid connectorId, Guid companyId) => @@ -82,8 +107,12 @@ public IQueryable GetAllCompanyConnectorsForCompanyId(Guid companyId) connector.HostId, connector.Host!.Name, connector.SelfDescriptionDocumentId, - connector.SelfDescriptionDocument!.DocumentName - ), + connector.SelfDescriptionDocument!.DocumentName, + connector.CompanyServiceAccountId == default ? null : new TechnicalUserData( + connector.CompanyServiceAccount!.Id, + connector.CompanyServiceAccount.Name, + connector.CompanyServiceAccount.ClientId!, + connector.CompanyServiceAccount.Description)), connector.ProviderId == companyId )) .SingleOrDefaultAsync(); diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IConnectorsRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IConnectorsRepository.cs index 1ed7021c79..ba75654719 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IConnectorsRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IConnectorsRepository.cs @@ -34,7 +34,7 @@ public interface IConnectorsRepository /// /// The id of the provider company. /// Queryable of connectors that allows transformation. - IQueryable GetAllCompanyConnectorsForCompanyId(Guid companyId); + Func?>> GetAllCompanyConnectorsForCompanyId(Guid companyId); /// /// Get all managed connectors of a user's company by iam user ID. diff --git a/tests/administration/Administration.Service.Tests/BusinessLogic/ConnectorsBusinessLogicTests.cs b/tests/administration/Administration.Service.Tests/BusinessLogic/ConnectorsBusinessLogicTests.cs index a329fcdef7..c4c579843a 100644 --- a/tests/administration/Administration.Service.Tests/BusinessLogic/ConnectorsBusinessLogicTests.cs +++ b/tests/administration/Administration.Service.Tests/BusinessLogic/ConnectorsBusinessLogicTests.cs @@ -109,20 +109,30 @@ public ConnectorsBusinessLogicTests() #region GetAllCompanyConnectorDatas - [Fact] - public async Task GetAllCompanyConnectorDatas_WithValidData_ReturnsExpected() + [Theory] + [InlineData(0, 10, 5, 1, 0, 5)] + [InlineData(1, 10, 5, 1, 1, 0)] + [InlineData(0, 10, 20, 2, 0, 10)] + [InlineData(1, 10, 20, 2, 1, 10)] + [InlineData(1, 15, 20, 2, 1, 5)] + public async Task GetAllCompanyConnectorDatas_WithValidData_ReturnsExpected(int page, int size, int numberOfElements, int numberOfPages, int resultPage, int resultPageSize) { - // Arrange - var connectors = new AsyncEnumerableStub(_fixture.CreateMany(5)); - A.CallTo(() => _connectorsRepository.GetAllCompanyConnectorsForCompanyId(_identity.CompanyId)) - .Returns(connectors.AsQueryable()); + var data = _fixture.CreateMany(numberOfElements).ToImmutableArray(); + + A.CallTo(() => _connectorsRepository.GetAllCompanyConnectorsForCompanyId(A._)) + .Returns((int skip, int take) => Task.FromResult((Pagination.Source?)new Pagination.Source(data.Length, data.Skip(skip).Take(take)))); // Act - var result = await _logic.GetAllCompanyConnectorDatas(0, 10).ConfigureAwait(false); + var result = await _logic.GetAllCompanyConnectorDatas(page, size); // Assert - result.Content.Should().HaveCount(connectors.Count()); - result.Meta.NumberOfElements.Should().Be(connectors.Count()); + A.CallTo(() => _connectorsRepository.GetAllCompanyConnectorsForCompanyId(_identity.CompanyId)).MustHaveHappenedOnceExactly(); + result.Should().NotBeNull(); + result.Meta.NumberOfElements.Should().Be(numberOfElements); + result.Meta.NumberOfPages.Should().Be(numberOfPages); + result.Meta.Page.Should().Be(resultPage); + result.Meta.PageSize.Should().Be(resultPageSize); + result.Content.Should().HaveCount(resultPageSize); } #endregion diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/ConnectorRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/ConnectorRepositoryTests.cs index ccc73f4a6e..70955aa75e 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/ConnectorRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/ConnectorRepositoryTests.cs @@ -56,13 +56,16 @@ public async Task GetAllCompanyConnectorsForCompanyId_ReturnsExpectedAppCount() var (sut, _) = await CreateSut().ConfigureAwait(false); // Act - var result = await sut.GetAllCompanyConnectorsForCompanyId(_userCompanyId).ToListAsync().ConfigureAwait(false); + var result = await sut.GetAllCompanyConnectorsForCompanyId(_userCompanyId).Invoke(0, 10).ConfigureAwait(false); // Assert result.Should().NotBeNull(); - result.Should().HaveCount(2).And.Satisfy( - x => x.Name == "Test Connector 6", - x => x.Name == "Test Connector 1"); + result!.Data.Should().HaveCount(2).And.Satisfy( + x => x.Name == "Test Connector 6" + && x.TechnicalUser!.Id == new Guid("cd436931-8399-4c1d-bd81-7dffb298c7ca") + && x.TechnicalUser.Name == "test-user-service-accounts", + x => x.Name == "Test Connector 1" + && x.TechnicalUser == null); } #endregion @@ -157,6 +160,8 @@ public async Task GetConnectorByIdForIamUser_ReturnsExpectedAppCount() // Assert result.Should().NotBeNull(); result.IsProviderCompany.Should().BeTrue(); + result.ConnectorData.Name.Should().Be("Test Connector 1"); + result.ConnectorData.TechnicalUser.Should().BeNull(); } [Fact] @@ -358,7 +363,13 @@ public async Task GetManagedConnectorsForIamUser_ReturnsExpectedAppCount() // Assert result.Should().NotBeNull(); result!.Count.Should().Be(1); - result.Data.Should().ContainSingle().Which.Name.Should().Be("Test Connector 3"); + result.Data.Should().ContainSingle().And.Satisfy( + x => x.Name == "Test Connector 3" && + x.Type == ConnectorTypeId.CONNECTOR_AS_A_SERVICE && + x.Status == ConnectorStatusId.PENDING && + x.TechnicalUser!.Id == new Guid("d0c8ae19-d4f3-49cc-9cb4-6c766d4680f4") && + x.TechnicalUser.Name == "sa-test" && + x.TechnicalUser.Description == "SA with connector"); } [Fact] diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_service_accounts.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_service_accounts.test.json index 4c290a785d..c7ce894670 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_service_accounts.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_service_accounts.test.json @@ -40,6 +40,16 @@ "offer_subscription_id": "0b2ca541-206d-48ad-bc02-fb61fbcb5562", "company_id": "41fd2ab8-71cd-4546-9bef-a388d91b2543", "client_client_id": "sa-x-2" + }, + + { + "id": "cd436931-8399-4c1d-bd81-7dffb298c7ca", + "name": "test-user-service-accounts", + "description": "test-user-service-account-descs", + "company_service_account_type_id": 1, + "offer_subscription_id": null, + "company_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f8", + "client_client_id": "sa-x-3" } ] diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/connectors.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/connectors.test.json index ad2bafac39..2adf0dc12a 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/connectors.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/connectors.test.json @@ -19,7 +19,8 @@ "provider_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87", "host_id": "2dc4249f-b5ca-4d42-bef1-7a7a950a4f87", "location_id": "DE", - "self_description_document_id": null + "self_description_document_id": null, + "company_service_account_id": "cd436931-8399-4c1d-bd81-7dffb298c7ca" }, { "id": "727365d6-5599-4598-a888-58733fa138e7",