Class AchievementSettingsCreatorTests
EditMode tests for AchievementSettingsCreator. Every test targets fixture assets under a
private temp folder via Input.SettingsAssetPath, so the project's real achievements configuration
is never touched. Mirrors Serenity.GameSave.Tests.Editor.Builder.GameSaveCreatorTests.
Deliberately never sets Input.RetrofitThemes to true: that path calls
AchievementsThemeRetrofitter.RetrofitAllThemesMissingAchievements, which scans every
UnityUiThemeDefinition in the whole project — exercising it here would retrofit the real shipped
themes as a side effect of running the test suite, exactly as AchievementsThemeRetrofitterTests
documents for the same reason. Only the not-requested path is asserted here; the retrofit itself is
covered by that suite.
Inherited Members
Namespace: Serenity.UnityAchievements.Tests.Editor
Assembly: Tests.Editor.dll
Syntax
public class AchievementSettingsCreatorTests
Constructors
AchievementSettingsCreatorTests()
Declaration
public AchievementSettingsCreatorTests()
Methods
Create_ExistingAssetSeededOnEverySerializedField_RestoresThemAll()
Field-by-field regression guard for the generic capture Create(Input, Action)
now rolls back through (transaction.TrackExistingAsset), replacing the hand-rolled
SettingsSnapshot this migration deleted. Writes a distinct value into EVERY serialized field of
a real UnityAchievementSettings via reflection — the ten
ApplyTo(UnityAchievementSettings) knows about plus Id/Guid/the table
names/Backend/Platforms — and asserts the rollback puts every one of them back.
What the walk actually PROVES splits in two. The fields this run overwrites — Backend (hence
ReplaceExistingBackend and a second-run backend name of
its own), Platforms (hence an enabled storefront) and every option field — are restored from a
state the run genuinely rewrote, which is why the failure is forced through
afterOptionsApplied: this creator's last asset step, the view, writes BEFORE the options are
applied, so a disk-level forced failure can only ever catch a half-mutated asset. The fields this run
never touches (Id, Guid, the table names — it resolves the settings asset by path, not
by matching them) are carried along as coverage of the capture's REACH, not of a restore: they prove
the walk sees whatever the type declares, so a future field this creator does start writing cannot be
added without landing inside this assertion.
Declaration
public void Create_ExistingAssetSeededOnEverySerializedField_RestoresThemAll()
Create_MidCreateFailureOnAnExistingSettingsAsset_RestoresItsPreviousOptions()
The half-applied-settings hazard: when the run EDITS an existing settings asset instead of creating one, a rollback has to restore its option values too. Nothing on disk would show that it did not — the asset is still there, still valid, just quietly carrying a configuration nobody chose.
Declaration
public void Create_MidCreateFailureOnAnExistingSettingsAsset_RestoresItsPreviousOptions()
Create_MidCreateFailure_RollsBackTheSettingsBackendAndPlatformAssets()
Forces a failure AFTER the settings, backend and platform assets have been written — the view is the
last asset step — and asserts the whole tree is gone again. Uses the stale-folder-cache trick
LeaderboardCreatorTests.Create_MidCreateFailure_RollsBackBoardsBackendAndMenuOptions introduced:
create + save + refresh a folder so UnityEditor.AssetDatabase.IsValidFolder(System.String) keeps reporting it valid
(so validation passes), then delete the physical directory straight off disk, so the view's
UnityEditor.AssetDatabase.CreateAsset(UnityEngine.Object,System.String) silently writes nothing and the creator's write check throws.
Declaration
public void Create_MidCreateFailure_RollsBackTheSettingsBackendAndPlatformAssets()
Create_RegisterAsAddressablesFalse_LeavesAddressablesUntouched()
Declaration
public void Create_RegisterAsAddressablesFalse_LeavesAddressablesUntouched()
Create_RerunWithTheSameBackendAssetName_IsAcceptedAndCreatesNoSecondBackend()
A rerun over a configuration this creator already authored must be possible: the backend path is occupied by the backend the settings asset itself points at, which is a reuse, not a collision.
Declaration
public void Create_RerunWithTheSameBackendAssetName_IsAcceptedAndCreatesNoSecondBackend()
Create_RerunWithTheSamePlatform_ReconfiguresTheExistingAssetInsteadOfAddingASecond(AchievementPlatformKind)
Reuse is by Id, not by path: a rerun must reconfigure the definition the settings asset already points at rather than orphaning it behind a second one. Run for every storefront, because each kind resolves its own concrete type and a switch is exactly the shape that grows a missing case.
Declaration
public void Create_RerunWithTheSamePlatform_ReconfiguresTheExistingAssetInsteadOfAddingASecond(AchievementPlatformKind kind)
Parameters
| Type | Name | Description |
|---|---|---|
| AchievementPlatformKind | kind |
Create_RerunWithoutTheReplaceFlag_KeepsTheAlreadyAssignedBackend()
Declaration
public void Create_RerunWithoutTheReplaceFlag_KeepsTheAlreadyAssignedBackend()
Create_RetrofitThemesNotRequested_ReportsNoRetrofitSummary()
Declaration
public void Create_RetrofitThemesNotRequested_ReportsNoRetrofitSummary()
Create_SamePlatformListedTwice_ProducesOnePlatformAsset()
Declaration
public void Create_SamePlatformListedTwice_ProducesOnePlatformAsset()
Create_WireInstallTaskIntoAProfileThatAlreadyRunsInstallMenu_InsertsBeforeIt()
The ordering hint the wiring exists for: InstallMenu's fan-out installs the achievements view,
so an InstallAchievements task placed after it silently installs nothing.
Declaration
public void Create_WireInstallTaskIntoAProfileThatAlreadyRunsInstallMenu_InsertsBeforeIt()
Create_WireInstallTaskIntoAProfile_EnsuresTheTaskAndInsertsIt()
Declaration
public void Create_WireInstallTaskIntoAProfile_EnsuresTheTaskAndInsertsIt()
Create_WireInstallTaskTwiceIntoTheSameProfile_SkipsTheSecondInsertAndStillSucceeds()
Two things at once, because they are the same run. Idempotency: a second Create against the same profiles must not insert the task twice. And the phase boundary: the wiring runs AFTER the asset transaction commits, so the warning it reports here cannot roll back the settings asset the same run just wrote — the result stays successful and every reference survives.
Declaration
public void Create_WireInstallTaskTwiceIntoTheSameProfile_SkipsTheSecondInsertAndStillSucceeds()
Create_WireMenuOptionTwice_UpsertsInsteadOfDuplicating()
Declaration
public void Create_WireMenuOptionTwice_UpsertsInsteadOfDuplicating()
Create_WireMenuOption_AddsATransitionOptionAndDerivesTheReturnView()
Declaration
public void Create_WireMenuOption_AddsATransitionOptionAndDerivesTheReturnView()
Create_WithAView_WritesTheViewDefinitionCarryingItsTitleAndReturnView()
Declaration
public void Create_WithAView_WritesTheViewDefinitionCarryingItsTitleAndReturnView()
Create_WithAddressablesRegistration_RegistersEverySettingsAndPlatformAsset()
Declaration
public void Create_WithAddressablesRegistration_RegistersEverySettingsAndPlatformAsset()
Create_WithAnExistingBackendAssigned_ReusesItInsteadOfCreatingOne()
Declaration
public void Create_WithAnExistingBackendAssigned_ReusesItInsteadOfCreatingOne()
Create_WithHttpBackend_FillsTheSharedBackendAssetsFields()
Declaration
public void Create_WithHttpBackend_FillsTheSharedBackendAssetsFields()
Create_WithPlayerPrefsBackend_WritesTheSettingsAssetWithTheBackendAndTheOptions()
Declaration
public void Create_WithPlayerPrefsBackend_WritesTheSettingsAssetWithTheBackendAndTheOptions()
Create_WithTwoPlatforms_CreatesOneAssetPerPlatformAndReferencesThemInOrder()
Declaration
public void Create_WithTwoPlatforms_CreatesOneAssetPerPlatformAndReferencesThemInOrder()
OneTimeTearDown()
Declaration
public void OneTimeTearDown()
SetUp()
Declaration
public void SetUp()
TearDown()
Declaration
public void TearDown()
ValidateIdentity_BlankId_ReturnsError()
Declaration
public void ValidateIdentity_BlankId_ReturnsError()
Validate_AnotherSettingsAssetInTheFolderCarriesTheSameId_ReturnsError()
Declaration
public void Validate_AnotherSettingsAssetInTheFolderCarriesTheSameId_ReturnsError()
Validate_CreateViewWithBlankViewId_ReturnsError()
Declaration
public void Validate_CreateViewWithBlankViewId_ReturnsError()
Validate_EnabledPlatformMissingItsRequiredIdentifier_ReturnsError()
Declaration
public void Validate_EnabledPlatformMissingItsRequiredIdentifier_ReturnsError()
Validate_EpicEnabledWithAMissingField_ReportsThatFieldOnItsOwn(string)
Declaration
public void Validate_EpicEnabledWithAMissingField_ReportsThatFieldOnItsOwn(string missingFieldLabel)
Parameters
| Type | Name | Description |
|---|---|---|
| string | missingFieldLabel |
Validate_NegativePlatformCallTimeout_ReturnsError()
Declaration
public void Validate_NegativePlatformCallTimeout_ReturnsError()
Validate_NegativePlatformSyncRetry_ReturnsError()
Declaration
public void Validate_NegativePlatformSyncRetry_ReturnsError()
Validate_NullInput_ReportsMissingInput()
Declaration
public void Validate_NullInput_ReportsMissingInput()
Validate_PlatformAssetPathOccupiedByAForeignAsset_ReturnsError()
The occupied-path policy the class doc promises, applied to platform definitions: an asset already sitting at the conventional path under a foreign Id belongs to something else, so the run refuses rather than overwriting it or quietly writing a second, uniquely-named copy beside it.
Declaration
public void Validate_PlatformAssetPathOccupiedByAForeignAsset_ReturnsError()
Validate_PlatformAssetPathOccupiedByTheRunsOwnDefinition_IsAccepted()
The same path occupied by the run's OWN by-Id match is a reuse, not a collision.
Declaration
public void Validate_PlatformAssetPathOccupiedByTheRunsOwnDefinition_IsAccepted()
Validate_PlayStationWithANegativeServiceLabel_ReturnsError()
Declaration
public void Validate_PlayStationWithANegativeServiceLabel_ReturnsError()
Validate_ProgressPushStepPercentAtTheBounds_IsAccepted(int)
Declaration
public void Validate_ProgressPushStepPercentAtTheBounds_IsAccepted(int percent)
Parameters
| Type | Name | Description |
|---|---|---|
| int | percent |
Validate_ProgressPushStepPercentOutsideOneToOneHundred_ReturnsError(int)
Declaration
public void Validate_ProgressPushStepPercentOutsideOneToOneHundred_ReturnsError(int percent)
Parameters
| Type | Name | Description |
|---|---|---|
| int | percent |
Validate_ReplaceExistingBackendAtTheSameAssetName_ReturnsError()
The other half of the same rule: replacing the backend AT THE SAME ASSET NAME is refused, because writing over the path would leave a rollback deleting a backend the project already depended on.
Declaration
public void Validate_ReplaceExistingBackendAtTheSameAssetName_ReturnsError()
Validate_ScreenshotMaxWidthNotPositive_ReturnsError()
Declaration
public void Validate_ScreenshotMaxWidthNotPositive_ReturnsError()
Validate_SteamEnabledWithoutAnAppId_WarnsButDoesNotBlock()
Declaration
public void Validate_SteamEnabledWithoutAnAppId_WarnsButDoesNotBlock()
Validate_TargetFolderOutsideAssets_ReturnsError()
Declaration
public void Validate_TargetFolderOutsideAssets_ReturnsError()
Validate_ViewAssetPathAlreadyOccupied_ReturnsError()
Declaration
public void Validate_ViewAssetPathAlreadyOccupied_ReturnsError()
Validate_ViewFolderOutsideAssets_ReturnsError()
Declaration
public void Validate_ViewFolderOutsideAssets_ReturnsError()
Validate_WireMenuOptionWithBlankViewId_ReturnsError()
Declaration
public void Validate_WireMenuOptionWithBlankViewId_ReturnsError()
Validate_WireMenuOptionWithoutAMenu_ReturnsError()
Declaration
public void Validate_WireMenuOptionWithoutAMenu_ReturnsError()