using BuildFlow.Infrastructure.Extractors;
using BuildFlow.Shared.Domain.Exceptions;
using Microsoft.Extensions.Logging.Abstractions;
using Xunit;
namespace BuildFlow.Rag.Tests;
///
/// JSON 文档提取器测试。确保结构化 JSON 会规范化为可按标题和路径检索的 Markdown 文本。
///
public class JsonExtractorTests
{
[Fact]
public void DocumentExtractorFactoryShouldRouteJsonToJsonExtractor()
{
var factory = new DocumentExtractorFactory(
new MarkdownExtractor(),
new PdfExtractor(),
new JsonExtractor(),
new DocxExtractor(),
new PptxExtractor(),
new HtmlExtractor(),
new TextExtractor(),
NullLogger.Instance);
Assert.IsType(factory.GetExtractor("settings.json"));
Assert.DoesNotContain("json", new TextExtractor().SupportedExtensions);
}
[Fact]
public async Task ExtractAsyncShouldNormalizeJsonIntoMarkdownAndPathValues()
{
var filePath = Path.Combine(Path.GetTempPath(), $"settings-{Guid.NewGuid():N}.json");
await File.WriteAllTextAsync(
filePath,
"""
{
"service": {
"name": "BuildFlow",
"enabled": true
},
"ports": [5999, 8080]
}
""");
try
{
var result = await new JsonExtractor().ExtractAsync(filePath);
Assert.StartsWith("# settings-", result.Content);
Assert.Contains("## JSON 路径值", result.Content);
Assert.Contains("- $.service.name: BuildFlow", result.Content);
Assert.Contains("- $.ports[0]: 5999", result.Content);
Assert.Contains("```json", result.Content);
Assert.Contains("\"name\": \"BuildFlow\"", result.Content);
Assert.Contains("\"format\":\"json\"", result.MetadataJson);
}
finally
{
File.Delete(filePath);
}
}
[Fact]
public async Task ExtractAsyncShouldRejectInvalidJson()
{
var filePath = Path.Combine(Path.GetTempPath(), $"invalid-{Guid.NewGuid():N}.json");
await File.WriteAllTextAsync(filePath, "{ invalid json");
try
{
var ex = await Assert.ThrowsAsync(() =>
new JsonExtractor().ExtractAsync(filePath));
Assert.Contains("JSON 文件格式无效", ex.Message);
}
finally
{
File.Delete(filePath);
}
}
}