Skip to content
Original file line number Diff line number Diff line change
@@ -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<DbDirectoriesContext, UserEntity>(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<InteractionResponse<GetUserProfileResponse>>();
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<DbDirectoriesContext, UserEntity>(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<InteractionResponse<GetUserProfileResponse>>();
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<DbDirectoriesContext, UserEntity>(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<InteractionResponse<GetUserProfileResponse>>();
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);
}
}
Original file line number Diff line number Diff line change
@@ -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<DbDirectoriesContext, UserEntity>(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<InteractionResponse<GetUserStatusResponse>>();
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<DbDirectoriesContext, UserEntity>(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<InteractionResponse<GetUserStatusResponse>>();
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<InteractionResponse<GetUserStatusResponse>>();
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<InteractionResponse<GetUserStatusResponse>>();
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);
}
}
Loading