using System.Collections; using NUnit.Framework; using TKS.OutGame; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TestTools; namespace TKS.Tests { /// /// 보물 메뉴 디자인 개선(PD 2026-11-13) — ① 보유 중·세트 = 보물고 배경 + 콜렉션 진열대 칸(칸 틀 · 선반) ② 상자 = 금고 배경 + 받침대 위 상자(표 chest_spot 자리 · 크기) /// ③ 상자 5종 = 새 납품 그림(Assets/UI/Samguk/chest · 같은 256² 규격) ④ 열기는 그대로 동작. 기대 값은 표 Resources/UI/treasure_scene.csv 에서 읽음(C45). /// public class TreasureSceneTests { OutGameRoot og; IEnumerator Boot() { WorldProgress.Reset(); SaveStore.UseMemory(true); SceneManager.LoadScene("Battle"); yield return null; yield return null; og = OutGameRoot.Instance; Assert.IsNotNull(og); og.ShowLobby(); TreasureScene.Reload(); } [UnityTest] public IEnumerator Vault_Shelves_Chest_OnPedestal() { yield return Boot(); var s = og.Session; og.OnTab(1); var tr = og.Treasures; Assert.AreEqual(tr, og.Current); tr.SetPage(0); yield return null; Assert.AreEqual("vault", tr.ShownScene, "보유 중 = 보물고 배경"); Assert.IsTrue(tr.ShelfCells, "보유 중 = 진열대 칸"); Assert.AreEqual(s.Db.Treasures.items.Count, tr.GridCount); tr.SetPage(1); yield return null; Assert.AreEqual("vault", tr.ShownScene, "세트 = 같은 보물고 배경"); Assert.IsTrue(tr.ShelfCells, "세트 = 진열대 칸"); Counts.Set(s.Save.inv.chests, s.Db.Economy.StageChest, 2); tr.SetPage(2); tr.SelectChest(s.Db.Economy.StageChest); yield return null; Assert.AreEqual("chest", tr.ShownScene, "상자 = 금고 배경"); Assert.IsTrue(tr.ChestOnPedestal, "받침대 배치"); var ic = tr.PedestalChest; Assert.IsNotNull(ic, "받침대 위 상자"); Assert.AreSame(UISkin.Icon("chest_" + s.Db.Economy.StageChest), ic.sprite, "고른 상자 그림"); var spot = DomesticScene.First(TreasureScene.Scene("chest"), "spot"); Assert.IsNotNull(spot, "표 chest_spot"); Assert.AreEqual(spot.w, ic.rectTransform.sizeDelta.x, 0.5f, "상자 크기 = 표"); // 화면에서 상자 가운데가 금고 그림의 방석 자리(표 좌표)에 있음 — 그림 기준 정규화 위치로 비교 var view = DomesticScene.First(TreasureScene.Scene("chest"), "view"); var art = GameObject.Find("Scene_chest").transform.Find("Art") as RectTransform; Assert.IsNotNull(art, "금고 그림"); var c = new Vector3[4]; art.GetWorldCorners(c); // 0 = 왼아래 · 2 = 오른위 var want = new Vector3(Mathf.Lerp(c[0].x, c[2].x, spot.x / view.w), Mathf.Lerp(c[2].y, c[0].y, spot.y / view.h), 0f); var got = ic.rectTransform.position; float px = (c[2].x - c[0].x) / view.w; // 그림 1 px 의 월드 길이 Assert.Less(Mathf.Abs(got.x - want.x) / px, 2f, "상자 x = 방석 가운데(그림 px 오차)"); Assert.Less(Mathf.Abs(got.y - want.y) / px, 2f, "상자 y = 표 자리(그림 px 오차)"); // 상자 5종 = 새 납품 그림(같은 규격) foreach (var ch in s.Db.Chests.chests) { Assert.IsTrue(UiKit.HasFinalIcon("chest_" + ch.id), ch.id + ": 납품 그림"); var sp = UISkin.Icon("chest_" + ch.id); Assert.AreEqual(256f, sp.rect.width, 0.5f, ch.id + ": 256²"); Assert.AreEqual(256f, sp.rect.height, 0.5f, ch.id + ": 256²"); } // 열기(받침대 위 상자가 흔들린 뒤 결과 · QA r1 U1) — 흔드는 동안은 아직 결과 없음 · 0.4 초 뒤 결과 · 상자 자세 복귀 int before = TreasureRules.ChestCount(s.Save, s.Db.Economy.StageChest); tr.OpenAnimated(s.Db.Economy.StageChest); yield return null; yield return null; var rt = tr.PedestalChest.rectTransform; Assert.AreEqual(before, TreasureRules.ChestCount(s.Save, s.Db.Economy.StageChest), "흔드는 중 = 아직 안 엶"); Assert.Greater(Mathf.Abs(rt.localEulerAngles.z) + Mathf.Abs(rt.localScale.x - 1f), 0.0001f, "상자가 흔들림"); yield return new WaitForSecondsRealtime(0.6f); Assert.AreEqual(before - 1, TreasureRules.ChestCount(s.Save, s.Db.Economy.StageChest), "흔든 뒤 열림"); Assert.IsNotNull(tr.LastOpen, "결과"); og.CloseModal(); // 유물 정보 = 선반 진열 무대(PD 2026-11-13 2차) — 얻은 유물을 열면 무대 위 방석에 그 유물 아이콘 if (tr.LastOpen.treasureId != null) { tr.SetPage(0); yield return null; tr.Detail(tr.LastOpen.treasureId); yield return null; Assert.IsTrue(og.ModalVisible, "정보 팝업"); Assert.IsNotNull(tr.DetailRelic, "무대 위 유물"); var stage = DomesticScene.First(TreasureScene.Scene("detail"), "stage"); Assert.AreEqual(stage.min, tr.DetailRelic.rectTransform.sizeDelta.x, 0.5f, "유물 크기 = 표"); og.CloseModal(); } } } }