mirror of
https://github.com/Cleanuparr/Cleanuparr.git
synced 2026-09-21 10:37:14 -04:00
156 lines
6.3 KiB
C#
156 lines
6.3 KiB
C#
using Cleanuparr.Api.Features.MalwareBlocker.Contracts.Requests;
|
|
using Cleanuparr.Api.Features.MalwareBlocker.Controllers;
|
|
using Cleanuparr.Api.Tests.TestHelpers;
|
|
using Cleanuparr.Domain.Enums;
|
|
using Cleanuparr.Infrastructure.Services.Interfaces;
|
|
using Cleanuparr.Persistence;
|
|
using Cleanuparr.Persistence.Models.Configuration.MalwareBlocker;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using NSubstitute;
|
|
using Shouldly;
|
|
using Xunit;
|
|
|
|
namespace Cleanuparr.Api.Tests.Features.MalwareBlocker;
|
|
|
|
public class MalwareBlockerConfigControllerTests : IDisposable
|
|
{
|
|
private readonly DataContext _dataContext;
|
|
private readonly IJobManagementService _jobManagementService;
|
|
private readonly MalwareBlockerConfigController _controller;
|
|
|
|
public MalwareBlockerConfigControllerTests()
|
|
{
|
|
_dataContext = ConfigControllerTestDataFactory.CreateDataContext();
|
|
var logger = Substitute.For<ILogger<MalwareBlockerConfigController>>();
|
|
_jobManagementService = Substitute.For<IJobManagementService>();
|
|
_controller = new MalwareBlockerConfigController(logger, _dataContext, _jobManagementService);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_dataContext.Dispose();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetMalwareBlockerConfig_ReturnsExistingConfig()
|
|
{
|
|
// Act
|
|
var result = await _controller.GetMalwareBlockerConfig();
|
|
|
|
// Assert
|
|
var ok = result.ShouldBeOfType<OkObjectResult>();
|
|
ok.Value.ShouldBeOfType<ContentBlockerConfig>();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateMalwareBlockerConfig_Enabled_StartsJobWithCron()
|
|
{
|
|
// Arrange — Enabled requires at least one blocklist with a valid path
|
|
var request = new UpdateMalwareBlockerConfigRequest
|
|
{
|
|
Enabled = true,
|
|
CronExpression = "0/5 * * * * ?",
|
|
Sonarr = new BlocklistSettings { Enabled = true, BlocklistPath = "https://example.com/blocklist.txt" },
|
|
Radarr = new BlocklistSettings { Enabled = false },
|
|
Lidarr = new BlocklistSettings { Enabled = false },
|
|
Readarr = new BlocklistSettings { Enabled = false },
|
|
Whisparr = new BlocklistSettings { Enabled = false },
|
|
Sportarr = new BlocklistSettings { Enabled = false },
|
|
};
|
|
|
|
// Act
|
|
var result = await _controller.UpdateMalwareBlockerConfig(request);
|
|
|
|
// Assert
|
|
result.ShouldBeOfType<OkObjectResult>();
|
|
await _jobManagementService.Received(1).StartJob(JobType.MalwareBlocker, null, "0/5 * * * * ?");
|
|
await _jobManagementService.DidNotReceive().StopJob(Arg.Any<JobType>());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateMalwareBlockerConfig_Disabled_StopsJob()
|
|
{
|
|
// Arrange — pre-enable
|
|
var existing = await _dataContext.ContentBlockerConfigs.FirstAsync();
|
|
existing.Enabled = true;
|
|
await _dataContext.SaveChangesAsync();
|
|
|
|
var request = new UpdateMalwareBlockerConfigRequest
|
|
{
|
|
Enabled = false,
|
|
CronExpression = "0/5 * * * * ?",
|
|
Sonarr = new BlocklistSettings { Enabled = false },
|
|
Radarr = new BlocklistSettings { Enabled = false },
|
|
Lidarr = new BlocklistSettings { Enabled = false },
|
|
Readarr = new BlocklistSettings { Enabled = false },
|
|
Whisparr = new BlocklistSettings { Enabled = false },
|
|
Sportarr = new BlocklistSettings { Enabled = false },
|
|
};
|
|
|
|
// Act
|
|
var result = await _controller.UpdateMalwareBlockerConfig(request);
|
|
|
|
// Assert
|
|
result.ShouldBeOfType<OkObjectResult>();
|
|
await _jobManagementService.Received(1).StopJob(JobType.MalwareBlocker);
|
|
await _jobManagementService.DidNotReceive().StartJob(Arg.Any<JobType>(), Arg.Any<Cleanuparr.Infrastructure.Models.JobSchedule?>(), Arg.Any<string?>());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateMalwareBlockerConfig_InvalidCronExpression_PropagatesValidationException()
|
|
{
|
|
// Arrange — CronValidationHelper throws Cleanuparr.Domain.Exceptions.ValidationException,
|
|
// which the controller's catch (System.ComponentModel.DataAnnotations.ValidationException) does NOT match.
|
|
var request = new UpdateMalwareBlockerConfigRequest
|
|
{
|
|
Enabled = true,
|
|
CronExpression = "definitely-not-a-cron",
|
|
Sonarr = new BlocklistSettings { Enabled = false },
|
|
Radarr = new BlocklistSettings { Enabled = false },
|
|
Lidarr = new BlocklistSettings { Enabled = false },
|
|
Readarr = new BlocklistSettings { Enabled = false },
|
|
Whisparr = new BlocklistSettings { Enabled = false },
|
|
Sportarr = new BlocklistSettings { Enabled = false },
|
|
};
|
|
|
|
// Act / Assert
|
|
await Should.ThrowAsync<Cleanuparr.Domain.Exceptions.ValidationException>(
|
|
() => _controller.UpdateMalwareBlockerConfig(request));
|
|
await _jobManagementService.DidNotReceive().StartJob(Arg.Any<JobType>(), Arg.Any<Cleanuparr.Infrastructure.Models.JobSchedule?>(), Arg.Any<string?>());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateMalwareBlockerConfig_PersistsChanges()
|
|
{
|
|
// Arrange
|
|
var request = new UpdateMalwareBlockerConfigRequest
|
|
{
|
|
Enabled = true,
|
|
CronExpression = "0/10 * * * * ?",
|
|
IgnorePrivate = true,
|
|
DeletePrivate = false,
|
|
Sonarr = new BlocklistSettings { Enabled = true, BlocklistPath = "https://example.com/list.txt" },
|
|
Radarr = new BlocklistSettings { Enabled = false },
|
|
Lidarr = new BlocklistSettings { Enabled = false },
|
|
Readarr = new BlocklistSettings { Enabled = false },
|
|
Whisparr = new BlocklistSettings { Enabled = false },
|
|
Sportarr = new BlocklistSettings { Enabled = false },
|
|
IgnoredDownloads = new List<string> { "foo" },
|
|
};
|
|
|
|
// Act
|
|
await _controller.UpdateMalwareBlockerConfig(request);
|
|
|
|
// Assert
|
|
var saved = await _dataContext.ContentBlockerConfigs.AsNoTracking().FirstAsync();
|
|
saved.Enabled.ShouldBeTrue();
|
|
saved.CronExpression.ShouldBe("0/10 * * * * ?");
|
|
saved.IgnorePrivate.ShouldBeTrue();
|
|
saved.Sonarr.Enabled.ShouldBeTrue();
|
|
saved.IgnoredDownloads.ShouldContain("foo");
|
|
}
|
|
}
|