From e0cca894589354dcbd7388a5e9c602c922d3000a Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Thu, 20 Jul 2023 10:43:33 +0200 Subject: [PATCH 1/3] fix(invitedUsers): filter deleted users for invitedUsers endpoint Refs: CPLP-2986 --- .../Repositories/InvitationRepository.cs | 24 ++++++---- .../InMemoryDbContextFactory.cs | 36 --------------- .../InvitationRepositoryTests.cs | 44 ++++++++++++++++++- .../Seeder/Data/company_users.test.json | 18 ++++++++ .../Seeder/Data/identities.test.json | 16 +++++++ .../Seeder/Data/invitations.test.json | 16 ++++++- 6 files changed, 106 insertions(+), 48 deletions(-) delete mode 100644 tests/portalbackend/PortalBackend.DBAccess.Tests/InMemoryDbContextFactory.cs diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs index 547f5a39be..82625d957d 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs @@ -22,6 +22,7 @@ using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities; using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories; @@ -35,15 +36,20 @@ public InvitationRepository(PortalDbContext dbContext) } public IAsyncEnumerable GetInvitedUserDetailsUntrackedAsync(Guid applicationId) => - (from invitation in _dbContext.Invitations - join invitationStatus in _dbContext.InvitationStatuses on invitation.InvitationStatusId equals invitationStatus.Id - join companyuser in _dbContext.CompanyUsers on invitation.CompanyUserId equals companyuser.Id - where invitation.CompanyApplicationId == applicationId - select new InvitedUserDetail( - companyuser.Identity!.UserEntityId, - invitationStatus.Id, - companyuser.Email - )) + _dbContext.Invitations + .Join(_dbContext.InvitationStatuses, + i => i.InvitationStatusId, + invitationStatus => invitationStatus.Id, + (i, invitationStatus) => new { Invitation = i, InvitationStatus = invitationStatus }) + .Join(_dbContext.CompanyUsers, + i => i.Invitation.CompanyUserId, + cu => cu.Id, + (i, cu) => new { i.Invitation, i.InvitationStatus, CompanyUser = cu }) + .Where(i => i.Invitation.CompanyApplicationId == applicationId && i.CompanyUser.Identity!.UserStatusId != UserStatusId.DELETED) + .Select(i => new InvitedUserDetail( + i.CompanyUser.Identity!.UserEntityId, + i.InvitationStatus.Id, + i.CompanyUser.Email)) .AsNoTracking() .AsAsyncEnumerable(); diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/InMemoryDbContextFactory.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/InMemoryDbContextFactory.cs deleted file mode 100644 index 497c54f7f7..0000000000 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/InMemoryDbContextFactory.cs +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2021, 2023 BMW Group AG - * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ - -using Microsoft.EntityFrameworkCore; -using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities; - -namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Tests -{ - public static class InMemoryDbContextFactory - { - public static PortalDbContext GetPortalDbContext() - { - var options = new DbContextOptionsBuilder() - .UseInMemoryDatabase(databaseName: "InMemoryPortalDatabase").Options; - var dbContext = new PortalDbContext(options); - return dbContext; - } - } -} diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs index fc9c5f8749..1fa9c371b0 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs @@ -1,7 +1,47 @@ +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Tests.Setup; +using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums; +using Xunit.Extensions.AssemblyFixture; + namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Tests; -public class InvitationRepositoryTests +public class InvitationRepositoryTests : IAssemblyFixture { + private readonly TestDbFixture _dbTestDbFixture; + private readonly Guid _applicationId = new("6b2d1263-c073-4a48-bfaf-704dc154ca9e"); + + public InvitationRepositoryTests(TestDbFixture testDbFixture) + { + var fixture = new Fixture().Customize(new AutoFakeItEasyCustomization { ConfigureMembers = true }); + fixture.Behaviors.OfType().ToList() + .ForEach(b => fixture.Behaviors.Remove(b)); + + fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + _dbTestDbFixture = testDbFixture; + } + + [Fact] + public async Task GetInvitedUserDetailsUntrackedAsync_WithValid_ReturnsExpected() + { + var sut = await CreateSut().ConfigureAwait(false); + + var result = await sut.GetInvitedUserDetailsUntrackedAsync(_applicationId).ToListAsync().ConfigureAwait(false); + + result.Should().NotBeNull(); + result.Should().HaveCount(2); + result.Should().Satisfy( + x => x.EmailId == "test@user.com" && x.InvitationStatus == InvitationStatusId.CREATED, + x => x.EmailId == "company.admin1@acme.corp" && x.InvitationStatus == InvitationStatusId.CREATED); + } + + #region Setup + + private async Task CreateSut() + { + var context = await _dbTestDbFixture.GetPortalDbContext().ConfigureAwait(false); + var sut = new InvitationRepository(context); + return sut; + } - // TODO (PS): GetInvitedUserDetailsUntrackedAsync + #endregion } diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_users.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_users.test.json index 397cb5899b..b2802a1af8 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_users.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/company_users.test.json @@ -70,5 +70,23 @@ "lastlogin": null, "lastname": "Provider", "last_editor_id": null + }, + { + "id": "d0c8ae19-d4f3-49cc-9cb4-6c766d4680f5", + "date_last_changed": "2022-10-01 18:01:33.570000 +00:00", + "email": "test@user.com", + "firstname": "Test", + "lastlogin": null, + "lastname": "User", + "last_editor_id": null + }, + { + "id": "1dceacb8-c5a5-4573-a77d-e2487ac4a8aa", + "date_last_changed": "2022-10-01 18:01:33.570000 +00:00", + "email": "test@user.com", + "firstname": "Deleted", + "lastlogin": null, + "lastname": "User", + "last_editor_id": null } ] diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identities.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identities.test.json index da9cd1c656..c491aa8f2b 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identities.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/identities.test.json @@ -102,5 +102,21 @@ "user_status_id": 1, "user_entity_id": null, "identity_type_id": 2 + }, + { + "id": "d0c8ae19-d4f3-49cc-9cb4-6c766d4680f5", + "date_created": "2022-06-01 18:01:33.439000 +00:00", + "company_id": "41fd2ab8-71cd-4546-9bef-a388d91b2542", + "user_status_id": 1, + "user_entity_id": null, + "identity_type_id": 1 + }, + { + "id": "1dceacb8-c5a5-4573-a77d-e2487ac4a8aa", + "date_created": "2022-06-01 18:01:33.439000 +00:00", + "company_id": "41fd2ab8-71cd-4546-9bef-a388d91b2542", + "user_status_id": 3, + "user_entity_id": null, + "identity_type_id": 1 } ] diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json index 9f8131d0fc..c0e1e7fd58 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/Seeder/Data/invitations.test.json @@ -12,5 +12,19 @@ "invitation_status_id": 1, "company_application_id": "6b2d1263-c073-4a48-bfaf-704dc154ca9e", "company_user_id": "ac1cf001-7fbc-1f2f-817f-bce058019994" + }, + { + "id": "d54db875-774c-479f-9f14-375f2cb8b263", + "date_created": "2022-03-24 18:01:33.439000 +00:00", + "invitation_status_id": 1, + "company_application_id": "6b2d1263-c073-4a48-bfaf-704dc154ca9e", + "company_user_id": "d0c8ae19-d4f3-49cc-9cb4-6c766d4680f5" + }, + { + "id": "d54db875-774c-479f-9f14-375f2cb8b264", + "date_created": "2022-03-24 18:01:33.439000 +00:00", + "invitation_status_id": 1, + "company_application_id": "6b2d1263-c073-4a48-bfaf-704dc154ca9e", + "company_user_id": "1dceacb8-c5a5-4573-a77d-e2487ac4a8aa" } -] \ No newline at end of file +] From 6af5f97f9c9321b4f3854f7992618bd5e0dbae10 Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Sat, 29 Jul 2023 17:20:09 +0200 Subject: [PATCH 2/3] chore: adjust database query Refs: CPLP-2986 --- .../Repositories/InvitationRepository.cs | 25 +++++++------------ .../InvitationRepositoryTests.cs | 9 +++---- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs index 82625d957d..67aad6204d 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs @@ -34,24 +34,17 @@ public InvitationRepository(PortalDbContext dbContext) { _dbContext = dbContext; } - public IAsyncEnumerable GetInvitedUserDetailsUntrackedAsync(Guid applicationId) => _dbContext.Invitations - .Join(_dbContext.InvitationStatuses, - i => i.InvitationStatusId, - invitationStatus => invitationStatus.Id, - (i, invitationStatus) => new { Invitation = i, InvitationStatus = invitationStatus }) - .Join(_dbContext.CompanyUsers, - i => i.Invitation.CompanyUserId, - cu => cu.Id, - (i, cu) => new { i.Invitation, i.InvitationStatus, CompanyUser = cu }) - .Where(i => i.Invitation.CompanyApplicationId == applicationId && i.CompanyUser.Identity!.UserStatusId != UserStatusId.DELETED) - .Select(i => new InvitedUserDetail( - i.CompanyUser.Identity!.UserEntityId, - i.InvitationStatus.Id, - i.CompanyUser.Email)) - .AsNoTracking() - .AsAsyncEnumerable(); + .AsNoTracking() + .Where(invitation => + invitation.CompanyApplicationId == applicationId && + invitation.CompanyUser!.Identity!.UserStatusId != UserStatusId.DELETED) + .Select(invitation => new InvitedUserDetail( + invitation.CompanyUser!.Identity!.UserEntityId, + invitation.InvitationStatusId, + invitation.CompanyUser.Email)) + .AsAsyncEnumerable(); public Task GetInvitationStatusAsync(Guid companyUserId) => _dbContext.Invitations diff --git a/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs b/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs index 1fa9c371b0..a060ad8650 100644 --- a/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs +++ b/tests/portalbackend/PortalBackend.DBAccess.Tests/InvitationRepositoryTests.cs @@ -27,11 +27,10 @@ public async Task GetInvitedUserDetailsUntrackedAsync_WithValid_ReturnsExpected( var result = await sut.GetInvitedUserDetailsUntrackedAsync(_applicationId).ToListAsync().ConfigureAwait(false); - result.Should().NotBeNull(); - result.Should().HaveCount(2); - result.Should().Satisfy( - x => x.EmailId == "test@user.com" && x.InvitationStatus == InvitationStatusId.CREATED, - x => x.EmailId == "company.admin1@acme.corp" && x.InvitationStatus == InvitationStatusId.CREATED); + result.Should().HaveCount(2) + .And.Satisfy( + x => x.EmailId == "test@user.com" && x.InvitationStatus == InvitationStatusId.CREATED, + x => x.EmailId == "company.admin1@acme.corp" && x.InvitationStatus == InvitationStatusId.CREATED); } #region Setup From b26e11c10e5a8b1210b1ab47ac89a656cdfa8bfb Mon Sep 17 00:00:00 2001 From: Phil Schneider Date: Sun, 30 Jul 2023 00:35:42 +0200 Subject: [PATCH 3/3] chore: fix formatting issue Refs: CPLP-2986 --- .../Repositories/InvitationRepository.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs index 67aad6204d..1a435a024c 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/InvitationRepository.cs @@ -37,8 +37,8 @@ public InvitationRepository(PortalDbContext dbContext) public IAsyncEnumerable GetInvitedUserDetailsUntrackedAsync(Guid applicationId) => _dbContext.Invitations .AsNoTracking() - .Where(invitation => - invitation.CompanyApplicationId == applicationId && + .Where(invitation => + invitation.CompanyApplicationId == applicationId && invitation.CompanyUser!.Identity!.UserStatusId != UserStatusId.DELETED) .Select(invitation => new InvitedUserDetail( invitation.CompanyUser!.Identity!.UserEntityId,