mirror of
https://github.com/valitydev/disputes-api.git
synced 2024-11-06 00:55:23 +00:00
increase test coverage (#13)
This commit is contained in:
parent
1cbbda9909
commit
5f866d78da
@ -69,14 +69,6 @@ public class DisputeDao extends AbstractGenericDao {
|
||||
return Optional.ofNullable(fetchOne(query, disputeRowMapper));
|
||||
}
|
||||
|
||||
public Optional<Dispute> getForUpdateSkipLocked(long disputeId) {
|
||||
var query = getDslContext().selectFrom(DISPUTE)
|
||||
.where(DISPUTE.ID.eq(disputeId))
|
||||
.forUpdate()
|
||||
.skipLocked();
|
||||
return Optional.ofNullable(fetchOne(query, disputeRowMapper));
|
||||
}
|
||||
|
||||
public List<Dispute> getDisputesForUpdateSkipLocked(int limit, DisputeStatus disputeStatus) {
|
||||
var query = getDslContext().selectFrom(DISPUTE)
|
||||
.where(DISPUTE.STATUS.eq(disputeStatus)
|
||||
|
@ -42,12 +42,11 @@ public class ManualParsingDisputesService {
|
||||
public void cancelPendingDispute(CancelParams cancelParams) {
|
||||
var disputeId = cancelParams.getDisputeId();
|
||||
log.debug("Trying to getForUpdateSkipLocked {}", disputeId);
|
||||
var disputeOptional = disputeDao.getForUpdateSkipLocked(Long.parseLong(disputeId));
|
||||
if (disputeOptional.isEmpty()) {
|
||||
var dispute = disputeDao.getDisputeForUpdateSkipLocked(Long.parseLong(disputeId));
|
||||
if (dispute == null) {
|
||||
return;
|
||||
}
|
||||
var cancelReason = cancelParams.getCancelReason().orElse(null);
|
||||
var dispute = disputeOptional.get();
|
||||
log.debug("GetForUpdateSkipLocked has been found {}", dispute);
|
||||
if (DISPUTE_PENDING.contains(dispute.getStatus())) {
|
||||
// используется не failed, а cancelled чтоб можно было понять, что зафейлен по внешнему вызову
|
||||
@ -63,11 +62,10 @@ public class ManualParsingDisputesService {
|
||||
public void approvePendingDispute(ApproveParams approveParam) {
|
||||
var disputeId = approveParam.getDisputeId();
|
||||
log.debug("Trying to getForUpdateSkipLocked {}", disputeId);
|
||||
var disputeOptional = disputeDao.getForUpdateSkipLocked(Long.parseLong(disputeId));
|
||||
if (disputeOptional.isEmpty()) {
|
||||
var dispute = disputeDao.getDisputeForUpdateSkipLocked(Long.parseLong(disputeId));
|
||||
if (dispute == null) {
|
||||
return;
|
||||
}
|
||||
var dispute = disputeOptional.get();
|
||||
log.debug("GetForUpdateSkipLocked has been found {}", dispute);
|
||||
var skipCallHg = approveParam.isSkipCallHgForCreateAdjustment();
|
||||
var targetStatus = skipCallHg ? DisputeStatus.succeeded : DisputeStatus.create_adjustment;
|
||||
@ -92,12 +90,11 @@ public class ManualParsingDisputesService {
|
||||
public void bindCreatedDispute(BindParams bindParam) {
|
||||
var disputeId = bindParam.getDisputeId();
|
||||
log.debug("Trying to getForUpdateSkipLocked {}", disputeId);
|
||||
var disputeOptional = disputeDao.getForUpdateSkipLocked(Long.parseLong(disputeId));
|
||||
if (disputeOptional.isEmpty()) {
|
||||
var dispute = disputeDao.getDisputeForUpdateSkipLocked(Long.parseLong(disputeId));
|
||||
if (dispute == null) {
|
||||
return;
|
||||
}
|
||||
var providerDisputeId = bindParam.getProviderDisputeId();
|
||||
var dispute = disputeOptional.get();
|
||||
log.debug("GetForUpdateSkipLocked has been found {}", dispute);
|
||||
if (dispute.getStatus() == DisputeStatus.manual_created) {
|
||||
// обрабатываем здесь только вручную созданные диспуты, у остальных предполагается,
|
||||
|
@ -28,7 +28,7 @@ public class InvoicePaymentAdjustmentParamsConverter {
|
||||
return params;
|
||||
}
|
||||
|
||||
private String getReason(Dispute dispute) {
|
||||
public String getReason(Dispute dispute) {
|
||||
return Optional.ofNullable(dispute.getReason())
|
||||
.map(s -> String.format(DISPUTE_MASK + ", reason=%s", dispute.getId(), s))
|
||||
.orElse(String.format(DISPUTE_MASK, dispute.getId()));
|
||||
|
@ -6,6 +6,7 @@ import dev.vality.damsel.domain.InvoicePaymentStatus;
|
||||
import dev.vality.damsel.payment_processing.InvoicePayment;
|
||||
import dev.vality.disputes.domain.tables.pojos.Dispute;
|
||||
import jakarta.annotation.Nonnull;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
@ -21,14 +22,14 @@ public class AdjustmentExtractor {
|
||||
public Optional<InvoicePaymentAdjustment> searchAdjustmentByDispute(InvoicePayment invoicePayment, Dispute dispute) {
|
||||
return getInvoicePaymentAdjustmentStream(invoicePayment)
|
||||
.filter(adj -> adj.getReason() != null)
|
||||
.filter(adj -> isDisputesAdjustment(adj, dispute))
|
||||
.filter(adj -> isDisputesAdjustment(adj.getReason(), dispute))
|
||||
.findFirst()
|
||||
.or(() -> getInvoicePaymentAdjustmentStream(invoicePayment)
|
||||
.filter(s -> s.getState() != null)
|
||||
.filter(s -> s.getState().isSetStatusChange())
|
||||
.filter(s -> getTargetStatus(s).isSetCaptured())
|
||||
.filter(s -> getTargetStatus(s).getCaptured().getReason() != null)
|
||||
.filter(s -> isDisputesAdjustment(s, dispute))
|
||||
.filter(s -> isDisputesAdjustment(getTargetStatus(s).getCaptured().getReason(), dispute))
|
||||
.findFirst());
|
||||
}
|
||||
|
||||
@ -48,7 +49,7 @@ public class AdjustmentExtractor {
|
||||
return s.getState().getStatusChange().getScenario().getTargetStatus();
|
||||
}
|
||||
|
||||
private boolean isDisputesAdjustment(InvoicePaymentAdjustment adj, Dispute dispute) {
|
||||
return adj.getReason().contains(String.format(DISPUTE_MASK, dispute.getId()));
|
||||
private boolean isDisputesAdjustment(String reason, Dispute dispute) {
|
||||
return !StringUtils.isBlank(reason) && reason.contains(String.format(DISPUTE_MASK, dispute.getId()));
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class CreateAdjustmentsService {
|
||||
return;
|
||||
}
|
||||
} catch (InvoicingPaymentStatusPendingException e) {
|
||||
// в теории 0%, что сюда попдает выполнение кода, но если попадет, то:
|
||||
// в теории 0%, что сюда попадает выполнение кода, но если попадет, то:
|
||||
// платеж с не финальным статусом будет заблочен для создания корректировок на стороне хелгейта
|
||||
// и тогда диспут будет пулиться, пока платеж не зафиналится,
|
||||
// и тк никакой записи в коде выше нет, то пуллинг не проблема
|
||||
|
@ -55,9 +55,9 @@ public class InvoicingServiceImpl implements InvoicingService {
|
||||
InvoicePaymentAdjustmentParams params) {
|
||||
try {
|
||||
log.debug("createPaymentAdjustment with id: {}", invoiceId);
|
||||
var invoice = invoicingClient.createPaymentAdjustment(invoiceId, paymentId, params);
|
||||
var invoicePaymentAdjustment = invoicingClient.createPaymentAdjustment(invoiceId, paymentId, params);
|
||||
log.debug("Done createPaymentAdjustment with id: {}", invoiceId);
|
||||
return invoice;
|
||||
return invoicePaymentAdjustment;
|
||||
} catch (InvoiceNotFound | InvoicePaymentNotFound e) {
|
||||
// закрываем диспут с фейлом если получили не преодолимый отказ внешних шлюзов с ключевыми данными
|
||||
return null;
|
||||
|
@ -0,0 +1,183 @@
|
||||
package dev.vality.disputes.api;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import dev.vality.bouncer.decisions.ArbiterSrv;
|
||||
import dev.vality.damsel.payment_processing.InvoicingSrv;
|
||||
import dev.vality.disputes.auth.utils.JwtTokenBuilder;
|
||||
import dev.vality.disputes.config.WireMockSpringBootITest;
|
||||
import dev.vality.disputes.dao.DisputeDao;
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.schedule.service.config.WiremockAddressesHolder;
|
||||
import dev.vality.disputes.service.external.impl.dominant.DominantAsyncService;
|
||||
import dev.vality.disputes.util.MockUtil;
|
||||
import dev.vality.disputes.util.OpenApiUtil;
|
||||
import dev.vality.disputes.util.WiremockUtils;
|
||||
import dev.vality.file.storage.FileStorageSrv;
|
||||
import dev.vality.swag.disputes.model.Create200Response;
|
||||
import dev.vality.token.keeper.TokenAuthenticatorSrv;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static dev.vality.disputes.util.MockUtil.*;
|
||||
import static java.util.UUID.randomUUID;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@WireMockSpringBootITest
|
||||
@SuppressWarnings({"ParameterName", "LineLength"})
|
||||
@Import(WiremockAddressesHolder.class)
|
||||
public class DisputesApiDelegateServiceTest {
|
||||
|
||||
@MockBean
|
||||
private InvoicingSrv.Iface invoicingClient;
|
||||
@MockBean
|
||||
private TokenAuthenticatorSrv.Iface tokenKeeperClient;
|
||||
@MockBean
|
||||
private ArbiterSrv.Iface bouncerClient;
|
||||
@MockBean
|
||||
private DominantAsyncService dominantAsyncService;
|
||||
@MockBean
|
||||
private FileStorageSrv.Iface fileStorageClient;
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
@Autowired
|
||||
private JwtTokenBuilder tokenBuilder;
|
||||
@Autowired
|
||||
private DisputeDao disputeDao;
|
||||
@Autowired
|
||||
private WiremockAddressesHolder wiremockAddressesHolder;
|
||||
private AutoCloseable mocks;
|
||||
private Object[] preparedMocks;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
mocks = MockitoAnnotations.openMocks(this);
|
||||
preparedMocks = new Object[]{invoicingClient, tokenKeeperClient, bouncerClient,
|
||||
fileStorageClient, dominantAsyncService};
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void clean() throws Exception {
|
||||
verifyNoMoreInteractions(preparedMocks);
|
||||
mocks.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void testFullApiFlowSuccess() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
when(invoicingClient.get(any(), any()))
|
||||
.thenReturn(MockUtil.createInvoice(invoiceId, paymentId));
|
||||
when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData());
|
||||
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
|
||||
when(dominantAsyncService.getTerminal(any())).thenReturn(createTerminal());
|
||||
when(dominantAsyncService.getCurrency(any())).thenReturn(createCurrency());
|
||||
when(fileStorageClient.createNewFile(any(), any())).thenReturn(createNewFileResult(wiremockAddressesHolder.getUploadUrl()));
|
||||
WiremockUtils.mockS3AttachmentUpload();
|
||||
var resultActions = mvc.perform(post("/disputes/create")
|
||||
.header("Authorization", "Bearer " + tokenBuilder.generateJwtWithRoles())
|
||||
.header("X-Request-ID", randomUUID())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(OpenApiUtil.getContentCreateRequest(invoiceId, paymentId)))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andExpect(jsonPath("$.disputeId").isNotEmpty());
|
||||
var response = new ObjectMapper().readValue(resultActions.andReturn().getResponse().getContentAsString(), Create200Response.class);
|
||||
verify(invoicingClient, times(1)).get(any(), any());
|
||||
verify(tokenKeeperClient, times(1)).authenticate(any(), any());
|
||||
verify(bouncerClient, times(1)).judge(any(), any());
|
||||
verify(dominantAsyncService, times(1)).getTerminal(any());
|
||||
verify(dominantAsyncService, times(1)).getCurrency(any());
|
||||
verify(fileStorageClient, times(1)).createNewFile(any(), any());
|
||||
mvc.perform(get("/disputes/status")
|
||||
.header("Authorization", "Bearer " + tokenBuilder.generateJwtWithRoles())
|
||||
.header("X-Request-ID", randomUUID())
|
||||
.params(OpenApiUtil.getStatusRequiredParams(response.getDisputeId(), invoiceId, paymentId))
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(""))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andExpect(jsonPath("$.status").isNotEmpty());
|
||||
verify(invoicingClient, times(2)).get(any(), any());
|
||||
verify(tokenKeeperClient, times(2)).authenticate(any(), any());
|
||||
verify(bouncerClient, times(2)).judge(any(), any());
|
||||
// exist
|
||||
resultActions = mvc.perform(post("/disputes/create")
|
||||
.header("Authorization", "Bearer " + tokenBuilder.generateJwtWithRoles())
|
||||
.header("X-Request-ID", randomUUID())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(OpenApiUtil.getContentCreateRequest(invoiceId, paymentId)))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andExpect(jsonPath("$.disputeId").isNotEmpty());
|
||||
assertEquals(response.getDisputeId(), new ObjectMapper().readValue(resultActions.andReturn().getResponse().getContentAsString(), Create200Response.class).getDisputeId());
|
||||
verify(invoicingClient, times(3)).get(any(), any());
|
||||
verify(tokenKeeperClient, times(3)).authenticate(any(), any());
|
||||
verify(bouncerClient, times(3)).judge(any(), any());
|
||||
disputeDao.update(Long.parseLong(response.getDisputeId()), DisputeStatus.failed);
|
||||
// new after failed
|
||||
when(fileStorageClient.createNewFile(any(), any())).thenReturn(createNewFileResult(wiremockAddressesHolder.getUploadUrl()));
|
||||
resultActions = mvc.perform(post("/disputes/create")
|
||||
.header("Authorization", "Bearer " + tokenBuilder.generateJwtWithRoles())
|
||||
.header("X-Request-ID", randomUUID())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(OpenApiUtil.getContentCreateRequest(invoiceId, paymentId)))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andExpect(jsonPath("$.disputeId").isNotEmpty());
|
||||
assertNotEquals(response.getDisputeId(), new ObjectMapper().readValue(resultActions.andReturn().getResponse().getContentAsString(), Create200Response.class).getDisputeId());
|
||||
verify(invoicingClient, times(4)).get(any(), any());
|
||||
verify(tokenKeeperClient, times(4)).authenticate(any(), any());
|
||||
verify(bouncerClient, times(4)).judge(any(), any());
|
||||
verify(dominantAsyncService, times(2)).getTerminal(any());
|
||||
verify(dominantAsyncService, times(2)).getCurrency(any());
|
||||
verify(fileStorageClient, times(2)).createNewFile(any(), any());
|
||||
disputeDao.update(Long.parseLong(response.getDisputeId()), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void testBadRequestWhenInvalidCreateRequest() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
mvc.perform(post("/disputes/create")
|
||||
.header("Authorization", "Bearer " + tokenBuilder.generateJwtWithRoles())
|
||||
.header("X-Request-ID", randomUUID())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(OpenApiUtil.getContentInvalidCreateRequest(paymentId)))
|
||||
.andExpect(status().is4xxClientError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
void testNotFoundWhenUnknownDisputeId() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = String.valueOf(Long.MAX_VALUE);
|
||||
when(invoicingClient.get(any(), any()))
|
||||
.thenReturn(MockUtil.createInvoice(invoiceId, paymentId));
|
||||
when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData());
|
||||
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
|
||||
mvc.perform(get("/disputes/status")
|
||||
.header("Authorization", "Bearer " + tokenBuilder.generateJwtWithRoles())
|
||||
.header("X-Request-ID", randomUUID())
|
||||
.params(OpenApiUtil.getStatusRequiredParams(disputeId, invoiceId, paymentId))
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(""))
|
||||
.andExpect(status().is4xxClientError());
|
||||
verify(invoicingClient, times(1)).get(any(), any());
|
||||
verify(tokenKeeperClient, times(1)).authenticate(any(), any());
|
||||
verify(bouncerClient, times(1)).judge(any(), any());
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package dev.vality.disputes.auth;
|
||||
|
||||
import dev.vality.disputes.auth.utils.JwtTokenBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.*;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.Properties;
|
||||
|
||||
@Configuration
|
||||
public class JwtTokenTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public static PropertySourcesPlaceholderConfigurer properties(KeyPair keyPair)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
|
||||
KeyFactory fact = KeyFactory.getInstance("RSA");
|
||||
X509EncodedKeySpec spec = fact.getKeySpec(keyPair.getPublic(), X509EncodedKeySpec.class);
|
||||
String publicKey = Base64.getEncoder().encodeToString(spec.getEncoded());
|
||||
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
|
||||
Properties properties = new Properties();
|
||||
properties.load(new ClassPathResource("application.yml").getInputStream());
|
||||
properties.setProperty("keycloak.realm-public-key", publicKey);
|
||||
pspc.setProperties(properties);
|
||||
pspc.setLocalOverride(true);
|
||||
return pspc;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JwtTokenBuilder jwtTokenBuilder(KeyPair keyPair) {
|
||||
return new JwtTokenBuilder(keyPair.getPrivate());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KeyPair keyPair() throws GeneralSecurityException {
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(2048);
|
||||
return keyGen.generateKeyPair();
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package dev.vality.disputes.auth.utils;
|
||||
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class JwtTokenBuilder {
|
||||
|
||||
private static final String DEFAULT_USERNAME = "Darth Vader";
|
||||
private static final String DEFAULT_EMAIL = "darkside-the-best@mail.com";
|
||||
|
||||
private final String userId;
|
||||
private final String username;
|
||||
private final String email;
|
||||
private final PrivateKey privateKey;
|
||||
|
||||
public JwtTokenBuilder(PrivateKey privateKey) {
|
||||
this(UUID.randomUUID().toString(), DEFAULT_USERNAME, DEFAULT_EMAIL, privateKey);
|
||||
}
|
||||
|
||||
public JwtTokenBuilder(String userId, String username, String email, PrivateKey privateKey) {
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
this.privateKey = privateKey;
|
||||
}
|
||||
|
||||
public String generateJwtWithRoles(String... roles) {
|
||||
long iat = Instant.now().getEpochSecond();
|
||||
long exp = iat + 60 * 10;
|
||||
return generateJwtWithRoles(iat, exp, roles);
|
||||
}
|
||||
|
||||
public String generateJwtWithRoles(long iat, long exp, String... roles) {
|
||||
String payload;
|
||||
try {
|
||||
payload = new JSONObject()
|
||||
.put("jti", UUID.randomUUID().toString())
|
||||
.put("exp", exp)
|
||||
.put("nbf", "0")
|
||||
.put("iat", iat)
|
||||
.put("aud", "private-api")
|
||||
.put("sub", userId)
|
||||
.put("typ", "Bearer")
|
||||
.put("azp", "private-api")
|
||||
.put("resource_access", new JSONObject()
|
||||
.put("common-api", new JSONObject()
|
||||
.put("roles", new JSONArray(roles))))
|
||||
.put("preferred_username", username)
|
||||
.put("email", email).toString();
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return Jwts.builder()
|
||||
.content(payload)
|
||||
.signWith(privateKey, Jwts.SIG.RS256)
|
||||
.compact();
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package dev.vality.disputes.config;
|
||||
|
||||
import dev.vality.disputes.config.testconfiguration.EmbeddedPostgresWithFlywayConfiguration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package dev.vality.disputes.config.testconfiguration;
|
||||
package dev.vality.disputes.config;
|
||||
|
||||
import io.zonky.test.db.postgres.embedded.FlywayPreparer;
|
||||
import io.zonky.test.db.postgres.embedded.PreparedDbProvider;
|
@ -0,0 +1,27 @@
|
||||
package dev.vality.disputes.config;
|
||||
|
||||
import dev.vality.disputes.DisputesApiApplication;
|
||||
import dev.vality.testcontainers.annotations.postgresql.PostgresqlTestcontainerSingleton;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@DisableScheduling
|
||||
@PostgresqlTestcontainerSingleton
|
||||
@AutoConfigureMockMvc
|
||||
@AutoConfigureWireMock(port = 0)
|
||||
@SpringBootTest(
|
||||
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = DisputesApiApplication.class,
|
||||
properties = {
|
||||
"wiremock.server.baseUrl=http://localhost:${wiremock.server.port}",
|
||||
"logging.level.WireMock=WARN"})
|
||||
public @interface WireMockSpringBootITest {
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package dev.vality.disputes.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Value("${wiremock.server.port}")
|
||||
public @interface WiremockServerPort {
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package dev.vality.disputes.dao;
|
||||
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.domain.tables.pojos.Dispute;
|
||||
import dev.vality.disputes.exception.NotFoundException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -21,6 +22,7 @@ public abstract class DisputeDaoTest {
|
||||
@Test
|
||||
public void testInsertAndFind() {
|
||||
var random = random(Dispute.class);
|
||||
random.setStatus(DisputeStatus.failed);
|
||||
disputeDao.save(random);
|
||||
assertEquals(random,
|
||||
disputeDao.get(random.getId(), random.getInvoiceId(), random.getPaymentId()));
|
||||
@ -38,6 +40,7 @@ public abstract class DisputeDaoTest {
|
||||
random.setId(null);
|
||||
random.setInvoiceId("setInvoiceId");
|
||||
random.setPaymentId("setPaymentId");
|
||||
random.setStatus(DisputeStatus.failed);
|
||||
disputeDao.save(random);
|
||||
disputeDao.save(random);
|
||||
disputeDao.save(random);
|
||||
@ -48,6 +51,7 @@ public abstract class DisputeDaoTest {
|
||||
@Test
|
||||
public void testNextCheckAfter() {
|
||||
var random = random(Dispute.class);
|
||||
random.setStatus(DisputeStatus.already_exist_created);
|
||||
var createdAt = LocalDateTime.now(ZoneOffset.UTC);
|
||||
random.setCreatedAt(createdAt);
|
||||
random.setPollingBefore(createdAt.plusSeconds(10));
|
||||
@ -56,5 +60,24 @@ public abstract class DisputeDaoTest {
|
||||
assertTrue(disputeDao.getDisputesForUpdateSkipLocked(10, random.getStatus()).isEmpty());
|
||||
disputeDao.update(random.getId(), random.getStatus(), createdAt.plusSeconds(0));
|
||||
assertFalse(disputeDao.getDisputesForUpdateSkipLocked(10, random.getStatus()).isEmpty());
|
||||
disputeDao.update(random.getId(), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDisputesForHgCall() {
|
||||
var random = random(Dispute.class);
|
||||
random.setId(null);
|
||||
random.setInvoiceId("setInvoiceId");
|
||||
random.setPaymentId("setPaymentId");
|
||||
random.setSkipCallHgForCreateAdjustment(true);
|
||||
random.setStatus(DisputeStatus.create_adjustment);
|
||||
disputeDao.save(random);
|
||||
disputeDao.save(random);
|
||||
random.setSkipCallHgForCreateAdjustment(false);
|
||||
disputeDao.save(random);
|
||||
assertEquals(1, disputeDao.getDisputesForHgCall(10).size());
|
||||
for (var dispute : disputeDao.get("setInvoiceId", "setPaymentId")) {
|
||||
disputeDao.update(dispute.getId(), DisputeStatus.failed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
src/test/java/dev/vality/disputes/dao/FileMetaDaoTest.java
Normal file
28
src/test/java/dev/vality/disputes/dao/FileMetaDaoTest.java
Normal file
@ -0,0 +1,28 @@
|
||||
package dev.vality.disputes.dao;
|
||||
|
||||
import dev.vality.disputes.config.PostgresqlSpringBootITest;
|
||||
import dev.vality.disputes.domain.tables.pojos.FileMeta;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static dev.vality.testcontainers.annotations.util.RandomBeans.random;
|
||||
import static dev.vality.testcontainers.annotations.util.ValuesGenerator.generateId;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@PostgresqlSpringBootITest
|
||||
public class FileMetaDaoTest {
|
||||
|
||||
@Autowired
|
||||
private FileMetaDao fileMetaDao;
|
||||
|
||||
@Test
|
||||
public void testInsertAndFind() {
|
||||
var random = random(FileMeta.class);
|
||||
random.setFileId(generateId());
|
||||
random.setDisputeId(1L);
|
||||
fileMetaDao.save(random);
|
||||
random.setFileId(generateId());
|
||||
fileMetaDao.save(random);
|
||||
assertEquals(2, fileMetaDao.getDisputeFiles(1L).size());
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package dev.vality.disputes.dao;
|
||||
|
||||
import dev.vality.disputes.config.PostgresqlSpringBootITest;
|
||||
import dev.vality.disputes.domain.tables.pojos.ProviderDispute;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static dev.vality.testcontainers.annotations.util.RandomBeans.random;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@PostgresqlSpringBootITest
|
||||
public class ProviderDisputeDaoTest {
|
||||
|
||||
@Autowired
|
||||
private ProviderDisputeDao providerDisputeDao;
|
||||
|
||||
@Test
|
||||
public void testInsertAndFind() {
|
||||
var random = random(ProviderDispute.class);
|
||||
providerDisputeDao.save(random);
|
||||
assertEquals(random, providerDisputeDao.get(random.getDisputeId()));
|
||||
}
|
||||
}
|
@ -2,7 +2,9 @@ package dev.vality.disputes.dao.disputestartup;
|
||||
|
||||
import dev.vality.disputes.config.EmbeddedPostgresWithFlywaySpringBootITest;
|
||||
import dev.vality.disputes.dao.DisputeDaoTest;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
@Disabled
|
||||
@EmbeddedPostgresWithFlywaySpringBootITest
|
||||
public class WithEmbeddedPostgresWithFlywayDisputeDaoTest extends DisputeDaoTest {
|
||||
}
|
||||
|
@ -2,7 +2,9 @@ package dev.vality.disputes.dao.disputestartup;
|
||||
|
||||
import dev.vality.disputes.config.ZonkyEmbeddedPostgresSpringBootITest;
|
||||
import dev.vality.disputes.dao.DisputeDaoTest;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
@Disabled
|
||||
@ZonkyEmbeddedPostgresSpringBootITest
|
||||
public class WithZonkyEmbeddedPostgresDisputeDaoTest extends DisputeDaoTest {
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ public class DebugManualParsingControllerTest {
|
||||
|
||||
@MockBean
|
||||
private ManualParsingServiceSrv.Iface manualParsingHandler;
|
||||
|
||||
@Autowired
|
||||
private DebugManualParsingController debugManualParsingController;
|
||||
|
||||
|
@ -0,0 +1,139 @@
|
||||
package dev.vality.disputes.manualparsing;
|
||||
|
||||
import dev.vality.disputes.config.WireMockSpringBootITest;
|
||||
import dev.vality.disputes.dao.DisputeDao;
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.schedule.service.config.CreatedDisputesTestService;
|
||||
import dev.vality.disputes.schedule.service.config.DisputeApiTestService;
|
||||
import dev.vality.disputes.schedule.service.config.PendingDisputesTestService;
|
||||
import dev.vality.disputes.util.WiremockUtils;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static dev.vality.disputes.util.OpenApiUtil.*;
|
||||
import static dev.vality.testcontainers.annotations.util.ValuesGenerator.generateId;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@WireMockSpringBootITest
|
||||
@Import({PendingDisputesTestService.class})
|
||||
public class DebugManualParsingHandlerTest {
|
||||
|
||||
@Autowired
|
||||
private DisputeDao disputeDao;
|
||||
@Autowired
|
||||
private DisputeApiTestService disputeApiTestService;
|
||||
@Autowired
|
||||
private CreatedDisputesTestService createdDisputesTestService;
|
||||
@Autowired
|
||||
private PendingDisputesTestService pendingDisputesTestService;
|
||||
@Autowired
|
||||
private DebugManualParsingController debugManualParsingController;
|
||||
|
||||
@Test
|
||||
public void testCancelCreateAdjustment() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
debugManualParsingController.cancelPending(getCancelRequest(disputeId));
|
||||
assertEquals(DisputeStatus.cancelled, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelPending() {
|
||||
var disputeId = createdDisputesTestService.callCreateDisputeRemotely();
|
||||
debugManualParsingController.cancelPending(getCancelRequest(disputeId));
|
||||
assertEquals(DisputeStatus.cancelled, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelFailed() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
debugManualParsingController.cancelPending(getCancelRequest(disputeId));
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApproveCreateAdjustmentWithCallHg() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
debugManualParsingController.approvePending(getApproveRequest(disputeId, false));
|
||||
assertEquals(DisputeStatus.create_adjustment, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApproveCreateAdjustmentWithSkipHg() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
debugManualParsingController.approvePending(getApproveRequest(disputeId, true));
|
||||
assertEquals(DisputeStatus.succeeded, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApprovePendingWithSkipHg() {
|
||||
var disputeId = createdDisputesTestService.callCreateDisputeRemotely();
|
||||
debugManualParsingController.approvePending(getApproveRequest(disputeId, true));
|
||||
assertEquals(DisputeStatus.succeeded, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApproveFailed() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
debugManualParsingController.approvePending(getApproveRequest(disputeId, true));
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindCreatedCreateAdjustment() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
var providerDisputeId = generateId();
|
||||
debugManualParsingController.bindCreated(getBindCreatedRequest(disputeId, providerDisputeId));
|
||||
assertEquals(DisputeStatus.create_adjustment, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindCreatedPending() {
|
||||
var disputeId = createdDisputesTestService.callCreateDisputeRemotely();
|
||||
var providerDisputeId = generateId();
|
||||
debugManualParsingController.bindCreated(getBindCreatedRequest(disputeId, providerDisputeId));
|
||||
assertEquals(DisputeStatus.pending, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindCreatedManualCreated() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var providerDisputeId = generateId();
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.manual_created);
|
||||
debugManualParsingController.bindCreated(getBindCreatedRequest(disputeId, providerDisputeId));
|
||||
assertEquals(DisputeStatus.manual_pending, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindCreatedAlreadyExist() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var providerDisputeId = generateId();
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.already_exist_created);
|
||||
debugManualParsingController.bindCreated(getBindCreatedRequest(disputeId, providerDisputeId));
|
||||
assertEquals(DisputeStatus.pending, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testGetDispute() {
|
||||
WiremockUtils.mockS3AttachmentDownload();
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
var disputes = debugManualParsingController.getDisputes(getGetDisputeRequest(disputeId, true));
|
||||
assertEquals(1, disputes.getDisputes().size());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package dev.vality.disputes.schedule.service;
|
||||
|
||||
import dev.vality.damsel.domain.InvoicePaymentCaptured;
|
||||
import dev.vality.damsel.domain.InvoicePaymentStatus;
|
||||
import dev.vality.damsel.payment_processing.InvoicingSrv;
|
||||
import dev.vality.disputes.config.WireMockSpringBootITest;
|
||||
import dev.vality.disputes.constant.ErrorReason;
|
||||
import dev.vality.disputes.dao.DisputeDao;
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.schedule.converter.InvoicePaymentAdjustmentParamsConverter;
|
||||
import dev.vality.disputes.schedule.service.config.DisputeApiTestService;
|
||||
import dev.vality.disputes.schedule.service.config.PendingDisputesTestService;
|
||||
import dev.vality.disputes.util.MockUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static dev.vality.disputes.util.MockUtil.getInvoicePaymentAdjustment;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@WireMockSpringBootITest
|
||||
@Import({PendingDisputesTestService.class})
|
||||
@SuppressWarnings({"ParameterName", "LineLength"})
|
||||
public class CreateAdjustmentsServiceTest {
|
||||
|
||||
@Autowired
|
||||
private InvoicingSrv.Iface invoicingClient;
|
||||
@Autowired
|
||||
private DisputeDao disputeDao;
|
||||
@Autowired
|
||||
private CreateAdjustmentsService createAdjustmentsService;
|
||||
@Autowired
|
||||
private DisputeApiTestService disputeApiTestService;
|
||||
@Autowired
|
||||
private PendingDisputesTestService pendingDisputesTestService;
|
||||
@Autowired
|
||||
private InvoicePaymentAdjustmentParamsConverter invoicePaymentAdjustmentParamsConverter;
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testPaymentNotFound() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.create_adjustment);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createAdjustmentsService.callHgForCreateAdjustment(dispute.get());
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
assertEquals(ErrorReason.PAYMENT_NOT_FOUND, disputeDao.get(Long.parseLong(disputeId)).get().getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testDisputesAdjustmentExist() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.create_adjustment);
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
dispute.get().setReason("test adj");
|
||||
var adjustmentId = "adjustmentId";
|
||||
var invoicePaymentAdjustment = getInvoicePaymentAdjustment(adjustmentId, invoicePaymentAdjustmentParamsConverter.getReason(dispute.get()));
|
||||
invoicePayment.setAdjustments(List.of(invoicePaymentAdjustment));
|
||||
when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment);
|
||||
createAdjustmentsService.callHgForCreateAdjustment(dispute.get());
|
||||
assertEquals(DisputeStatus.succeeded, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testInvoiceNotFound() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
var paymentId = "1";
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createAdjustmentsService.callHgForCreateAdjustment(dispute.get());
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
assertEquals(ErrorReason.INVOICE_NOT_FOUND, disputeDao.get(Long.parseLong(disputeId)).get().getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testFullSuccessFlow() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
var paymentId = "1";
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
dispute.get().setReason("test adj");
|
||||
var adjustmentId = "adjustmentId";
|
||||
var reason = invoicePaymentAdjustmentParamsConverter.getReason(dispute.get());
|
||||
when(invoicingClient.createPaymentAdjustment(any(), any(), any()))
|
||||
.thenReturn(getInvoicePaymentAdjustment(adjustmentId, reason));
|
||||
createAdjustmentsService.callHgForCreateAdjustment(dispute.get());
|
||||
assertEquals(DisputeStatus.succeeded, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package dev.vality.disputes.schedule.service;
|
||||
|
||||
import dev.vality.damsel.domain.InvoicePaymentCaptured;
|
||||
import dev.vality.damsel.domain.InvoicePaymentStatus;
|
||||
import dev.vality.damsel.payment_processing.InvoicingSrv;
|
||||
import dev.vality.disputes.ProviderDisputesServiceSrv;
|
||||
import dev.vality.disputes.config.WireMockSpringBootITest;
|
||||
import dev.vality.disputes.constant.ErrorReason;
|
||||
import dev.vality.disputes.dao.DisputeDao;
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.schedule.service.config.CreatedDisputesTestService;
|
||||
import dev.vality.disputes.schedule.service.config.DisputeApiTestService;
|
||||
import dev.vality.disputes.schedule.service.config.WiremockAddressesHolder;
|
||||
import dev.vality.disputes.service.external.DominantService;
|
||||
import dev.vality.disputes.util.MockUtil;
|
||||
import dev.vality.file.storage.FileStorageSrv;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static dev.vality.disputes.util.MockUtil.*;
|
||||
import static dev.vality.testcontainers.annotations.util.ValuesGenerator.generateId;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@WireMockSpringBootITest
|
||||
@Import({CreatedDisputesTestService.class})
|
||||
public class CreatedDisputesServiceTest {
|
||||
|
||||
@Autowired
|
||||
private ProviderIfaceBuilder providerIfaceBuilder;
|
||||
@Autowired
|
||||
private DominantService dominantService;
|
||||
@Autowired
|
||||
private InvoicingSrv.Iface invoicingClient;
|
||||
@Autowired
|
||||
private FileStorageSrv.Iface fileStorageClient;
|
||||
@Autowired
|
||||
private DisputeDao disputeDao;
|
||||
@Autowired
|
||||
private CreatedDisputesService createdDisputesService;
|
||||
@Autowired
|
||||
private DisputeApiTestService disputeApiTestService;
|
||||
@Autowired
|
||||
private WiremockAddressesHolder wiremockAddressesHolder;
|
||||
@Autowired
|
||||
private CreatedDisputesTestService createdDisputesTestService;
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testPaymentNotFound() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createdDisputesService.callCreateDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
assertEquals(ErrorReason.PAYMENT_NOT_FOUND, disputeDao.get(Long.parseLong(disputeId)).get().getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testSkipDisputeWhenPaymentNonFinalStatus() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
when(invoicingClient.getPayment(any(), any())).thenReturn(MockUtil.createInvoicePayment(paymentId));
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createdDisputesService.callCreateDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.created, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testNoAttachments() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createdDisputesService.callCreateDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
assertEquals(ErrorReason.NO_ATTACHMENTS, disputeDao.get(Long.parseLong(disputeId)).get().getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testManualCreatedWhenIsNotProvidersDisputesApiExist() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment);
|
||||
when(fileStorageClient.generateDownloadUrl(any(), any())).thenReturn(wiremockAddressesHolder.getDownloadUrl());
|
||||
when(dominantService.getTerminal(any())).thenReturn(createTerminal().get());
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createdDisputesService.callCreateDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.manual_created, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisputeCreatedSuccessResult() {
|
||||
var disputeId = createdDisputesTestService.callCreateDisputeRemotely();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testDisputeCreatedFailResult() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var providerDisputeId = generateId();
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment);
|
||||
when(fileStorageClient.generateDownloadUrl(any(), any())).thenReturn(wiremockAddressesHolder.getDownloadUrl());
|
||||
var terminal = createTerminal().get();
|
||||
terminal.getOptions().putAll(getOptions());
|
||||
when(dominantService.getTerminal(any())).thenReturn(terminal);
|
||||
when(dominantService.getProvider(any())).thenReturn(createProvider().get());
|
||||
when(dominantService.getProxy(any())).thenReturn(createProxy().get());
|
||||
var providerMock = mock(ProviderDisputesServiceSrv.Client.class);
|
||||
when(providerMock.createDispute(any())).thenReturn(createDisputeCreatedFailResult());
|
||||
when(providerIfaceBuilder.buildTHSpawnClient(any(), any())).thenReturn(providerMock);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createdDisputesService.callCreateDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testDisputeCreatedAlreadyExistResult() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var providerDisputeId = generateId();
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment);
|
||||
when(fileStorageClient.generateDownloadUrl(any(), any())).thenReturn(wiremockAddressesHolder.getDownloadUrl());
|
||||
var terminal = createTerminal().get();
|
||||
terminal.getOptions().putAll(getOptions());
|
||||
when(dominantService.getTerminal(any())).thenReturn(terminal);
|
||||
when(dominantService.getProvider(any())).thenReturn(createProvider().get());
|
||||
when(dominantService.getProxy(any())).thenReturn(createProxy().get());
|
||||
var providerMock = mock(ProviderDisputesServiceSrv.Client.class);
|
||||
when(providerMock.createDispute(any())).thenReturn(createDisputeAlreadyExistResult());
|
||||
when(providerIfaceBuilder.buildTHSpawnClient(any(), any())).thenReturn(providerMock);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createdDisputesService.callCreateDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.already_exist_created, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package dev.vality.disputes.schedule.service;
|
||||
|
||||
import dev.vality.disputes.ProviderDisputesServiceSrv;
|
||||
import dev.vality.disputes.config.WireMockSpringBootITest;
|
||||
import dev.vality.disputes.dao.DisputeDao;
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.schedule.service.config.CreatedDisputesTestService;
|
||||
import dev.vality.disputes.schedule.service.config.DisputeApiTestService;
|
||||
import dev.vality.disputes.schedule.service.config.PendingDisputesTestService;
|
||||
import dev.vality.disputes.service.external.DominantService;
|
||||
import lombok.SneakyThrows;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static dev.vality.disputes.util.MockUtil.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@WireMockSpringBootITest
|
||||
@Import({PendingDisputesTestService.class})
|
||||
public class PendingDisputesServiceTest {
|
||||
|
||||
@Autowired
|
||||
private ProviderIfaceBuilder providerIfaceBuilder;
|
||||
@Autowired
|
||||
private DominantService dominantService;
|
||||
@Autowired
|
||||
private DisputeDao disputeDao;
|
||||
@Autowired
|
||||
private PendingDisputesService pendingDisputesService;
|
||||
@Autowired
|
||||
private DisputeApiTestService disputeApiTestService;
|
||||
@Autowired
|
||||
private CreatedDisputesTestService createdDisputesTestService;
|
||||
@Autowired
|
||||
private PendingDisputesTestService pendingDisputesTestService;
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testProviderDisputeNotFound() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.pending);
|
||||
var terminal = createTerminal().get();
|
||||
terminal.getOptions().putAll(getOptions());
|
||||
when(dominantService.getTerminal(any())).thenReturn(terminal);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
pendingDisputesService.callPendingDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.created, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testDisputeStatusSuccessResult() {
|
||||
var disputeId = pendingDisputesTestService.callPendingDisputeRemotely();
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testDisputeStatusFailResult() {
|
||||
var disputeId = createdDisputesTestService.callCreateDisputeRemotely();
|
||||
var providerMock = mock(ProviderDisputesServiceSrv.Client.class);
|
||||
when(providerMock.checkDisputeStatus(any())).thenReturn(createDisputeStatusFailResult());
|
||||
when(providerIfaceBuilder.buildTHSpawnClient(any(), any())).thenReturn(providerMock);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
pendingDisputesService.callPendingDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.failed, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testDisputeStatusPendingResult() {
|
||||
var disputeId = createdDisputesTestService.callCreateDisputeRemotely();
|
||||
var providerMock = mock(ProviderDisputesServiceSrv.Client.class);
|
||||
when(providerMock.checkDisputeStatus(any())).thenReturn(createDisputeStatusPendingResult());
|
||||
when(providerIfaceBuilder.buildTHSpawnClient(any(), any())).thenReturn(providerMock);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
pendingDisputesService.callPendingDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.pending, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
disputeDao.update(Long.parseLong(disputeId), DisputeStatus.failed);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package dev.vality.disputes.schedule.service.config;
|
||||
|
||||
import dev.vality.damsel.domain.InvoicePaymentCaptured;
|
||||
import dev.vality.damsel.domain.InvoicePaymentStatus;
|
||||
import dev.vality.damsel.payment_processing.InvoicingSrv;
|
||||
import dev.vality.disputes.ProviderDisputesServiceSrv;
|
||||
import dev.vality.disputes.dao.DisputeDao;
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.schedule.service.CreatedDisputesService;
|
||||
import dev.vality.disputes.schedule.service.ProviderIfaceBuilder;
|
||||
import dev.vality.disputes.service.external.DominantService;
|
||||
import dev.vality.disputes.util.MockUtil;
|
||||
import dev.vality.disputes.util.TestUrlPaths;
|
||||
import dev.vality.file.storage.FileStorageSrv;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.TestComponent;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static dev.vality.disputes.util.MockUtil.*;
|
||||
import static dev.vality.testcontainers.annotations.util.ValuesGenerator.generateId;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@TestComponent
|
||||
@Import({DisputeApiTestService.class, RemoteClientTestConfig.class})
|
||||
@SuppressWarnings({"ParameterName", "LineLength"})
|
||||
public class CreatedDisputesTestService {
|
||||
|
||||
@Autowired
|
||||
private ProviderIfaceBuilder providerIfaceBuilder;
|
||||
@Autowired
|
||||
private DominantService dominantService;
|
||||
@Autowired
|
||||
private InvoicingSrv.Iface invoicingClient;
|
||||
@Autowired
|
||||
private FileStorageSrv.Iface fileStorageClient;
|
||||
@Autowired
|
||||
private DisputeDao disputeDao;
|
||||
@Autowired
|
||||
private CreatedDisputesService createdDisputesService;
|
||||
@Autowired
|
||||
private DisputeApiTestService disputeApiTestService;
|
||||
@Autowired
|
||||
private WiremockAddressesHolder wiremockAddressesHolder;
|
||||
|
||||
@SneakyThrows
|
||||
public String callCreateDisputeRemotely() {
|
||||
var invoiceId = "20McecNnWoy";
|
||||
var paymentId = "1";
|
||||
var providerDisputeId = generateId();
|
||||
var disputeId = disputeApiTestService.createDisputeViaApi(invoiceId, paymentId).getDisputeId();
|
||||
var invoicePayment = MockUtil.createInvoicePayment(paymentId);
|
||||
invoicePayment.getPayment().setStatus(InvoicePaymentStatus.captured(new InvoicePaymentCaptured()));
|
||||
when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment);
|
||||
when(fileStorageClient.generateDownloadUrl(any(), any())).thenReturn(wiremockAddressesHolder.getDownloadUrl());
|
||||
var terminal = createTerminal().get();
|
||||
terminal.getOptions().putAll(getOptions());
|
||||
when(dominantService.getTerminal(any())).thenReturn(terminal);
|
||||
when(dominantService.getProvider(any())).thenReturn(createProvider().get());
|
||||
when(dominantService.getProxy(any())).thenReturn(createProxy(String.format("http://127.0.0.1:%s%s", 8023, TestUrlPaths.ADAPTER)).get());
|
||||
var providerMock = mock(ProviderDisputesServiceSrv.Client.class);
|
||||
when(providerMock.createDispute(any())).thenReturn(createDisputeCreatedSuccessResult(providerDisputeId));
|
||||
when(providerIfaceBuilder.buildTHSpawnClient(any(), any())).thenReturn(providerMock);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
createdDisputesService.callCreateDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.pending, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
return disputeId;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package dev.vality.disputes.schedule.service.config;
|
||||
|
||||
import dev.vality.bouncer.decisions.ArbiterSrv;
|
||||
import dev.vality.damsel.payment_processing.InvoicingSrv;
|
||||
import dev.vality.disputes.service.external.impl.dominant.DominantAsyncService;
|
||||
import dev.vality.file.storage.FileStorageSrv;
|
||||
import dev.vality.token.keeper.TokenAuthenticatorSrv;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
@TestConfiguration
|
||||
public class DisputeApiTestConfig {
|
||||
|
||||
@MockBean
|
||||
private InvoicingSrv.Iface invoicingClient;
|
||||
@MockBean
|
||||
private TokenAuthenticatorSrv.Iface tokenKeeperClient;
|
||||
@MockBean
|
||||
private ArbiterSrv.Iface bouncerClient;
|
||||
@MockBean
|
||||
private DominantAsyncService dominantAsyncService;
|
||||
@MockBean
|
||||
private FileStorageSrv.Iface fileStorageClient;
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package dev.vality.disputes.schedule.service.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import dev.vality.bouncer.decisions.ArbiterSrv;
|
||||
import dev.vality.damsel.payment_processing.InvoicingSrv;
|
||||
import dev.vality.disputes.auth.utils.JwtTokenBuilder;
|
||||
import dev.vality.disputes.service.external.impl.dominant.DominantAsyncService;
|
||||
import dev.vality.disputes.util.MockUtil;
|
||||
import dev.vality.disputes.util.OpenApiUtil;
|
||||
import dev.vality.disputes.util.WiremockUtils;
|
||||
import dev.vality.file.storage.FileStorageSrv;
|
||||
import dev.vality.swag.disputes.model.Create200Response;
|
||||
import dev.vality.token.keeper.TokenAuthenticatorSrv;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.TestComponent;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static dev.vality.disputes.util.MockUtil.*;
|
||||
import static java.util.UUID.randomUUID;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@TestComponent
|
||||
@Import({DisputeApiTestConfig.class, WiremockAddressesHolder.class})
|
||||
@SuppressWarnings({"ParameterName", "LineLength"})
|
||||
public class DisputeApiTestService {
|
||||
|
||||
@Autowired
|
||||
private InvoicingSrv.Iface invoicingClient;
|
||||
@Autowired
|
||||
private TokenAuthenticatorSrv.Iface tokenKeeperClient;
|
||||
@Autowired
|
||||
private ArbiterSrv.Iface bouncerClient;
|
||||
@Autowired
|
||||
private DominantAsyncService dominantAsyncService;
|
||||
@Autowired
|
||||
private FileStorageSrv.Iface fileStorageClient;
|
||||
@Autowired
|
||||
private JwtTokenBuilder tokenBuilder;
|
||||
@Autowired
|
||||
private MockMvc mvc;
|
||||
@Autowired
|
||||
private WiremockAddressesHolder wiremockAddressesHolder;
|
||||
|
||||
@SneakyThrows
|
||||
public Create200Response createDisputeViaApi(String invoiceId, String paymentId) {
|
||||
when(invoicingClient.get(any(), any())).thenReturn(MockUtil.createInvoice(invoiceId, paymentId));
|
||||
when(tokenKeeperClient.authenticate(any(), any())).thenReturn(createAuthData());
|
||||
when(bouncerClient.judge(any(), any())).thenReturn(createJudgementAllowed());
|
||||
when(dominantAsyncService.getTerminal(any())).thenReturn(createTerminal());
|
||||
when(dominantAsyncService.getCurrency(any())).thenReturn(createCurrency());
|
||||
when(fileStorageClient.createNewFile(any(), any())).thenReturn(createNewFileResult(wiremockAddressesHolder.getUploadUrl()));
|
||||
WiremockUtils.mockS3AttachmentUpload();
|
||||
var resultActions = mvc.perform(post("/disputes/create")
|
||||
.header("Authorization", "Bearer " + tokenBuilder.generateJwtWithRoles())
|
||||
.header("X-Request-ID", randomUUID())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(OpenApiUtil.getContentCreateRequest(invoiceId, paymentId)))
|
||||
.andExpect(status().is2xxSuccessful())
|
||||
.andExpect(jsonPath("$.disputeId").isNotEmpty());
|
||||
return new ObjectMapper().readValue(resultActions.andReturn().getResponse().getContentAsString(), Create200Response.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package dev.vality.disputes.schedule.service.config;
|
||||
|
||||
import dev.vality.disputes.ProviderDisputesServiceSrv;
|
||||
import dev.vality.disputes.dao.DisputeDao;
|
||||
import dev.vality.disputes.domain.enums.DisputeStatus;
|
||||
import dev.vality.disputes.schedule.service.PendingDisputesService;
|
||||
import dev.vality.disputes.schedule.service.ProviderIfaceBuilder;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.TestComponent;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static dev.vality.disputes.util.MockUtil.createDisputeStatusSuccessResult;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@TestComponent
|
||||
@Import({CreatedDisputesTestService.class})
|
||||
@SuppressWarnings({"ParameterName", "LineLength"})
|
||||
public class PendingDisputesTestService {
|
||||
|
||||
@Autowired
|
||||
private ProviderIfaceBuilder providerIfaceBuilder;
|
||||
@Autowired
|
||||
private DisputeDao disputeDao;
|
||||
@Autowired
|
||||
private PendingDisputesService pendingDisputesService;
|
||||
@Autowired
|
||||
private CreatedDisputesTestService createdDisputesTestService;
|
||||
|
||||
@SneakyThrows
|
||||
public String callPendingDisputeRemotely() {
|
||||
var disputeId = createdDisputesTestService.callCreateDisputeRemotely();
|
||||
var providerMock = mock(ProviderDisputesServiceSrv.Client.class);
|
||||
when(providerMock.checkDisputeStatus(any())).thenReturn(createDisputeStatusSuccessResult());
|
||||
when(providerIfaceBuilder.buildTHSpawnClient(any(), any())).thenReturn(providerMock);
|
||||
var dispute = disputeDao.get(Long.parseLong(disputeId));
|
||||
pendingDisputesService.callPendingDisputeRemotely(dispute.get());
|
||||
assertEquals(DisputeStatus.create_adjustment, disputeDao.get(Long.parseLong(disputeId)).get().getStatus());
|
||||
return disputeId;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package dev.vality.disputes.schedule.service.config;
|
||||
|
||||
import dev.vality.disputes.schedule.service.ProviderIfaceBuilder;
|
||||
import dev.vality.disputes.service.external.DominantService;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
|
||||
@TestConfiguration
|
||||
public class RemoteClientTestConfig {
|
||||
|
||||
@MockBean
|
||||
private ProviderIfaceBuilder providerIfaceBuilder;
|
||||
@MockBean
|
||||
private DominantService dominantService;
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package dev.vality.disputes.schedule.service.config;
|
||||
|
||||
import dev.vality.disputes.config.WiremockServerPort;
|
||||
import dev.vality.disputes.util.TestUrlPaths;
|
||||
import org.springframework.boot.test.context.TestComponent;
|
||||
|
||||
@TestComponent
|
||||
public class WiremockAddressesHolder {
|
||||
|
||||
@WiremockServerPort
|
||||
private int wiremockPort;
|
||||
|
||||
public String getDownloadUrl() {
|
||||
return String.format("http://127.0.0.1:%s%s%s", wiremockPort, TestUrlPaths.S3_PATH, TestUrlPaths.MOCK_DOWNLOAD);
|
||||
}
|
||||
|
||||
public String getUploadUrl() {
|
||||
return String.format("http://127.0.0.1:%s%s%s", wiremockPort, TestUrlPaths.S3_PATH, TestUrlPaths.MOCK_UPLOAD);
|
||||
}
|
||||
}
|
33
src/test/java/dev/vality/disputes/util/DamselUtil.java
Normal file
33
src/test/java/dev/vality/disputes/util/DamselUtil.java
Normal file
@ -0,0 +1,33 @@
|
||||
package dev.vality.disputes.util;
|
||||
|
||||
import dev.vality.geck.serializer.kit.mock.FieldHandler;
|
||||
import dev.vality.geck.serializer.kit.mock.MockMode;
|
||||
import dev.vality.geck.serializer.kit.mock.MockTBaseProcessor;
|
||||
import dev.vality.geck.serializer.kit.tbase.TBaseHandler;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.thrift.TBase;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
|
||||
@UtilityClass
|
||||
public class DamselUtil {
|
||||
|
||||
private static final MockTBaseProcessor mockRequiredTBaseProcessor;
|
||||
|
||||
static {
|
||||
mockRequiredTBaseProcessor = new MockTBaseProcessor(MockMode.REQUIRED_ONLY, 15, 1);
|
||||
Map.Entry<FieldHandler, String[]> timeFields = Map.entry(
|
||||
structHandler -> structHandler.value(Instant.now().toString()),
|
||||
new String[]{"created_at", "at", "due", "status_changed_at", "invoice_valid_until", "event_created_at",
|
||||
"held_until", "from_time", "to_time"}
|
||||
);
|
||||
mockRequiredTBaseProcessor.addFieldHandler(timeFields.getKey(), timeFields.getValue());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static <T extends TBase> T fillRequiredTBaseObject(T tbase, Class<T> type) {
|
||||
return DamselUtil.mockRequiredTBaseProcessor.process(tbase, new TBaseHandler<>(type));
|
||||
}
|
||||
}
|
169
src/test/java/dev/vality/disputes/util/MockUtil.java
Normal file
169
src/test/java/dev/vality/disputes/util/MockUtil.java
Normal file
@ -0,0 +1,169 @@
|
||||
package dev.vality.disputes.util;
|
||||
|
||||
import dev.vality.bouncer.ctx.ContextFragment;
|
||||
import dev.vality.bouncer.decisions.Judgement;
|
||||
import dev.vality.bouncer.decisions.Resolution;
|
||||
import dev.vality.bouncer.decisions.ResolutionAllowed;
|
||||
import dev.vality.damsel.domain.Cash;
|
||||
import dev.vality.damsel.domain.*;
|
||||
import dev.vality.damsel.payment_processing.Invoice;
|
||||
import dev.vality.damsel.payment_processing.InvoicePayment;
|
||||
import dev.vality.disputes.*;
|
||||
import dev.vality.disputes.constant.TerminalOptionsField;
|
||||
import dev.vality.file.storage.NewFileResult;
|
||||
import dev.vality.geck.common.util.TypeUtil;
|
||||
import dev.vality.token.keeper.AuthData;
|
||||
import dev.vality.token.keeper.AuthDataStatus;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.thrift.TSerializer;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@UtilityClass
|
||||
public class MockUtil {
|
||||
|
||||
public static Invoice createInvoice(String invoiceId, String paymentId) {
|
||||
return new Invoice()
|
||||
.setInvoice(new dev.vality.damsel.domain.Invoice()
|
||||
.setId(invoiceId)
|
||||
.setCreatedAt(TypeUtil.temporalToString(LocalDateTime.now()))
|
||||
.setDue(TypeUtil.temporalToString(LocalDateTime.now().plusDays(1)))
|
||||
.setDetails(new InvoiceDetails()
|
||||
.setProduct("test_product"))
|
||||
.setCost(new Cash().setCurrency(new CurrencyRef().setSymbolicCode("RUB"))))
|
||||
.setPayments(List.of(createInvoicePayment(paymentId)));
|
||||
}
|
||||
|
||||
public static InvoicePayment createInvoicePayment(String paymentId) {
|
||||
return new InvoicePayment()
|
||||
.setPayment(new dev.vality.damsel.domain.InvoicePayment()
|
||||
.setId(paymentId)
|
||||
.setCreatedAt(TypeUtil.temporalToString(LocalDateTime.now()))
|
||||
.setPayer(Payer.payment_resource(new PaymentResourcePayer()
|
||||
.setContactInfo(DamselUtil.fillRequiredTBaseObject(new ContactInfo(),
|
||||
ContactInfo.class))
|
||||
.setResource(new DisposablePaymentResource()
|
||||
.setPaymentTool(
|
||||
PaymentTool.bank_card(DamselUtil.fillRequiredTBaseObject(new BankCard(),
|
||||
BankCard.class))))))
|
||||
.setCost(new Cash()
|
||||
.setCurrency(new CurrencyRef().setSymbolicCode("RUB")))
|
||||
.setStatus(InvoicePaymentStatus.pending(new InvoicePaymentPending())))
|
||||
.setRoute(new PaymentRoute()
|
||||
.setProvider(DamselUtil.fillRequiredTBaseObject(new ProviderRef(), ProviderRef.class))
|
||||
.setTerminal(DamselUtil.fillRequiredTBaseObject(new TerminalRef(), TerminalRef.class)))
|
||||
.setLastTransactionInfo(new TransactionInfo("trxId", Map.of()));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static ContextFragment createContextFragment() {
|
||||
ContextFragment fragment = DamselUtil.fillRequiredTBaseObject(new ContextFragment(), ContextFragment.class);
|
||||
fragment.setContent(new TSerializer().serialize(new dev.vality.bouncer.context.v1.ContextFragment()));
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public static Judgement createJudgementAllowed() {
|
||||
Resolution resolution = new Resolution();
|
||||
resolution.setAllowed(new ResolutionAllowed());
|
||||
return new Judgement().setResolution(resolution);
|
||||
}
|
||||
|
||||
public static CompletableFuture<Provider> createProvider() {
|
||||
return CompletableFuture.completedFuture(new Provider()
|
||||
.setName("propropro")
|
||||
.setDescription("pepepepe")
|
||||
.setProxy(new Proxy().setRef(new ProxyRef().setId(1))));
|
||||
}
|
||||
|
||||
public static CompletableFuture<ProxyDefinition> createProxy() {
|
||||
return createProxy("http://ya.ru");
|
||||
}
|
||||
|
||||
public static CompletableFuture<ProxyDefinition> createProxy(String url) {
|
||||
return CompletableFuture.completedFuture(new ProxyDefinition()
|
||||
.setName("prprpr")
|
||||
.setDescription("pepepepe")
|
||||
.setUrl(url));
|
||||
}
|
||||
|
||||
public static CompletableFuture<Terminal> createTerminal() {
|
||||
return CompletableFuture.completedFuture(new Terminal()
|
||||
.setName("prprpr")
|
||||
.setDescription("pepepepe")
|
||||
.setOptions(new HashMap<>()));
|
||||
}
|
||||
|
||||
public static Map<String, String> getOptions() {
|
||||
Map<String, String> options = new HashMap<>();
|
||||
options.put(TerminalOptionsField.DISPUTE_FLOW_MAX_TIME_POLLING_MIN, "5");
|
||||
options.put(TerminalOptionsField.DISPUTE_FLOW_PROVIDERS_API_EXIST, "true");
|
||||
return options;
|
||||
}
|
||||
|
||||
public static CompletableFuture<Currency> createCurrency() {
|
||||
return CompletableFuture.completedFuture(new Currency()
|
||||
.setName("Ruble")
|
||||
.setSymbolicCode("RUB")
|
||||
.setExponent((short) 2)
|
||||
.setNumericCode((short) 643));
|
||||
}
|
||||
|
||||
public static AuthData createAuthData() {
|
||||
return new AuthData()
|
||||
.setId(UUID.randomUUID().toString())
|
||||
.setAuthority(UUID.randomUUID().toString())
|
||||
.setToken(UUID.randomUUID().toString())
|
||||
.setStatus(AuthDataStatus.active)
|
||||
.setContext(createContextFragment());
|
||||
}
|
||||
|
||||
public static NewFileResult createNewFileResult(String uploadUrl) {
|
||||
return new NewFileResult(UUID.randomUUID().toString(), uploadUrl);
|
||||
}
|
||||
|
||||
public static DisputeCreatedResult createDisputeCreatedSuccessResult(String providerDisputeId) {
|
||||
return DisputeCreatedResult.successResult(new DisputeCreatedSuccessResult(providerDisputeId));
|
||||
}
|
||||
|
||||
public static DisputeCreatedResult createDisputeCreatedFailResult() {
|
||||
return DisputeCreatedResult.failResult(new DisputeCreatedFailResult(createFailure()));
|
||||
}
|
||||
|
||||
public static DisputeCreatedResult createDisputeAlreadyExistResult() {
|
||||
return DisputeCreatedResult.alreadyExistResult(new DisputeAlreadyExistResult());
|
||||
}
|
||||
|
||||
public static DisputeStatusResult createDisputeStatusSuccessResult() {
|
||||
return DisputeStatusResult.statusSuccess(new DisputeStatusSuccessResult().setChangedAmount(100));
|
||||
}
|
||||
|
||||
public static DisputeStatusResult createDisputeStatusFailResult() {
|
||||
return DisputeStatusResult.statusFail(new DisputeStatusFailResult(createFailure()));
|
||||
}
|
||||
|
||||
public static DisputeStatusResult createDisputeStatusPendingResult() {
|
||||
return DisputeStatusResult.statusPending(new DisputeStatusPendingResult());
|
||||
}
|
||||
|
||||
public static InvoicePaymentAdjustment getInvoicePaymentAdjustment(String adjustmentId, String reason) {
|
||||
return new InvoicePaymentAdjustment()
|
||||
.setId(adjustmentId)
|
||||
.setState(InvoicePaymentAdjustmentState.status_change(new InvoicePaymentAdjustmentStatusChangeState()
|
||||
.setScenario(new InvoicePaymentAdjustmentStatusChange()
|
||||
.setTargetStatus(new InvoicePaymentStatus(InvoicePaymentStatus.captured(
|
||||
new InvoicePaymentCaptured()
|
||||
.setReason(reason)))))));
|
||||
}
|
||||
|
||||
public static Failure createFailure() {
|
||||
Failure failure = new Failure("some_error");
|
||||
failure.setSub(new SubFailure("some_suberror"));
|
||||
return failure;
|
||||
}
|
||||
}
|
103
src/test/java/dev/vality/disputes/util/OpenApiUtil.java
Normal file
103
src/test/java/dev/vality/disputes/util/OpenApiUtil.java
Normal file
File diff suppressed because one or more lines are too long
14
src/test/java/dev/vality/disputes/util/TestUrlPaths.java
Normal file
14
src/test/java/dev/vality/disputes/util/TestUrlPaths.java
Normal file
@ -0,0 +1,14 @@
|
||||
package dev.vality.disputes.util;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class TestUrlPaths {
|
||||
|
||||
public static final String S3_PATH = "/s3";
|
||||
public static final String MOCK_UPLOAD = "/mock/upload";
|
||||
public static final String MOCK_DOWNLOAD = "/mock/download";
|
||||
public static final String ADAPTER = "/adapter";
|
||||
|
||||
}
|
27
src/test/java/dev/vality/disputes/util/WiremockUtils.java
Normal file
27
src/test/java/dev/vality/disputes/util/WiremockUtils.java
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user