using System; using System.Collections.Generic; using NUnit.Framework; using UnityEngine; using Quests.Runtime; using Core.Runtime; namespace GuildTycoon.Tests.Editor { public class QuestManagerTests { private GameObject _gmGO; private GameObject _qmGO; private GameManager _gameManager; private QuestManager _questManager; [SetUp] public void SetUp() { // Create and initialize GameManager (Awake will set up facts dictionary) _gmGO = new GameObject("GameManager_Test"); _gameManager = _gmGO.AddComponent(); // Ensure profile and base facts are set _gameManager.Profile = "UnitTestProfile"; _gameManager.Fact = new FactDictionnary(); GameManager.m_gameFacts = _gameManager.Fact; // ensure BaseMonobehaviour access works // Pre-seed facts used by QuestManager _gameManager.Fact.SetFact("accepted_quests", new List(), BaseMonobehaviour.FactPersistence.Normal); _gameManager.Fact.SetFact("events_quests_history", new Dictionary>(), BaseMonobehaviour.FactPersistence.Normal); // Create QuestManager _qmGO = new GameObject("QuestManager_Test"); _questManager = _qmGO.AddComponent(); // Initialize lists to avoid nulls and isolate from Start() DB usage _questManager.ActiveQuests = new List(); _questManager.CompletedQuests = new List(); _questManager.DisponibleQuests = new List(); } [TearDown] public void TearDown() { if (_qmGO != null) UnityEngine.Object.DestroyImmediate(_qmGO); if (_gmGO != null) UnityEngine.Object.DestroyImmediate(_gmGO); } [Test] public void CompletingQuest_MovesItFromActiveToCompleted_AndUpdatesFacts() { // Arrange: create a simple quest in progress var questId = Guid.NewGuid(); var quest = new QuestClass(questId, "Test Quest", "Desc", "Obj", duration: 1, difficulty: QuestDifficultyEnum.Easy, reward: new List(), minLevel: 1) { State = QuestStateEnum.InProgress, StartSeconds = 0, EndSeconds = 10, AssignedAdventurersID = new List() }; _questManager.ActiveQuests.Add(quest); // Seed facts with the same quest so QuestManager can update saved state var accepted = new List { new QuestClass(questId, quest.Name, quest.Description, quest.Objective, quest.Duration, quest.Difficulty, quest.Rewards, quest.MinLevel) { State = QuestStateEnum.InProgress } }; _gameManager.Fact.SetFact("accepted_quests", accepted, BaseMonobehaviour.FactPersistence.Normal); QuestClass completedRaised = null; Action handler = q => completedRaised = q; QuestManager.OnQuestCompleted += handler; try { // Act: Directly complete the quest _questManager.CompleteQuest(quest, quest.AssignedAdventurersID); } finally { QuestManager.OnQuestCompleted -= handler; // ensure unsubscribe even if assertion fails } // Assert: quest state and lists updated Assert.AreEqual(QuestStateEnum.Completed, quest.State, "La quête devrait être marquée comme complétée."); CollectionAssert.DoesNotContain(_questManager.ActiveQuests, quest, "La quête ne doit plus être dans la liste des quêtes actives."); CollectionAssert.Contains(_questManager.CompletedQuests, quest, "La quête devrait apparaître dans la liste des quêtes complétées."); // Facts: accepted_quests should reflect Completed state for the same ID var saved = _gameManager.Fact.GetFact>("accepted_quests"); var savedQuest = saved.Find(q => q.ID == questId); Assert.IsNotNull(savedQuest, "La quête devrait être présente dans les faits 'accepted_quests'."); Assert.AreEqual(QuestStateEnum.Completed, savedQuest.State, "L'état sauvegardé de la quête devrait être 'Completed'."); // Event notification raised Assert.IsNotNull(completedRaised, "Un événement OnQuestCompleted devrait être déclenché."); Assert.AreEqual(questId, completedRaised.ID, "L'événement devrait concerner la même quête."); } } }