1+ package com .outfitlab .project .domain .useCases .dashboard ;
2+
3+ import com .outfitlab .project .domain .interfaces .repositories .CombinationAttemptRepository ;
4+ import com .outfitlab .project .domain .model .CombinationAttemptModel ;
5+ import com .outfitlab .project .domain .model .CombinationModel ;
6+ import com .outfitlab .project .domain .model .PrendaModel ;
7+ import com .outfitlab .project .domain .model .BrandModel ;
8+ import com .outfitlab .project .domain .model .ColorModel ;
9+ import com .outfitlab .project .domain .model .dto .PrendaDashboardDTO .ColorConversion ;
10+ import org .junit .jupiter .api .BeforeEach ;
11+ import org .junit .jupiter .api .Test ;
12+ import java .util .*;
13+
14+ import static org .junit .jupiter .api .Assertions .*;
15+ import static org .mockito .Mockito .*;
16+
17+ public class GetColorConversionTest {
18+
19+ private CombinationAttemptRepository combinationAttemptRepository = mock (CombinationAttemptRepository .class );
20+ private GetColorConversion getColorConversion ;
21+
22+ private final String TARGET_BRAND = "ADIDAS" ;
23+ private final String OTHER_BRAND = "NIKE" ;
24+ private final String COLOR_RED = "Rojo" ;
25+ private final String COLOR_BLUE = "Azul" ;
26+
27+ @ BeforeEach
28+ void setUp () {
29+ getColorConversion = new GetColorConversion (combinationAttemptRepository );
30+ }
31+
32+
33+ @ Test
34+ public void shouldReturnCorrectCountsAndSortByPruebasForTargetBrand () {
35+ List <CombinationAttemptModel > mockAttempts = new ArrayList <>();
36+ mockAttempts .add (createAttempt (TARGET_BRAND , COLOR_RED , OTHER_BRAND , COLOR_BLUE ));
37+ mockAttempts .add (createAttempt (TARGET_BRAND , COLOR_RED , TARGET_BRAND , COLOR_BLUE ));
38+ mockAttempts .add (createAttempt (OTHER_BRAND , COLOR_BLUE , TARGET_BRAND , COLOR_RED ));
39+ mockAttempts .add (createAttempt (TARGET_BRAND , COLOR_BLUE , OTHER_BRAND , COLOR_RED ));
40+
41+ givenRepositoryReturnsAttempts (mockAttempts );
42+
43+ List <ColorConversion > result = whenExecuteGetColorConversion (TARGET_BRAND );
44+
45+ thenResultSizeIsCorrect (result , 2 );
46+ thenResultIsSortedAndCountedCorrectly (result , COLOR_RED , 3 , COLOR_BLUE , 2 );
47+ }
48+
49+ @ Test
50+ public void shouldReturnEmptyListWhenNoAttemptsAreFound () {
51+ givenRepositoryReturnsAttempts (Collections .emptyList ());
52+
53+ List <ColorConversion > result = whenExecuteGetColorConversion (TARGET_BRAND );
54+
55+ thenResultSizeIsCorrect (result , 0 );
56+ }
57+
58+ @ Test
59+ public void shouldCountColorOncePerAttemptEvenIfUsedTwice () {
60+ List <CombinationAttemptModel > mockAttempts = List .of (
61+ createAttempt (TARGET_BRAND , COLOR_RED , TARGET_BRAND , COLOR_RED )
62+ );
63+ givenRepositoryReturnsAttempts (mockAttempts );
64+
65+ List <ColorConversion > result = whenExecuteGetColorConversion (TARGET_BRAND );
66+
67+ thenResultSizeIsCorrect (result , 1 );
68+ thenResultIsSortedAndCountedCorrectly (result , COLOR_RED , 1 );
69+ }
70+
71+ @ Test
72+ public void shouldHandleNullPrendasOrNullColorNamesWithoutNPE () {
73+ List <CombinationAttemptModel > mockAttempts = new ArrayList <>();
74+
75+ mockAttempts .add (createAttempt (TARGET_BRAND , COLOR_RED , null , COLOR_BLUE ));
76+ mockAttempts .add (createAttempt (null , COLOR_RED , TARGET_BRAND , COLOR_BLUE ));
77+ mockAttempts .add (createAttempt (null , null , null , null ));
78+
79+ givenRepositoryReturnsAttempts (mockAttempts );
80+
81+ List <ColorConversion > result = whenExecuteGetColorConversion (TARGET_BRAND );
82+
83+ thenResultSizeIsCorrect (result , 2 );
84+ thenResultIsSortedAndCountedCorrectly (result , COLOR_RED , 1 , COLOR_BLUE , 1 );
85+ }
86+
87+ @ Test
88+ public void shouldReturnEmptyListWhenTargetBrandCodeIsNull () {
89+ givenRepositoryReturnsAttempts (List .of (createAttempt (TARGET_BRAND , COLOR_RED , TARGET_BRAND , COLOR_RED )));
90+
91+ List <ColorConversion > result = whenExecuteGetColorConversion (null );
92+
93+ thenResultSizeIsCorrect (result , 0 );
94+ }
95+
96+
97+ //privadoss
98+ private void givenRepositoryReturnsAttempts (List <CombinationAttemptModel > attempts ) {
99+ when (combinationAttemptRepository .findAll ()).thenReturn (attempts );
100+ }
101+
102+ private CombinationAttemptModel createAttempt (String supBrandCode , String supColorName ,
103+ String infBrandCode , String infColorName ) {
104+
105+ final String safeSupBrandCode = supBrandCode != null ? supBrandCode : "" ;
106+ final String safeInfBrandCode = infBrandCode != null ? infBrandCode : "" ;
107+ final String safeSupColorName = supColorName != null ? supColorName : "" ;
108+ final String safeInfColorName = infColorName != null ? infColorName : "" ;
109+
110+ CombinationAttemptModel attempt = mock (CombinationAttemptModel .class );
111+ CombinationModel combination = mock (CombinationModel .class );
112+
113+ PrendaModel prendaSup = mock (PrendaModel .class );
114+
115+ BrandModel brandSup = mock (BrandModel .class );
116+ when (brandSup .getCodigoMarca ()).thenReturn (safeSupBrandCode );
117+ when (prendaSup .getMarca ()).thenReturn (brandSup );
118+
119+ ColorModel colorSup = mock (ColorModel .class );
120+ when (colorSup .getNombre ()).thenReturn (safeSupColorName );
121+ when (prendaSup .getColor ()).thenReturn (colorSup );
122+
123+ PrendaModel prendaInf = mock (PrendaModel .class );
124+
125+ BrandModel brandInf = mock (BrandModel .class );
126+ when (brandInf .getCodigoMarca ()).thenReturn (safeInfBrandCode );
127+ when (prendaInf .getMarca ()).thenReturn (brandInf );
128+
129+ ColorModel colorInf = mock (ColorModel .class );
130+ when (colorInf .getNombre ()).thenReturn (safeInfColorName );
131+ when (prendaInf .getColor ()).thenReturn (colorInf );
132+
133+ when (combination .getPrendaSuperior ()).thenReturn (prendaSup );
134+ when (combination .getPrendaInferior ()).thenReturn (prendaInf );
135+
136+ when (attempt .getCombination ()).thenReturn (combination );
137+
138+ return attempt ;
139+ }
140+
141+ private List <ColorConversion > whenExecuteGetColorConversion (String brandCode ) {
142+ return getColorConversion .execute (brandCode );
143+ }
144+
145+ private void thenResultSizeIsCorrect (List <ColorConversion > result , int size ) {
146+ assertNotNull (result );
147+ assertEquals (size , result .size (), "La lista resultante debe tener el tamaño esperado." );
148+ }
149+
150+ private void thenResultIsSortedAndCountedCorrectly (List <ColorConversion > result , Object ... expectedPairs ) {
151+
152+ if (result .size () > 1 ) {
153+ assertTrue (result .get (0 ).pruebas () >= result .get (1 ).pruebas (), "El resultado debe estar ordenado por 'pruebas' descendente." );
154+ }
155+
156+ Map <String , Integer > actualCounts = new HashMap <>();
157+ result .forEach (cc -> actualCounts .put (cc .color (), cc .pruebas ()));
158+
159+ for (int i = 0 ; i < expectedPairs .length ; i += 2 ) {
160+ String colorName = (String ) expectedPairs [i ];
161+ int expectedCount = (Integer ) expectedPairs [i + 1 ];
162+
163+ assertTrue (actualCounts .containsKey (colorName ), "El color '" + colorName + "' debe estar en la lista." );
164+ assertEquals (expectedCount , actualCounts .get (colorName ), "El conteo de pruebas para " + colorName + " es incorrecto." );
165+
166+ result .stream ()
167+ .filter (cc -> cc .color ().equals (colorName ))
168+ .findFirst ()
169+ .ifPresent (cc -> {
170+ assertEquals (0 , cc .favoritos (), "El campo 'favoritos' debe ser 0." );
171+ assertEquals (0.0 , cc .conversion (), 0.001 , "El campo 'conversion' debe ser 0.0." );
172+ });
173+ }
174+ }
175+ }
0 commit comments