Files
douyin/tests/dy.net.Tests/QuartzTaskContextTests.cs

153 lines
5.5 KiB
C#

using dy.net.job;
using dy.net.model.dto;
using dy.net.model.entity;
using dy.net.model.response;
using dy.net.service;
using Quartz;
namespace dy.net.Tests;
public class QuartzTaskContextTests
{
[Fact]
public void EmptyScheduledJobData_DoesNotRequireManualTaskKeys()
{
var context = DouyinBasicSyncJob.ResolveTaskContext(new JobDataMap());
Assert.Null(context.TaskId);
Assert.Equal(VideoTaskTrigger.Scheduled, context.Trigger);
}
[Fact]
public void ManualJobData_ReusesProvidedTaskId()
{
var data = new JobDataMap
{
["video-task-id"] = "task-id",
["video-task-trigger"] = "manual"
};
var context = DouyinBasicSyncJob.ResolveTaskContext(data);
Assert.Equal("task-id", context.TaskId);
Assert.Equal(VideoTaskTrigger.Manual, context.Trigger);
}
[Fact]
public void LocalRecord_IsReplacedWhenCurrentStorageIsWebDav()
{
var local = new dy.net.model.entity.DouyinVideo { StorageType = StorageType.Local };
var remote = new dy.net.model.entity.DouyinVideo { StorageType = StorageType.WebDav };
Assert.True(DouyinBasicSyncJob.ShouldReplaceOldStorageRecord(local, StorageType.WebDav));
Assert.False(DouyinBasicSyncJob.ShouldReplaceOldStorageRecord(remote, StorageType.WebDav));
Assert.False(DouyinBasicSyncJob.ShouldReplaceOldStorageRecord(remote, StorageType.Local));
Assert.False(DouyinBasicSyncJob.ShouldReplaceOldStorageRecord(null, StorageType.WebDav));
}
[Theory]
[InlineData(true, null, null)]
[InlineData(false, true, null)]
[InlineData(false, false, true)]
[InlineData(false, false, false)]
public void BestMatchedVideoUrl_MissingMediaData_ReturnsNull(
bool nullAweme,
bool? nullVideo,
bool? nullBitRates)
{
Aweme aweme = null;
if (!nullAweme)
{
aweme = new Aweme();
if (nullVideo != true)
aweme.Video = new Video { BitRate = nullBitRates == true ? null : new List<VideoBitRate>() };
}
var selected = DouyinBasicSyncJob.GetBestMatchedVideoUrl(aweme, new AppConfig());
Assert.Null(selected);
}
[Fact]
public void BestMatchedVideoUrl_IgnoresMalformedBitRatesAndEmptyUrls()
{
var aweme = new Aweme
{
Video = new Video
{
BitRate = new List<VideoBitRate>
{
null,
new() { PlayAddr = null },
new() { PlayAddr = new PlayAddr { UrlList = null } },
new() { PlayAddr = new PlayAddr { UrlList = new List<string> { "", " " } } }
}
}
};
Assert.Null(DouyinBasicSyncJob.GetBestMatchedVideoUrl(aweme, new AppConfig()));
Assert.Empty(DouyinBasicSyncJob.GetMediaCandidates(aweme, null));
}
[Fact]
public void BestMatchedVideoUrl_PrefersH265AndFallsBackToH264()
{
var h264Low = BitRate("https://media.test/h264-low", isH265: 0, value: 100);
var h264High = BitRate("https://media.test/h264-high", isH265: 0, value: 300);
var h265 = BitRate("https://media.test/h265", isH265: 1, value: 200);
var aweme = new Aweme { Video = new Video { BitRate = new List<VideoBitRate> { h264Low, h265, h264High } } };
Assert.Same(h265, DouyinBasicSyncJob.GetBestMatchedVideoUrl(aweme, new AppConfig { VideoEncoder = 265 }));
Assert.Same(h264High, DouyinBasicSyncJob.GetBestMatchedVideoUrl(aweme, new AppConfig { VideoEncoder = 264 }));
aweme.Video.BitRate = new List<VideoBitRate> { h264Low, h264High };
Assert.Same(h264High, DouyinBasicSyncJob.GetBestMatchedVideoUrl(aweme, new AppConfig { VideoEncoder = 265 }));
}
[Fact]
public void MediaCandidates_UsesSelectedFirstAndRemovesEmptyAndDuplicateUrls()
{
var selected = BitRate("https://media.test/preferred", isH265: 1, value: 200);
selected.PlayAddr.UrlList.Add("https://media.test/shared");
var fallback = BitRate("https://media.test/shared", isH265: 0, value: 100);
fallback.PlayAddr.UrlList.Add("");
fallback.PlayAddr.UrlList.Add("https://media.test/fallback");
var aweme = new Aweme
{
Video = new Video { BitRate = new List<VideoBitRate> { null, fallback, selected } }
};
var candidates = DouyinBasicSyncJob.GetMediaCandidates(aweme, selected);
Assert.Equal(new[]
{
"https://media.test/preferred",
"https://media.test/shared",
"https://media.test/fallback"
}, candidates);
}
[Theory]
[InlineData(VideoTypeEnum.dy_favorite, true)]
[InlineData(VideoTypeEnum.dy_collects, true)]
[InlineData(VideoTypeEnum.dy_follows, true)]
[InlineData(VideoTypeEnum.dy_custom_collect, true)]
[InlineData(VideoTypeEnum.dy_mix, true)]
[InlineData(VideoTypeEnum.dy_series, true)]
[InlineData(VideoTypeEnum.ImageVideo, false)]
[InlineData(VideoTypeEnum.dy_followuser, false)]
[InlineData(VideoTypeEnum.dy_followuser_once, false)]
[InlineData(VideoTypeEnum.dy_live_monitor, false)]
public void ManualVideoSyncType_OnlyAllowsDownloadJobs(VideoTypeEnum type, bool expected)
{
Assert.Equal(expected, DouyinQuartzJobService.IsVideoSyncType(type));
}
private static VideoBitRate BitRate(string url, int isH265, int value) => new()
{
IsH265 = isH265,
BitRateValue = value,
PlayAddr = new PlayAddr { UrlList = new List<string> { url } }
};
}