using System.Reflection; using OF_DL.Models.Config; using OF_DL.Models.Downloads; using OF_DL.Services; namespace OF_DL.Tests.Services; public class DownloadServiceTests { [Fact] public async Task ProcessMediaDownload_RenamesServerFileAndUpdatesDb_WhenNotDownloadedButServerFileExists() { using TempFolder temp = new(); string folder = NormalizeFolder(Path.Combine(temp.Path, "creator")); string path = "/Posts/Free"; string url = "https://example.com/image.jpg"; string serverFilename = "server"; string resolvedFilename = "custom"; string serverFilePath = $"{folder}{path}/{serverFilename}.jpg"; Directory.CreateDirectory(Path.GetDirectoryName(serverFilePath) ?? throw new InvalidOperationException()); await File.WriteAllTextAsync(serverFilePath, "abc"); MediaTrackingDbService dbService = new() { CheckDownloadedResult = false }; FakeConfigService configService = new(new Config { ShowScrapeSize = false }); DownloadService service = CreateService(configService, dbService); ProgressRecorder progress = new(); bool isNew = await service.ProcessMediaDownload(folder, 1, "Posts", url, path, serverFilename, resolvedFilename, ".jpg", progress); string renamedPath = $"{folder}{path}/{resolvedFilename}.jpg"; Assert.False(isNew); Assert.False(File.Exists(serverFilePath)); Assert.True(File.Exists(renamedPath)); Assert.NotNull(dbService.LastUpdateMedia); Assert.Equal($"{folder}{path}", dbService.LastUpdateMedia.Value.directory); Assert.Equal("custom.jpg", dbService.LastUpdateMedia.Value.filename); Assert.Equal(new FileInfo(renamedPath).Length, dbService.LastUpdateMedia.Value.size); Assert.Equal(1, progress.Total); } [Fact] public async Task ProcessMediaDownload_RenamesExistingFile_WhenDownloadedAndCustomFormatEnabled() { using TempFolder temp = new(); string folder = NormalizeFolder(Path.Combine(temp.Path, "creator")); string path = "/Posts/Free"; string url = "https://example.com/image.jpg"; string serverFilename = "server"; string resolvedFilename = "custom"; string serverFilePath = $"{folder}{path}/{serverFilename}.jpg"; Directory.CreateDirectory(Path.GetDirectoryName(serverFilePath) ?? throw new InvalidOperationException()); await File.WriteAllTextAsync(serverFilePath, "abc"); MediaTrackingDbService dbService = new() { CheckDownloadedResult = true, StoredFileSize = 123 }; FakeConfigService configService = new(new Config { ShowScrapeSize = false, RenameExistingFilesWhenCustomFormatIsSelected = true }); DownloadService service = CreateService(configService, dbService); ProgressRecorder progress = new(); bool isNew = await service.ProcessMediaDownload(folder, 1, "Posts", url, path, serverFilename, resolvedFilename, ".jpg", progress); string renamedPath = $"{folder}{path}/{resolvedFilename}.jpg"; Assert.False(isNew); Assert.False(File.Exists(serverFilePath)); Assert.True(File.Exists(renamedPath)); Assert.NotNull(dbService.LastUpdateMedia); Assert.Equal("custom.jpg", dbService.LastUpdateMedia.Value.filename); Assert.Equal(123, dbService.LastUpdateMedia.Value.size); Assert.Equal(1, progress.Total); } [Fact] public async Task GetDecryptionInfo_UsesOfdlWhenCdmMissing() { StaticApiService apiService = new(); DownloadService service = CreateService(new FakeConfigService(new Config()), new MediaTrackingDbService(), apiService); (string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)? result = await service.GetDecryptionInfo( "https://example.com/file.mpd", "policy", "signature", "kvp", "1", "2", "post", true, false); Assert.NotNull(result); Assert.Equal("ofdl-key", result.Value.decryptionKey); Assert.Equal(apiService.LastModifiedToReturn, result.Value.lastModified); Assert.True(apiService.OfdlCalled); Assert.False(apiService.CdmCalled); } [Fact] public async Task GetDecryptionInfo_UsesCdmWhenAvailable() { StaticApiService apiService = new(); DownloadService service = CreateService(new FakeConfigService(new Config()), new MediaTrackingDbService(), apiService); (string decryptionKey, DateTime lastModified, double? mpdDurationSeconds)? result = await service.GetDecryptionInfo( "https://example.com/file.mpd", "policy", "signature", "kvp", "1", "2", "post", false, false); Assert.NotNull(result); Assert.Equal("cdm-key", result.Value.decryptionKey); Assert.Equal(apiService.LastModifiedToReturn, result.Value.lastModified); Assert.True(apiService.CdmCalled); Assert.False(apiService.OfdlCalled); } [Fact] public async Task FinalizeDrmDownload_DoesNotDeleteFile_WhenCustomPathMatchesTempPath() { using TempFolder temp = new(); string folder = NormalizeFolder(Path.Combine(temp.Path, "creator")); string path = "/Posts/Free"; string filename = "video"; string customFileName = "video_source"; string tempFilename = $"{folder}{path}/{filename}_source.mp4"; Directory.CreateDirectory(Path.GetDirectoryName(tempFilename) ?? throw new InvalidOperationException()); await File.WriteAllTextAsync(tempFilename, "abc"); MediaTrackingDbService dbService = new(); DownloadService service = CreateService(new FakeConfigService(new Config { ShowScrapeSize = false }), dbService); ProgressRecorder progress = new(); MethodInfo? finalizeMethod = typeof(DownloadService).GetMethod("FinalizeDrmDownload", BindingFlags.Instance | BindingFlags.NonPublic); Assert.NotNull(finalizeMethod); object? resultObject = finalizeMethod.Invoke(service, [ tempFilename, DateTime.UtcNow, folder, path, customFileName, filename, 1L, "Posts", progress ]); bool result = await Assert.IsType>(resultObject!); Assert.True(result); Assert.True(File.Exists(tempFilename)); Assert.NotNull(dbService.LastUpdateMedia); Assert.Equal("video_source.mp4", dbService.LastUpdateMedia.Value.filename); } [Fact] public async Task DownloadHighlights_ReturnsZeroWhenNoMedia() { StaticApiService apiService = new() { MediaToReturn = new Dictionary() }; DownloadService service = CreateService(new FakeConfigService(new Config()), new MediaTrackingDbService(), apiService); DownloadResult result = await service.DownloadHighlights("user", 1, "/tmp/creator", new HashSet(), new ProgressRecorder()); Assert.Equal(0, result.TotalCount); Assert.Equal(0, result.NewDownloads); Assert.Equal(0, result.ExistingDownloads); Assert.Equal("Highlights", result.MediaType); Assert.True(result.Success); } [Fact] public async Task DownloadHighlights_CountsExistingWhenAlreadyDownloaded() { using TempFolder temp = new(); string folder = NormalizeFolder(Path.Combine(temp.Path, "creator")); StaticApiService apiService = new() { MediaToReturn = new Dictionary { { 1, "https://example.com/one.jpg" }, { 2, "https://example.com/two.jpg" } } }; MediaTrackingDbService dbService = new() { CheckDownloadedResult = true }; FakeConfigService configService = new(new Config { ShowScrapeSize = false }); ProgressRecorder progress = new(); DownloadService service = CreateService(configService, dbService, apiService); DownloadResult result = await service.DownloadHighlights("user", 1, folder, new HashSet(), progress); Assert.Equal(2, result.TotalCount); Assert.Equal(0, result.NewDownloads); Assert.Equal(2, result.ExistingDownloads); Assert.Equal("Highlights", result.MediaType); Assert.True(result.Success); Assert.Equal(2, progress.Total); } private static DownloadService CreateService(FakeConfigService configService, MediaTrackingDbService dbService, StaticApiService? apiService = null) => new(new FakeAuthService(), configService, dbService, new FakeFileNameService(), apiService ?? new StaticApiService()); private static string NormalizeFolder(string folder) => folder.Replace("\\", "/"); }