Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions tests/CoreTest/Compress/CompressProviderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using GeneralUpdate.Core.Compress;

namespace CoreTest.Compress;

public class CompressProviderTests
{
[Fact]
public void Compress_ZipFormat_UsesZipStrategy()
{
var tempDir = Path.Combine(Path.GetTempPath(), $"compress_test_{Guid.NewGuid():N}");
var destZip = Path.Combine(Path.GetTempPath(), $"result_{Guid.NewGuid():N}.zip");
Directory.CreateDirectory(tempDir);
File.WriteAllText(Path.Combine(tempDir, "test.txt"), "hello");
try
{
var ex = Record.Exception(() =>
CompressProvider.Compress(".zip", tempDir, destZip, false, System.Text.Encoding.UTF8));
Assert.Null(ex);
Assert.True(File.Exists(destZip));
}
finally
{
if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true);
if (File.Exists(destZip)) File.Delete(destZip);
}
}

[Fact]
public void Compress_UnknownFormat_ThrowsArgumentException()
{
Assert.Throws<ArgumentException>(() =>
CompressProvider.Compress("RAR", "source", "dest", false, System.Text.Encoding.UTF8));
}

[Fact]
public void Decompress_ZipFormat_UsesZipStrategy()
{
var tempDir = Path.Combine(Path.GetTempPath(), $"decompress_src_{Guid.NewGuid():N}");
var zipPath = Path.Combine(Path.GetTempPath(), $"test_{Guid.NewGuid():N}.zip");
var destDir = Path.Combine(Path.GetTempPath(), $"decompress_dst_{Guid.NewGuid():N}");
Directory.CreateDirectory(tempDir);
File.WriteAllText(Path.Combine(tempDir, "test.txt"), "hello world");
try
{
System.IO.Compression.ZipFile.CreateFromDirectory(tempDir, zipPath);
var ex = Record.Exception(() =>
CompressProvider.Decompress(".zip", zipPath, destDir, System.Text.Encoding.UTF8));
Assert.Null(ex);
Assert.True(File.Exists(Path.Combine(destDir, "test.txt")));
}
finally
{
if (Directory.Exists(tempDir)) Directory.Delete(tempDir, true);
if (File.Exists(zipPath)) File.Delete(zipPath);
if (Directory.Exists(destDir)) Directory.Delete(destDir, true);
}
}

[Fact]
public void Decompress_UnknownFormat_ThrowsArgumentException()
{
Assert.Throws<ArgumentException>(() =>
CompressProvider.Decompress("7z", "source", "dest", System.Text.Encoding.UTF8));
}
}
171 changes: 171 additions & 0 deletions tests/CoreTest/Compress/ZipCompressionStrategyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
using System.Text;
using GeneralUpdate.Core.Compress;

namespace CoreTest.Compress;

public class ZipCompressionStrategyTests
{
private readonly ZipCompressionStrategy _strategy = new();

[Fact]
public void Compress_DirectoryToNewZip_CreatesArchive()
{
var srcDir = Path.Combine(Path.GetTempPath(), $"src_{Guid.NewGuid():N}");
var destZip = Path.Combine(Path.GetTempPath(), $"dest_{Guid.NewGuid():N}.zip");
Directory.CreateDirectory(srcDir);
File.WriteAllText(Path.Combine(srcDir, "file.txt"), "content");
try
{
_strategy.Compress(srcDir, destZip, false, Encoding.UTF8);
Assert.True(File.Exists(destZip));
}
finally
{
if (Directory.Exists(srcDir)) Directory.Delete(srcDir, true);
if (File.Exists(destZip)) File.Delete(destZip);
}
}

[Fact]
public void Compress_DirectoryToExistingZip_UpdatesArchive()
{
var srcDir = Path.Combine(Path.GetTempPath(), $"src_{Guid.NewGuid():N}");
var destZip = Path.Combine(Path.GetTempPath(), $"dest_{Guid.NewGuid():N}.zip");
Directory.CreateDirectory(srcDir);
File.WriteAllText(Path.Combine(srcDir, "file1.txt"), "first");
// Create initial zip
System.IO.Compression.ZipFile.CreateFromDirectory(srcDir, destZip);
// Add second file
File.WriteAllText(Path.Combine(srcDir, "file2.txt"), "second");
try
{
_strategy.Compress(srcDir, destZip, false, Encoding.UTF8);
Assert.True(File.Exists(destZip));
}
finally
{
if (Directory.Exists(srcDir)) Directory.Delete(srcDir, true);
if (File.Exists(destZip)) File.Delete(destZip);
}
}

[Fact]
public void Compress_SingleFileInDirectoryToNewZip_CreatesArchive()
{
var srcDir = Path.Combine(Path.GetTempPath(), $"src_{Guid.NewGuid():N}");
var destZip = Path.Combine(Path.GetTempPath(), $"dest_{Guid.NewGuid():N}.zip");
Directory.CreateDirectory(srcDir);
File.WriteAllText(Path.Combine(srcDir, "single.txt"), "single file content");
try
{
_strategy.Compress(srcDir, destZip, false, Encoding.UTF8);
Assert.True(File.Exists(destZip));
}
finally
{
if (Directory.Exists(srcDir)) Directory.Delete(srcDir, true);
if (File.Exists(destZip)) File.Delete(destZip);
}
}

[Fact]
public void Decompress_ZipToDirectory_ExtractsFiles()
{
var srcDir = Path.Combine(Path.GetTempPath(), $"src_{Guid.NewGuid():N}");
var zipPath = Path.Combine(Path.GetTempPath(), $"test_{Guid.NewGuid():N}.zip");
var destDir = Path.Combine(Path.GetTempPath(), $"dst_{Guid.NewGuid():N}");
Directory.CreateDirectory(srcDir);
File.WriteAllText(Path.Combine(srcDir, "data.txt"), "decompress test");
System.IO.Compression.ZipFile.CreateFromDirectory(srcDir, zipPath);
try
{
_strategy.Decompress(zipPath, destDir, Encoding.UTF8);
Assert.True(File.Exists(Path.Combine(destDir, "data.txt")));
Assert.Equal("decompress test", File.ReadAllText(Path.Combine(destDir, "data.txt")));
}
finally
{
if (Directory.Exists(srcDir)) Directory.Delete(srcDir, true);
if (File.Exists(zipPath)) File.Delete(zipPath);
if (Directory.Exists(destDir)) Directory.Delete(destDir, true);
}
}

[Fact]
public void Decompress_ZipFileNotFound_ReturnsWithoutError()
{
var nonexistent = Path.Combine(Path.GetTempPath(), $"noexist_{Guid.NewGuid():N}.zip");
var destDir = Path.Combine(Path.GetTempPath(), $"dst_{Guid.NewGuid():N}");
var ex = Record.Exception(() => _strategy.Decompress(nonexistent, destDir, Encoding.UTF8));
Assert.Null(ex);
Comment on lines +99 to +100
}

[Fact]
public void Decompress_NestedDirectories_PreservesStructure()
{
var srcDir = Path.Combine(Path.GetTempPath(), $"src_{Guid.NewGuid():N}");
var nestedDir = Path.Combine(srcDir, "sub", "deep");
var zipPath = Path.Combine(Path.GetTempPath(), $"nested_{Guid.NewGuid():N}.zip");
var destDir = Path.Combine(Path.GetTempPath(), $"dst_{Guid.NewGuid():N}");
Directory.CreateDirectory(nestedDir);
File.WriteAllText(Path.Combine(nestedDir, "deep_file.txt"), "deep content");
System.IO.Compression.ZipFile.CreateFromDirectory(srcDir, zipPath);
try
{
_strategy.Decompress(zipPath, destDir, Encoding.UTF8);
Assert.True(File.Exists(Path.Combine(destDir, "sub", "deep", "deep_file.txt")));
}
finally
{
if (Directory.Exists(srcDir)) Directory.Delete(srcDir, true);
if (File.Exists(zipPath)) File.Delete(zipPath);
if (Directory.Exists(destDir)) Directory.Delete(destDir, true);
}
}

[Fact]
public void Decompress_EncodingPreserved_Utf8()
{
var srcDir = Path.Combine(Path.GetTempPath(), $"src_{Guid.NewGuid():N}");
var zipPath = Path.Combine(Path.GetTempPath(), $"utf8_{Guid.NewGuid():N}.zip");
var destDir = Path.Combine(Path.GetTempPath(), $"dst_{Guid.NewGuid():N}");
Directory.CreateDirectory(srcDir);
File.WriteAllText(Path.Combine(srcDir, "unicode.txt"), "你好世界", Encoding.UTF8);
System.IO.Compression.ZipFile.CreateFromDirectory(srcDir, zipPath);
try
{
_strategy.Decompress(zipPath, destDir, Encoding.UTF8);
Assert.Equal("你好世界", File.ReadAllText(Path.Combine(destDir, "unicode.txt"), Encoding.UTF8));
}
finally
{
if (Directory.Exists(srcDir)) Directory.Delete(srcDir, true);
if (File.Exists(zipPath)) File.Delete(zipPath);
if (Directory.Exists(destDir)) Directory.Delete(destDir, true);
}
}

[Fact]
public void Decompress_IncludesRootDirectory_WhenFlagTrue()
{
var srcDir = Path.Combine(Path.GetTempPath(), $"src_{Guid.NewGuid():N}");
var zipPath = Path.Combine(Path.GetTempPath(), $"includeRoot_{Guid.NewGuid():N}.zip");
var destDir = Path.Combine(Path.GetTempPath(), $"dst_{Guid.NewGuid():N}");
Directory.CreateDirectory(srcDir);
File.WriteAllText(Path.Combine(srcDir, "file.txt"), "content");
// Create zip with includeBaseDirectory=true for the test, then use Compress with includeRootDirectory
try
{
_strategy.Compress(srcDir, zipPath, true, Encoding.UTF8);
_strategy.Decompress(zipPath, destDir, Encoding.UTF8);
Assert.True(File.Exists(Path.Combine(destDir, "file.txt")) ||
Directory.Exists(Path.Combine(destDir, Path.GetFileName(srcDir))));
}
finally
{
if (Directory.Exists(srcDir)) Directory.Delete(srcDir, true);
if (File.Exists(zipPath)) File.Delete(zipPath);
if (Directory.Exists(destDir)) Directory.Delete(destDir, true);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using GeneralUpdate.Core.Download.Models;

namespace CoreTest.Download;

// NOTE: DownloadOrchestratorOptionsTests already exists in this namespace.
// See existing OrchestratorOptionsBehaviourTests.cs and DownloadOrchestratorOptionsTests.cs
// This file adds complementary tests.

public class DownloadOrchestratorOptionsComplementaryTests
{
[Fact]
public void From_DownloadTimeOutNegative_DefaultsTo30Seconds()
{
var config = new GeneralUpdate.Core.Configuration.GlobalConfigInfo
{
DownloadTimeOut = -5
};
var opts = DownloadOrchestratorOptions.From(config);
Assert.Equal(TimeSpan.FromSeconds(30), opts.DownloadTimeout);
}

[Fact]
public void From_RetryCountNegative_ClampedToZero()
{
var config = new GeneralUpdate.Core.Configuration.GlobalConfigInfo
{
RetryCount = -5
};
var opts = DownloadOrchestratorOptions.From(config);
Assert.Equal(0, opts.RetryCount);
}
}
118 changes: 118 additions & 0 deletions tests/CoreTest/HashAlgorithms/Sha256HashAlgorithmTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
using GeneralUpdate.Core.HashAlgorithms;

namespace CoreTest.HashAlgorithms;

public class Sha256HashAlgorithmTests
{
private readonly Sha256HashAlgorithm _algorithm = new();

[Fact]
public void ComputeHash_FileNotFound_ThrowsFileNotFoundException()
{
Assert.Throws<FileNotFoundException>(() =>
_algorithm.ComputeHash(Path.Combine(Path.GetTempPath(), $"no_file_{Guid.NewGuid():N}.dat")));
}

[Fact]
public void ComputeHash_EmptyFile_ReturnsKnownHash()
{
var emptyFile = Path.GetTempFileName();
try
{
var hash = _algorithm.ComputeHash(emptyFile);
Assert.NotNull(hash);
Assert.Equal(64, hash.Length);
}
finally { if (File.Exists(emptyFile)) File.Delete(emptyFile); }
}

[Fact]
public void ComputeHash_SameContentFile_SameHash()
{
var file1 = Path.GetTempFileName();
var file2 = Path.GetTempFileName();
try
{
File.WriteAllText(file1, "identical content");
File.WriteAllText(file2, "identical content");
var h1 = _algorithm.ComputeHash(file1);
var h2 = _algorithm.ComputeHash(file2);
Assert.Equal(h1, h2);
}
finally
{
if (File.Exists(file1)) File.Delete(file1);
if (File.Exists(file2)) File.Delete(file2);
}
}

[Fact]
public void ComputeHash_DifferentContent_DifferentHash()
{
var file1 = Path.GetTempFileName();
var file2 = Path.GetTempFileName();
try
{
File.WriteAllText(file1, "content A");
File.WriteAllText(file2, "content B");
var h1 = _algorithm.ComputeHash(file1);
var h2 = _algorithm.ComputeHash(file2);
Assert.NotEqual(h1, h2);
}
finally
{
if (File.Exists(file1)) File.Delete(file1);
if (File.Exists(file2)) File.Delete(file2);
}
}

[Fact]
public void ComputeHashBytes_ValidFile_Returns32Bytes()
{
var file = Path.GetTempFileName();
try
{
File.WriteAllText(file, "test data");
var bytes = _algorithm.ComputeHashBytes(file);
Assert.NotNull(bytes);
Assert.Equal(32, bytes.Length);
}
finally { if (File.Exists(file)) File.Delete(file); }
}

[Fact]
public void ComputeHashBytes_FileNotFound_ThrowsFileNotFoundException()
{
Assert.Throws<FileNotFoundException>(() =>
_algorithm.ComputeHashBytes(Path.Combine(Path.GetTempPath(), $"no_file_{Guid.NewGuid():N}.dat")));
}

[Fact]
public void ComputeHash_ConsistentAcrossCalls()
{
var file = Path.GetTempFileName();
try
{
File.WriteAllText(file, "stable content");
var h1 = _algorithm.ComputeHash(file);
var h2 = _algorithm.ComputeHash(file);
Assert.Equal(h1, h2);
}
finally { if (File.Exists(file)) File.Delete(file); }
}

[Fact]
public void ComputeHash_LargeFile_ComputesCorrectly()
{
var file = Path.GetTempFileName();
try
{
var data = new byte[1024 * 1024]; // 1MB
new Random(42).NextBytes(data);
File.WriteAllBytes(file, data);
var hash = _algorithm.ComputeHash(file);
Assert.Equal(64, hash.Length);
}
finally { if (File.Exists(file)) File.Delete(file); }
}
}
Loading
Loading