Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions Assets/Tests/Editor/SettingsPresentationDecisionPolicyTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using NUnit.Framework;

using io.github.hatayama.UnityCliLoop.Domain;

namespace io.github.hatayama.UnityCliLoop.Tests.Editor
{
/// <summary>
/// Verifies UnityEditor-independent Settings decision policies extracted for Presentation Move Method.
/// </summary>
public class SettingsPresentationDecisionPolicyTests
{
[TestCase(false, true, true)]
[TestCase(false, false, false)]
[TestCase(true, true, false)]
[TestCase(true, false, false)]
public void CliPathSetupCheckPolicy_ShouldCheck_UsesWindowsAndOwnership(
bool isWindowsEditor,
bool hasPackageOwnedCurrentUserInstall,
bool expected)
{
// Verifies PATH checks stay off for Windows and non package-owned installs.
bool result = CliPathSetupCheckPolicy.ShouldCheck(
isWindowsEditor,
hasPackageOwnedCurrentUserInstall);

Assert.That(result, Is.EqualTo(expected));
}

[Test]
public void SkillInstallDialogPolicy_ShouldShowForInstallableTargets_RequiresAllEligible()
{
// Verifies wizard dialog policy requires every target to be first-install eligible.
SkillSetupTargetInfo[] targets =
{
CreateSkillTarget(SkillInstallState.Missing, false),
CreateSkillTarget(SkillInstallState.Outdated, false)
};

bool result = SkillInstallDialogPolicy.ShouldShowForInstallableTargets(targets);

Assert.That(result, Is.False);
}

private static SkillSetupTargetInfo CreateSkillTarget(
SkillInstallState installState,
bool hasDifferentLayoutSkills)
{
return new SkillSetupTargetInfo(
"Claude Code",
".claude",
"--claude",
hasSkillsDirectory: true,
hasExistingSkills: true,
hasDifferentLayoutSkills,
installState);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void ShouldUninstallCliFromPrimaryButton_ReturnsExpectedAction(
bool expected)
{
// Verifies that package-owned installs route to uninstall only when the dispatcher minimum is satisfied.
bool result = UnityCliLoopSettingsWindow.ShouldUninstallCliFromPrimaryButton(
bool result = UnityCliLoopSettingsCliSetupPresenter.ShouldUninstallCliFromPrimaryButton(
cliVersion,
cliIsDispatcher,
canUninstallCli,
Expand All @@ -45,7 +45,7 @@ public void ShouldRepairCliPathFromPrimaryButton_ReturnsExpectedAction(
bool expected)
{
// Verifies that stale terminal PATH state routes to repair only when CLI replacement is not needed.
bool result = UnityCliLoopSettingsWindow.ShouldRepairCliPathFromPrimaryButton(
bool result = UnityCliLoopSettingsCliSetupPresenter.ShouldRepairCliPathFromPrimaryButton(
needsCliPathSetup,
needsUpdate);

Expand All @@ -70,7 +70,7 @@ public void ResolveCliPrimaryButtonAction_ReturnsClickedPrimaryAction(
{
// Verifies that the Settings window chooses repair only when dispatcher replacement is unnecessary.
CliSetupPrimaryAction result =
UnityCliLoopSettingsWindow.ResolveCliPrimaryButtonAction(
UnityCliLoopSettingsCliSetupPresenter.ResolveCliPrimaryButtonAction(
needsCliPathSetup,
cliVersion,
cliIsDispatcher,
Expand All @@ -94,7 +94,7 @@ public void ResolveExecutableCliPrimaryButtonAction_IgnoresUnsafeStaleActions(
{
// Verifies that a refreshed Settings state cannot turn a stale click into a destructive action.
CliSetupPrimaryAction result =
UnityCliLoopSettingsWindow.ResolveExecutableCliPrimaryButtonAction(
UnityCliLoopSettingsCliSetupPresenter.ResolveExecutableCliPrimaryButtonAction(
ParseAction(clickedAction),
ParseAction(refreshedAction));

Expand All @@ -111,7 +111,7 @@ public void ShouldCheckCliPathSetupForPlatform_RequiresPackageOwnedCli(
bool expected)
{
// Verifies that PATH repair only runs for POSIX package-owned current-user installs.
bool result = UnityCliLoopSettingsWindow.ShouldCheckCliPathSetupForPlatform(
bool result = UnityCliLoopSettingsCliSetupPresenter.ShouldCheckCliPathSetupForPlatform(
platform,
hasPackageOwnedCurrentUserInstall);

Expand All @@ -131,7 +131,7 @@ public void IsCliUpdateNeeded_UsesDispatcherMinimumVersion(
bool expected)
{
// Verifies that the settings UI updates non-dispatcher or older dispatcher installs.
bool result = UnityCliLoopSettingsWindow.IsCliUpdateNeeded(
bool result = UnityCliLoopSettingsCliSetupPresenter.IsCliUpdateNeeded(
cliVersion,
cliIsDispatcher,
TestMinimumDispatcherVersion);
Expand All @@ -150,7 +150,7 @@ public void ShouldShowSkillsInstalledDialog_ReturnsExpectedValue(
// Verifies that Settings keeps the success dialog for first install only.
SkillSetupTargetInfo targetInfo = CreateSkillTarget(installState, hasDifferentLayoutSkills);

bool result = UnityCliLoopSettingsWindow.ShouldShowSkillsInstalledDialog(targetInfo);
bool result = SkillInstallDialogPolicy.ShouldShowForSelectedTarget(targetInfo);

Assert.That(result, Is.EqualTo(expected));
}
Expand Down
18 changes: 18 additions & 0 deletions Packages/src/Editor/Domain/CliPathSetupCheckPolicy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace io.github.hatayama.UnityCliLoop.Domain
{
/// <summary>
/// Decides when Settings should run CLI PATH visibility checks.
/// </summary>
public static class CliPathSetupCheckPolicy
{
/// <summary>
/// PATH repair checks run only for non-Windows package-owned current-user installs.
/// </summary>
public static bool ShouldCheck(
bool isWindowsEditor,
bool hasPackageOwnedCurrentUserInstall)
{
return !isWindowsEditor && hasPackageOwnedCurrentUserInstall;
}
}
}
11 changes: 11 additions & 0 deletions Packages/src/Editor/Domain/CliPathSetupCheckPolicy.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions Packages/src/Editor/Domain/SkillInstallDialogPolicy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace io.github.hatayama.UnityCliLoop.Domain
{
/// <summary>
/// Decides when the skills-installed success dialog should appear after an install attempt.
/// </summary>
public static class SkillInstallDialogPolicy
{
/// <summary>
/// Returns true when Settings should show the success dialog for a single selected target.
/// </summary>
public static bool ShouldShowForSelectedTarget(SkillSetupTargetInfo targetInfo)
{
return targetInfo.InstallState != SkillInstallState.Outdated
&& !targetInfo.HasDifferentLayoutSkills;
}

/// <summary>
/// Returns true when Setup Wizard should show the success dialog for all installable targets.
/// </summary>
public static bool ShouldShowForInstallableTargets(IEnumerable<SkillSetupTargetInfo> targets)
{
Debug.Assert(targets != null, "targets must not be null");
return targets.All(ShouldShowForSelectedTarget);
}
}
}
11 changes: 11 additions & 0 deletions Packages/src/Editor/Domain/SkillInstallDialogPolicy.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ internal static bool HasSkillUpdateForSetupWizard(IEnumerable<SkillSetupTargetIn

internal void TryShowOnVersionChange()
{
EvaluateVersionChange(CancellationToken.None);
EvaluateVersionChange(CancellationToken.None).Forget();
}

private static bool TryGetMajorVersion(string version, out int majorVersion)
Expand All @@ -170,7 +170,7 @@ private static bool TryGetMajorVersion(string version, out int majorVersion)
return int.TryParse(majorText, out majorVersion);
}

private async void EvaluateVersionChange(CancellationToken ct)
private async Task EvaluateVersionChange(CancellationToken ct)
{
string currentVersion = UnityCliLoopConstants.PackageInfo.version;
string currentMinimumDispatcherVersion = _cliSetupApplicationService.GetMinimumRequiredCliVersion();
Expand Down
13 changes: 6 additions & 7 deletions Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -541,10 +541,7 @@ private void CancelSkillInstallStateRefresh()
internal static bool ShouldShowSkillsInstalledDialog(
IEnumerable<SkillSetupTargetInfo> targets)
{
Debug.Assert(targets != null, "targets must not be null");
return targets.All(target =>
target.InstallState != SkillInstallState.Outdated
&& !target.HasDifferentLayoutSkills);
return SkillInstallDialogPolicy.ShouldShowForInstallableTargets(targets);
}

internal static bool ShouldUseFirstInstallSkillsUi(string lastSeenSetupWizardVersion)
Expand Down Expand Up @@ -579,8 +576,9 @@ internal static bool ShouldCheckCliPathSetupForSetupWizard(
RuntimePlatform platform,
bool hasPackageOwnedCurrentUserInstall)
{
return platform != RuntimePlatform.WindowsEditor
&& hasPackageOwnedCurrentUserInstall;
return CliPathSetupCheckPolicy.ShouldCheck(
isWindowsEditor: platform == RuntimePlatform.WindowsEditor,
hasPackageOwnedCurrentUserInstall);
}

private static CliSetupCompatibilityState EvaluateCliSetupCompatibilityForSetupWizard(
Expand Down Expand Up @@ -762,7 +760,8 @@ private async Task HandleInstallSkillsAsync(CancellationToken ct)
: SetupWizardSkillsStepPresenter.FilterInstallableSkillTargets(targets);
if (installableTargets.Count == 0) return;

bool shouldShowSkillsInstalledDialog = ShouldShowSkillsInstalledDialog(installableTargets);
bool shouldShowSkillsInstalledDialog =
SkillInstallDialogPolicy.ShouldShowForInstallableTargets(installableTargets);
_isInstallingSkills = true;
UpdateSkillsStep(true, targets);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,10 @@ private void CreateGUI()
InitializeApplicationServices();
_view = ThirdPartyToolMigrationWizardView.Create(
rootVisualElement,
RefreshUI,
HandleMigrateThirdPartyTools,
() => RefreshUI().Forget(),
() => HandleMigrateThirdPartyTools().Forget(),
HandleMigrationSkillTargetChanged,
HandleToggleMigrationSkill,
() => HandleToggleMigrationSkill().Forget(),
Close);
_resizer = new ThirdPartyToolMigrationWizardWindowResizer(this, _view.MainScrollView);
_resizer.BindSizeUpdates();
Expand Down Expand Up @@ -425,10 +425,10 @@ private void ScheduleInitialRefresh(bool shouldStartInitialRefresh)
return;
}

rootVisualElement.schedule.Execute(RefreshUI).StartingIn(0);
rootVisualElement.schedule.Execute(() => RefreshUI().Forget()).StartingIn(0);
}

private async void RefreshUI()
private async Task RefreshUI()
{
CancellationToken ct = BeginMigrationOperation();
ShowCheckingState(new ThirdPartyToolMigrationProgress(0, 0));
Expand Down Expand Up @@ -477,7 +477,7 @@ private async void RefreshUI()
ShowMigrationTargetsState(preview.FilePaths);
}

private async void HandleMigrateThirdPartyTools()
private async Task HandleMigrateThirdPartyTools()
{
if (!ConfirmMigrationApply(
_pendingMigrationFilePaths.Length,
Expand Down Expand Up @@ -546,7 +546,7 @@ private async void HandleMigrateThirdPartyTools()
CompleteMigrationOperation(ct);
if (shouldRefreshAfterInterruptedMigration)
{
RefreshUI();
await RefreshUI();
}
}

Expand All @@ -557,7 +557,7 @@ private async void HandleMigrateThirdPartyTools()

if (ShouldRefreshAfterMigration(result))
{
RefreshUI();
await RefreshUI();
return;
}

Expand Down Expand Up @@ -626,7 +626,7 @@ private void HandleMigrationSkillTargetChanged(SkillsTarget target)
RefreshMigrationSkillState();
}

private async void HandleToggleMigrationSkill()
private async Task HandleToggleMigrationSkill()
{
CancellationToken ct = BeginMigrationSkillOperation();
string projectRoot = UnityCliLoopPathResolver.GetProjectRoot();
Expand Down Expand Up @@ -767,7 +767,7 @@ private void TryStartInitialRefresh()
}

ShowCheckingState(new ThirdPartyToolMigrationProgress(0, 0));
rootVisualElement.schedule.Execute(RefreshUI).StartingIn(0);
rootVisualElement.schedule.Execute(() => RefreshUI().Forget()).StartingIn(0);
}

private void CompleteMigrationOperation(CancellationToken ct)
Expand Down
Loading