feat(entitlement): pivot to paid app ownership
Check Steam ownership of the paid app with BIsSubscribedApp; keep Debug fake ownership out of Release. Ref: https://partner.steamgames.com/doc/api/ISteamApps#BIsSubscribedApp
This commit is contained in:
@@ -7,12 +7,10 @@ using ytLive.ViewModels;
|
||||
namespace ytLive.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// The entitlement seam (2026-11-01): one question — "may this session emit Pro output?" — with a
|
||||
/// Steam DLC rail, a Polar rail to come, and a fail-closed default.
|
||||
/// Steam ownership is cached once into the app-wide binary flag.
|
||||
///
|
||||
/// <para>The rule that must never break: **no configured rail means the free profile**. A missing
|
||||
/// DLC id, a missing Steam client or a thrown native load all resolve to false; none of them may
|
||||
/// crash the app or quietly grant Pro.</para>
|
||||
/// <para>The rule that must never break: a missing paid app ID, Steam client, or native library
|
||||
/// fails closed.</para>
|
||||
/// </summary>
|
||||
// Shares the static MainViewModel.LayoutPathOverride with the sibling class; without a
|
||||
// shared collection xUnit runs them in parallel and the two view models fight over one temp DB.
|
||||
@@ -20,27 +18,44 @@ namespace ytLive.Tests;
|
||||
public class EntitlementTests
|
||||
{
|
||||
[Fact]
|
||||
public void No_configured_dlc_id_reads_as_no_entitlement()
|
||||
public void No_configured_paid_app_id_reads_as_not_owned()
|
||||
{
|
||||
// The state before the Steamworks app exists: pure false, no native call attempted.
|
||||
Assert.False(SteamEntitlement.NotConfigured().IsPro);
|
||||
Assert.False(SteamEntitlement.NotConfigured().IsAppOwned);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_steam_entitlement_without_a_client_is_the_free_tier_not_a_crash()
|
||||
public void Steam_ownership_checks_the_paid_app_id()
|
||||
{
|
||||
// No steam_appid.txt in the test host and no client running: Init fails, we report false.
|
||||
var entitlement = new SteamEntitlement(1234567u);
|
||||
Assert.False(entitlement.IsPro);
|
||||
const uint paidAppId = 1234567u;
|
||||
uint queriedAppId = 0;
|
||||
var entitlement = new SteamEntitlement(
|
||||
paidAppId,
|
||||
initializeSteam: () => true,
|
||||
isAppSubscribed: appId =>
|
||||
{
|
||||
queriedAppId = appId;
|
||||
return true;
|
||||
},
|
||||
shutdownSteam: () => { });
|
||||
|
||||
Assert.True(entitlement.IsAppOwned);
|
||||
Assert.Equal(paidAppId, queriedAppId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_steam_entitlement_without_a_client_fails_closed()
|
||||
{
|
||||
var entitlement = new SteamEntitlement(1234567u, () => false, _ => true, () => { });
|
||||
Assert.False(entitlement.IsAppOwned);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_fake_reports_what_a_test_sets()
|
||||
{
|
||||
var fake = new FakeEntitlement(true);
|
||||
Assert.True(fake.IsPro);
|
||||
fake.IsPro = false;
|
||||
Assert.False(fake.IsPro);
|
||||
Assert.True(fake.IsAppOwned);
|
||||
fake.IsAppOwned = false;
|
||||
Assert.False(fake.IsAppOwned);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -52,14 +67,16 @@ public class EntitlementTests
|
||||
{
|
||||
var vm = new MainViewModel();
|
||||
|
||||
// Default rail is NotConfigured → free output.
|
||||
Assert.False(vm.HasProOutput);
|
||||
|
||||
vm.EntitlementOverride = new FakeEntitlement(true);
|
||||
Assert.True(vm.IsAppOwned);
|
||||
Assert.True(vm.HasProOutput);
|
||||
|
||||
vm.EntitlementOverride = new FakeEntitlement(false);
|
||||
Assert.False(vm.IsAppOwned);
|
||||
Assert.False(vm.HasProOutput);
|
||||
|
||||
vm.EntitlementOverride = new FakeEntitlement(true);
|
||||
Assert.True(vm.IsAppOwned);
|
||||
Assert.True(vm.HasProOutput);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user