From 7ed77176e2c36fbcb5841f765841155f2208629e Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Thu, 29 Jan 2026 17:09:21 +0000 Subject: [PATCH] Refactor organization user acceptance tests to utilize feature flags - Converted existing tests to use [Theory] with [InlineData] for feature flag variations. - Updated assertions to reflect expected status codes based on feature flag state. - Enhanced user confirmation checks to ensure proper linking and email verification after acceptance. - Improved test coverage for organization initialization scenarios with and without collections. --- ...anizationUsersControllerAcceptInitTests.cs | 259 +++++++++++++----- 1 file changed, 196 insertions(+), 63 deletions(-) diff --git a/test/Api.IntegrationTest/AdminConsole/Controllers/OrganizationUsersControllerAcceptInitTests.cs b/test/Api.IntegrationTest/AdminConsole/Controllers/OrganizationUsersControllerAcceptInitTests.cs index d106fd03b0..cdff298c71 100644 --- a/test/Api.IntegrationTest/AdminConsole/Controllers/OrganizationUsersControllerAcceptInitTests.cs +++ b/test/Api.IntegrationTest/AdminConsole/Controllers/OrganizationUsersControllerAcceptInitTests.cs @@ -94,11 +94,13 @@ public class OrganizationUsersControllerAcceptInitTests : IClassFixture(); @@ -134,13 +137,20 @@ public class OrganizationUsersControllerAcceptInitTests : IClassFixture(); var confirmedOrgUser = await organizationUserRepository.GetByIdAsync(_invitedOrgUser.Id); Assert.NotNull(confirmedOrgUser); Assert.Equal(OrganizationUserStatusType.Confirmed, confirmedOrgUser.Status); Assert.Equal("test-user-key", confirmedOrgUser.Key); + Assert.Equal(_invitedUser.Id, confirmedOrgUser.UserId); + Assert.Null(confirmedOrgUser.Email); // Email should be cleared after acceptance + + // Verify user's email was verified + var userRepository = _factory.GetService(); + var user = await userRepository.GetByEmailAsync(_invitedUserEmail); + Assert.True(user.EmailVerified); // Verify default collection was created var collectionRepository = _factory.GetService(); @@ -159,11 +169,13 @@ public class OrganizationUsersControllerAcceptInitTests : IClassFixture(); @@ -211,11 +224,13 @@ public class OrganizationUsersControllerAcceptInitTests : IClassFixture(); @@ -286,11 +303,13 @@ public class OrganizationUsersControllerAcceptInitTests : IClassFixture(); + _pendingOrganization.Enabled = false; + _pendingOrganization.Status = OrganizationStatusType.Created; + await organizationRepository.ReplaceAsync(_pendingOrganization); await _loginHelper.LoginAsync(_invitedUserEmail); @@ -352,47 +379,29 @@ public class OrganizationUsersControllerAcceptInitTests : IClassFixture(); - var updatedOrganization = await organizationRepository.GetByIdAsync(_pendingOrganization.Id); - - Assert.NotNull(updatedOrganization); - Assert.True(updatedOrganization.Enabled); - Assert.Equal(OrganizationStatusType.Created, updatedOrganization.Status); - Assert.Equal(_mockPublicKey, updatedOrganization.PublicKey); - Assert.Equal(_mockEncryptedPrivateKey, updatedOrganization.PrivateKey); - - // Verify user was confirmed (not just accepted) - var organizationUserRepository = _factory.GetService(); - var confirmedOrgUser = await organizationUserRepository.GetByIdAsync(_invitedOrgUser.Id); - - Assert.NotNull(confirmedOrgUser); - Assert.Equal(OrganizationUserStatusType.Confirmed, confirmedOrgUser.Status); - Assert.Equal("test-user-key", confirmedOrgUser.Key); - Assert.Equal(_invitedUser.Id, confirmedOrgUser.UserId); - Assert.Null(confirmedOrgUser.Email); - - // Verify default collection was created - var collectionRepository = _factory.GetService(); - var collections = await collectionRepository.GetManyByOrganizationIdAsync(_pendingOrganization.Id); - - Assert.Single(collections); - Assert.Equal(_mockEncryptedString, collections.First().Name); + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } - [Fact] - public async Task AcceptInit_WithFeatureFlagEnabled_InvalidToken_ReturnsBadRequest() + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task AcceptInit_WithExistingPublicKey_ReturnsBadRequest(bool featureFlagEnabled) { // Arrange - _featureService.IsEnabled(FeatureFlagKeys.RefactorOrgAcceptInit).Returns(true); + _featureService.IsEnabled(FeatureFlagKeys.RefactorOrgAcceptInit).Returns(featureFlagEnabled); + + // Update the organization to already have a public key + var organizationRepository = _factory.GetService(); + _pendingOrganization.PublicKey = _mockPublicKey; + await organizationRepository.ReplaceAsync(_pendingOrganization); await _loginHelper.LoginAsync(_invitedUserEmail); + var token = GenerateInviteToken(_invitedOrgUser, _invitedUser.Email); + var acceptInitRequest = new OrganizationUserAcceptInitRequestModel { - Token = "invalid-token", + Token = token, Key = "test-user-key", Keys = new OrganizationKeysRequestModel { @@ -409,20 +418,144 @@ public class OrganizationUsersControllerAcceptInitTests : IClassFixture(); - var organization = await organizationRepository.GetByIdAsync(_pendingOrganization.Id); + _pendingOrganization.PrivateKey = _mockEncryptedPrivateKey; + await organizationRepository.ReplaceAsync(_pendingOrganization); - Assert.False(organization.Enabled); - Assert.Equal(OrganizationStatusType.Pending, organization.Status); - Assert.Null(organization.PublicKey); - Assert.Null(organization.PrivateKey); + await _loginHelper.LoginAsync(_invitedUserEmail); - var organizationUserRepository = _factory.GetService(); - var orgUser = await organizationUserRepository.GetByIdAsync(_invitedOrgUser.Id); + var token = GenerateInviteToken(_invitedOrgUser, _invitedUser.Email); - Assert.Equal(OrganizationUserStatusType.Invited, orgUser.Status); - Assert.Null(orgUser.UserId); + var acceptInitRequest = new OrganizationUserAcceptInitRequestModel + { + Token = token, + Key = "test-user-key", + Keys = new OrganizationKeysRequestModel + { + PublicKey = _mockPublicKey, + EncryptedPrivateKey = _mockEncryptedPrivateKey + }, + CollectionName = _mockEncryptedString + }; + + // Act + var response = await _client.PostAsJsonAsync( + $"organizations/{_pendingOrganization.Id}/users/{_invitedOrgUser.Id}/accept-init", + acceptInitRequest); + + // Assert + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task AcceptInit_WithInvalidOrganizationUserId_ReturnsBadRequestOrNotFound(bool featureFlagEnabled) + { + // Arrange + _featureService.IsEnabled(FeatureFlagKeys.RefactorOrgAcceptInit).Returns(featureFlagEnabled); + + await _loginHelper.LoginAsync(_invitedUserEmail); + + var token = GenerateInviteToken(_invitedOrgUser, _invitedUser.Email); + + var acceptInitRequest = new OrganizationUserAcceptInitRequestModel + { + Token = token, + Key = "test-user-key", + Keys = new OrganizationKeysRequestModel + { + PublicKey = _mockPublicKey, + EncryptedPrivateKey = _mockEncryptedPrivateKey + }, + CollectionName = _mockEncryptedString + }; + + // Act - use a non-existent organization user ID + var response = await _client.PostAsJsonAsync( + $"organizations/{_pendingOrganization.Id}/users/{Guid.NewGuid()}/accept-init", + acceptInitRequest); + + // Assert + // Both implementations should reject invalid org user IDs + // Old returns BadRequest, new returns NotFound (more RESTful) + Assert.True(response.StatusCode == HttpStatusCode.NotFound || response.StatusCode == HttpStatusCode.BadRequest); + } + + [Fact] + public async Task AcceptInit_WithFeatureFlagEnabled_WithWrongOrganizationId_ReturnsNotFound() + { + // Arrange: New implementation validates org exists before checking mismatch + _featureService.IsEnabled(FeatureFlagKeys.RefactorOrgAcceptInit).Returns(true); + + await _loginHelper.LoginAsync(_invitedUserEmail); + + var token = GenerateInviteToken(_invitedOrgUser, _invitedUser.Email); + + var acceptInitRequest = new OrganizationUserAcceptInitRequestModel + { + Token = token, + Key = "test-user-key", + Keys = new OrganizationKeysRequestModel + { + PublicKey = _mockPublicKey, + EncryptedPrivateKey = _mockEncryptedPrivateKey + }, + CollectionName = _mockEncryptedString + }; + + // Act - use a non-existent organization ID + var response = await _client.PostAsJsonAsync( + $"organizations/{Guid.NewGuid()}/users/{_invitedOrgUser.Id}/accept-init", + acceptInitRequest); + + // Assert - Non-existent organization returns NotFound + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + [Fact] + public async Task AcceptInit_WithFeatureFlagEnabled_WithMismatchedEmail_ReturnsBadRequest() + { + // Arrange + _featureService.IsEnabled(FeatureFlagKeys.RefactorOrgAcceptInit).Returns(true); + + // Create a different user and log in as them + var differentEmail = $"{Guid.NewGuid()}@example.com"; + await _factory.LoginWithNewAccount(differentEmail); + await _loginHelper.LoginAsync(differentEmail); + + // But use a token for the originally invited user + var token = GenerateInviteToken(_invitedOrgUser, _invitedUser.Email); + + var acceptInitRequest = new OrganizationUserAcceptInitRequestModel + { + Token = token, + Key = "test-user-key", + Keys = new OrganizationKeysRequestModel + { + PublicKey = _mockPublicKey, + EncryptedPrivateKey = _mockEncryptedPrivateKey + }, + CollectionName = _mockEncryptedString + }; + + // Act + var response = await _client.PostAsJsonAsync( + $"organizations/{_pendingOrganization.Id}/users/{_invitedOrgUser.Id}/accept-init", + acceptInitRequest); + + // Assert - Email mismatch should fail + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } }