using System.Linq;
using Dpz.Core.Entity.Base.Image;
using Dpz.Core.Public.ViewModel.Request;
using Dpz.Core.Service.Mediator.Features.Media.Contracts;
namespace Dpz.Core.ServiceTest;
[TestFixture]
public class ImageMetadataBackfillHelperTest
{
[Test]
public void CreateCandidate_WhenAllUrlsHaveMetadata_ReturnsNull()
{
var candidate = ImageMetadataBackfillHelper.CreateCandidate(
"id",
["https://cdn.example.com/a.jpg"],
[
new ImageMetadata
{
Url = "https://cdn.example.com/a.jpg",
Width = 100,
Height = 100,
},
]
);
Assert.That(candidate, Is.Null);
}
[Test]
public void CreateCandidate_WhenForced_ReturnsCandidateEvenIfAllUrlsHaveMetadata()
{
var candidate = ImageMetadataBackfillHelper.CreateCandidate(
"id",
["https://cdn.example.com/a.jpg"],
[
new ImageMetadata
{
Url = "https://cdn.example.com/a.jpg",
Width = 100,
Height = 100,
},
],
forceCreate: true
);
Assert.That(candidate, Is.Not.Null);
Assert.That(candidate.Urls, Is.EqualTo(["https://cdn.example.com/a.jpg"]));
}
[Test]
public void CreateCandidate_WhenAnyUrlMissesMetadata_ReturnsAllTargetUrls()
{
var candidate = ImageMetadataBackfillHelper.CreateCandidate(
"id",
["https://cdn.example.com/a.jpg", "https://cdn.example.com/b.jpg"],
[
new ImageMetadata
{
Url = "https://cdn.example.com/a.jpg",
Width = 100,
Height = 100,
},
]
);
Assert.That(candidate, Is.Not.Null);
Assert.That(
candidate.Urls,
Is.EqualTo(["https://cdn.example.com/a.jpg", "https://cdn.example.com/b.jpg"])
);
}
[Test]
public void FilterObjectStorageUrls_WhenHostMissing_ReturnsEmptyList()
{
var urls = ImageMetadataBackfillHelper.FilterObjectStorageUrls(
["https://cdn.example.com/a.jpg"],
""
);
Assert.That(urls, Is.Empty);
}
[Test]
public void FilterObjectStorageUrls_OnlyReturnsUrlsUnderConfiguredHost()
{
var urls = ImageMetadataBackfillHelper.FilterObjectStorageUrls(
[
"https://cdn.example.com/a.jpg",
"https://cdn.example.com.evil/a.jpg",
"https://other.example.com/a.jpg",
],
"https://cdn.example.com/"
);
Assert.That(urls, Is.EqualTo(new[] { "https://cdn.example.com/a.jpg" }));
}
[Test]
public void MergeByUrl_PreservesTargetOrderAndCollectedMetadataWins()
{
var result = ImageMetadataBackfillHelper.MergeByUrl(
["https://cdn.example.com/b.jpg", "https://cdn.example.com/a.jpg"],
[
new ImageMetadata
{
Url = "https://cdn.example.com/a.jpg",
Width = 100,
Height = 100,
},
new ImageMetadata
{
Url = "https://cdn.example.com/b.jpg",
Width = 200,
Height = 200,
},
],
[
new ImageMetadata
{
Url = "https://cdn.example.com/a.jpg",
Width = 300,
Height = 300,
},
]
);
Assert.That(
result.Select(x => x.Url),
Is.EqualTo(new[] { "https://cdn.example.com/b.jpg", "https://cdn.example.com/a.jpg" })
);
Assert.That(result[1].Width, Is.EqualTo(300));
}
[Test]
public void EditMumbleRequest_ImagesDefaultIsNullAndEmptyListMeansClear()
{
var keepExisting = new EditMumbleRequest { Id = "id", Markdown = "content" };
var clear = new EditMumbleRequest
{
Id = "id",
Markdown = "content",
Images = [],
};
Assert.That(keepExisting.Images, Is.Null);
Assert.That(clear.Images, Is.Empty);
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
代码说明
这是一个 C# 单元测试类,用于测试 ImageMetadataBackfillHelper 工具类的功能。该工具类主要用于处理图片元数据的回填(backfill)操作。
测试类概述
类名: ImageMetadataBackfillHelperTest
测试框架: NUnit(通过 [TestFixture] 和 [Test] 特性标识)
各测试方法说明
1. CreateCandidate_WhenAllUrlsHaveMetadata_ReturnsNull
- 测试场景: 当所有 URL 都已有元数据时
- 预期结果: 返回 null(无需回填)
- 验证逻辑: 传入的 URL 已经存在对应的元数据,因此不需要创建候选项
2. CreateCandidate_WhenForced_ReturnsCandidateEvenIfAllUrlsHaveMetadata
- 测试场景: 强制创建模式下,即使所有 URL 已有元数据
- 预期结果: 仍然返回候选项(
forceCreate: true参数的作用) - 验证逻辑: 候选项不为 null,且包含指定的 URL
3. CreateCandidate_WhenAnyUrlMissesMetadata_ReturnsAllTargetUrls
- 测试场景: 当任意 URL 缺少元数据时
- 预期结果: 返回包含所有目标 URL 的候选项
- 验证逻辑: 两个 URL 中只有一个有元数据,应返回包含两个 URL 的候选项
4. FilterObjectStorageUrls_WhenHostMissing_ReturnsEmptyList
- 测试场景: 对象存储主机地址为空时
- 预期结果: 返回空列表
- 验证逻辑: 没有配置主机地址,无法过滤,返回空
5. FilterObjectStorageUrls_OnlyReturnsUrlsUnderConfiguredHost
- 测试场景: 只返回匹配配置主机的 URL
- 预期结果: 过滤掉不匹配的 URL(防止恶意 URL 或其他域名)
- 验证逻辑: 三个 URL 中只有严格匹配
cdn.example.com的一个被保留
6. MergeByUrl_PreservesTargetOrderAndCollectedMetadataWins
- 测试场景: 合并元数据时的优先级和顺序处理
- 预期结果:
- 保持目标 URL 的原始顺序
- 新收集的元数据优先于旧数据(覆盖策略)
- 验证逻辑: URL 按 b、a 顺序排列,且 a 的宽度被更新为 300(新值)
7. EditMumbleRequest_ImagesDefaultIsNullAndEmptyListMeansClear
- 测试场景: 测试
EditMumbleRequest的 Images 属性语义 - 预期结果:
null表示保持现有图片- 空列表
[]表示清空图片
- 验证逻辑: 这是一个重要的 API 设计约定测试
核心业务逻辑
该测试类验证的功能围绕:
- 智能回填: 只为缺失元数据的图片创建回填任务
- URL 过滤: 安全地只处理指定域名下的图片
- 元数据合并: 正确合并旧数据和新收集的数据
- API 语义: 确保请求对象的字段语义明确(null vs 空集合)
这是一个典型的数据处理工具类测试,关注边界条件和业务规则的正确性。
AI 正在分析代码…
评论加载中...