feat: advance legacy UI behavior parity

This commit is contained in:
2026-07-18 10:18:29 +09:00
parent d7ec571343
commit 1302b1b92f
71 changed files with 11244 additions and 1153 deletions

View File

@@ -22,6 +22,8 @@ public sealed class LegacyIndustrySelectionWorkflowTests
Assert.Null(state.SelectedIndustry);
Assert.Null(state.FirstIndustry);
Assert.Null(state.SecondIndustry);
Assert.Equal(string.Empty, state.FirstText);
Assert.Equal(string.Empty, state.SecondText);
var rows = Assert.IsAssignableFrom<IList<IndustrySelection>>(state.Industries);
Assert.Throws<NotSupportedException>(() => rows.RemoveAt(0));
@@ -29,6 +31,26 @@ public sealed class LegacyIndustrySelectionWorkflowTests
Assert.Throws<NotSupportedException>(() => actions.RemoveAt(0));
}
[Fact]
public async Task LoadMarketPreservesDuplicateRowsAndSelectionUsesTheClickedIndex()
{
var workflow = new LegacyIndustrySelectionWorkflow(new QueueIndustryService(
[
new IndustrySelection(IndustryMarket.Kospi, "동명이 업종", "013"),
new IndustrySelection(IndustryMarket.Kospi, "동명이 업종", "014"),
new IndustrySelection(IndustryMarket.Kospi, "다른 업종", "013")
]));
var loaded = await workflow.LoadMarketAsync(IndustryMarket.Kospi);
var selected = workflow.SelectIndustry(1);
Assert.Equal(3, loaded.Industries.Count);
Assert.Equal(["013", "014", "013"],
loaded.Industries.Select(static row => row.IndustryCode));
Assert.Equal(1, selected.SelectedIndex);
Assert.Equal("014", selected.SelectedIndustry?.IndustryCode);
}
[Fact]
public async Task ListDoubleClickRotatesFirstIntoSecondBeforeAssigningNewFirst()
{
@@ -62,10 +84,76 @@ public sealed class LegacyIndustrySelectionWorkflowTests
var swapped = workflow.SwapIndustries();
Assert.Null(swapped.FirstIndustry);
Assert.Equal("전기전자", swapped.SecondIndustry?.IndustryName);
Assert.Equal(string.Empty, swapped.FirstText);
Assert.Equal("전기전자", swapped.SecondText);
var restored = workflow.SwapIndustries();
Assert.Equal("전기전자", restored.FirstIndustry?.IndustryName);
Assert.Null(restored.SecondIndustry);
Assert.Equal("전기전자", restored.FirstText);
Assert.Equal(string.Empty, restored.SecondText);
}
[Fact]
public async Task EditableComparisonTextRemainsCSharpAuthoritativeAndAffectsOnlyPairAction()
{
var workflow = await KospiWorkflowAsync();
workflow.SelectIndustry(0);
var first = workflow.SetComparisonText(
LegacyIndustryComparisonSlot.First,
"직접 입력 업종");
var second = workflow.SetComparisonText(
LegacyIndustryComparisonSlot.Second,
"또 다른 업종");
Assert.Null(first.FirstIndustry);
Assert.Equal("직접 입력 업종", second.FirstText);
Assert.Equal("또 다른 업종", second.SecondText);
Assert.Equal("직접 입력 업종-또 다른 업종",
workflow.MaterializePlaylistDraft("two-column").Selection.Subject);
Assert.Equal("전기전자",
workflow.MaterializePlaylistDraft("one-column").Selection.Subject);
var swapped = workflow.SwapIndustries();
Assert.Equal("또 다른 업종", swapped.FirstText);
Assert.Equal("직접 입력 업종", swapped.SecondText);
workflow.SetComparisonText(LegacyIndustryComparisonSlot.First, "수동 보존값");
var rotated = workflow.DoubleClickIndustry(2);
Assert.Equal("화학", rotated.FirstText);
Assert.Equal("수동 보존값", rotated.SecondText);
Assert.Equal("화학", rotated.FirstIndustry?.IndustryName);
Assert.Null(rotated.SecondIndustry);
}
[Fact]
public async Task EditableComparisonTextValidatesAtBridgeCompatibleBoundary()
{
var workflow = await KospiWorkflowAsync();
workflow.SelectIndustry(0);
var maximum = new string('가', LegacyIndustrySelectionWorkflow.MaximumComparisonTextLength);
Assert.Equal(maximum, workflow.SetComparisonText(
LegacyIndustryComparisonSlot.First,
maximum).FirstText);
Assert.Throws<LegacyIndustryWorkflowException>(() => workflow.SetComparisonText(
LegacyIndustryComparisonSlot.First,
maximum + "가"));
Assert.Throws<LegacyIndustryWorkflowException>(() => workflow.SetComparisonText(
LegacyIndustryComparisonSlot.First,
"업종\n이름"));
Assert.Throws<LegacyIndustryWorkflowException>(() => workflow.SetComparisonText(
LegacyIndustryComparisonSlot.First,
"업종\ud83d\ude00"));
workflow.SetComparisonText(LegacyIndustryComparisonSlot.First, "공백 아님");
workflow.SetComparisonText(LegacyIndustryComparisonSlot.Second, " ");
Assert.Throws<LegacyIndustryWorkflowException>(() =>
workflow.MaterializePlaylistDraft("two-column"));
workflow.SetComparisonText(LegacyIndustryComparisonSlot.Second, "하이-픈");
Assert.Throws<LegacyIndustryWorkflowException>(() =>
workflow.MaterializePlaylistDraft("two-column"));
}
[Fact]
@@ -86,6 +174,8 @@ public sealed class LegacyIndustrySelectionWorkflowTests
Assert.Equal("운수장비", reconciled.SelectedIndustry?.IndustryName);
Assert.Equal("운수장비", reconciled.FirstIndustry?.IndustryName);
Assert.Equal("전기전자", reconciled.SecondIndustry?.IndustryName);
Assert.Equal("운수장비", reconciled.FirstText);
Assert.Equal("전기전자", reconciled.SecondText);
var changed = await workflow.LoadMarketAsync(IndustryMarket.Kosdaq);
Assert.Equal(IndustryMarket.Kosdaq, changed.Market);
@@ -93,6 +183,8 @@ public sealed class LegacyIndustrySelectionWorkflowTests
Assert.Null(changed.SelectedIndustry);
Assert.Null(changed.FirstIndustry);
Assert.Null(changed.SecondIndustry);
Assert.Equal(string.Empty, changed.FirstText);
Assert.Equal(string.Empty, changed.SecondText);
}
[Fact]