Skip to content

Commit 1026050

Browse files
committed
merge pull
2 parents 67ee3a0 + 37a6ee2 commit 1026050

File tree

2 files changed

+122
-43
lines changed

2 files changed

+122
-43
lines changed
Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,62 @@
11
package com.outfitlab.project.domain.useCases.subscription;
22

33
import com.mercadopago.exceptions.MPApiException;
4-
import com.mercadopago.exceptions.MPException;
54
import org.junit.jupiter.api.BeforeEach;
65
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.api.extension.ExtendWith;
7+
import org.mockito.junit.jupiter.MockitoExtension;
78
import java.math.BigDecimal;
89

910
import static org.junit.jupiter.api.Assertions.*;
1011

12+
@ExtendWith(MockitoExtension.class)
1113
public class CreateMercadoPagoPreferenceTest {
1214

1315
private CreateMercadoPagoPreference createPreferenceUseCase;
1416
private final String PLAN_ID = "premium-demo-1";
1517
private final String USER_EMAIL = "[email protected]";
16-
private final BigDecimal PRICE = new BigDecimal("100.00");
18+
private final BigDecimal VALID_PRICE = new BigDecimal("25000.00");
1719
private final String CURRENCY = "ARS";
20+
private final String WEBHOOK_URL = "http://localhost:8080";
21+
private final String FRONTEND_URL = "http://localhost:5173";
1822

1923
@BeforeEach
2024
void setUp() {
21-
String webhookBaseUrl = "http://localhost:8080";
22-
String frontendBaseUrl = "http://localhost:5173";
23-
createPreferenceUseCase = new CreateMercadoPagoPreference(webhookBaseUrl, frontendBaseUrl);
25+
createPreferenceUseCase = new CreateMercadoPagoPreference(WEBHOOK_URL, FRONTEND_URL);
26+
}
27+
28+
29+
@Test
30+
public void shouldThrowMPApiExceptionWhenPriceIsNull() {
31+
BigDecimal invalidPrice = null;
32+
33+
//when y then
34+
thenExecutionThrowsMPApiException(PLAN_ID, USER_EMAIL, invalidPrice, CURRENCY);
35+
}
36+
37+
@Test
38+
public void shouldThrowMPApiExceptionWhenPriceIsZeroOrNegative() {
39+
BigDecimal zeroPrice = BigDecimal.ZERO;
40+
BigDecimal negativePrice = new BigDecimal("-1.00");
41+
42+
thenExecutionThrowsMPApiException(PLAN_ID, USER_EMAIL, zeroPrice, CURRENCY);
43+
thenExecutionThrowsMPApiException(PLAN_ID, USER_EMAIL, negativePrice, CURRENCY);
2444
}
2545

2646
@Test
27-
public void givenNullPriceWhenExecuteThenThrowMPApiException() {
47+
public void shouldThrowMPExceptionOrMPApiExceptionWhenUserEmailIsNull() {
48+
String invalidEmail = null;
49+
50+
assertThrows(MPApiException.class,
51+
() -> createPreferenceUseCase.execute(PLAN_ID, invalidEmail, VALID_PRICE, CURRENCY),
52+
"Se esperaba una MPApiException cuando el email del usuario es nulo.");
53+
}
54+
2855

29-
assertThrows(MPApiException.class, () -> createPreferenceUseCase.execute(PLAN_ID, USER_EMAIL, null, CURRENCY));
56+
//privado
57+
private void thenExecutionThrowsMPApiException(String planId, String email, BigDecimal price, String currency) {
58+
assertThrows(MPApiException.class,
59+
() -> createPreferenceUseCase.execute(planId, email, price, currency),
60+
"Se esperaba una MPApiException.");
3061
}
3162
}
Lines changed: 84 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package com.outfitlab.project.domain.useCases.subscription;
22

3-
import com.mercadopago.net.MPResponse;
43
import com.mercadopago.exceptions.MPApiException;
54
import com.mercadopago.exceptions.MPException;
5+
import com.mercadopago.net.MPResponse;
66
import com.mercadopago.resources.payment.Payment;
7-
import com.outfitlab.project.domain.interfaces.repositories.UserRepository;
7+
import com.outfitlab.project.domain.exceptions.SubscriptionNotFoundException;
88
import com.outfitlab.project.domain.interfaces.gateways.MercadoPagoPaymentGateway;
9+
import com.outfitlab.project.domain.interfaces.repositories.SubscriptionRepository;
10+
import com.outfitlab.project.domain.interfaces.repositories.UserSubscriptionRepository;
11+
import com.outfitlab.project.domain.interfaces.repositories.UserRepository;
12+
import com.outfitlab.project.domain.model.SubscriptionModel;
13+
import com.outfitlab.project.domain.model.UserSubscriptionModel;
914
import org.junit.jupiter.api.BeforeEach;
1015
import org.junit.jupiter.api.Test;
1116

@@ -16,63 +21,106 @@ public class ProcessPaymentNotificationTest {
1621

1722
private UserRepository userRepository = mock(UserRepository.class);
1823
private MercadoPagoPaymentGateway paymentGateway = mock(MercadoPagoPaymentGateway.class);
19-
private com.outfitlab.project.domain.interfaces.repositories.UserSubscriptionRepository userSubscriptionRepository = mock(com.outfitlab.project.domain.interfaces.repositories.UserSubscriptionRepository.class);
20-
private com.outfitlab.project.domain.interfaces.repositories.SubscriptionRepository subscriptionRepository = mock(com.outfitlab.project.domain.interfaces.repositories.SubscriptionRepository.class);
24+
private UserSubscriptionRepository userSubscriptionRepository = mock(UserSubscriptionRepository.class);
25+
private SubscriptionRepository subscriptionRepository = mock(SubscriptionRepository.class);
26+
2127
private ProcessPaymentNotification processNotificationUseCase;
2228

2329
private final Long PAYMENT_ID = 12345L;
2430
private final String EXTERNAL_REFERENCE = "user-id-5678";
31+
private final String PLAN_CODE = "premium";
32+
private final String PAYMENT_STATUS_APPROVED = "approved";
33+
private final String PAYMENT_STATUS_REJECTED = "rejected";
2534

2635
@BeforeEach
2736
void setUp() {
28-
processNotificationUseCase = new ProcessPaymentNotification(userRepository, paymentGateway, userSubscriptionRepository, subscriptionRepository);
37+
processNotificationUseCase = new ProcessPaymentNotification(
38+
userRepository,
39+
paymentGateway,
40+
userSubscriptionRepository,
41+
subscriptionRepository
42+
);
2943
}
3044

45+
3146
@Test
32-
public void givenApprovedPaymentWhenExecuteThenActivateUserPremium() throws MPException, MPApiException, com.outfitlab.project.domain.exceptions.SubscriptionNotFoundException {
33-
Payment mockPayment = mock(Payment.class);
34-
when(mockPayment.getStatus()).thenReturn("approved");
35-
when(mockPayment.getExternalReference()).thenReturn(EXTERNAL_REFERENCE);
36-
// Mock description to contain plan info if needed, or just ensure it doesn't crash
37-
when(mockPayment.getDescription()).thenReturn("Plan Premium");
38-
39-
when(paymentGateway.getPaymentDetails(PAYMENT_ID)).thenReturn(mockPayment);
40-
41-
// Mock subscription behavior
42-
com.outfitlab.project.domain.model.SubscriptionModel mockPlan = new com.outfitlab.project.domain.model.SubscriptionModel();
43-
mockPlan.setPlanCode("premium");
44-
mockPlan.setFeature2("Unlimited"); // For limit parsing
45-
when(subscriptionRepository.getByPlanCode(anyString())).thenReturn(mockPlan);
46-
47-
com.outfitlab.project.domain.model.UserSubscriptionModel mockUserSub = new com.outfitlab.project.domain.model.UserSubscriptionModel();
48-
when(userSubscriptionRepository.findByUserEmail(anyString())).thenReturn(mockUserSub);
47+
public void shouldActivateUserPremiumWhenPaymentIsApproved() throws MPException, MPApiException, SubscriptionNotFoundException {
48+
givenApprovedPaymentDetails(PAYMENT_ID, EXTERNAL_REFERENCE, "Plan Premium");
49+
givenSubscriptionModelsExist(PLAN_CODE);
4950

50-
processNotificationUseCase.execute(PAYMENT_ID);
51+
whenExecuteProcessNotification(PAYMENT_ID);
5152

52-
verify(paymentGateway, times(1)).getPaymentDetails(PAYMENT_ID);
53+
thenPaymentDetailsAreFetched(PAYMENT_ID);
5354
}
5455

5556
@Test
56-
public void givenRejectedPaymentWhenExecuteThenDoNotActivateUserPremium() throws MPException, MPApiException, com.outfitlab.project.domain.exceptions.SubscriptionNotFoundException {
57-
Payment mockPayment = mock(Payment.class);
58-
when(mockPayment.getStatus()).thenReturn("rejected");
59-
when(mockPayment.getExternalReference()).thenReturn(EXTERNAL_REFERENCE);
60-
when(paymentGateway.getPaymentDetails(PAYMENT_ID)).thenReturn(mockPayment);
57+
public void shouldNotUpdateSubscriptionWhenPaymentIsRejected() throws MPException, MPApiException, SubscriptionNotFoundException {
58+
givenRejectedPaymentDetails(PAYMENT_ID, EXTERNAL_REFERENCE);
6159

62-
processNotificationUseCase.execute(PAYMENT_ID);
60+
whenExecuteProcessNotification(PAYMENT_ID);
6361

64-
verify(paymentGateway, times(1)).getPaymentDetails(PAYMENT_ID);
65-
verify(userSubscriptionRepository, never()).update(any());
62+
thenPaymentDetailsAreFetched(PAYMENT_ID);
63+
thenUpdateWasNeverCalled();
6664
}
6765

6866
@Test
69-
public void givenMPApiExceptionWhenExecuteThenPropagateException() throws MPException, MPApiException, com.outfitlab.project.domain.exceptions.SubscriptionNotFoundException {
67+
public void shouldPropagateMPApiExceptionWhenFetchingPaymentDetailsFails() throws MPException, MPApiException {
68+
givenPaymentGatewayThrowsMPApiException(PAYMENT_ID);
69+
70+
assertThrows(MPApiException.class, () -> whenExecuteProcessNotification(PAYMENT_ID));
71+
72+
thenPaymentDetailsAreFetched(PAYMENT_ID);
73+
thenUpdateWasNeverCalled();
74+
}
75+
76+
77+
//privadoss
78+
private void givenApprovedPaymentDetails(Long paymentId, String externalReference, String planDescription) throws MPException, MPApiException {
79+
Payment mockPayment = mock(Payment.class);
80+
81+
when(mockPayment.getStatus()).thenReturn(PAYMENT_STATUS_APPROVED);
82+
when(mockPayment.getExternalReference()).thenReturn(externalReference);
83+
when(mockPayment.getDescription()).thenReturn(planDescription);
84+
85+
when(paymentGateway.getPaymentDetails(paymentId)).thenReturn(mockPayment);
86+
}
87+
88+
private void givenRejectedPaymentDetails(Long paymentId, String externalReference) throws MPException, MPApiException {
89+
Payment mockPayment = mock(Payment.class);
90+
when(mockPayment.getStatus()).thenReturn(PAYMENT_STATUS_REJECTED);
91+
when(mockPayment.getExternalReference()).thenReturn(externalReference);
92+
93+
when(paymentGateway.getPaymentDetails(paymentId)).thenReturn(mockPayment);
94+
}
95+
96+
private void givenSubscriptionModelsExist(String planCode) throws SubscriptionNotFoundException {
97+
SubscriptionModel mockPlan = mock(SubscriptionModel.class);
98+
when(mockPlan.getPlanCode()).thenReturn(planCode);
99+
when(mockPlan.getFeature2()).thenReturn("Unlimited");
100+
101+
when(subscriptionRepository.getByPlanCode(anyString())).thenReturn(mockPlan);
102+
103+
UserSubscriptionModel mockUserSub = mock(UserSubscriptionModel.class);
104+
when(userSubscriptionRepository.findByUserEmail(anyString())).thenReturn(mockUserSub);
105+
}
106+
107+
private void givenPaymentGatewayThrowsMPApiException(Long paymentId) throws MPException, MPApiException {
70108
MPResponse mockResponse = mock(MPResponse.class);
71109
doThrow(new MPApiException("Error de API simulado", mockResponse))
72-
.when(paymentGateway).getPaymentDetails(PAYMENT_ID);
110+
.when(paymentGateway).getPaymentDetails(paymentId);
111+
}
73112

74-
assertThrows(MPApiException.class, () -> processNotificationUseCase.execute(PAYMENT_ID));
75113

76-
verify(paymentGateway, times(1)).getPaymentDetails(PAYMENT_ID);
114+
private void whenExecuteProcessNotification(Long paymentId) throws MPException, MPApiException, SubscriptionNotFoundException {
115+
processNotificationUseCase.execute(paymentId);
116+
}
117+
118+
119+
private void thenPaymentDetailsAreFetched(Long paymentId) throws MPException, MPApiException {
120+
verify(paymentGateway, times(1)).getPaymentDetails(paymentId);
121+
}
122+
123+
private void thenUpdateWasNeverCalled() {
124+
verify(userSubscriptionRepository, never()).update(any());
77125
}
78126
}

0 commit comments

Comments
 (0)