211 lines
6.8 KiB
C#
211 lines
6.8 KiB
C#
using ColaFlow.Modules.Identity.Domain.Aggregates.Tenants;
|
|
using ColaFlow.Modules.Identity.Domain.Aggregates.Tenants.Events;
|
|
using FluentAssertions;
|
|
using Xunit;
|
|
|
|
namespace ColaFlow.Modules.Identity.Domain.Tests.Aggregates;
|
|
|
|
public sealed class TenantTests
|
|
{
|
|
[Fact]
|
|
public void Create_ShouldSucceed()
|
|
{
|
|
// Arrange
|
|
var name = TenantName.Create("Acme Corporation");
|
|
var slug = TenantSlug.Create("acme");
|
|
|
|
// Act
|
|
var tenant = Tenant.Create(name, slug);
|
|
|
|
// Assert
|
|
tenant.Should().NotBeNull();
|
|
tenant.Id.Should().NotBe(Guid.Empty);
|
|
tenant.Name.Value.Should().Be("Acme Corporation");
|
|
tenant.Slug.Value.Should().Be("acme");
|
|
tenant.Status.Should().Be(TenantStatus.Active);
|
|
tenant.Plan.Should().Be(SubscriptionPlan.Free);
|
|
tenant.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
|
}
|
|
|
|
[Fact]
|
|
public void Create_ShouldRaiseTenantCreatedEvent()
|
|
{
|
|
// Arrange
|
|
var name = TenantName.Create("Acme Corporation");
|
|
var slug = TenantSlug.Create("acme");
|
|
|
|
// Act
|
|
var tenant = Tenant.Create(name, slug);
|
|
|
|
// Assert
|
|
tenant.DomainEvents.Should().ContainSingle();
|
|
tenant.DomainEvents.Should().ContainItemsAssignableTo<TenantCreatedEvent>();
|
|
var domainEvent = tenant.DomainEvents.First() as TenantCreatedEvent;
|
|
domainEvent.Should().NotBeNull();
|
|
domainEvent!.TenantId.Should().Be(tenant.Id);
|
|
domainEvent.Slug.Should().Be("acme");
|
|
}
|
|
|
|
[Fact]
|
|
public void Activate_ShouldChangeStatus()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
tenant.Suspend("Payment failed");
|
|
tenant.ClearDomainEvents();
|
|
|
|
// Act
|
|
tenant.Activate();
|
|
|
|
// Assert
|
|
tenant.Status.Should().Be(TenantStatus.Active);
|
|
tenant.SuspendedAt.Should().BeNull();
|
|
tenant.SuspensionReason.Should().BeNull();
|
|
tenant.DomainEvents.Should().ContainSingle();
|
|
tenant.DomainEvents.Should().ContainItemsAssignableTo<TenantActivatedEvent>();
|
|
}
|
|
|
|
[Fact]
|
|
public void Suspend_ShouldChangeStatus()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
tenant.ClearDomainEvents();
|
|
|
|
// Act
|
|
tenant.Suspend("Payment failed");
|
|
|
|
// Assert
|
|
tenant.Status.Should().Be(TenantStatus.Suspended);
|
|
tenant.SuspendedAt.Should().NotBeNull();
|
|
tenant.SuspendedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));
|
|
tenant.SuspensionReason.Should().Be("Payment failed");
|
|
tenant.DomainEvents.Should().ContainSingle();
|
|
tenant.DomainEvents.Should().ContainItemsAssignableTo<TenantSuspendedEvent>();
|
|
}
|
|
|
|
[Fact]
|
|
public void Cancel_ShouldChangeStatus()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
tenant.ClearDomainEvents();
|
|
|
|
// Act
|
|
tenant.Cancel();
|
|
|
|
// Assert
|
|
tenant.Status.Should().Be(TenantStatus.Cancelled);
|
|
tenant.DomainEvents.Should().ContainSingle();
|
|
tenant.DomainEvents.Should().ContainItemsAssignableTo<TenantCancelledEvent>();
|
|
}
|
|
|
|
[Fact]
|
|
public void CancelledTenant_CannotBeActivated()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
tenant.Cancel();
|
|
|
|
// Act & Assert
|
|
var act = () => tenant.Activate();
|
|
act.Should().Throw<InvalidOperationException>()
|
|
.WithMessage("Cannot activate cancelled tenant");
|
|
}
|
|
|
|
[Fact]
|
|
public void ConfigureSso_ShouldSucceed_ForProfessionalPlan()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
tenant.UpgradePlan(SubscriptionPlan.Professional);
|
|
tenant.ClearDomainEvents();
|
|
|
|
var ssoConfig = SsoConfiguration.CreateOidc(
|
|
SsoProvider.AzureAD,
|
|
"https://login.microsoftonline.com/tenant-id",
|
|
"client-id",
|
|
"client-secret");
|
|
|
|
// Act
|
|
tenant.ConfigureSso(ssoConfig);
|
|
|
|
// Assert
|
|
tenant.SsoConfig.Should().NotBeNull();
|
|
tenant.SsoConfig!.Provider.Should().Be(SsoProvider.AzureAD);
|
|
tenant.DomainEvents.Should().ContainSingle();
|
|
tenant.DomainEvents.Should().ContainItemsAssignableTo<SsoConfiguredEvent>();
|
|
}
|
|
|
|
[Fact]
|
|
public void ConfigureSso_ShouldThrow_ForFreePlan()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
var ssoConfig = SsoConfiguration.CreateOidc(
|
|
SsoProvider.AzureAD,
|
|
"https://login.microsoftonline.com/tenant-id",
|
|
"client-id",
|
|
"client-secret");
|
|
|
|
// Act & Assert
|
|
var act = () => tenant.ConfigureSso(ssoConfig);
|
|
act.Should().Throw<InvalidOperationException>()
|
|
.WithMessage("SSO is only available for Professional and Enterprise plans");
|
|
}
|
|
|
|
[Fact]
|
|
public void UpgradePlan_ShouldIncreaseResourceLimits()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
tenant.ClearDomainEvents();
|
|
|
|
// Act
|
|
tenant.UpgradePlan(SubscriptionPlan.Professional);
|
|
|
|
// Assert
|
|
tenant.Plan.Should().Be(SubscriptionPlan.Professional);
|
|
tenant.MaxUsers.Should().Be(100);
|
|
tenant.MaxProjects.Should().Be(100);
|
|
tenant.MaxStorageGB.Should().Be(100);
|
|
tenant.DomainEvents.Should().ContainSingle();
|
|
tenant.DomainEvents.Should().ContainItemsAssignableTo<TenantPlanUpgradedEvent>();
|
|
}
|
|
|
|
[Fact]
|
|
public void UpgradePlan_ShouldThrow_WhenDowngrading()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"), SubscriptionPlan.Professional);
|
|
|
|
// Act & Assert
|
|
var act = () => tenant.UpgradePlan(SubscriptionPlan.Free);
|
|
act.Should().Throw<InvalidOperationException>()
|
|
.WithMessage("New plan must be higher than current plan");
|
|
}
|
|
|
|
[Fact]
|
|
public void DisableSso_ShouldSucceed()
|
|
{
|
|
// Arrange
|
|
var tenant = Tenant.Create(TenantName.Create("Test"), TenantSlug.Create("test"));
|
|
tenant.UpgradePlan(SubscriptionPlan.Enterprise);
|
|
var ssoConfig = SsoConfiguration.CreateOidc(
|
|
SsoProvider.Google,
|
|
"https://accounts.google.com",
|
|
"client-id",
|
|
"client-secret");
|
|
tenant.ConfigureSso(ssoConfig);
|
|
tenant.ClearDomainEvents();
|
|
|
|
// Act
|
|
tenant.DisableSso();
|
|
|
|
// Assert
|
|
tenant.SsoConfig.Should().BeNull();
|
|
tenant.DomainEvents.Should().ContainSingle();
|
|
tenant.DomainEvents.Should().ContainItemsAssignableTo<SsoDisabledEvent>();
|
|
}
|
|
}
|