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.
Inherited Members
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()