Files
Cleanuparr/code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/TransmissionItemWrapperTests.cs
2026-04-11 17:13:41 +03:00

424 lines
11 KiB
C#

using Cleanuparr.Infrastructure.Features.DownloadClient.Transmission;
using Shouldly;
using Transmission.API.RPC.Entity;
using Xunit;
namespace Cleanuparr.Infrastructure.Tests.Features.DownloadClient;
public class TransmissionItemWrapperTests
{
[Fact]
public void Constructor_WithNullTorrentInfo_ThrowsArgumentNullException()
{
// Act & Assert
Should.Throw<ArgumentNullException>(() => new TransmissionItemWrapper(null!));
}
[Fact]
public void Hash_ReturnsCorrectValue()
{
// Arrange
var expectedHash = "test-hash-123";
var torrentInfo = new TorrentInfo { HashString = expectedHash };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Hash;
// Assert
result.ShouldBe(expectedHash);
}
[Fact]
public void Hash_WithNullValue_ReturnsEmptyString()
{
// Arrange
var torrentInfo = new TorrentInfo { HashString = null };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Hash;
// Assert
result.ShouldBe(string.Empty);
}
[Fact]
public void Name_ReturnsCorrectValue()
{
// Arrange
var expectedName = "Test Torrent";
var torrentInfo = new TorrentInfo { Name = expectedName };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Name;
// Assert
result.ShouldBe(expectedName);
}
[Fact]
public void Name_WithNullValue_ReturnsEmptyString()
{
// Arrange
var torrentInfo = new TorrentInfo { Name = null };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Name;
// Assert
result.ShouldBe(string.Empty);
}
[Theory]
[InlineData(true, true)]
[InlineData(false, false)]
[InlineData(null, false)]
public void IsPrivate_ReturnsCorrectValue(bool? isPrivate, bool expected)
{
// Arrange
var torrentInfo = new TorrentInfo { IsPrivate = isPrivate };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.IsPrivate;
// Assert
result.ShouldBe(expected);
}
[Theory]
[InlineData(1024L * 1024 * 1024, 1024L * 1024 * 1024)] // 1GB
[InlineData(0L, 0L)]
[InlineData(null, 0L)]
public void Size_ReturnsCorrectValue(long? totalSize, long expected)
{
// Arrange
var torrentInfo = new TorrentInfo { TotalSize = totalSize };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Size;
// Assert
result.ShouldBe(expected);
}
[Theory]
[InlineData(0L, 1024L, 0.0)]
[InlineData(512L, 1024L, 50.0)]
[InlineData(768L, 1024L, 75.0)]
[InlineData(1024L, 1024L, 100.0)]
[InlineData(0L, 0L, 0.0)] // Edge case: zero size
[InlineData(null, 1024L, 0.0)] // Edge case: null downloaded
[InlineData(512L, null, 0.0)] // Edge case: null total size
public void CompletionPercentage_ReturnsCorrectValue(long? downloadedEver, long? totalSize, double expectedPercentage)
{
// Arrange
var torrentInfo = new TorrentInfo
{
DownloadedEver = downloadedEver,
TotalSize = totalSize
};
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.CompletionPercentage;
// Assert
result.ShouldBe(expectedPercentage);
}
[Theory]
[InlineData(1024L * 1024 * 100, 1024L * 1024 * 100)] // 100MB
[InlineData(0L, 0L)]
[InlineData(null, 0L)]
public void DownloadedBytes_ReturnsCorrectValue(long? downloadedEver, long expected)
{
// Arrange
var torrentInfo = new TorrentInfo { DownloadedEver = downloadedEver };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.DownloadedBytes;
// Assert
result.ShouldBe(expected);
}
[Theory]
[InlineData(2.0, 2.0)]
[InlineData(0.5, 0.5)]
[InlineData(1.0, 1.0)]
[InlineData(0.0, 0.0)]
[InlineData(null, 0.0)]
public void Ratio_ReturnsCorrectValue(double? uploadRatio, double expected)
{
// Arrange
var torrentInfo = new TorrentInfo
{
uploadRatio = uploadRatio
};
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Ratio;
// Assert
result.ShouldBe(expected);
}
[Theory]
[InlineData(3600L, 3600L)] // 1 hour
[InlineData(0L, 0L)]
[InlineData(-1L, -1L)] // Unknown/infinite
[InlineData(null, 0L)]
public void Eta_ReturnsCorrectValue(long? eta, long expected)
{
// Arrange
var torrentInfo = new TorrentInfo { Eta = eta };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Eta;
// Assert
result.ShouldBe(expected);
}
[Theory]
[InlineData(86400L, 86400L)] // 1 day
[InlineData(0L, 0L)]
[InlineData(null, 0L)]
public void SeedingTimeSeconds_ReturnsCorrectValue(long? secondsSeeding, long expected)
{
// Arrange
var torrentInfo = new TorrentInfo { SecondsSeeding = secondsSeeding };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.SeedingTimeSeconds;
// Assert
result.ShouldBe(expected);
}
// TrackerDomains property tests
[Fact]
public void TrackerDomains_WithMultipleTrackers_ReturnsExtractedDomains()
{
// Arrange
var torrentInfo = new TorrentInfo
{
Trackers = new TransmissionTorrentTrackers[]
{
new() { Announce = "http://tracker.example.com/announce" },
new() { Announce = "udp://open.stealth.si:80/announce" }
}
};
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.TrackerDomains;
// Assert
result.Count.ShouldBe(2);
result.ShouldContain("tracker.example.com");
result.ShouldContain("open.stealth.si");
}
[Fact]
public void TrackerDomains_WithNullTrackers_ReturnsEmptyList()
{
// Arrange
var torrentInfo = new TorrentInfo { Trackers = null };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.TrackerDomains;
// Assert
result.ShouldBeEmpty();
}
[Fact]
public void TrackerDomains_WithEmptyTrackers_ReturnsEmptyList()
{
// Arrange
var torrentInfo = new TorrentInfo { Trackers = Array.Empty<TransmissionTorrentTrackers>() };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.TrackerDomains;
// Assert
result.ShouldBeEmpty();
}
[Fact]
public void TrackerDomains_WithNullAnnounceUrls_FiltersThemOut()
{
// Arrange
var torrentInfo = new TorrentInfo
{
Trackers = new TransmissionTorrentTrackers[]
{
new() { Announce = "http://tracker.example.com/announce" },
new() { Announce = null },
new() { Announce = "" }
}
};
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.TrackerDomains;
// Assert
result.Count.ShouldBe(1);
result.ShouldContain("tracker.example.com");
}
// Tags property tests
[Fact]
public void Tags_ReturnsLabels()
{
// Arrange
var torrentInfo = new TorrentInfo { Labels = new[] { "tag1", "tag2", "tag3" } };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Tags;
// Assert
result.Count.ShouldBe(3);
result.ShouldContain("tag1");
result.ShouldContain("tag2");
result.ShouldContain("tag3");
}
[Fact]
public void Tags_WithNullLabels_ReturnsEmptyList()
{
// Arrange
var torrentInfo = new TorrentInfo { Labels = null };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Tags;
// Assert
result.ShouldBeEmpty();
}
[Fact]
public void Tags_WithEmptyLabels_ReturnsEmptyList()
{
// Arrange
var torrentInfo = new TorrentInfo { Labels = Array.Empty<string>() };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.Tags;
// Assert
result.ShouldBeEmpty();
}
[Fact]
public void IsIgnored_WithEmptyList_ReturnsFalse()
{
// Arrange
var torrentInfo = new TorrentInfo { HashString = "abc123", Name = "Test Torrent" };
var wrapper = new TransmissionItemWrapper(torrentInfo);
// Act
var result = wrapper.IsIgnored(Array.Empty<string>());
// Assert
result.ShouldBeFalse();
}
[Fact]
public void IsIgnored_MatchingHash_ReturnsTrue()
{
// Arrange
var torrentInfo = new TorrentInfo { HashString = "abc123", Name = "Test Torrent" };
var wrapper = new TransmissionItemWrapper(torrentInfo);
var ignoredDownloads = new[] { "abc123" };
// Act
var result = wrapper.IsIgnored(ignoredDownloads);
// Assert
result.ShouldBeTrue();
}
[Fact]
public void IsIgnored_MatchingCategory_ReturnsTrue()
{
// Arrange
var torrentInfo = new TorrentInfo
{
HashString = "abc123",
Name = "Test Torrent",
DownloadDir = "/downloads/test-category"
};
var wrapper = new TransmissionItemWrapper(torrentInfo);
var ignoredDownloads = new[] { "test-category" };
// Act
var result = wrapper.IsIgnored(ignoredDownloads);
// Assert
result.ShouldBeTrue();
}
[Fact]
public void IsIgnored_MatchingTracker_ReturnsTrue()
{
// Arrange
var torrentInfo = new TorrentInfo
{
HashString = "abc123",
Name = "Test Torrent",
Trackers = new TransmissionTorrentTrackers[]
{
new() { Announce = "http://tracker.example.com/announce" }
}
};
var wrapper = new TransmissionItemWrapper(torrentInfo);
var ignoredDownloads = new[] { "tracker.example.com" };
// Act
var result = wrapper.IsIgnored(ignoredDownloads);
// Assert
result.ShouldBeTrue();
}
[Fact]
public void IsIgnored_NotMatching_ReturnsFalse()
{
// Arrange
var torrentInfo = new TorrentInfo
{
HashString = "abc123",
Name = "Test Torrent",
Labels = new[] { "some-category" },
Trackers = new TransmissionTorrentTrackers[]
{
new() { Announce = "http://tracker.example.com/announce" }
}
};
var wrapper = new TransmissionItemWrapper(torrentInfo);
var ignoredDownloads = new[] { "notmatching" };
// Act
var result = wrapper.IsIgnored(ignoredDownloads);
// Assert
result.ShouldBeFalse();
}
}