remediate: replace eval cookie writes with safe JS helper + add tests (18.6 Track A)
Both SettingsCookieService and DarkModeCookieService now call window.DeepDrftSettings.setCookie (new Interop/settings/settings.ts) instead of eval. New tests cover SettingsServiceBase parse/format round-trip and the PreferenceAwareStreamingPlayerService invariant (Lossless skips probe; LowData inherits base).
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
using DeepDrftPublic.Client.Common;
|
||||
using DeepDrftPublic.Client.Services;
|
||||
|
||||
namespace DeepDrftTests;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for the <see cref="SettingsServiceBase"/> parse/format contract (Phase 18 wave 18.6):
|
||||
/// the <c>streamQuality</c> cookie round-trips through <c>FormatStreamQuality</c> → wire string →
|
||||
/// <c>ParseStreamQuality</c>, and an absent, empty, or unrecognized cookie value defaults to
|
||||
/// <see cref="StreamQuality.LowData"/> (the OQ2 default — a missing preference should never force
|
||||
/// lossless unnecessarily on a low-bandwidth listener).
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class SettingsServiceBaseTests
|
||||
{
|
||||
// Expose the protected static helpers via a concrete subclass — no other members needed.
|
||||
private sealed class Exposed : SettingsServiceBase
|
||||
{
|
||||
public static StreamQuality Parse(string? v) => ParseStreamQuality(v);
|
||||
public static string Format(StreamQuality q) => FormatStreamQuality(q);
|
||||
}
|
||||
|
||||
// ── round-trip ──
|
||||
|
||||
// LowData serializes and deserializes intact.
|
||||
[Test]
|
||||
public void FormatThenParse_LowData_RoundTrips()
|
||||
{
|
||||
var wire = Exposed.Format(StreamQuality.LowData);
|
||||
Assert.That(Exposed.Parse(wire), Is.EqualTo(StreamQuality.LowData));
|
||||
}
|
||||
|
||||
// Lossless serializes and deserializes intact.
|
||||
[Test]
|
||||
public void FormatThenParse_Lossless_RoundTrips()
|
||||
{
|
||||
var wire = Exposed.Format(StreamQuality.Lossless);
|
||||
Assert.That(Exposed.Parse(wire), Is.EqualTo(StreamQuality.Lossless));
|
||||
}
|
||||
|
||||
// ── default for absent / garbled cookie ──
|
||||
|
||||
// A null cookie (no cookie present) defaults to LowData, not Lossless.
|
||||
[Test]
|
||||
public void Parse_Null_DefaultsToLowData()
|
||||
=> Assert.That(Exposed.Parse(null), Is.EqualTo(StreamQuality.LowData));
|
||||
|
||||
// An empty string (cookie present but blank) defaults to LowData.
|
||||
[Test]
|
||||
public void Parse_Empty_DefaultsToLowData()
|
||||
=> Assert.That(Exposed.Parse(string.Empty), Is.EqualTo(StreamQuality.LowData));
|
||||
|
||||
// A garbled/unknown name defaults to LowData rather than throwing.
|
||||
// Note: Enum.TryParse accepts numeric strings as valid (e.g. "0" → LowData, "1" → Lossless),
|
||||
// so only non-numeric unrecognized names are tested here.
|
||||
[TestCase("garbage")]
|
||||
[TestCase("lossless_extra")]
|
||||
public void Parse_Unrecognized_DefaultsToLowData(string value)
|
||||
=> Assert.That(Exposed.Parse(value), Is.EqualTo(StreamQuality.LowData));
|
||||
|
||||
// Case-insensitive parse: the enum parse is case-insensitive, so wire values survive case drift.
|
||||
[TestCase("lossless")]
|
||||
[TestCase("LOSSLESS")]
|
||||
[TestCase("Lossless")]
|
||||
public void Parse_LosslessCaseVariants_ParseCorrectly(string value)
|
||||
=> Assert.That(Exposed.Parse(value), Is.EqualTo(StreamQuality.Lossless));
|
||||
|
||||
[TestCase("lowdata")]
|
||||
[TestCase("LOWDATA")]
|
||||
[TestCase("LowData")]
|
||||
public void Parse_LowDataCaseVariants_ParseCorrectly(string value)
|
||||
=> Assert.That(Exposed.Parse(value), Is.EqualTo(StreamQuality.LowData));
|
||||
}
|
||||
Reference in New Issue
Block a user