using System.Collections; using System.Reflection; using BumpCombat.Combat; using BumpCombat.Core; using BumpCombat.Enemies; using BumpCombat.Player; using BumpCombat.Progression; using BumpCombat.Spawning; using NUnit.Framework; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestTools; namespace BumpCombat.PlayModeTests { public sealed class HurtRecoveryVisualTests { [UnityTest] public IEnumerator HurtBlink_PausesWithImmunityAndClearsAfterRecovery() { ArtifactRewardController.GrantCatalogForTests = true; RunManager.ForceProductionModeForTests = false; Time.timeScale = 1f; yield return SceneManager.LoadSceneAsync("CombatPrototype"); yield return null; yield return null; Object.FindAnyObjectByType().enabled = false; foreach (var enemy in Object.FindObjectsByType(FindObjectsSortMode.None)) enemy.gameObject.SetActive(false); var health = Object.FindAnyObjectByType(); var feedback = health.GetComponent(); var body = health.GetComponent(); var routine = typeof(CombatFeedback).GetField("playerVisualCoroutine", BindingFlags.NonPublic | BindingFlags.Instance); Color original = body.color; Assert.That(health.TryTakeDamage(1f, Vector2.zero, 0f), Is.True); yield return new WaitForSeconds(0.2f); Assert.That(RunManager.Instance.TryOpenPause(), Is.True); yield return null; Color paused = body.color; yield return new WaitForSecondsRealtime(1.2f); Assert.That(health.IsInvulnerable, Is.True); Assert.That(routine.GetValue(feedback), Is.Not.Null, "Damage blink must not expire on real time during pause."); Assert.That(body.color, Is.EqualTo(paused), "Blink phase freezes with game time."); Assert.That(RunManager.Instance.ClosePause(), Is.True); yield return new WaitForSeconds(0.4f); Assert.That(health.IsHurtMovementLocked, Is.False); Assert.That(health.IsInvulnerable, Is.True); Assert.That(routine.GetValue(feedback), Is.Not.Null); yield return new WaitForSeconds(0.5f); Assert.That(health.IsInvulnerable, Is.False); Assert.That(routine.GetValue(feedback), Is.Null); Assert.That(body.color, Is.EqualTo(original)); } [TearDown] public void TearDown() { ArtifactRewardController.GrantCatalogForTests = false; RunManager.ForceProductionModeForTests = false; Time.timeScale = 1f; } } }