TASK 4 ship step 5.5: social bar bug fixes + bar on the live output — direction-snap drag (SocialBarSnap.Decide + ClearValue, local Canvas.Top was overriding the binding), fediverse nodeinfo subdomain probing + load-time heal (settable FediverseSoftware), SocialBarRenderer strip blitted above the flash via a re-read FramePump socialBar seam — 155 tests passing, 0 warnings
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Xunit;
|
||||
using ytLive.Models;
|
||||
using ytLive.Services;
|
||||
using ytLive.ViewModels;
|
||||
|
||||
namespace ytLive.Tests;
|
||||
|
||||
@@ -16,6 +19,102 @@ public class SocialBarTests
|
||||
return path;
|
||||
}
|
||||
|
||||
/// <summary>Resolves every fediverse domain as Mastodon — the heal test only
|
||||
/// cares that a missing stored software name gets filled in and persisted.</summary>
|
||||
private sealed class MastodonValidator : ISocialValidator
|
||||
{
|
||||
public Task<string?> ResolveFediverseSoftwareAsync(string domain, CancellationToken ct)
|
||||
=> Task.FromResult<string?>("mastodon");
|
||||
|
||||
public Task<SocialLookupResult> LookupAsync(SocialService service, string handleOrUrl, CancellationToken ct)
|
||||
=> throw new System.NotSupportedException();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SocialBarSnap_Decide_DirectionAndDeadzone()
|
||||
{
|
||||
Assert.Equal(SocialBarPosition.Top, SocialBarSnap.Decide(-10));
|
||||
Assert.Equal(SocialBarPosition.Top, SocialBarSnap.Decide(-6));
|
||||
Assert.Equal(SocialBarPosition.Bottom, SocialBarSnap.Decide(10));
|
||||
Assert.Equal(SocialBarPosition.Bottom, SocialBarSnap.Decide(6));
|
||||
Assert.Null(SocialBarSnap.Decide(5));
|
||||
Assert.Null(SocialBarSnap.Decide(0));
|
||||
Assert.Null(SocialBarSnap.Decide(-5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SocialBarSnap_Decide_HonorsCustomDeadzone()
|
||||
{
|
||||
Assert.Null(SocialBarSnap.Decide(10, 20));
|
||||
Assert.Equal(SocialBarPosition.Top, SocialBarSnap.Decide(-21, 20));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SocialEntry_FediverseSoftware_SettableUpdatesLogo()
|
||||
{
|
||||
var entry = new SocialEntry
|
||||
{
|
||||
Service = SocialService.Fediverse,
|
||||
Handle = "@gramps@llamachile.tube",
|
||||
ProfileUrl = "https://llamachile.tube/@gramps",
|
||||
};
|
||||
var honeycomb = entry.LogoData;
|
||||
entry.FediverseSoftware = "mastodon";
|
||||
Assert.Equal(SocialServiceIcons.LogoDataForFediverse("mastodon"), entry.LogoData);
|
||||
Assert.NotEqual(honeycomb, entry.LogoData);
|
||||
}
|
||||
|
||||
/// <summary>The single integration test for this branch: a fediverse entry
|
||||
/// persisted with a NULL software name is loaded, healed via the real validator
|
||||
/// seam, and the resolved name is persisted back — surviving a second load.</summary>
|
||||
[Fact]
|
||||
public async Task Socials_HealMissingFediverseSoftware_RoundTripsThroughDb()
|
||||
{
|
||||
var path = TempDbPath();
|
||||
try
|
||||
{
|
||||
var socials = new SocialsConfig();
|
||||
socials.Entries.Add(new SocialEntry
|
||||
{
|
||||
Service = SocialService.Fediverse,
|
||||
Handle = "@gramps@llamachile.tube",
|
||||
ProfileUrl = "https://llamachile.tube/@gramps",
|
||||
});
|
||||
using (var store = new LayoutStore(path))
|
||||
store.Save(new[] { new Scene { Name = "Live" } }, null, socials);
|
||||
|
||||
SocialsConfig? loaded;
|
||||
using (var store = new LayoutStore(path))
|
||||
{
|
||||
store.Load();
|
||||
loaded = store.Socials;
|
||||
Assert.NotNull(loaded);
|
||||
Assert.Null(loaded!.Entries[0].FediverseSoftware);
|
||||
}
|
||||
|
||||
var healed = await MainViewModel.HealFediverseSoftwareAsync(loaded!, new MastodonValidator());
|
||||
Assert.Single(healed);
|
||||
Assert.Equal("mastodon", healed["@gramps@llamachile.tube"]);
|
||||
loaded.Entries[0].FediverseSoftware = healed["@gramps@llamachile.tube"];
|
||||
|
||||
using (var store = new LayoutStore(path))
|
||||
store.Save(new[] { new Scene { Name = "Live" } }, null, loaded);
|
||||
|
||||
using (var store = new LayoutStore(path))
|
||||
{
|
||||
store.Load();
|
||||
var again = store.Socials;
|
||||
Assert.NotNull(again);
|
||||
Assert.Equal("mastodon", again!.Entries[0].FediverseSoftware);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
SqliteConnection.ClearAllPools();
|
||||
if (File.Exists(path)) File.Delete(path);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SocialsConfig_RoundTrip_PersistsEntriesAndBarSettings()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user