mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-01-20 03:38:03 -05:00
137 lines
5.2 KiB
C#
137 lines
5.2 KiB
C#
using Cleanuparr.Domain.Exceptions;
|
|
using Cleanuparr.Infrastructure.Models;
|
|
using Cleanuparr.Infrastructure.Utilities;
|
|
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace Cleanuparr.Infrastructure.Tests.Utilities;
|
|
|
|
public class CronValidationHelperTests
|
|
{
|
|
[Theory]
|
|
[InlineData("0 */5 * * * ?")] // Every 5 minutes
|
|
[InlineData("0 0 */2 * * ?")] // Every 2 hours
|
|
[InlineData("0 0 0/4 * * ?")] // Every 4 hours
|
|
[InlineData("*/30 * * * * ?")] // Every 30 seconds
|
|
public void ValidateCronExpression_ValidExpression_DoesNotThrow(string cronExpression)
|
|
{
|
|
// Act & Assert
|
|
Should.NotThrow(() => CronValidationHelper.ValidateCronExpression(cronExpression));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("invalid")]
|
|
[InlineData("* * *")]
|
|
[InlineData("0 0 0 0 0 0 0")]
|
|
[InlineData("not a cron")]
|
|
public void ValidateCronExpression_InvalidSyntax_ThrowsValidationException(string cronExpression)
|
|
{
|
|
// Act & Assert
|
|
var exception = Should.Throw<ValidationException>(
|
|
() => CronValidationHelper.ValidateCronExpression(cronExpression));
|
|
exception.Message.ShouldContain("Invalid cron expression");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(null)]
|
|
[InlineData("")]
|
|
[InlineData(" ")]
|
|
public void ValidateCronExpression_NullOrEmpty_ThrowsValidationException(string? cronExpression)
|
|
{
|
|
// Act & Assert
|
|
var exception = Should.Throw<ValidationException>(
|
|
() => CronValidationHelper.ValidateCronExpression(cronExpression!));
|
|
exception.Message.ShouldContain("cannot be null or empty");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("*/1 * * * * ?")] // Every 1 second
|
|
[InlineData("*/5 * * * * ?")] // Every 5 seconds
|
|
[InlineData("*/10 * * * * ?")] // Every 10 seconds
|
|
[InlineData("*/15 * * * * ?")] // Every 15 seconds
|
|
public void ValidateCronExpression_TriggersTooFast_ThrowsValidationException(string cronExpression)
|
|
{
|
|
// Act & Assert - minimum is 30 seconds
|
|
var exception = Should.Throw<ValidationException>(
|
|
() => CronValidationHelper.ValidateCronExpression(cronExpression));
|
|
exception.Message.ShouldContain("minimum");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("0 0 0 * * ?")] // Once per day (24 hours)
|
|
[InlineData("0 0 0 1 * ?")] // Once per month
|
|
public void ValidateCronExpression_TriggersTooSlow_ThrowsValidationException(string cronExpression)
|
|
{
|
|
// Act & Assert - maximum is 6 hours
|
|
var exception = Should.Throw<ValidationException>(
|
|
() => CronValidationHelper.ValidateCronExpression(cronExpression));
|
|
exception.Message.ShouldContain("maximum");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("*/1 * * * * ?")] // Every 1 second - too fast for other jobs
|
|
[InlineData("*/5 * * * * ?")] // Every 5 seconds - too fast for other jobs
|
|
public void ValidateCronExpression_MalwareBlocker_HasDifferentLimits(string cronExpression)
|
|
{
|
|
// Act & Assert - MalwareBlocker allows faster triggers (no minimum)
|
|
Should.NotThrow(() => CronValidationHelper.ValidateCronExpression(cronExpression, JobType.MalwareBlocker));
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateCronExpression_AtExactMinimumInterval_DoesNotThrow()
|
|
{
|
|
// Arrange - exactly 30 seconds
|
|
const string cronExpression = "*/30 * * * * ?";
|
|
|
|
// Act & Assert
|
|
Should.NotThrow(() => CronValidationHelper.ValidateCronExpression(cronExpression));
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateCronExpression_AtExactMaximumInterval_DoesNotThrow()
|
|
{
|
|
// Arrange - exactly 6 hours
|
|
const string cronExpression = "0 0 */6 * * ?";
|
|
|
|
// Act & Assert
|
|
Should.NotThrow(() => CronValidationHelper.ValidateCronExpression(cronExpression));
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateCronExpression_NullJobType_UsesDefaultLimits()
|
|
{
|
|
// Arrange - 5 seconds would fail default limits but pass MalwareBlocker
|
|
const string cronExpression = "*/5 * * * * ?";
|
|
|
|
// Act & Assert - should fail because null uses default limits (30 second minimum)
|
|
var exception = Should.Throw<ValidationException>(
|
|
() => CronValidationHelper.ValidateCronExpression(cronExpression, null));
|
|
exception.Message.ShouldContain("minimum");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(JobType.QueueCleaner)]
|
|
[InlineData(JobType.DownloadCleaner)]
|
|
[InlineData(JobType.BlacklistSynchronizer)]
|
|
public void ValidateCronExpression_NonMalwareBlockerJobs_EnforceMinimumLimit(JobType jobType)
|
|
{
|
|
// Arrange - 5 seconds is below minimum
|
|
const string cronExpression = "*/5 * * * * ?";
|
|
|
|
// Act & Assert
|
|
var exception = Should.Throw<ValidationException>(
|
|
() => CronValidationHelper.ValidateCronExpression(cronExpression, jobType));
|
|
exception.Message.ShouldContain("minimum");
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("0 0 */1 * * ?")] // Every 1 hour
|
|
[InlineData("0 */30 * * * ?")] // Every 30 minutes
|
|
[InlineData("0 */1 * * * ?")] // Every 1 minute
|
|
public void ValidateCronExpression_WithinValidRange_DoesNotThrow(string cronExpression)
|
|
{
|
|
// Act & Assert
|
|
Should.NotThrow(() => CronValidationHelper.ValidateCronExpression(cronExpression));
|
|
}
|
|
}
|