Skip to content

Commit

Permalink
Refactor KeycloakRealmResource and enhance validation
Browse files Browse the repository at this point in the history
The `KeycloakRealmResource` class has been refactored to include null checks in its constructor for parameters `name`, `realmName`, and `parent`. A private field `_parentEndpoint` and a property `ParentEndpoint` have been added. The `Parent` and `RealmName` properties now rely on the constructor for initialization.

New unit tests in `KeycloakPublicApiTests.cs` ensure that the constructor throws an `ArgumentNullException` for null parameters. Additional tests validate that the `AddRealm` method correctly handles null values for the builder and realm name, improving input validation across the API.
  • Loading branch information
paulomorgado committed Jan 18, 2025
1 parent de17d96 commit cf0c19a
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 6 deletions.
25 changes: 19 additions & 6 deletions src/Aspire.Hosting.Keycloak/KeycloakRealmResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,25 @@ namespace Aspire.Hosting.Keycloak;
/// <summary>
/// Represents a Keycloak Realm resource.
/// </summary>
/// <param name="name">The name of the realm resource.</param>
/// <param name="realmName">The name of the realm.</param>
/// <param name="parent">The Keycloak server resource associated with this database.</param>
public sealed class KeycloakRealmResource(string name, string realmName, KeycloakResource parent) : Resource(name), IResourceWithParent<KeycloakResource>, IResourceWithConnectionString
public sealed class KeycloakRealmResource : Resource, IResourceWithParent<KeycloakResource>, IResourceWithConnectionString
{
private EndpointReference? _parentEndpoint;

/// <summary>
/// Initializes a new instance of the <see cref="KeycloakRealmResource"/> class.
/// </summary>
/// <param name="name">The name of the realm resource.</param>
/// <param name="realmName">The name of the realm.</param>
/// <param name="parent">The Keycloak server resource associated with this database.</param>
public KeycloakRealmResource(string name, string realmName, KeycloakResource parent) : base(name)
{
ArgumentNullException.ThrowIfNull(realmName);
ArgumentNullException.ThrowIfNull(parent);

RealmName = realmName;
Parent = parent;
}

private EndpointReference ParentEndpoint => _parentEndpoint ??= new(Parent, "http");

/// <inheritdoc/>
Expand Down Expand Up @@ -96,10 +109,10 @@ public sealed class KeycloakRealmResource(string name, string realmName, Keycloa
public ReferenceExpression RegistrationEndpointExpression => ReferenceExpression.Create($"{ConnectionStringExpression}{RegistrationEndpoint}");

/// <inheritdoc/>
public KeycloakResource Parent { get; } = parent;
public KeycloakResource Parent { get; }

/// <summary>
/// Gets the name of the realm.
/// </summary>
public string RealmName { get; } = realmName;
public string RealmName { get; }
}
68 changes: 68 additions & 0 deletions tests/Aspire.Hosting.Keycloak.Tests/KeycloakPublicApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,49 @@ public void CtorKeycloakResourceShouldThrowWhenAdminPasswordIsNull()
Assert.Equal(nameof(adminPassword), exception.ParamName);
}

[Fact]
public void CtorKeycloakRealmResourceShouldThrowWhenNameIsNull()
{
string name = null!;
var realmName = "realm1";
var builder = TestDistributedApplicationBuilder.Create();
var adminPassword = builder.AddParameter("Password");
var parent = new KeycloakResource("keycloak", default(ParameterResource?), adminPassword.Resource);

var action = () => new KeycloakRealmResource(name, realmName, parent);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}

[Fact]
public void CtorMongoKeycloakRealmResourceShouldThrowWhenRealmNameIsNull()
{
var name = "keycloak";
string realmName = null!;
var builder = TestDistributedApplicationBuilder.Create();
var adminPassword = builder.AddParameter("Password");
var parent = new KeycloakResource("keycloak", default(ParameterResource?), adminPassword.Resource);

var action = () => new KeycloakRealmResource(name, realmName, parent);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(realmName), exception.ParamName);
}

[Fact]
public void CtorMongoKeycloakRealmResourceShouldThrowWhenDatabaseParentIsNull()
{
var name = "keycloak";
var realmName = "realm1";
KeycloakResource parent = null!;

var action = () => new KeycloakRealmResource(name, realmName, parent);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(parent), exception.ParamName);
}

[Fact]
public void AddKeycloakContainerShouldThrowWhenBuilderIsNull()
{
Expand Down Expand Up @@ -129,4 +172,29 @@ public void WithRealmImportShouldThrowWhenImportDirectoryDoesNotExist()

Assert.Throws<DirectoryNotFoundException>(action);
}

[Fact]
public void AddRealmShouldThrowWhenBuilderIsNull()
{
IResourceBuilder<KeycloakResource> builder = null!;
const string name = "realm1";

var action = () => builder.AddRealm(name);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(builder), exception.ParamName);
}

[Fact]
public void AddRealmShouldThrowWhenNameIsNull()
{
var builderResource = TestDistributedApplicationBuilder.Create();
var MongoDB = builderResource.AddKeycloak("realm1");
string name = null!;

var action = () => MongoDB.AddRealm(name);

var exception = Assert.Throws<ArgumentNullException>(action);
Assert.Equal(nameof(name), exception.ParamName);
}
}

0 comments on commit cf0c19a

Please sign in to comment.