164 lines
6.8 KiB
C#
164 lines
6.8 KiB
C#
using System.Globalization;
|
|
using System.Text.Json;
|
|
using MBN_STOCK_WEBVIEW.LegacyApplication;
|
|
using MMoneyCoderSharp.Data;
|
|
|
|
namespace MBN_STOCK_WEBVIEW.LegacyBridge.Tests;
|
|
|
|
public sealed class LegacyThemeBridgeTests
|
|
{
|
|
[Fact]
|
|
public async Task ProjectionPreservesFiveThousandRowsAndExplicitTruncationWarningState()
|
|
{
|
|
var workflow = new LegacyThemeWorkflow(new TruncatedThemeService());
|
|
var theme = await workflow.SearchAsync(
|
|
workflow.CreateInitial(),
|
|
string.Empty,
|
|
ThemeSession.PreMarket);
|
|
var snapshot = new LegacyOperatorSnapshot(
|
|
1,
|
|
string.Empty,
|
|
[],
|
|
null,
|
|
[],
|
|
[],
|
|
null,
|
|
"테마 검색 결과가 최대 5,000건으로 제한되었습니다.",
|
|
LegacyOperatorStatusKind.Warning,
|
|
Theme: theme);
|
|
|
|
using var document = JsonDocument.Parse(
|
|
LegacyBridgeProtocol.SerializeState(snapshot));
|
|
var payload = document.RootElement.GetProperty("payload");
|
|
var projected = payload.GetProperty("theme");
|
|
|
|
Assert.True(projected.GetProperty("searchIsTruncated").GetBoolean());
|
|
Assert.Equal(5_000, projected.GetProperty("searchResults").GetArrayLength());
|
|
Assert.Equal("warning", payload.GetProperty("statusKind").GetString());
|
|
Assert.Contains("5,000", payload.GetProperty("statusMessage").GetString());
|
|
Assert.DoesNotContain("themeCode", projected.GetRawText(), StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ProjectionPreservesRawLegacyTitlesExplicitMarketAndEmptyPreviewGuards()
|
|
{
|
|
var workflow = new LegacyThemeWorkflow(new CompatibilityThemeService());
|
|
var search = await workflow.SearchAsync(
|
|
workflow.CreateInitial(),
|
|
string.Empty,
|
|
ThemeSession.PreMarket);
|
|
var theme = await workflow.SelectAsync(search, "theme-result-005");
|
|
var snapshot = new LegacyOperatorSnapshot(
|
|
1,
|
|
string.Empty,
|
|
[],
|
|
null,
|
|
[],
|
|
[],
|
|
null,
|
|
"Theme compatibility",
|
|
LegacyOperatorStatusKind.Information,
|
|
Theme: theme);
|
|
|
|
using var document = JsonDocument.Parse(
|
|
LegacyBridgeProtocol.SerializeState(snapshot));
|
|
var projected = document.RootElement.GetProperty("payload").GetProperty("theme");
|
|
var rows = projected.GetProperty("searchResults").EnumerateArray().ToArray();
|
|
|
|
Assert.Equal(5, rows.Length);
|
|
Assert.Equal(" Legacy ", rows[0].GetProperty("displayTitle").GetString());
|
|
Assert.Equal("Same", rows[1].GetProperty("displayTitle").GetString());
|
|
Assert.Equal("Same", rows[2].GetProperty("displayTitle").GetString());
|
|
Assert.Equal("Desk(NXT)", rows[3].GetProperty("displayTitle").GetString());
|
|
Assert.Equal("krx", rows[3].GetProperty("market").GetString());
|
|
Assert.Equal(" Empty NXT(NXT)", rows[4].GetProperty("displayTitle").GetString());
|
|
Assert.Equal("nxt", rows[4].GetProperty("market").GetString());
|
|
Assert.Equal(0, projected.GetProperty("previewItems").GetArrayLength());
|
|
Assert.All(projected.GetProperty("actions").EnumerateArray(), action =>
|
|
{
|
|
Assert.False(action.GetProperty("isAvailable").GetBoolean());
|
|
Assert.Equal(
|
|
"theme-preview-is-empty",
|
|
action.GetProperty("unavailableReason").GetString());
|
|
});
|
|
Assert.DoesNotContain("themeCode", projected.GetRawText(), StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
private sealed class TruncatedThemeService : IThemeSelectionService
|
|
{
|
|
public Task<ThemeSearchResult> SearchAsync(
|
|
string query,
|
|
ThemeSession nxtSession,
|
|
int maximumResults = LegacyThemeSelectionService.DefaultMaximumResults,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
Assert.Equal(LegacyThemeWorkflow.MaximumSearchResults, maximumResults);
|
|
var rows = Enumerable.Range(0, maximumResults)
|
|
.Select(index => new ThemeSelectorItem(
|
|
new ThemeSelectionIdentity(
|
|
ThemeMarket.Krx,
|
|
ThemeSession.NotApplicable,
|
|
index.ToString("D8", CultureInfo.InvariantCulture),
|
|
$"Theme {index}"),
|
|
DataSourceKind.Oracle))
|
|
.ToArray();
|
|
return Task.FromResult(new ThemeSearchResult(
|
|
query,
|
|
nxtSession,
|
|
DateTimeOffset.UtcNow,
|
|
rows,
|
|
IsTruncated: true));
|
|
}
|
|
|
|
public Task<ThemePreviewResult> PreviewAsync(
|
|
ThemeSelectionIdentity identity,
|
|
int maximumItems = LegacyThemeSelectionService.DefaultMaximumPreviewItems,
|
|
CancellationToken cancellationToken = default) =>
|
|
Task.FromResult(new ThemePreviewResult(
|
|
identity,
|
|
DateTimeOffset.UtcNow,
|
|
[],
|
|
IsTruncated: false));
|
|
}
|
|
|
|
private sealed class CompatibilityThemeService : IThemeSelectionService
|
|
{
|
|
public Task<ThemeSearchResult> SearchAsync(
|
|
string query,
|
|
ThemeSession nxtSession,
|
|
int maximumResults = LegacyThemeSelectionService.DefaultMaximumResults,
|
|
CancellationToken cancellationToken = default) =>
|
|
Task.FromResult(new ThemeSearchResult(
|
|
query,
|
|
nxtSession,
|
|
DateTimeOffset.UtcNow,
|
|
[
|
|
Item(ThemeMarket.Krx, ThemeSession.NotApplicable, "00000001", " Legacy "),
|
|
Item(ThemeMarket.Krx, ThemeSession.NotApplicable, "00000002", "Same"),
|
|
Item(ThemeMarket.Krx, ThemeSession.NotApplicable, "00000003", "Same"),
|
|
Item(ThemeMarket.Krx, ThemeSession.NotApplicable, "00000004", "Desk(NXT)"),
|
|
Item(ThemeMarket.Nxt, nxtSession, "00000005", " Empty NXT")
|
|
],
|
|
IsTruncated: false));
|
|
|
|
public Task<ThemePreviewResult> PreviewAsync(
|
|
ThemeSelectionIdentity identity,
|
|
int maximumItems = LegacyThemeSelectionService.DefaultMaximumPreviewItems,
|
|
CancellationToken cancellationToken = default) =>
|
|
Task.FromResult(new ThemePreviewResult(
|
|
identity,
|
|
DateTimeOffset.UtcNow,
|
|
[],
|
|
IsTruncated: false));
|
|
|
|
private static ThemeSelectorItem Item(
|
|
ThemeMarket market,
|
|
ThemeSession session,
|
|
string code,
|
|
string title) =>
|
|
new(
|
|
new ThemeSelectionIdentity(market, session, code, title),
|
|
market == ThemeMarket.Krx ? DataSourceKind.Oracle : DataSourceKind.MariaDb);
|
|
}
|
|
}
|