too much for one commit

This commit is contained in:
Nils Blomgren
2026-05-13 14:01:32 +02:00
parent a96dd33039
commit 328d494530
394 changed files with 98104 additions and 78 deletions

View File

@@ -0,0 +1,192 @@
using EntKube.Provisioning.Domain;
using FluentAssertions;
namespace EntKube.Provisioning.Tests.Domain;
public class IdentityRealmTests
{
[Fact]
public void Create_ValidName_ReturnsRealmInProvisioningState()
{
// When creating a new realm, it starts in Provisioning status
// with the given name and cluster association.
Guid environmentId = Guid.NewGuid();
Guid clusterId = Guid.NewGuid();
IdentityRealm realm = IdentityRealm.Create(environmentId, "my-app", clusterId);
realm.Id.Should().NotBeEmpty();
realm.EnvironmentId.Should().Be(environmentId);
realm.ClusterId.Should().Be(clusterId);
realm.Name.Should().Be("my-app");
realm.Status.Should().Be(IdentityRealmStatus.Provisioning);
realm.Branding.Should().Be(RealmBranding.Default);
realm.Pages.LoginEnabled.Should().BeTrue();
realm.Pages.ProfileEnabled.Should().BeFalse();
}
[Fact]
public void Create_EmptyName_ThrowsArgumentException()
{
// A realm must have a name — empty is not valid.
Action act = () => IdentityRealm.Create(Guid.NewGuid(), "", Guid.NewGuid());
act.Should().Throw<ArgumentException>();
}
[Fact]
public void UpdateBranding_ChangesBrandingAndTimestamp()
{
// After updating branding, the new values stick and
// the last modified timestamp is updated.
IdentityRealm realm = IdentityRealm.Create(Guid.NewGuid(), "branded", Guid.NewGuid());
RealmBranding newBranding = new(
LogoUrl: "https://example.com/logo.png",
BackgroundImageUrl: null,
BackgroundColor: "#1a1a2e",
PrimaryColor: "#16213e",
SecondaryColor: "#0f3460",
TextColor: "#ffffff");
realm.UpdateBranding(newBranding);
realm.Branding.LogoUrl.Should().Be("https://example.com/logo.png");
realm.Branding.BackgroundColor.Should().Be("#1a1a2e");
realm.LastModifiedAt.Should().NotBeNull();
}
[Fact]
public void UpdatePages_EnablesProfile()
{
// A realm starts with only login enabled. We can enable profile pages too.
IdentityRealm realm = IdentityRealm.Create(Guid.NewGuid(), "with-profile", Guid.NewGuid());
RealmPages pages = new(
LoginEnabled: true,
ProfileEnabled: true,
RegistrationEnabled: false,
ForgotPasswordEnabled: true);
realm.UpdatePages(pages);
realm.Pages.ProfileEnabled.Should().BeTrue();
}
[Fact]
public void AddIdentityProvider_NewProvider_AddsToList()
{
// Adding an OIDC identity provider to the realm.
IdentityRealm realm = IdentityRealm.Create(Guid.NewGuid(), "idp-realm", Guid.NewGuid());
RealmIdentityProvider provider = RealmIdentityProvider.Create(
alias: "azure-ad",
displayName: "Azure AD",
type: IdentityProviderType.Oidc,
authorizationUrl: "https://login.microsoftonline.com/authorize",
tokenUrl: "https://login.microsoftonline.com/token",
clientId: "my-client-id");
realm.AddIdentityProvider(provider);
realm.IdentityProviders.Should().HaveCount(1);
realm.IdentityProviders[0].Alias.Should().Be("azure-ad");
realm.IdentityProviders[0].Type.Should().Be(IdentityProviderType.Oidc);
}
[Fact]
public void AddIdentityProvider_DuplicateAlias_Throws()
{
// Each provider must have a unique alias within the realm.
IdentityRealm realm = IdentityRealm.Create(Guid.NewGuid(), "dup-realm", Guid.NewGuid());
RealmIdentityProvider first = RealmIdentityProvider.Create("github", "GitHub", IdentityProviderType.GitHub);
RealmIdentityProvider duplicate = RealmIdentityProvider.Create("github", "GitHub Copy", IdentityProviderType.GitHub);
realm.AddIdentityProvider(first);
Action act = () => realm.AddIdentityProvider(duplicate);
act.Should().Throw<InvalidOperationException>();
}
[Fact]
public void RemoveIdentityProvider_ExistingAlias_RemovesFromList()
{
// Removing an identity provider by alias.
IdentityRealm realm = IdentityRealm.Create(Guid.NewGuid(), "remove-realm", Guid.NewGuid());
RealmIdentityProvider provider = RealmIdentityProvider.Create("google", "Google", IdentityProviderType.Google);
realm.AddIdentityProvider(provider);
realm.RemoveIdentityProvider("google");
realm.IdentityProviders.Should().BeEmpty();
}
[Fact]
public void AddOrganization_NewOrg_AddsToList()
{
// Organizations let you group users within a realm.
IdentityRealm realm = IdentityRealm.Create(Guid.NewGuid(), "org-realm", Guid.NewGuid());
RealmOrganization org = RealmOrganization.Create("Acme Corp", "Top-level org");
realm.AddOrganization(org);
realm.Organizations.Should().HaveCount(1);
realm.Organizations[0].Name.Should().Be("Acme Corp");
}
[Fact]
public void Organization_AddChild_CreatesHierarchy()
{
// Organizations support nested children for hierarchical structure.
RealmOrganization parent = RealmOrganization.Create("Acme Corp");
RealmOrganization child = RealmOrganization.Create("Engineering");
RealmOrganization grandchild = RealmOrganization.Create("Backend Team");
parent.AddChild(child);
child.AddChild(grandchild);
parent.Children.Should().HaveCount(1);
parent.Children[0].Name.Should().Be("Engineering");
parent.Children[0].Children.Should().HaveCount(1);
parent.Children[0].Children[0].Name.Should().Be("Backend Team");
}
[Fact]
public void Organization_DuplicateChildName_Throws()
{
// Child names must be unique within a parent.
RealmOrganization parent = RealmOrganization.Create("Acme Corp");
RealmOrganization child1 = RealmOrganization.Create("Engineering");
RealmOrganization child2 = RealmOrganization.Create("Engineering");
parent.AddChild(child1);
Action act = () => parent.AddChild(child2);
act.Should().Throw<InvalidOperationException>();
}
[Fact]
public void MarkActive_ChangesStatusToActive()
{
IdentityRealm realm = IdentityRealm.Create(Guid.NewGuid(), "active-realm", Guid.NewGuid());
realm.MarkActive();
realm.Status.Should().Be(IdentityRealmStatus.Active);
}
}