1+ package com .outfitlab .project .domain .useCases .gmail ;
2+
3+ import com .outfitlab .project .domain .interfaces .gateways .GmailGateway ;
4+ import org .junit .jupiter .api .BeforeEach ;
5+ import org .junit .jupiter .api .Test ;
6+ import org .mockito .ArgumentCaptor ;
7+
8+ import static org .junit .jupiter .api .Assertions .*;
9+ import static org .mockito .Mockito .*;
10+
11+ public class SubscribeUserTest {
12+
13+ private GmailGateway gmailGateway = mock (GmailGateway .class );
14+ private SubscribeUser subscribeUser ;
15+
16+ private final String VALID_EMAIL =
"[email protected] " ;
17+ private final String EXPECTED_SUBJECT = "¡Bienvenido a OutfitLab! 🥳" ;
18+
19+ @ BeforeEach
20+ void setUp () {
21+ subscribeUser = new SubscribeUser (gmailGateway );
22+ }
23+
24+
25+ @ Test
26+ public void shouldSendWelcomeEmailToValidUser () {
27+ whenExecuteSubscribeUser (VALID_EMAIL );
28+
29+ thenWelcomeEmailWasSent (VALID_EMAIL );
30+ }
31+
32+ @ Test
33+ public void shouldThrowIllegalArgumentExceptionWhenEmailIsNull () {
34+ String nullEmail = null ;
35+
36+ assertThrows (IllegalArgumentException .class ,
37+ () -> whenExecuteSubscribeUser (nullEmail ),
38+ "Debe fallar si el email es nulo." );
39+
40+ thenEmailWasNeverSent ();
41+ }
42+
43+ @ Test
44+ public void shouldThrowIllegalArgumentExceptionWhenEmailIsEmpty () {
45+ String emptyEmail = "" ;
46+
47+ assertThrows (IllegalArgumentException .class ,
48+ () -> whenExecuteSubscribeUser (emptyEmail ),
49+ "Debe fallar si el email está vacío." );
50+
51+ thenEmailWasNeverSent ();
52+ }
53+
54+ @ Test
55+ public void shouldThrowIllegalArgumentExceptionWhenEmailIsBlank () {
56+ String blankEmail = " " ;
57+
58+ assertThrows (IllegalArgumentException .class ,
59+ () -> whenExecuteSubscribeUser (blankEmail ),
60+ "Debe fallar si el email contiene solo espacios." );
61+
62+ thenEmailWasNeverSent ();
63+ }
64+
65+ @ Test
66+ public void shouldThrowIllegalArgumentExceptionWhenEmailDoesNotContainAtSymbol () {
67+ String invalidEmail = "usuario.test.com" ;
68+
69+ assertThrows (IllegalArgumentException .class ,
70+ () -> whenExecuteSubscribeUser (invalidEmail ),
71+ "Debe fallar si el email no contiene '@'." );
72+
73+ thenEmailWasNeverSent ();
74+ }
75+
76+ @ Test
77+ public void shouldSendEmailWhenEmailIsOnlyAtSymbolAsValidationAllowsIt () {
78+ String email = "@" ;
79+
80+ whenExecuteSubscribeUser (email );
81+
82+ thenWelcomeEmailWasSent (email );
83+ }
84+
85+ @ Test
86+ public void shouldPropagateRuntimeExceptionWhenGmailGatewayFails () {
87+ givenGmailGatewayThrowsRuntimeException ();
88+
89+ assertThrows (RuntimeException .class ,
90+ () -> whenExecuteSubscribeUser (VALID_EMAIL ),
91+ "Debe propagar la excepción de Runtime si el gateway falla." );
92+
93+ thenEmailWasSent (VALID_EMAIL , 1 );
94+ }
95+
96+
97+ //privaadoss
98+ private void givenGmailGatewayThrowsRuntimeException () {
99+ doThrow (new RuntimeException ("Simulated network failure" ))
100+ .when (gmailGateway ).sendEmail (anyString (), anyString (), anyString ());
101+ }
102+
103+ private void whenExecuteSubscribeUser (String email ) {
104+ subscribeUser .execute (email );
105+ }
106+
107+ private void thenWelcomeEmailWasSent (String expectedEmail ) {
108+ ArgumentCaptor <String > emailCaptor = ArgumentCaptor .forClass (String .class );
109+ ArgumentCaptor <String > subjectCaptor = ArgumentCaptor .forClass (String .class );
110+ ArgumentCaptor <String > bodyCaptor = ArgumentCaptor .forClass (String .class );
111+
112+ verify (gmailGateway , times (1 )).sendEmail (emailCaptor .capture (), subjectCaptor .capture (), bodyCaptor .capture ());
113+
114+ assertEquals (expectedEmail , emailCaptor .getValue (), "El email del destinatario es incorrecto." );
115+ assertEquals (EXPECTED_SUBJECT , subjectCaptor .getValue (), "El asunto del correo es incorrecto." );
116+
117+ String actualBody = bodyCaptor .getValue ();
118+ assertNotNull (actualBody , "El cuerpo del correo no debe ser nulo." );
119+ assertTrue (actualBody .contains ("¡Gracias por suscribirte a OutfitLab!" ), "El cuerpo debe contener el mensaje de bienvenida." );
120+ assertTrue (actualBody .contains ("<html>" ), "El cuerpo debe contener formato HTML." );
121+ }
122+
123+ private void thenEmailWasSent (String expectedEmail , int times ) {
124+ verify (gmailGateway , times (times )).sendEmail (eq (expectedEmail ), anyString (), anyString ());
125+ }
126+
127+ private void thenEmailWasNeverSent () {
128+ verify (gmailGateway , never ()).sendEmail (anyString (), anyString (), anyString ());
129+ }
130+ }
0 commit comments