135 lines
5.3 KiB
C#
135 lines
5.3 KiB
C#
using dy.net.model.dto;
|
||
using dy.net.model.entity;
|
||
using dy.net.model.response;
|
||
using dy.net.storage;
|
||
using dy.net.utils;
|
||
|
||
namespace dy.net.Tests;
|
||
|
||
public class StorageMigrationPathPolicyTests
|
||
{
|
||
private readonly DouyinCookie _cookie = new()
|
||
{
|
||
Id = "cookie",
|
||
WebDavCollectPath = "/账号/收藏",
|
||
WebDavFavoritePath = "/账号/喜欢",
|
||
WebDavFollowPath = "/账号/关注",
|
||
WebDavMixPath = "/账号/合集",
|
||
WebDavSeriesPath = "/账号/短剧"
|
||
};
|
||
|
||
[Theory]
|
||
[InlineData(VideoTypeEnum.dy_collects, "/账号/收藏")]
|
||
[InlineData(VideoTypeEnum.dy_favorite, "/账号/喜欢")]
|
||
public void Build_CollectionTypes_UseAuthorTitleAndStableAwemeSuffix(VideoTypeEnum type, string root)
|
||
{
|
||
var plan = StorageMigrationPathPolicy.Build(Video(type), _cookie, null, null, new AppConfig());
|
||
|
||
Assert.StartsWith(root + "/测试博主/Unicode标题123_aweme-1/", plan.VideoPath);
|
||
Assert.EndsWith("/aweme-1.mp4", plan.VideoPath);
|
||
Assert.EndsWith("/aweme-1-poster.jpg", plan.CoverPath);
|
||
}
|
||
|
||
[Fact]
|
||
public void Build_CustomCollection_UsesCurrentCategoryFolderRule()
|
||
{
|
||
var video = Video(VideoTypeEnum.dy_custom_collect);
|
||
var category = new DouyinCollectCate { SaveFolder = "专题 / 一", Name = "fallback" };
|
||
|
||
var plan = StorageMigrationPathPolicy.Build(video, _cookie, category, null, new AppConfig());
|
||
|
||
Assert.StartsWith("/账号/收藏/专题一/Unicode标题123_aweme-1/", plan.VideoPath);
|
||
}
|
||
|
||
[Theory]
|
||
[InlineData(VideoTypeEnum.dy_mix, "/账号/合集")]
|
||
[InlineData(VideoTypeEnum.dy_series, "/账号/短剧")]
|
||
public void Build_SeriesTypes_PreserveExistingEpisodeNumber(VideoTypeEnum type, string root)
|
||
{
|
||
var video = Video(type);
|
||
video.VideoSavePath = "/old/S01E07.mp4";
|
||
var category = new DouyinCollectCate { SaveFolder = "第一季", Name = "剧名" };
|
||
|
||
var plan = StorageMigrationPathPolicy.Build(video, _cookie, category, null, new AppConfig(), 2);
|
||
|
||
Assert.Equal(root + "/第一季/S01E07.mp4", plan.VideoPath);
|
||
Assert.Equal(root + "/第一季/poster.jpg", plan.CoverPath);
|
||
}
|
||
|
||
[Fact]
|
||
public void Build_Followed_UsesCustomFolderAndCurrentTitleTemplate()
|
||
{
|
||
var video = Video(VideoTypeEnum.dy_follows);
|
||
var followed = new DouyinFollowed { SavePath = "自定义博主目录" };
|
||
var config = new AppConfig { FullFollowedTitleTemplate = "{ReleaseTime}-{Author}-{Id}" };
|
||
|
||
var plan = StorageMigrationPathPolicy.Build(video, _cookie, null, followed, config);
|
||
|
||
Assert.Contains("/账号/关注/自定义博主目录/Unicode标题123/", plan.VideoPath);
|
||
Assert.EndsWith("/20260728-测试博主-aweme-1.mp4", plan.VideoPath);
|
||
}
|
||
|
||
[Theory]
|
||
[InlineData(VideoTypeEnum.dy_collects)]
|
||
[InlineData(VideoTypeEnum.dy_favorite)]
|
||
[InlineData(VideoTypeEnum.dy_follows)]
|
||
[InlineData(VideoTypeEnum.dy_custom_collect)]
|
||
[InlineData(VideoTypeEnum.dy_mix)]
|
||
[InlineData(VideoTypeEnum.dy_series)]
|
||
public void Build_CurrentSyncAndMigrationUseTheSameRemotePolicy(VideoTypeEnum type)
|
||
{
|
||
var timestamp = new DateTimeOffset(2026, 7, 28, 0, 0, 0, TimeSpan.Zero).ToUnixTimeSeconds();
|
||
var aweme = new Aweme
|
||
{
|
||
AwemeId = "aweme-1",
|
||
Desc = "Unicode 标题 / 123",
|
||
CreateTime = timestamp,
|
||
Author = new Author { Uid = "author-1", Nickname = "测试 博主" },
|
||
MixInfo = new MixInfo { Statis = new MixStatis { CurrentEpisode = 7 } },
|
||
Video = new Video
|
||
{
|
||
BitRate = new List<VideoBitRate>
|
||
{
|
||
new() { Format = "mp4", PlayAddr = new PlayAddr { FileHash = "hash", Width = 1080, Height = 1920 } }
|
||
}
|
||
}
|
||
};
|
||
var category = new DouyinCollectCate { SaveFolder = "第一季", Name = "剧名", CateType = type };
|
||
var followed = new DouyinFollowed { SavePath = "自定义博主目录" };
|
||
var config = new AppConfig { FullFollowedTitleTemplate = "{ReleaseTime}-{Author}-{Id}" };
|
||
|
||
var currentSync = StorageMigrationPathPolicy.Build(aweme, type, _cookie, category, followed, config);
|
||
var persisted = new DouyinVideo
|
||
{
|
||
Id = "record-1",
|
||
AwemeId = aweme.AwemeId,
|
||
ViedoType = type,
|
||
VideoTitle = aweme.Desc,
|
||
VideoSavePath = currentSync.VideoPath,
|
||
Author = aweme.Author.Nickname,
|
||
AuthorId = aweme.Author.Uid,
|
||
CreateTime = DateTimeUtil.Convert10BitTimestamp(timestamp),
|
||
FileHash = "hash",
|
||
Resolution = "1080×1920"
|
||
};
|
||
|
||
var migration = StorageMigrationPathPolicy.Build(persisted, _cookie, category, followed, config, 7);
|
||
|
||
Assert.Equal(currentSync.VideoPath, migration.VideoPath);
|
||
Assert.Equal(currentSync.CoverPath, migration.CoverPath);
|
||
}
|
||
|
||
private static DouyinVideo Video(VideoTypeEnum type) => new()
|
||
{
|
||
Id = "record-1",
|
||
AwemeId = "aweme-1",
|
||
ViedoType = type,
|
||
VideoTitle = "Unicode 标题 / 123",
|
||
VideoSavePath = "/old/video.mp4",
|
||
Author = "测试 博主",
|
||
AuthorId = "author-1",
|
||
CreateTime = new DateTime(2026, 7, 28),
|
||
Resolution = "1080×1920"
|
||
};
|
||
}
|