diff --git a/tests/Dfe.SignIn.InternalApi.IntegrationTests/Endpoints/Users/GetUserProfileTests.cs b/tests/Dfe.SignIn.InternalApi.IntegrationTests/Endpoints/Users/GetUserProfileTests.cs new file mode 100644 index 00000000..b75f3fb3 --- /dev/null +++ b/tests/Dfe.SignIn.InternalApi.IntegrationTests/Endpoints/Users/GetUserProfileTests.cs @@ -0,0 +1,162 @@ +using System.Net; +using System.Net.Http.Json; +using Dfe.SignIn.Core.Contracts.Users; +using Dfe.SignIn.Core.Entities.Directories; +using Dfe.SignIn.Gateways.EntityFramework; +using Dfe.SignIn.InternalApi.Contracts; +using Dfe.SignIn.TestHelpers.Integration.Data; +using Dfe.SignIn.TestHelpers.Integration.Extensions; +using Assert = Xunit.Assert; + +namespace Dfe.SignIn.InternalApi.IntegrationTests.Endpoints.Users; + +[Trait("Category", "Integration")] +public class GetUserProfileTests : InternalApiIntegrationEndpointTestBase +{ + private const string endpoint = "interaction/Users.GetUserProfile"; + + public GetUserProfileTests(InternalApiWebApplicationFactory factory) + : base(factory) + { + } + + [Fact] + public async Task GetUserProfile_ReturnsSuccess_WhenUserExists() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var user = EntityFaker.User + .RuleFor(x => x.IsEntra, (_, _) => true) + .RuleFor(x => x.IsInternalUser, (_, _) => false) + .RuleFor(x => x.FirstName, (_, _) => "Jane") + .RuleFor(x => x.LastName, (_, _) => "Smith") + .RuleFor(x => x.JobTitle, (_, _) => "Software Developer") + .RuleFor(x => x.Email, (_, _) => "jane.smith@example.com") + .RuleFor(x => x.Status, (_, _) => (short)1) + .Generate(); + + await this.InsertEntityAsync(user); + + var request = new GetUserProfileRequest { + UserId = user.Sub + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var body = await response.Content.ReadFromJsonAsync>(); + Assert.NotNull(body); + Assert.NotNull(body.Data); + Assert.Equal(user.IsEntra, body.Data.IsEntra); + Assert.Equal(user.IsInternalUser, body.Data.IsInternalUser); + Assert.Equal(user.FirstName, body.Data.FirstName); + Assert.Equal(user.LastName, body.Data.LastName); + Assert.Equal(user.JobTitle, body.Data.JobTitle); + Assert.Equal(user.Email, body.Data.EmailAddress); + Assert.Equal(user.Status, body.Data.Status); + } + + [Fact] + public async Task GetUserProfile_Returns404_WhenUserDoesNotExist() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var request = new GetUserProfileRequest { + UserId = Guid.NewGuid() + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + [Fact] + public async Task GetUserProfile_Returns401_WhenUnauthenticated() + { + var anonymousClient = this.CreateClient(); + + var request = new GetUserProfileRequest { + UserId = Guid.NewGuid() + }; + + var response = await anonymousClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + [Fact] + public async Task GetUserProfile_Returns404_WhenUserIdIsEmpty() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var request = new GetUserProfileRequest { + UserId = Guid.Empty + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData(" ")] + public async Task GetUserProfile_NormalisesWhitespaceOrNullJobTitle(string? dbJobTitle) + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var user = EntityFaker.User + .RuleFor(x => x.JobTitle, (_, _) => dbJobTitle) + .Generate(); + + await this.InsertEntityAsync(user); + + var request = new GetUserProfileRequest { + UserId = user.Sub + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var body = await response.Content.ReadFromJsonAsync>(); + Assert.NotNull(body); + Assert.NotNull(body.Data); + Assert.Null(body.Data.JobTitle); + } + + [Theory] + [InlineData(true, true, 0)] + [InlineData(false, false, 1)] + [InlineData(false, true, 1)] + [InlineData(true, false, 0)] + public async Task GetUserProfile_MapsUserFlagAndStatusPermutations(bool isEntra, bool isInternalUser, short status) + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var user = EntityFaker.User + .RuleFor(x => x.IsEntra, (_, _) => isEntra) + .RuleFor(x => x.IsInternalUser, (_, _) => isInternalUser) + .RuleFor(x => x.Status, (_, _) => status) + .Generate(); + + await this.InsertEntityAsync(user); + + var request = new GetUserProfileRequest { + UserId = user.Sub + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var body = await response.Content.ReadFromJsonAsync>(); + Assert.NotNull(body); + Assert.NotNull(body.Data); + Assert.Equal(isEntra, body.Data.IsEntra); + Assert.Equal(isInternalUser, body.Data.IsInternalUser); + Assert.Equal(status, body.Data.Status); + } +} diff --git a/tests/Dfe.SignIn.InternalApi.IntegrationTests/Endpoints/Users/GetUserStatusTests.cs b/tests/Dfe.SignIn.InternalApi.IntegrationTests/Endpoints/Users/GetUserStatusTests.cs new file mode 100644 index 00000000..be438090 --- /dev/null +++ b/tests/Dfe.SignIn.InternalApi.IntegrationTests/Endpoints/Users/GetUserStatusTests.cs @@ -0,0 +1,183 @@ +using System.Net; +using System.Net.Http.Json; +using Dfe.SignIn.Core.Contracts.Users; +using Dfe.SignIn.Core.Entities.Directories; +using Dfe.SignIn.Gateways.EntityFramework; +using Dfe.SignIn.InternalApi.Contracts; +using Dfe.SignIn.TestHelpers.Integration.Data; +using Dfe.SignIn.TestHelpers.Integration.Extensions; +using Assert = Xunit.Assert; + +namespace Dfe.SignIn.InternalApi.IntegrationTests.Endpoints.Users; + +[Trait("Category", "Integration")] +public class GetUserStatusTests : InternalApiIntegrationEndpointTestBase +{ + private const string endpoint = "interaction/Users.GetUserStatus"; + + public GetUserStatusTests(InternalApiWebApplicationFactory factory) + : base(factory) + { + } + + [Theory] + [InlineData(0, AccountStatus.Inactive)] + [InlineData(1, AccountStatus.Active)] + public async Task GetUserStatus_ReturnsSuccess_WithUserExistsTrue_WhenUserExistsByEmail(short dbStatus, AccountStatus expectedStatus) + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var user = EntityFaker.User + .RuleFor(x => x.Email, (_, _) => "test.user@example.com") + .RuleFor(x => x.Status, (_, _) => dbStatus) + .Generate(); + + await this.InsertEntityAsync(user); + + var request = new GetUserStatusRequest { + EmailAddress = "test.user@example.com" + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var body = await response.Content.ReadFromJsonAsync>(); + Assert.NotNull(body); + Assert.NotNull(body.Data); + Assert.True(body.Data.UserExists); + Assert.Equal(user.Sub, body.Data.UserId); + Assert.Equal(expectedStatus, body.Data.AccountStatus); + } + + [Theory] + [InlineData(0, AccountStatus.Inactive)] + [InlineData(1, AccountStatus.Active)] + public async Task GetUserStatus_ReturnsSuccess_WithUserExistsTrue_WhenUserExistsByEntraOid(short dbStatus, AccountStatus expectedStatus) + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var entraOid = Guid.NewGuid(); + var user = EntityFaker.User + .RuleFor(x => x.EntraOid, (_, _) => entraOid) + .RuleFor(x => x.Status, (_, _) => dbStatus) + .Generate(); + + await this.InsertEntityAsync(user); + + var request = new GetUserStatusRequest { + EntraUserId = entraOid + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var body = await response.Content.ReadFromJsonAsync>(); + Assert.NotNull(body); + Assert.NotNull(body.Data); + Assert.True(body.Data.UserExists); + Assert.Equal(user.Sub, body.Data.UserId); + Assert.Equal(expectedStatus, body.Data.AccountStatus); + } + + [Fact] + public async Task GetUserStatus_ReturnsSuccess_WithUserExistsFalse_WhenUserDoesNotExistByEmail() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var request = new GetUserStatusRequest { + EmailAddress = "nonexistent@example.com" + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var body = await response.Content.ReadFromJsonAsync>(); + Assert.NotNull(body); + Assert.NotNull(body.Data); + Assert.False(body.Data.UserExists); + Assert.Null(body.Data.UserId); + Assert.Null(body.Data.AccountStatus); + } + + [Fact] + public async Task GetUserStatus_ReturnsSuccess_WithUserExistsFalse_WhenUserDoesNotExistByEntraOid() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var request = new GetUserStatusRequest { + EntraUserId = Guid.NewGuid() + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var body = await response.Content.ReadFromJsonAsync>(); + Assert.NotNull(body); + Assert.NotNull(body.Data); + Assert.False(body.Data.UserExists); + Assert.Null(body.Data.UserId); + Assert.Null(body.Data.AccountStatus); + } + + [Fact] + public async Task GetUserStatus_Returns401_WhenUnauthenticated() + { + var anonymousClient = this.CreateClient(); + + var request = new GetUserStatusRequest { + EmailAddress = "test@example.com" + }; + + var response = await anonymousClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + [Fact] + public async Task GetUserStatus_Returns400_WhenBothEmailAndEntraUserIdProvided() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var request = new GetUserStatusRequest { + EmailAddress = "test@example.com", + EntraUserId = Guid.NewGuid() + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } + + [Fact] + public async Task GetUserStatus_Returns400_WhenNeitherEmailNorEntraUserIdProvided() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var request = new GetUserStatusRequest { + EmailAddress = null, + EntraUserId = null + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } + + [Fact] + public async Task GetUserStatus_Returns400_WhenEmailIsInvalid() + { + var authenticatedClient = this.CreateClient().WithAuthentication(); + + var request = new GetUserStatusRequest { + EmailAddress = "invalid-email-format" + }; + + var response = await authenticatedClient.PostAsJsonAsync(endpoint, request); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } +}