Skip to content

Commit

Permalink
Fixed existing tests by implementing support for fusion profile
Browse files Browse the repository at this point in the history
  • Loading branch information
kjetilhau committed Dec 4, 2024
1 parent e9c7a08 commit 856188e
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ namespace Equinor.ProjectExecutionPortal.WebApi.ViewModels.Portal;

public class ApiPortalAdmin
{
#pragma warning disable CS8618 // For integration tests only
public ApiPortalAdmin() { }
#pragma warning restore CS8618 // For integration tests only

public ApiPortalAdmin(PortalAdminDto adminDto)
{
Id = adminDto.Id;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using Fusion.Integration.Profile;

namespace Equinor.ProjectExecutionPortal.Tests.WebApi.Data;

internal static class FusionProfileApiData
{
public static Guid ValidProfileAzureUniquePersonId = new(UserData.AuthenticatedUserWithPortalAdminId);

public static readonly ResolvedPersonProfile ValidResolvedProfile = new(new FusionPersonProfile(FusionAccountType.External, string.Empty, ValidProfileAzureUniquePersonId, "Name"))
{
Identifier = ValidProfile,
Success = true,
StatusCode = 200,
Profile = new FusionPersonProfile(FusionAccountType.External, string.Empty, ValidProfileAzureUniquePersonId, "Name"),
Message = string.Empty
};

public static PersonIdentifier ValidProfile => new(ValidProfileAzureUniquePersonId);

public static List<ResolvedPersonProfile> ValidFusionProfiles => [ValidResolvedProfile];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Equinor.ProjectExecutionPortal.Tests.WebApi.Data;
internal static class UserData
{
public const string AuthenticatedUserId = "11111111-0000-0000-0000-222222222222";
public const string AuthenticatedUserWithPortalAdminId = "22222222-0000-0000-0000-333333333333";
public const string AdministratorUserId = "66666666-0000-0000-0000-999999999999";

public static TestUser Anonymous => new()
Expand All @@ -24,6 +25,16 @@ internal static class UserData
},
};

public static TestUser AuthenticatedPortalAdmin => new()
{
Profile =
new TokenProfile
{
FirstName = "Portalis",
LastName = "Administraterson",
Oid = AuthenticatedUserWithPortalAdminId
}
};
public static TestUser Administrator => new()
{
Profile =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public async Task Create_Portal_AsAdministratorUser_ShouldReturnOk()
Subtext = "Created subtext",
Icon = "Created icon",
ContextTypes = [ContextTypeData.ValidContextTypes.ProjectMasterContextTypeKey],
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserId) }]
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserWithPortalAdminId) }]
};

// Act
Expand Down Expand Up @@ -113,7 +113,7 @@ public async Task Create_Portal_AsAuthenticatedUser_ShouldReturnForbidden()
Subtext = "Created subtext",
Icon = "Created icon",
ContextTypes = [ContextTypeData.ValidContextTypes.ProjectMasterContextTypeKey],
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserId) }]
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserWithPortalAdminId) }]
};

// Act
Expand All @@ -135,7 +135,7 @@ public async Task Create_Portal_AsAnonymousUser_ShouldReturnUnauthorized()
Subtext = "Created subtext",
Icon = "Created icon",
ContextTypes = [ContextTypeData.ValidContextTypes.ProjectMasterContextTypeKey],
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserId) }]
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserWithPortalAdminId) }]
};

// Act
Expand All @@ -160,7 +160,7 @@ public async Task Update_Portal_AsAdministratorUser_ShouldReturnOk()
Subtext = "Updated subtext",
Icon = "Updated icon",
ContextTypes = [ContextTypeData.ValidContextTypes.ProjectMasterContextTypeKey],
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserId) }]
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserWithPortalAdminId) }]
};

// Act
Expand Down Expand Up @@ -192,7 +192,7 @@ public async Task Update_Portal_AsAuthenticatedUser_ShouldReturnForbidden()
Subtext = "Updated subtext",
Icon = "Updated icon",
ContextTypes = [ContextTypeData.ValidContextTypes.ProjectMasterContextTypeKey],
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserId) }]
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserWithPortalAdminId) }]
};

// Act
Expand All @@ -214,7 +214,7 @@ public async Task Update_Portal_AsAnonymousUser_ShouldReturnUnauthorized()
Subtext = "Updated subtext",
Icon = "Updated icon",
ContextTypes = [ContextTypeData.ValidContextTypes.ProjectMasterContextTypeKey],
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserId) }]
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserWithPortalAdminId) }]
};

// Act
Expand Down Expand Up @@ -441,7 +441,7 @@ public async Task Delete_Portal_AsAdministrator_ShouldReturnOk()
Subtext = "Created subtext",
Icon = "Created icon",
ContextTypes = [ContextTypeData.ValidContextTypes.ProjectMasterContextTypeKey],
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserId) }]
Admins = [new ApiAccountIdentifier { AzureUniqueId = Guid.Parse(UserData.AuthenticatedUserWithPortalAdminId) }]
};

await CreatePortal(UserType.Administrator, payload);
Expand All @@ -460,7 +460,7 @@ public async Task Delete_Portal_AsAdministrator_ShouldReturnOk()
}

[TestMethod]
public async Task Delete_PortalWithApps_AsAdministrator_ShouldReturnForbidden()
public async Task Delete_PortalWithApps_AsAdministrator_ShouldReturnBadRequest()
{
// Arrange
var portals = await AssertGetAllPortals(UserType.Administrator, HttpStatusCode.OK);
Expand All @@ -476,7 +476,7 @@ public async Task Delete_PortalWithApps_AsAdministrator_ShouldReturnForbidden()
var response = await DeletePortal(portalToDelete.Id, UserType.Administrator);

// Assert
Assert.AreEqual(HttpStatusCode.Forbidden, response.StatusCode);
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);

// Verify the portal is not deleted
var deletedPortal = await AssertGetPortal(portalToDelete.Id, UserType.Administrator, HttpStatusCode.OK);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
using Equinor.ProjectExecutionPortal.Tests.WebApi.Data;
using Equinor.ProjectExecutionPortal.Tests.WebApi.Misc;
using Equinor.ProjectExecutionPortal.Tests.WebApi.Setup;
using Equinor.ProjectExecutionPortal.WebApi.Authorization;
using Fusion.Integration;
using Fusion.Integration.Apps.Abstractions.Abstractions;
using Fusion.Integration.Apps.Abstractions.Models;
using Fusion.Integration.Profile;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
Expand All @@ -20,15 +20,24 @@ namespace Equinor.ProjectExecutionPortal.Tests.WebApi;
public sealed class TestFactory : WebApplicationFactory<Program>
{
private const string IntegrationTestEnvironment = "IntegrationTests";
private readonly string _localDbConnectionString;
private readonly string _configPath;
private readonly List<Action> _teardownList = [];
private readonly List<IDisposable> _disposables = [];
private readonly Mock<IFusionContextResolver> _fusionContextResolverMock = new();
private readonly Mock<IAppsClient> _fusionAppsClientMock = new();
public static Dictionary<UserType, ITestUser> TestUsersDictionary = new();
private static TestFactory? _sInstance;
private static readonly object SPadlock = new();
private readonly string _configPath;
private readonly List<IDisposable> _disposables = [];
private readonly Mock<IAppsClient> _fusionAppsClientMock = new();
private readonly Mock<IFusionContextResolver> _fusionContextResolverMock = new();
private readonly Mock<IFusionProfileResolver> _fusionProfileResolverMock = new();
private readonly string _localDbConnectionString;
private readonly List<Action> _teardownList = [];

private TestFactory()
{
var projectDir = Directory.GetCurrentDirectory();
_localDbConnectionString = GetTestLocalDbConnectionString(projectDir);
_configPath = Path.Combine(projectDir, "appsettings.json");
SetupTestUsers();
}

public static TestFactory Instance
{
Expand All @@ -49,14 +58,6 @@ public static TestFactory Instance
}
}

private TestFactory()
{
var projectDir = Directory.GetCurrentDirectory();
_localDbConnectionString = GetTestLocalDbConnectionString(projectDir);
_configPath = Path.Combine(projectDir, "appsettings.json");
SetupTestUsers();
}

public new void Dispose()
{
// Run teardown
Expand All @@ -72,7 +73,11 @@ private TestFactory()

foreach (var disposable in _disposables)
{
try { disposable.Dispose(); } catch { /* Ignore */ }
try { disposable.Dispose(); }
catch
{
/* Ignore */
}
}

//lock (s_padlock)
Expand All @@ -92,7 +97,10 @@ public HttpClient GetHttpClient(UserType userType)
return testUser.HttpClient;
}

public TokenProfile? GetTestProfile(UserType userType) => TestUsersDictionary[userType].Profile;
public TokenProfile? GetTestProfile(UserType userType)
{
return TestUsersDictionary[userType].Profile;
}

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
Expand All @@ -107,6 +115,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)

services.AddScoped(_ => _fusionContextResolverMock.Object);
services.AddScoped(_ => _fusionAppsClientMock.Object);
services.AddScoped(_ => _fusionProfileResolverMock.Object);
});

builder.ConfigureServices(async services =>
Expand Down Expand Up @@ -161,11 +170,13 @@ private static async Task SeedData(ProjectExecutionPortalContext dbContext, ISer
}

private void EnsureTestDatabaseDeletedAtTeardown(IServiceCollection services)
=> _teardownList.Add(() =>
{
_teardownList.Add(() =>
{
using var dbContext = DatabaseContext(services);
dbContext.Database.EnsureDeleted();
});
}

private ProjectExecutionPortalContext DatabaseContext(IServiceCollection services)
{
Expand Down Expand Up @@ -216,6 +227,18 @@ private void SetupServiceMock()
{
return Task.FromResult(FusionContextApiData.ValidFusionContexts.FirstOrDefault(x => x.Id == contextId))!;
});

_fusionProfileResolverMock.Setup(service => service.ResolvePersonsAsync(It.IsAny<IEnumerable<PersonIdentifier>>(), default))
.Returns((IEnumerable<PersonIdentifier> personIdentifiers, CancellationToken token) =>
{
var matchingProfiles = FusionProfileApiData.ValidFusionProfiles
.Where(resolvedProfile => personIdentifiers
.Select(x => x.AzureUniquePersonId)
.Contains(resolvedProfile.Profile!.AzureUniqueId!.Value))
.AsEnumerable();

return Task.FromResult(matchingProfiles);
});
}

private void SetupTestUsers()
Expand Down Expand Up @@ -245,11 +268,20 @@ private static void CreateAuthenticatedHttpClients(WebApplicationFactory<Program
}
}

private static void SetupAuthenticatedUser() => TestUsersDictionary.Add(UserType.Authenticated, UserData.Authenticated);
private static void SetupAuthenticatedUser()
{
TestUsersDictionary.Add(UserType.Authenticated, UserData.Authenticated);
}

private static void SetupAdministratorUser() => TestUsersDictionary.Add(UserType.Administrator, UserData.Administrator);
private static void SetupAdministratorUser()
{
TestUsersDictionary.Add(UserType.Administrator, UserData.Administrator);
}

private static void SetupAnonymousUser() => TestUsersDictionary.Add(UserType.Anonymous, UserData.Anonymous);
private static void SetupAnonymousUser()
{
TestUsersDictionary.Add(UserType.Anonymous, UserData.Anonymous);
}

private static void AuthenticateUser(ITestUser user)
{
Expand Down

0 comments on commit 856188e

Please sign in to comment.