test(socials): a real preview test — and the Cancel bug it immediately found

The two regressions that reached the creator both lived in preview XAML that no test loads: the
appearance controls painted nothing, then the bar vanished when the plate was off. Every existing
test was green through both.

This test drives the real drawer on a real MainWindow (hermetic temp DB, per the layout-pollution
rule) and reads the real preview elements:
- the bar is VISIBLE, whatever the plate switch says
- a drawer text colour reaches the glyph
- the plate carries its colour and ~50% alpha, and its 18,6 padding only when enabled
- the shadow is an actual DropShadowEffect on the glyph, and off by default
- Cancel restores the pre-edit look

It paid for itself on the first run: Cancel did NOT revert. The snapshot held the same config
object the live preview mutates, so "restore" restored the edited object. The snapshot is now the
six values, written back on cancel — entries untouched.

Also fixes the harness details that made the first attempts fail: everything runs on the app's STA
thread (window creation AND close), and the exception is rethrown with its stack so a failure is
diagnosable next time.
This commit is contained in:
2026-10-30 10:02:06 -07:00
parent 0822552830
commit e89cc3682a
2 changed files with 140 additions and 5 deletions
+18 -5
View File
@@ -149,7 +149,11 @@ public partial class MainViewModel
_socials);
// Live preview: the drawer edits the REAL config, so colour/opacity/shadow land on the
// preview immediately instead of waiting for Save. Cancel restores the snapshot below.
_socialsBeforeEdit = _socials;
// Snapshot the VALUES, not the object: the drawer edits the live config in place for the
// preview, so holding the reference would "restore" the very object that was mutated.
_appearanceBeforeEdit = _socials is null ? null : (
_socials.BarEnabled, _socials.BarTextColor, _socials.BarBackgroundEnabled,
_socials.BarBackgroundColor, _socials.BarBackgroundOpacity, _socials.BarTextShadow);
dialog.PropertyChanged += (_, e) =>
{
if (e.PropertyName is null) return;
@@ -164,9 +168,17 @@ public partial class MainViewModel
};
dialog.CancelRequested += () =>
{
_socials = _socialsBeforeEdit;
NotifySocialsChanged();
OnPropertyChanged(nameof(SocialBarVisible));
if (_socials is { } live && _appearanceBeforeEdit is { } before)
{
live.BarEnabled = before.BarEnabled;
live.BarTextColor = before.TextColor;
live.BarBackgroundEnabled = before.BackgroundEnabled;
live.BarBackgroundColor = before.BackgroundColor;
live.BarBackgroundOpacity = before.BackgroundOpacity;
live.BarTextShadow = before.TextShadow;
NotifySocialsChanged();
OnPropertyChanged(nameof(SocialBarVisible));
}
CloseSocialsDrawer();
};
SocialsDrawer = dialog;
@@ -178,7 +190,8 @@ public partial class MainViewModel
OnPropertyChanged(nameof(SocialsDrawerOpen));
}
private SocialsConfig? _socialsBeforeEdit;
private (bool BarEnabled, string TextColor, bool BackgroundEnabled, string BackgroundColor,
double BackgroundOpacity, bool TextShadow)? _appearanceBeforeEdit;
private static bool IsAppearanceProperty(string name) => name is
nameof(SocialsDialogViewModel.BarEnabled) or nameof(SocialsDialogViewModel.BarTextColor)