logo SERENITY
Game Systems Foundation
Search Results for

    Show / Hide Table of Contents

    Class CreatePrefetchPolicyWindowRowBindingTests

    Proves the row-binding rule CreatePrefetchPolicyWindow and CreateFromDrafts(IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>>, string, string, bool, UnboundRowWriteMode) enforce together: a row seeded from an existing profile stays bound to THAT asset regardless of an Id edit, and any row whose current Id collides with a DIFFERENT existing profile blocks the primary action instead of silently overwriting it — retyping a seeded row's Id to match another existing profile's Id never resolves-and-overwrites that OTHER asset, and the original is never dropped from the registry.

    Inheritance
    object
    CreatePrefetchPolicyWindowRowBindingTests
    Inherited Members
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    object.GetType()
    object.MemberwiseClone()
    Namespace: Serenity.AssetPrefetcher.Tests.Editor.Builder
    Assembly: Serenity.AssetPrefetcher.Tests.Editor.dll
    Syntax
    public class CreatePrefetchPolicyWindowRowBindingTests

    Constructors

    CreatePrefetchPolicyWindowRowBindingTests()

    Declaration
    public CreatePrefetchPolicyWindowRowBindingTests()

    Methods

    AddRowForTests_AfterCacheWasBuilt_InvalidatesTheCacheSoANewlyCreatedCollisionIsCaught()

    WARNING fix: PrefetchPolicyProfileRowsEditor.AddRow must invalidate its own row-binding cache rather than relying on the window's GUI change-check — the Serenity.AssetPrefetcher.Infrastructure.Editor.Builder.CreatePrefetchPolicyWindow.AddRowForTests(System.String) seam bypasses that change-check entirely. Without the invalidation, a profile created on disk after the cache was built would go undetected until some unrelated recompute happened to run.

    Declaration
    public void AddRowForTests_AfterCacheWasBuilt_InvalidatesTheCacheSoANewlyCreatedCollisionIsCaught()

    OneTimeTearDown()

    Declaration
    public void OneTimeTearDown()

    PickTargetForTests_SimulateReloadThenConfirmWithZeroEdits_IsNotBlockedAndBothAssetsRoundTrip()

    Regression test for the CRITICAL reload bug: Serenity.Global.Infrastructure.Editor.SerenityWizardDraftListLifecycle`1's first version reattached every row with a null source after a domain reload, so a row's own unchanged Id (still matching its own asset) read as "belongs to a different asset" and blocked Confirm permanently. Seeds two real profiles, simulates a reload, then confirms with ZERO edits through the shared UpdateInPlaceRoundTripContract — must not be blocked, and both assets must come back completely unchanged.

    Declaration
    public void PickTargetForTests_SimulateReloadThenConfirmWithZeroEdits_IsNotBlockedAndBothAssetsRoundTrip()

    PickTargetForTests_SimulateReloadThenRetypeToTheOtherRowsId_IsStillBlocked()

    Companion to the round-trip test above: after the SAME simulated reload, retyping a row onto a DIFFERENT existing profile's Id must still be blocked — the binding survived the reload, so the rule still catches the collision.

    Declaration
    public void PickTargetForTests_SimulateReloadThenRetypeToTheOtherRowsId_IsStillBlocked()

    RemoveRowForTests_AfterCacheWasBuilt_InvalidatesTheCacheSoALaterEditIsValidatedAgainstFreshDisk()

    Companion to the Add test above for RemoveRowAt: isolates removal's own invalidation by editing the SURVIVING row's Id afterwards, rather than adding a new row (which would invalidate the cache on its own and mask whether Remove did anything).

    Declaration
    public void RemoveRowForTests_AfterCacheWasBuilt_InvalidatesTheCacheSoALaterEditIsValidatedAgainstFreshDisk()

    RunPrimaryActionForTests_NewRowWithIdOfAnExistingUnlistedProfile_IsBlocked()

    Declaration
    public void RunPrimaryActionForTests_NewRowWithIdOfAnExistingUnlistedProfile_IsBlocked()

    RunPrimaryActionForTests_RemovingASeededRow_UnlinksItFromTheRegistryButLeavesItsAssetOnDisk()

    Declaration
    public void RunPrimaryActionForTests_RemovingASeededRow_UnlinksItFromTheRegistryButLeavesItsAssetOnDisk()

    RunPrimaryActionForTests_RowRetypedToACaseVariantOfAnExistingDifferentProfilesId_IsBlocked()

    Case-only collisions are real collisions too — both Ids sanitize to the same file name.

    Declaration
    public void RunPrimaryActionForTests_RowRetypedToACaseVariantOfAnExistingDifferentProfilesId_IsBlocked()

    RunPrimaryActionForTests_RowRetypedToAFreeId_UpdatesTheSameAssetAndKeepsItsGuid()

    Declaration
    public void RunPrimaryActionForTests_RowRetypedToAFreeId_UpdatesTheSameAssetAndKeepsItsGuid()

    RunPrimaryActionForTests_RowRetypedToAnExistingDifferentProfilesId_IsBlockedAndNeitherAssetChanges()

    Declaration
    public void RunPrimaryActionForTests_RowRetypedToAnExistingDifferentProfilesId_IsBlockedAndNeitherAssetChanges()

    RunPrimaryActionForTests_UnboundRowCollidesWithAProfileCreatedAfterTheCacheWasBuilt_IsBlocked()

    The window-level half of the cache-staleness guarantee: unlike RunPrimaryActionForTests_NewRowWithIdOfAnExistingUnlistedProfile_IsBlocked() — which creates the orphan asset BEFORE the window's cache exists, so the cache already covers it — this builds the window rows and the validation cache FIRST, THEN creates the colliding profile asset on disk, THEN runs the primary action. The write-boundary create-only refusal in CreateFromDrafts(IReadOnlyList<SerenityWizardScratchDraft<PrefetchPolicyProfile>>, string, string, bool, UnboundRowWriteMode) must still catch it even though the window's own cache never saw the collision.

    Declaration
    public void RunPrimaryActionForTests_UnboundRowCollidesWithAProfileCreatedAfterTheCacheWasBuilt_IsBlocked()

    SetUp()

    Declaration
    public void SetUp()

    TearDown()

    Declaration
    public void TearDown()
    In this article
    © 2026 Serenity. All Rights Reserved