too much for one commit
This commit is contained in:
192
tests/EntKube.Provisioning.Tests/Domain/KeycloakRealmTests.cs
Normal file
192
tests/EntKube.Provisioning.Tests/Domain/KeycloakRealmTests.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user